yg-team-cli 2.1.0 → 2.1.2
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/cli.js +146 -127
- package/dist/cli.js.map +1 -1
- package/dist/index.js +145 -126
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -416,6 +416,7 @@ var init_utils = __esm({
|
|
|
416
416
|
|
|
417
417
|
// src/lib/claude.ts
|
|
418
418
|
import { execa } from "execa";
|
|
419
|
+
import path3 from "path";
|
|
419
420
|
var ClaudeAI, claudeAI;
|
|
420
421
|
var init_claude = __esm({
|
|
421
422
|
"src/lib/claude.ts"() {
|
|
@@ -456,7 +457,7 @@ var init_claude = __esm({
|
|
|
456
457
|
async prompt(promptText, options) {
|
|
457
458
|
const spinner = logger.startLoading("\u6B63\u5728\u8C03\u7528 Claude...");
|
|
458
459
|
try {
|
|
459
|
-
|
|
460
|
+
let finalPrompt = promptText;
|
|
460
461
|
const validContextFiles = [];
|
|
461
462
|
if (options?.contextFiles && options.contextFiles.length > 0) {
|
|
462
463
|
for (const file of options.contextFiles) {
|
|
@@ -467,11 +468,29 @@ var init_claude = __esm({
|
|
|
467
468
|
logger.warn(`\u4E0A\u4E0B\u6587\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u5DF2\u8DF3\u8FC7: ${file}`);
|
|
468
469
|
}
|
|
469
470
|
}
|
|
470
|
-
|
|
471
|
-
|
|
471
|
+
if (validContextFiles.length > 0) {
|
|
472
|
+
const contextParts = [];
|
|
473
|
+
for (const file of validContextFiles) {
|
|
474
|
+
try {
|
|
475
|
+
const content = await FileUtils.read(file);
|
|
476
|
+
const fileName = path3.basename(file);
|
|
477
|
+
contextParts.push(`## Context from ${fileName}
|
|
478
|
+
|
|
479
|
+
${content}`);
|
|
480
|
+
} catch (error) {
|
|
481
|
+
logger.warn(`\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6 ${file}\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (contextParts.length > 0) {
|
|
485
|
+
finalPrompt = `${contextParts.join("\n\n---\n\n")}
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
${promptText}`;
|
|
490
|
+
}
|
|
472
491
|
}
|
|
473
492
|
}
|
|
474
|
-
args
|
|
493
|
+
const args = ["--no-confirm", "-p", finalPrompt];
|
|
475
494
|
const result = await execa("claude", args, {
|
|
476
495
|
stdio: this.verbose ? "inherit" : "pipe",
|
|
477
496
|
timeout: options?.timeout || 3e5,
|
|
@@ -743,9 +762,9 @@ ${projectContext}
|
|
|
743
762
|
|
|
744
763
|
// src/lib/template-version.ts
|
|
745
764
|
import { execa as execa2 } from "execa";
|
|
746
|
-
import
|
|
765
|
+
import path4 from "path";
|
|
747
766
|
function getConfigPath(projectPath) {
|
|
748
|
-
return
|
|
767
|
+
return path4.join(projectPath, ".team-cli", "template.json");
|
|
749
768
|
}
|
|
750
769
|
async function readTemplateConfig(projectPath) {
|
|
751
770
|
const configPath = getConfigPath(projectPath);
|
|
@@ -761,7 +780,7 @@ async function readTemplateConfig(projectPath) {
|
|
|
761
780
|
}
|
|
762
781
|
}
|
|
763
782
|
async function saveTemplateConfig(projectPath, config) {
|
|
764
|
-
const configDir =
|
|
783
|
+
const configDir = path4.join(projectPath, ".team-cli");
|
|
765
784
|
await FileUtils.ensureDir(configDir);
|
|
766
785
|
const configPath = getConfigPath(projectPath);
|
|
767
786
|
const content = JSON.stringify(config, null, 2);
|
|
@@ -876,7 +895,7 @@ __export(user_config_exports, {
|
|
|
876
895
|
UserConfigManager: () => UserConfigManager,
|
|
877
896
|
userConfigManager: () => userConfigManager
|
|
878
897
|
});
|
|
879
|
-
import
|
|
898
|
+
import path5 from "path";
|
|
880
899
|
import os from "os";
|
|
881
900
|
import crypto from "crypto";
|
|
882
901
|
var UserConfigManager, userConfigManager;
|
|
@@ -889,8 +908,8 @@ var init_user_config = __esm({
|
|
|
889
908
|
UserConfigManager = class {
|
|
890
909
|
configPath;
|
|
891
910
|
constructor() {
|
|
892
|
-
const configDir =
|
|
893
|
-
this.configPath =
|
|
911
|
+
const configDir = path5.join(os.homedir(), ".team-cli");
|
|
912
|
+
this.configPath = path5.join(configDir, "config.json");
|
|
894
913
|
}
|
|
895
914
|
/**
|
|
896
915
|
* 加载用户配置
|
|
@@ -917,7 +936,7 @@ var init_user_config = __esm({
|
|
|
917
936
|
*/
|
|
918
937
|
async save(config) {
|
|
919
938
|
try {
|
|
920
|
-
const configDir =
|
|
939
|
+
const configDir = path5.dirname(this.configPath);
|
|
921
940
|
await FileUtils.ensureDir(configDir);
|
|
922
941
|
const configToSave = { ...config };
|
|
923
942
|
if (configToSave.gitlab?.accessToken) {
|
|
@@ -1023,7 +1042,7 @@ var init_user_config = __esm({
|
|
|
1023
1042
|
* 获取配置目录
|
|
1024
1043
|
*/
|
|
1025
1044
|
getConfigDir() {
|
|
1026
|
-
return
|
|
1045
|
+
return path5.dirname(this.configPath);
|
|
1027
1046
|
}
|
|
1028
1047
|
/**
|
|
1029
1048
|
* 获取配置文件路径
|
|
@@ -1238,15 +1257,15 @@ var init_gitlab_api = __esm({
|
|
|
1238
1257
|
* 从 Git URL 中提取项目路径
|
|
1239
1258
|
*/
|
|
1240
1259
|
static parseProjectPath(repository) {
|
|
1241
|
-
let
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
const parts =
|
|
1260
|
+
let path18 = repository;
|
|
1261
|
+
path18 = path18.replace(/^https?:\/\//, "");
|
|
1262
|
+
path18 = path18.replace(/^git@/, "");
|
|
1263
|
+
const parts = path18.split("/");
|
|
1245
1264
|
if (parts.length > 1) {
|
|
1246
|
-
|
|
1265
|
+
path18 = parts.slice(1).join("/");
|
|
1247
1266
|
}
|
|
1248
|
-
|
|
1249
|
-
return
|
|
1267
|
+
path18 = path18.replace(/\.git$/, "");
|
|
1268
|
+
return path18;
|
|
1250
1269
|
}
|
|
1251
1270
|
/**
|
|
1252
1271
|
* 编码项目路径用于 API 请求
|
|
@@ -1300,7 +1319,7 @@ var init_gitlab_api = __esm({
|
|
|
1300
1319
|
// src/commands/init.ts
|
|
1301
1320
|
import { Command } from "commander";
|
|
1302
1321
|
import inquirer from "inquirer";
|
|
1303
|
-
import
|
|
1322
|
+
import path6 from "path";
|
|
1304
1323
|
import fs2 from "fs-extra";
|
|
1305
1324
|
import { Listr } from "listr2";
|
|
1306
1325
|
async function generateTechStack(projectPath) {
|
|
@@ -1399,7 +1418,7 @@ docs/
|
|
|
1399
1418
|
\u2514\u2500\u2500 sessions/ # \u5F00\u53D1\u4F1A\u8BDD\u8BB0\u5F55
|
|
1400
1419
|
\`\`\`
|
|
1401
1420
|
`;
|
|
1402
|
-
await FileUtils.write(
|
|
1421
|
+
await FileUtils.write(path6.join(projectPath, "TECH_STACK.md"), content);
|
|
1403
1422
|
}
|
|
1404
1423
|
async function generateConventions(projectPath) {
|
|
1405
1424
|
const content = `# \u5F00\u53D1\u89C4\u8303
|
|
@@ -1702,7 +1721,7 @@ test('renders user name', () => {
|
|
|
1702
1721
|
});
|
|
1703
1722
|
\`\`\`
|
|
1704
1723
|
`;
|
|
1705
|
-
await FileUtils.write(
|
|
1724
|
+
await FileUtils.write(path6.join(projectPath, "CONVENTIONS.md"), content);
|
|
1706
1725
|
}
|
|
1707
1726
|
async function generateAIMemory(projectPath, projectName) {
|
|
1708
1727
|
const content = `# AI Memory - \u9879\u76EE\u72B6\u6001\u8BB0\u5F55
|
|
@@ -1761,7 +1780,7 @@ async function generateAIMemory(projectPath, projectName) {
|
|
|
1761
1780
|
| Bug ID | \u65E5\u671F | \u95EE\u9898\u63CF\u8FF0 | \u72B6\u6001 |
|
|
1762
1781
|
|--------|------|---------|------|
|
|
1763
1782
|
`;
|
|
1764
|
-
await FileUtils.write(
|
|
1783
|
+
await FileUtils.write(path6.join(projectPath, "AI_MEMORY.md"), content);
|
|
1765
1784
|
}
|
|
1766
1785
|
async function generateSpecTemplate(projectPath) {
|
|
1767
1786
|
const content = `# [\u529F\u80FD\u6807\u9898]
|
|
@@ -1825,14 +1844,14 @@ async function generateSpecTemplate(projectPath) {
|
|
|
1825
1844
|
----
|
|
1826
1845
|
*\u751F\u6210\u4E8E: {{TIMESTAMP}} by team-cli*
|
|
1827
1846
|
`;
|
|
1828
|
-
await FileUtils.write(
|
|
1847
|
+
await FileUtils.write(path6.join(projectPath, "docs/specs/template.md"), content);
|
|
1829
1848
|
}
|
|
1830
1849
|
async function cloneBackendTemplate(projectPath, versionOptions) {
|
|
1831
1850
|
const templateRepo = process.env.TEMPLATE_REPO || "git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git";
|
|
1832
|
-
const backendPath =
|
|
1851
|
+
const backendPath = path6.join(projectPath, "backend");
|
|
1833
1852
|
try {
|
|
1834
1853
|
const { execaCommand } = await import("execa");
|
|
1835
|
-
const tempDir =
|
|
1854
|
+
const tempDir = path6.join(projectPath, ".template-temp");
|
|
1836
1855
|
if (versionOptions?.tag || versionOptions?.branch) {
|
|
1837
1856
|
const { userConfigManager: userConfigManager2 } = await Promise.resolve().then(() => (init_user_config(), user_config_exports));
|
|
1838
1857
|
const { GitLabAPI: GitLabAPI2 } = await Promise.resolve().then(() => (init_gitlab_api(), gitlab_api_exports));
|
|
@@ -1879,7 +1898,7 @@ async function cloneBackendTemplate(projectPath, versionOptions) {
|
|
|
1879
1898
|
filter: (src) => !src.includes(".git")
|
|
1880
1899
|
});
|
|
1881
1900
|
await fs2.remove(tempDir);
|
|
1882
|
-
const gitDir =
|
|
1901
|
+
const gitDir = path6.join(backendPath, ".git");
|
|
1883
1902
|
if (await FileUtils.exists(gitDir)) {
|
|
1884
1903
|
await FileUtils.remove(gitDir);
|
|
1885
1904
|
}
|
|
@@ -1890,13 +1909,13 @@ async function cloneBackendTemplate(projectPath, versionOptions) {
|
|
|
1890
1909
|
});
|
|
1891
1910
|
} catch (error) {
|
|
1892
1911
|
logger.warn("\u514B\u9686\u540E\u7AEF\u6A21\u677F\u5931\u8D25\uFF0C\u521B\u5EFA\u57FA\u7840\u7ED3\u6784");
|
|
1893
|
-
await FileUtils.ensureDir(
|
|
1894
|
-
await FileUtils.ensureDir(
|
|
1895
|
-
await FileUtils.ensureDir(
|
|
1912
|
+
await FileUtils.ensureDir(path6.join(backendPath, "src/main/java/com/example"));
|
|
1913
|
+
await FileUtils.ensureDir(path6.join(backendPath, "src/main/resources"));
|
|
1914
|
+
await FileUtils.ensureDir(path6.join(backendPath, "src/test/java"));
|
|
1896
1915
|
}
|
|
1897
1916
|
}
|
|
1898
1917
|
async function generateFrontendScaffold(projectPath) {
|
|
1899
|
-
const frontendPath =
|
|
1918
|
+
const frontendPath = path6.join(projectPath, "frontend");
|
|
1900
1919
|
try {
|
|
1901
1920
|
const prompt = `Read TECH_STACK.md and CONVENTIONS.md.
|
|
1902
1921
|
Initialize a Next.js 14 frontend in ./frontend with:
|
|
@@ -1909,16 +1928,16 @@ Initialize a Next.js 14 frontend in ./frontend with:
|
|
|
1909
1928
|
Do not run any servers, just generate the folder structure and configuration files.`;
|
|
1910
1929
|
await claudeAI.prompt(prompt, {
|
|
1911
1930
|
contextFiles: [
|
|
1912
|
-
|
|
1913
|
-
|
|
1931
|
+
path6.join(projectPath, "TECH_STACK.md"),
|
|
1932
|
+
path6.join(projectPath, "CONVENTIONS.md")
|
|
1914
1933
|
]
|
|
1915
1934
|
});
|
|
1916
1935
|
} catch (error) {
|
|
1917
1936
|
logger.warn("Claude \u751F\u6210\u524D\u7AEF\u5931\u8D25\uFF0C\u5C06\u521B\u5EFA\u57FA\u7840\u7ED3\u6784");
|
|
1918
|
-
await FileUtils.ensureDir(
|
|
1919
|
-
await FileUtils.ensureDir(
|
|
1920
|
-
await FileUtils.ensureDir(
|
|
1921
|
-
await FileUtils.ensureDir(
|
|
1937
|
+
await FileUtils.ensureDir(path6.join(frontendPath, "src/app"));
|
|
1938
|
+
await FileUtils.ensureDir(path6.join(frontendPath, "src/components"));
|
|
1939
|
+
await FileUtils.ensureDir(path6.join(frontendPath, "src/lib"));
|
|
1940
|
+
await FileUtils.ensureDir(path6.join(frontendPath, "public"));
|
|
1922
1941
|
}
|
|
1923
1942
|
}
|
|
1924
1943
|
async function generateDockerFiles(projectPath) {
|
|
@@ -1978,7 +1997,7 @@ var init_init = __esm({
|
|
|
1978
1997
|
logger.info("\u8BF7\u5B89\u88C5 Claude CLI: npm install -g @anthropic-ai/claude-code");
|
|
1979
1998
|
process.exit(1);
|
|
1980
1999
|
}
|
|
1981
|
-
const projectPath =
|
|
2000
|
+
const projectPath = path6.resolve(options.dir, projectName);
|
|
1982
2001
|
if (await FileUtils.exists(projectPath)) {
|
|
1983
2002
|
logger.error(`\u76EE\u5F55\u5DF2\u5B58\u5728: ${projectPath}`);
|
|
1984
2003
|
logger.info("\u8BF7\u9009\u62E9\u5176\u4ED6\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u73B0\u6709\u76EE\u5F55");
|
|
@@ -1997,11 +2016,11 @@ var init_init = __esm({
|
|
|
1997
2016
|
title: "\u521B\u5EFA\u9879\u76EE\u76EE\u5F55",
|
|
1998
2017
|
task: async () => {
|
|
1999
2018
|
await FileUtils.ensureDir(projectPath);
|
|
2000
|
-
await FileUtils.ensureDir(
|
|
2001
|
-
await FileUtils.ensureDir(
|
|
2002
|
-
await FileUtils.ensureDir(
|
|
2003
|
-
await FileUtils.ensureDir(
|
|
2004
|
-
await FileUtils.ensureDir(
|
|
2019
|
+
await FileUtils.ensureDir(path6.join(projectPath, "frontend"));
|
|
2020
|
+
await FileUtils.ensureDir(path6.join(projectPath, "backend"));
|
|
2021
|
+
await FileUtils.ensureDir(path6.join(projectPath, "docs/specs"));
|
|
2022
|
+
await FileUtils.ensureDir(path6.join(projectPath, "docs/api"));
|
|
2023
|
+
await FileUtils.ensureDir(path6.join(projectPath, "docs/sessions"));
|
|
2005
2024
|
}
|
|
2006
2025
|
},
|
|
2007
2026
|
{
|
|
@@ -2091,7 +2110,7 @@ var init_init = __esm({
|
|
|
2091
2110
|
// src/commands/breakdown.ts
|
|
2092
2111
|
import { Command as Command2 } from "commander";
|
|
2093
2112
|
import inquirer2 from "inquirer";
|
|
2094
|
-
import
|
|
2113
|
+
import path7 from "path";
|
|
2095
2114
|
import { Listr as Listr2 } from "listr2";
|
|
2096
2115
|
function buildBreakdownPrompt(specContent) {
|
|
2097
2116
|
return `Role: Senior Technical Lead and Agile Coach
|
|
@@ -2206,9 +2225,9 @@ var init_breakdown = __esm({
|
|
|
2206
2225
|
choices: ctx.specs
|
|
2207
2226
|
}
|
|
2208
2227
|
]);
|
|
2209
|
-
return
|
|
2228
|
+
return path7.join("docs/specs", selectedFile);
|
|
2210
2229
|
}
|
|
2211
|
-
const fullPath = specFile.startsWith("docs/specs/") ? specFile :
|
|
2230
|
+
const fullPath = specFile.startsWith("docs/specs/") ? specFile : path7.join("docs/specs", specFile);
|
|
2212
2231
|
const exists = await FileUtils.exists(fullPath);
|
|
2213
2232
|
if (!exists) {
|
|
2214
2233
|
throw new Error(`Spec \u6587\u4EF6\u4E0D\u5B58\u5728: ${specFile}`);
|
|
@@ -2278,7 +2297,7 @@ var init_breakdown = __esm({
|
|
|
2278
2297
|
// src/commands/dev.ts
|
|
2279
2298
|
import { Command as Command3 } from "commander";
|
|
2280
2299
|
import inquirer3 from "inquirer";
|
|
2281
|
-
import
|
|
2300
|
+
import path8 from "path";
|
|
2282
2301
|
async function selectSpec() {
|
|
2283
2302
|
logger.step("\u6B65\u9AA4 1/3: \u9009\u62E9 spec \u6587\u4EF6...");
|
|
2284
2303
|
logger.newLine();
|
|
@@ -2294,7 +2313,7 @@ async function selectSpec() {
|
|
|
2294
2313
|
}
|
|
2295
2314
|
const specs = [];
|
|
2296
2315
|
for (let i = 0; i < specFiles.length; i++) {
|
|
2297
|
-
const file =
|
|
2316
|
+
const file = path8.join(specDir, specFiles[i]);
|
|
2298
2317
|
const spec = await FileUtils.read(file);
|
|
2299
2318
|
const status = parseSpecStatus(spec);
|
|
2300
2319
|
const dependencies = parseDependencies(spec);
|
|
@@ -2608,8 +2627,8 @@ async function generateSessionLog(specFile, milestone, todo, taskDescription, re
|
|
|
2608
2627
|
const sessionDir = "docs/sessions";
|
|
2609
2628
|
await FileUtils.ensureDir(sessionDir);
|
|
2610
2629
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2611
|
-
const specName =
|
|
2612
|
-
const logFile =
|
|
2630
|
+
const specName = path8.basename(specFile, ".md");
|
|
2631
|
+
const logFile = path8.join(sessionDir, `${timestamp}_${specName}.md`);
|
|
2613
2632
|
const content = `# \u5F00\u53D1\u4F1A\u8BDD\u8BB0\u5F55
|
|
2614
2633
|
|
|
2615
2634
|
**\u65F6\u95F4**: ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN")}
|
|
@@ -2682,7 +2701,7 @@ var init_dev = __esm({
|
|
|
2682
2701
|
// src/commands/add-feature.ts
|
|
2683
2702
|
import { Command as Command4 } from "commander";
|
|
2684
2703
|
import inquirer4 from "inquirer";
|
|
2685
|
-
import
|
|
2704
|
+
import path9 from "path";
|
|
2686
2705
|
import { Listr as Listr3 } from "listr2";
|
|
2687
2706
|
async function addFeatureFromPrd(featureName, featureSlug, specFile) {
|
|
2688
2707
|
const { prdPath } = await inquirer4.prompt([
|
|
@@ -2711,7 +2730,7 @@ async function addFeatureFromPrd(featureName, featureSlug, specFile) {
|
|
|
2711
2730
|
const specs = files.filter((f) => !f.includes("template"));
|
|
2712
2731
|
ctx2.completedSpecs = [];
|
|
2713
2732
|
for (const file of specs) {
|
|
2714
|
-
const status = await SpecUtils.getSpecStatus(
|
|
2733
|
+
const status = await SpecUtils.getSpecStatus(path9.join(specDir, file));
|
|
2715
2734
|
if (status === "\u5DF2\u5B8C\u6210") {
|
|
2716
2735
|
ctx2.completedSpecs.push(file.replace(".md", ""));
|
|
2717
2736
|
}
|
|
@@ -2783,7 +2802,7 @@ async function addFeatureSimple(featureName, featureSlug, specFile) {
|
|
|
2783
2802
|
const specs = files.filter((f) => !f.includes("template"));
|
|
2784
2803
|
ctx2.completedSpecs = [];
|
|
2785
2804
|
for (const file of specs) {
|
|
2786
|
-
const status = await SpecUtils.getSpecStatus(
|
|
2805
|
+
const status = await SpecUtils.getSpecStatus(path9.join(specDir, file));
|
|
2787
2806
|
if (status === "\u5DF2\u5B8C\u6210") {
|
|
2788
2807
|
ctx2.completedSpecs.push(file.replace(".md", ""));
|
|
2789
2808
|
}
|
|
@@ -2880,7 +2899,7 @@ async function buildProjectContext() {
|
|
|
2880
2899
|
const files = await FileUtils.findFiles("*.md", "docs/specs");
|
|
2881
2900
|
const specs = files.filter((f) => !f.includes("template"));
|
|
2882
2901
|
for (const file of specs) {
|
|
2883
|
-
const status = await SpecUtils.getSpecStatus(
|
|
2902
|
+
const status = await SpecUtils.getSpecStatus(path9.join("docs/specs", file));
|
|
2884
2903
|
context.push(` - ${file.replace(".md", "")} [${status}]`);
|
|
2885
2904
|
}
|
|
2886
2905
|
}
|
|
@@ -3143,7 +3162,7 @@ var init_add_feature = __esm({
|
|
|
3143
3162
|
process.exit(1);
|
|
3144
3163
|
}
|
|
3145
3164
|
const featureSlug = StringUtils2.toKebabCase(featureName);
|
|
3146
|
-
const specFile =
|
|
3165
|
+
const specFile = path9.join("docs/specs", `${featureSlug}.md`);
|
|
3147
3166
|
const specExists = await FileUtils.exists(specFile);
|
|
3148
3167
|
if (specExists) {
|
|
3149
3168
|
logger.error(`Spec \u6587\u4EF6\u5DF2\u5B58\u5728: ${specFile}`);
|
|
@@ -3180,7 +3199,7 @@ var init_add_feature = __esm({
|
|
|
3180
3199
|
|
|
3181
3200
|
// src/commands/split-prd.ts
|
|
3182
3201
|
import { Command as Command5 } from "commander";
|
|
3183
|
-
import
|
|
3202
|
+
import path10 from "path";
|
|
3184
3203
|
import { Listr as Listr4 } from "listr2";
|
|
3185
3204
|
function buildSplitPrdPrompt(prdContent, screenshots, demoRepos) {
|
|
3186
3205
|
let prompt = `Role: Senior Product Manager and Technical Architect
|
|
@@ -3326,7 +3345,7 @@ var init_split_prd = __esm({
|
|
|
3326
3345
|
ctx2.prdFiles = [];
|
|
3327
3346
|
for (const ext of supportedExtensions) {
|
|
3328
3347
|
const files = await FileUtils.findFiles(`*.${ext}`, prdFolder);
|
|
3329
|
-
ctx2.prdFiles.push(...files.map((f) =>
|
|
3348
|
+
ctx2.prdFiles.push(...files.map((f) => path10.join(prdFolder, f)));
|
|
3330
3349
|
}
|
|
3331
3350
|
if (ctx2.prdFiles.length === 0) {
|
|
3332
3351
|
throw new Error(
|
|
@@ -3344,7 +3363,7 @@ var init_split_prd = __esm({
|
|
|
3344
3363
|
{
|
|
3345
3364
|
title: "\u626B\u63CF\u622A\u56FE\u6587\u4EF6",
|
|
3346
3365
|
task: async (ctx2) => {
|
|
3347
|
-
const screenshotDir =
|
|
3366
|
+
const screenshotDir = path10.join(prdFolder, "screenshots");
|
|
3348
3367
|
const dirExists = await FileUtils.exists(screenshotDir);
|
|
3349
3368
|
if (!dirExists) {
|
|
3350
3369
|
logger.info("\u672A\u627E\u5230 screenshots \u76EE\u5F55\uFF0C\u8DF3\u8FC7\u622A\u56FE");
|
|
@@ -3355,7 +3374,7 @@ var init_split_prd = __esm({
|
|
|
3355
3374
|
ctx2.screenshots = [];
|
|
3356
3375
|
for (const ext of imageExtensions) {
|
|
3357
3376
|
const files = await FileUtils.findFiles(`*.${ext}`, screenshotDir);
|
|
3358
|
-
ctx2.screenshots.push(...files.map((f) =>
|
|
3377
|
+
ctx2.screenshots.push(...files.map((f) => path10.join(screenshotDir, f)));
|
|
3359
3378
|
}
|
|
3360
3379
|
logger.success(`\u627E\u5230 ${ctx2.screenshots.length} \u4E2A\u622A\u56FE\u6587\u4EF6`);
|
|
3361
3380
|
}
|
|
@@ -3366,8 +3385,8 @@ var init_split_prd = __esm({
|
|
|
3366
3385
|
const entries = await FileUtils.findFiles("*/", prdFolder);
|
|
3367
3386
|
ctx2.demoRepos = [];
|
|
3368
3387
|
for (const entry of entries) {
|
|
3369
|
-
const dirPath =
|
|
3370
|
-
const gitDir =
|
|
3388
|
+
const dirPath = path10.join(prdFolder, entry);
|
|
3389
|
+
const gitDir = path10.join(dirPath, ".git");
|
|
3371
3390
|
const hasGit = await FileUtils.exists(gitDir);
|
|
3372
3391
|
if (hasGit) {
|
|
3373
3392
|
ctx2.demoRepos.push(dirPath);
|
|
@@ -3431,7 +3450,7 @@ var init_split_prd = __esm({
|
|
|
3431
3450
|
// src/commands/bugfix.ts
|
|
3432
3451
|
import { Command as Command6 } from "commander";
|
|
3433
3452
|
import inquirer5 from "inquirer";
|
|
3434
|
-
import
|
|
3453
|
+
import path11 from "path";
|
|
3435
3454
|
import { Listr as Listr5 } from "listr2";
|
|
3436
3455
|
function generateBugId() {
|
|
3437
3456
|
const date = /* @__PURE__ */ new Date();
|
|
@@ -3458,7 +3477,7 @@ async function findRelatedSpec(description) {
|
|
|
3458
3477
|
}
|
|
3459
3478
|
const keywords = extractKeywords(description);
|
|
3460
3479
|
for (const file of specs) {
|
|
3461
|
-
const filePath =
|
|
3480
|
+
const filePath = path11.join(specDir, file);
|
|
3462
3481
|
const content = await FileUtils.read(filePath);
|
|
3463
3482
|
for (const keyword of keywords) {
|
|
3464
3483
|
if (content.toLowerCase().includes(keyword.toLowerCase())) {
|
|
@@ -3598,7 +3617,7 @@ var init_bugfix = __esm({
|
|
|
3598
3617
|
const relatedSpec = await findRelatedSpec(answers.description);
|
|
3599
3618
|
const bugfixDir = "docs/bugfixes";
|
|
3600
3619
|
await FileUtils.ensureDir(bugfixDir);
|
|
3601
|
-
const bugfixFile =
|
|
3620
|
+
const bugfixFile = path11.join(bugfixDir, `${timestamp}_${bugId}.md`);
|
|
3602
3621
|
const content = formatBugfixDocument({
|
|
3603
3622
|
id: bugId,
|
|
3604
3623
|
severity: answers.severity,
|
|
@@ -3674,7 +3693,7 @@ var init_bugfix = __esm({
|
|
|
3674
3693
|
const timestamp = DateUtils.format(/* @__PURE__ */ new Date(), "YYYY-MM-DD HH:mm:ss");
|
|
3675
3694
|
const hotfixDir = "docs/hotfixes";
|
|
3676
3695
|
await FileUtils.ensureDir(hotfixDir);
|
|
3677
|
-
const hotfixFile =
|
|
3696
|
+
const hotfixFile = path11.join(hotfixDir, `${timestamp}_${hotfixId}.md`);
|
|
3678
3697
|
const content = formatHotfixDocument({
|
|
3679
3698
|
id: hotfixId,
|
|
3680
3699
|
description: answers.description,
|
|
@@ -3861,7 +3880,7 @@ var init_lint = __esm({
|
|
|
3861
3880
|
|
|
3862
3881
|
// src/commands/status.ts
|
|
3863
3882
|
import { Command as Command8 } from "commander";
|
|
3864
|
-
import
|
|
3883
|
+
import path12 from "path";
|
|
3865
3884
|
async function displayProjectInfo() {
|
|
3866
3885
|
logger.info("\u9879\u76EE\u4FE1\u606F:");
|
|
3867
3886
|
logger.newLine();
|
|
@@ -3897,7 +3916,7 @@ async function displayFeatureInventory() {
|
|
|
3897
3916
|
}
|
|
3898
3917
|
const inventory = [];
|
|
3899
3918
|
for (const file of specs) {
|
|
3900
|
-
const filePath =
|
|
3919
|
+
const filePath = path12.join(specDir, file);
|
|
3901
3920
|
const content = await FileUtils.read(filePath);
|
|
3902
3921
|
const status = parseSpecStatus2(content);
|
|
3903
3922
|
inventory.push({
|
|
@@ -3956,7 +3975,7 @@ async function displayRecentActivity() {
|
|
|
3956
3975
|
}
|
|
3957
3976
|
const sorted = files.sort().reverse().slice(0, 5);
|
|
3958
3977
|
for (const file of sorted) {
|
|
3959
|
-
const filePath =
|
|
3978
|
+
const filePath = path12.join(sessionDir, file);
|
|
3960
3979
|
const stat = await FileUtils.read(filePath);
|
|
3961
3980
|
const specMatch = stat.match(/\*\*Spec\*\*:\s*(.+)/);
|
|
3962
3981
|
const spec = specMatch ? specMatch[1].trim() : "\u672A\u77E5";
|
|
@@ -4026,13 +4045,13 @@ var init_status = __esm({
|
|
|
4026
4045
|
|
|
4027
4046
|
// src/commands/detect-deps.ts
|
|
4028
4047
|
import { Command as Command9 } from "commander";
|
|
4029
|
-
import
|
|
4048
|
+
import path13 from "path";
|
|
4030
4049
|
import inquirer6 from "inquirer";
|
|
4031
4050
|
async function detectDependencies(specFile) {
|
|
4032
4051
|
logger.step("\u81EA\u52A8\u68C0\u6D4B\u4F9D\u8D56\u5173\u7CFB...");
|
|
4033
4052
|
const projectDir = ".";
|
|
4034
4053
|
const allDeps = /* @__PURE__ */ new Set();
|
|
4035
|
-
const backendDir =
|
|
4054
|
+
const backendDir = path13.join(projectDir, "backend");
|
|
4036
4055
|
const backendExists = await FileUtils.exists(backendDir);
|
|
4037
4056
|
if (backendExists) {
|
|
4038
4057
|
const apiDeps = await scanBackendApiCalls(backendDir);
|
|
@@ -4042,7 +4061,7 @@ async function detectDependencies(specFile) {
|
|
|
4042
4061
|
const serviceDeps = await scanBackendServiceRefs(backendDir);
|
|
4043
4062
|
serviceDeps.forEach((d) => allDeps.add(d));
|
|
4044
4063
|
}
|
|
4045
|
-
const frontendDir =
|
|
4064
|
+
const frontendDir = path13.join(projectDir, "frontend");
|
|
4046
4065
|
const frontendExists = await FileUtils.exists(frontendDir);
|
|
4047
4066
|
if (frontendExists) {
|
|
4048
4067
|
const frontendDeps = await scanFrontendApiCalls(frontendDir);
|
|
@@ -4083,11 +4102,11 @@ async function detectDependencies(specFile) {
|
|
|
4083
4102
|
}
|
|
4084
4103
|
async function scanBackendApiCalls(backendDir) {
|
|
4085
4104
|
const deps = [];
|
|
4086
|
-
const srcDir =
|
|
4105
|
+
const srcDir = path13.join(backendDir, "src");
|
|
4087
4106
|
try {
|
|
4088
4107
|
const javaFiles = await FileUtils.findFiles("*.java", srcDir);
|
|
4089
4108
|
for (const file of javaFiles) {
|
|
4090
|
-
const filePath =
|
|
4109
|
+
const filePath = path13.join(srcDir, file);
|
|
4091
4110
|
const content = await FileUtils.read(filePath);
|
|
4092
4111
|
const pathRegex = /"(\/api\/[^"]+)"/g;
|
|
4093
4112
|
let match;
|
|
@@ -4105,11 +4124,11 @@ async function scanBackendApiCalls(backendDir) {
|
|
|
4105
4124
|
}
|
|
4106
4125
|
async function scanBackendEntityRelations(backendDir) {
|
|
4107
4126
|
const deps = [];
|
|
4108
|
-
const srcDir =
|
|
4127
|
+
const srcDir = path13.join(backendDir, "src");
|
|
4109
4128
|
try {
|
|
4110
4129
|
const javaFiles = await FileUtils.findFiles("*.java", srcDir);
|
|
4111
4130
|
for (const file of javaFiles) {
|
|
4112
|
-
const filePath =
|
|
4131
|
+
const filePath = path13.join(srcDir, file);
|
|
4113
4132
|
const content = await FileUtils.read(filePath);
|
|
4114
4133
|
if (content.includes("@JoinColumn") || content.includes("@ManyToOne") || content.includes("@OneToMany")) {
|
|
4115
4134
|
const typeRegex = /type\s*=\s*(\w+)/g;
|
|
@@ -4125,11 +4144,11 @@ async function scanBackendEntityRelations(backendDir) {
|
|
|
4125
4144
|
}
|
|
4126
4145
|
async function scanBackendServiceRefs(backendDir) {
|
|
4127
4146
|
const deps = [];
|
|
4128
|
-
const srcDir =
|
|
4147
|
+
const srcDir = path13.join(backendDir, "src");
|
|
4129
4148
|
try {
|
|
4130
4149
|
const javaFiles = await FileUtils.findFiles("*.java", srcDir);
|
|
4131
4150
|
for (const file of javaFiles) {
|
|
4132
|
-
const filePath =
|
|
4151
|
+
const filePath = path13.join(srcDir, file);
|
|
4133
4152
|
const content = await FileUtils.read(filePath);
|
|
4134
4153
|
const serviceRegex = /private\s+(\w+)Service/g;
|
|
4135
4154
|
let match;
|
|
@@ -4145,11 +4164,11 @@ async function scanBackendServiceRefs(backendDir) {
|
|
|
4145
4164
|
}
|
|
4146
4165
|
async function scanFrontendApiCalls(frontendDir) {
|
|
4147
4166
|
const deps = [];
|
|
4148
|
-
const srcDir =
|
|
4167
|
+
const srcDir = path13.join(frontendDir, "src");
|
|
4149
4168
|
try {
|
|
4150
4169
|
const tsFiles = await FileUtils.findFiles("*.{ts,tsx,js,jsx}", srcDir);
|
|
4151
4170
|
for (const file of tsFiles) {
|
|
4152
|
-
const filePath =
|
|
4171
|
+
const filePath = path13.join(srcDir, file);
|
|
4153
4172
|
const content = await FileUtils.read(filePath);
|
|
4154
4173
|
const pathRegex = /"(\/api\/[^"]+)"/g;
|
|
4155
4174
|
let match;
|
|
@@ -4266,7 +4285,7 @@ var init_detect_deps = __esm({
|
|
|
4266
4285
|
process.exit(1);
|
|
4267
4286
|
}
|
|
4268
4287
|
for (const spec of specs) {
|
|
4269
|
-
const specPath =
|
|
4288
|
+
const specPath = path13.join(specsDir, spec);
|
|
4270
4289
|
logger.step(`\u5904\u7406: ${spec}`);
|
|
4271
4290
|
await detectDependencies(specPath);
|
|
4272
4291
|
logger.newLine();
|
|
@@ -4293,10 +4312,10 @@ var init_detect_deps = __esm({
|
|
|
4293
4312
|
|
|
4294
4313
|
// src/commands/sync-memory.ts
|
|
4295
4314
|
import { Command as Command10 } from "commander";
|
|
4296
|
-
import
|
|
4315
|
+
import path14 from "path";
|
|
4297
4316
|
async function syncFeatureInventory(aiMemoryFile, projectDir) {
|
|
4298
4317
|
logger.step("\u540C\u6B65\u529F\u80FD\u6E05\u5355...");
|
|
4299
|
-
const specsDir =
|
|
4318
|
+
const specsDir = path14.join(projectDir, "docs/specs");
|
|
4300
4319
|
const exists = await FileUtils.exists(specsDir);
|
|
4301
4320
|
if (!exists) {
|
|
4302
4321
|
return;
|
|
@@ -4311,7 +4330,7 @@ async function syncFeatureInventory(aiMemoryFile, projectDir) {
|
|
|
4311
4330
|
for (const specFile of specs) {
|
|
4312
4331
|
const name = specFile.replace(".md", "");
|
|
4313
4332
|
const displayName = name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
4314
|
-
const specPath =
|
|
4333
|
+
const specPath = path14.join(specsDir, specFile);
|
|
4315
4334
|
const content = await FileUtils.read(specPath);
|
|
4316
4335
|
const status = parseSpecStatus3(content);
|
|
4317
4336
|
const progress = getSpecProgress(content);
|
|
@@ -4329,7 +4348,7 @@ async function syncFeatureInventory(aiMemoryFile, projectDir) {
|
|
|
4329
4348
|
}
|
|
4330
4349
|
async function syncApiInventory(aiMemoryFile, projectDir) {
|
|
4331
4350
|
logger.step("\u540C\u6B65 API \u5217\u8868...");
|
|
4332
|
-
const backendDir =
|
|
4351
|
+
const backendDir = path14.join(projectDir, "backend");
|
|
4333
4352
|
const exists = await FileUtils.exists(backendDir);
|
|
4334
4353
|
if (!exists) {
|
|
4335
4354
|
return;
|
|
@@ -4339,13 +4358,13 @@ async function syncApiInventory(aiMemoryFile, projectDir) {
|
|
|
4339
4358
|
lines.push("");
|
|
4340
4359
|
lines.push("> \u672C\u90E8\u5206\u7531 team-cli \u81EA\u52A8\u626B\u63CF\u540E\u7AEF Controller \u751F\u6210");
|
|
4341
4360
|
lines.push("");
|
|
4342
|
-
const srcDir =
|
|
4361
|
+
const srcDir = path14.join(backendDir, "src");
|
|
4343
4362
|
const controllers = await FileUtils.findFiles("*Controller.java", srcDir);
|
|
4344
4363
|
if (controllers.length === 0) {
|
|
4345
4364
|
lines.push("\u6682\u65E0 API");
|
|
4346
4365
|
} else {
|
|
4347
4366
|
for (const controllerFile of controllers) {
|
|
4348
|
-
const controllerPath =
|
|
4367
|
+
const controllerPath = path14.join(srcDir, controllerFile);
|
|
4349
4368
|
const controllerName = controllerFile.replace(".java", "");
|
|
4350
4369
|
const module = controllerName.replace(/Controller$/, "").toLowerCase();
|
|
4351
4370
|
lines.push(`### ${module} \u6A21\u5757`);
|
|
@@ -4422,7 +4441,7 @@ function extractMethodComment(content, methodName) {
|
|
|
4422
4441
|
}
|
|
4423
4442
|
async function syncDataModels(aiMemoryFile, projectDir) {
|
|
4424
4443
|
logger.step("\u540C\u6B65\u6570\u636E\u6A21\u578B...");
|
|
4425
|
-
const backendDir =
|
|
4444
|
+
const backendDir = path14.join(projectDir, "backend");
|
|
4426
4445
|
const exists = await FileUtils.exists(backendDir);
|
|
4427
4446
|
if (!exists) {
|
|
4428
4447
|
return;
|
|
@@ -4432,7 +4451,7 @@ async function syncDataModels(aiMemoryFile, projectDir) {
|
|
|
4432
4451
|
lines.push("");
|
|
4433
4452
|
lines.push("> \u672C\u90E8\u5206\u7531 team-cli \u81EA\u52A8\u626B\u63CF\u540E\u7AEF Entity \u751F\u6210");
|
|
4434
4453
|
lines.push("");
|
|
4435
|
-
const srcDir =
|
|
4454
|
+
const srcDir = path14.join(backendDir, "src");
|
|
4436
4455
|
const entities = await FileUtils.findFiles("*Entity.java", srcDir);
|
|
4437
4456
|
if (entities.length === 0) {
|
|
4438
4457
|
lines.push("\u6682\u65E0\u6570\u636E\u6A21\u578B");
|
|
@@ -4440,7 +4459,7 @@ async function syncDataModels(aiMemoryFile, projectDir) {
|
|
|
4440
4459
|
lines.push("| \u6A21\u578B | \u8BF4\u660E | \u5B57\u6BB5 | \u5173\u8054 |");
|
|
4441
4460
|
lines.push("|------|------|------|------|");
|
|
4442
4461
|
for (const entityFile of entities) {
|
|
4443
|
-
const entityPath =
|
|
4462
|
+
const entityPath = path14.join(srcDir, entityFile);
|
|
4444
4463
|
const entityName = entityFile.replace(".java", "").replace(/Entity$/, "");
|
|
4445
4464
|
const displayName = entityName.split(/(?=[A-Z])/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
4446
4465
|
const content = await FileUtils.read(entityPath);
|
|
@@ -4562,15 +4581,15 @@ async function syncTemplateVersions(aiMemoryFile, projectDir) {
|
|
|
4562
4581
|
await replaceOrInsertSection(aiMemoryFile, "## \u6A21\u677F\u7248\u672C\u4FE1\u606F", newContent);
|
|
4563
4582
|
}
|
|
4564
4583
|
function extractRepoName(repository) {
|
|
4565
|
-
let
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
const parts =
|
|
4584
|
+
let path18 = repository;
|
|
4585
|
+
path18 = path18.replace(/^https?:\/\//, "");
|
|
4586
|
+
path18 = path18.replace(/^git@/, "");
|
|
4587
|
+
const parts = path18.split("/");
|
|
4569
4588
|
if (parts.length > 1) {
|
|
4570
|
-
|
|
4589
|
+
path18 = parts.slice(1).join("/");
|
|
4571
4590
|
}
|
|
4572
|
-
|
|
4573
|
-
return
|
|
4591
|
+
path18 = path18.replace(/\.git$/, "");
|
|
4592
|
+
return path18;
|
|
4574
4593
|
}
|
|
4575
4594
|
var syncMemoryCommand;
|
|
4576
4595
|
var init_sync_memory = __esm({
|
|
@@ -4615,11 +4634,11 @@ var init_sync_memory = __esm({
|
|
|
4615
4634
|
|
|
4616
4635
|
// src/commands/check-api.ts
|
|
4617
4636
|
import { Command as Command11 } from "commander";
|
|
4618
|
-
import
|
|
4637
|
+
import path15 from "path";
|
|
4619
4638
|
import inquirer7 from "inquirer";
|
|
4620
4639
|
import { Listr as Listr6 } from "listr2";
|
|
4621
4640
|
async function checkApiConflicts(projectDir) {
|
|
4622
|
-
const backendDir =
|
|
4641
|
+
const backendDir = path15.join(projectDir, "backend");
|
|
4623
4642
|
const exists = await FileUtils.exists(backendDir);
|
|
4624
4643
|
if (!exists) {
|
|
4625
4644
|
logger.info("\u672A\u627E\u5230\u540E\u7AEF\u9879\u76EE");
|
|
@@ -4628,10 +4647,10 @@ async function checkApiConflicts(projectDir) {
|
|
|
4628
4647
|
logger.step("\u626B\u63CF\u540E\u7AEF API...");
|
|
4629
4648
|
logger.newLine();
|
|
4630
4649
|
const apiMap = /* @__PURE__ */ new Map();
|
|
4631
|
-
const srcDir =
|
|
4650
|
+
const srcDir = path15.join(backendDir, "src");
|
|
4632
4651
|
const controllers = await FileUtils.findFiles("*Controller.java", srcDir);
|
|
4633
4652
|
for (const controllerFile of controllers) {
|
|
4634
|
-
const controllerPath =
|
|
4653
|
+
const controllerPath = path15.join(srcDir, controllerFile);
|
|
4635
4654
|
const apis = await extractApisFromController(controllerPath);
|
|
4636
4655
|
for (const api of apis) {
|
|
4637
4656
|
const key = `${api.method}:${api.path}`;
|
|
@@ -4662,8 +4681,8 @@ async function checkApiConflicts(projectDir) {
|
|
|
4662
4681
|
}
|
|
4663
4682
|
}
|
|
4664
4683
|
async function detectApiChanges(projectDir) {
|
|
4665
|
-
const backendDir =
|
|
4666
|
-
const registryFile =
|
|
4684
|
+
const backendDir = path15.join(projectDir, "backend");
|
|
4685
|
+
const registryFile = path15.join(projectDir, "docs/api-registry.md");
|
|
4667
4686
|
const registryExists = await FileUtils.exists(registryFile);
|
|
4668
4687
|
if (!registryExists) {
|
|
4669
4688
|
logger.info("API Registry \u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u53D8\u66F4\u68C0\u6D4B");
|
|
@@ -4675,10 +4694,10 @@ async function detectApiChanges(projectDir) {
|
|
|
4675
4694
|
const registryContent = await FileUtils.read(registryFile);
|
|
4676
4695
|
const existingApis = extractApisFromRegistry(registryContent);
|
|
4677
4696
|
const currentApis = /* @__PURE__ */ new Map();
|
|
4678
|
-
const srcDir =
|
|
4697
|
+
const srcDir = path15.join(backendDir, "src");
|
|
4679
4698
|
const controllers = await FileUtils.findFiles("*Controller.java", srcDir);
|
|
4680
4699
|
for (const controllerFile of controllers) {
|
|
4681
|
-
const controllerPath =
|
|
4700
|
+
const controllerPath = path15.join(srcDir, controllerFile);
|
|
4682
4701
|
const apis = await extractApisFromController(controllerPath);
|
|
4683
4702
|
for (const api of apis) {
|
|
4684
4703
|
const key = `${api.method}:${api.path}`;
|
|
@@ -4740,9 +4759,9 @@ async function detectApiChanges(projectDir) {
|
|
|
4740
4759
|
}
|
|
4741
4760
|
}
|
|
4742
4761
|
async function generateApiRegistry(projectDir) {
|
|
4743
|
-
const registryFile =
|
|
4762
|
+
const registryFile = path15.join(projectDir, "docs/api-registry.md");
|
|
4744
4763
|
logger.step("\u626B\u63CF\u5E76\u751F\u6210 API Registry...");
|
|
4745
|
-
await FileUtils.ensureDir(
|
|
4764
|
+
await FileUtils.ensureDir(path15.dirname(registryFile));
|
|
4746
4765
|
const header = `# API Registry
|
|
4747
4766
|
|
|
4748
4767
|
> \u672C\u6587\u4EF6\u8BB0\u5F55\u6240\u6709 API \u7684\u5B9A\u4E49\u3001\u7248\u672C\u548C\u53D8\u66F4\u5386\u53F2
|
|
@@ -4771,14 +4790,14 @@ async function generateApiRegistry(projectDir) {
|
|
|
4771
4790
|
*\u6700\u540E\u66F4\u65B0: ${DateUtils.format(/* @__PURE__ */ new Date(), "YYYY-MM-DD HH:mm:ss")}*
|
|
4772
4791
|
`;
|
|
4773
4792
|
let content = header;
|
|
4774
|
-
const backendDir =
|
|
4793
|
+
const backendDir = path15.join(projectDir, "backend");
|
|
4775
4794
|
const exists = await FileUtils.exists(backendDir);
|
|
4776
4795
|
if (exists) {
|
|
4777
|
-
const srcDir =
|
|
4796
|
+
const srcDir = path15.join(backendDir, "src");
|
|
4778
4797
|
const controllers = await FileUtils.findFiles("*Controller.java", srcDir);
|
|
4779
4798
|
const moduleMap = /* @__PURE__ */ new Map();
|
|
4780
4799
|
for (const controllerFile of controllers) {
|
|
4781
|
-
const controllerPath =
|
|
4800
|
+
const controllerPath = path15.join(srcDir, controllerFile);
|
|
4782
4801
|
const controllerName = controllerFile.replace(".java", "");
|
|
4783
4802
|
const module = controllerName.replace(/Controller$/, "").toLowerCase();
|
|
4784
4803
|
if (!moduleMap.has(module)) {
|
|
@@ -4862,10 +4881,10 @@ function extractApisFromRegistry(registryContent) {
|
|
|
4862
4881
|
let match;
|
|
4863
4882
|
while ((match = apiRegex.exec(registryContent)) !== null) {
|
|
4864
4883
|
const method = match[1];
|
|
4865
|
-
const
|
|
4884
|
+
const path18 = match[2].trim();
|
|
4866
4885
|
const description = match[3].trim();
|
|
4867
|
-
const key = `${method}:${
|
|
4868
|
-
apis.set(key, { method, path:
|
|
4886
|
+
const key = `${method}:${path18}`;
|
|
4887
|
+
apis.set(key, { method, path: path18, description });
|
|
4869
4888
|
}
|
|
4870
4889
|
return apis;
|
|
4871
4890
|
}
|
|
@@ -4953,7 +4972,7 @@ var init_check_api = __esm({
|
|
|
4953
4972
|
|
|
4954
4973
|
// src/commands/logs.ts
|
|
4955
4974
|
import { Command as Command12 } from "commander";
|
|
4956
|
-
import
|
|
4975
|
+
import path16 from "path";
|
|
4957
4976
|
import inquirer8 from "inquirer";
|
|
4958
4977
|
async function collectLogFiles(targetDir) {
|
|
4959
4978
|
const logs = [];
|
|
@@ -4961,7 +4980,7 @@ async function collectLogFiles(targetDir) {
|
|
|
4961
4980
|
const allFiles = await FileUtils.findFiles("*.md", targetDir);
|
|
4962
4981
|
const filtered = allFiles.filter((f) => f !== "index.md");
|
|
4963
4982
|
for (const file of filtered) {
|
|
4964
|
-
const filePath =
|
|
4983
|
+
const filePath = path16.join(targetDir, file);
|
|
4965
4984
|
const stat = await FileUtils.exists(filePath);
|
|
4966
4985
|
if (stat) {
|
|
4967
4986
|
logs.push(filePath);
|
|
@@ -5001,7 +5020,7 @@ var init_logs = __esm({
|
|
|
5001
5020
|
case "":
|
|
5002
5021
|
case "today": {
|
|
5003
5022
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
5004
|
-
targetDir =
|
|
5023
|
+
targetDir = path16.join(sessionsDir, today);
|
|
5005
5024
|
const todayExists = await FileUtils.exists(targetDir);
|
|
5006
5025
|
if (!todayExists) {
|
|
5007
5026
|
logger.info("\u4ECA\u65E5\u6682\u65E0\u4F1A\u8BDD\u65E5\u5FD7");
|
|
@@ -5017,7 +5036,7 @@ var init_logs = __esm({
|
|
|
5017
5036
|
break;
|
|
5018
5037
|
}
|
|
5019
5038
|
default: {
|
|
5020
|
-
targetDir =
|
|
5039
|
+
targetDir = path16.join(sessionsDir, filter);
|
|
5021
5040
|
const dateExists = await FileUtils.exists(targetDir);
|
|
5022
5041
|
if (!dateExists) {
|
|
5023
5042
|
logger.error(`\u672A\u627E\u5230\u65E5\u671F '${filter}' \u7684\u65E5\u5FD7`);
|
|
@@ -5041,7 +5060,7 @@ var init_logs = __esm({
|
|
|
5041
5060
|
process.exit(0);
|
|
5042
5061
|
}
|
|
5043
5062
|
for (let i = 0; i < logs.length; i++) {
|
|
5044
|
-
const relPath =
|
|
5063
|
+
const relPath = path16.relative(sessionsDir, logs[i]);
|
|
5045
5064
|
logger.step(`${i + 1}) ${relPath}`);
|
|
5046
5065
|
}
|
|
5047
5066
|
logger.newLine();
|
|
@@ -5081,7 +5100,7 @@ var init_logs = __esm({
|
|
|
5081
5100
|
|
|
5082
5101
|
// src/commands/update.ts
|
|
5083
5102
|
import { Command as Command13 } from "commander";
|
|
5084
|
-
import
|
|
5103
|
+
import path17 from "path";
|
|
5085
5104
|
import { execa as execa4 } from "execa";
|
|
5086
5105
|
import inquirer9 from "inquirer";
|
|
5087
5106
|
import fs3 from "fs-extra";
|
|
@@ -5091,7 +5110,7 @@ async function performUpdate(projectPath, updates) {
|
|
|
5091
5110
|
for (const update of updates) {
|
|
5092
5111
|
const { type, info, updateOptions } = update;
|
|
5093
5112
|
const targetDir = type === "frontend" ? "frontend" : "backend";
|
|
5094
|
-
const targetPath =
|
|
5113
|
+
const targetPath = path17.join(projectPath, targetDir);
|
|
5095
5114
|
logger.newLine();
|
|
5096
5115
|
logger.step(`\u66F4\u65B0 ${type === "frontend" ? "\u524D\u7AEF" : "\u540E\u7AEF"}\u6A21\u677F...`);
|
|
5097
5116
|
if (updateOptions?.tag || updateOptions?.branch) {
|
|
@@ -5122,8 +5141,8 @@ async function performUpdate(projectPath, updates) {
|
|
|
5122
5141
|
}
|
|
5123
5142
|
}
|
|
5124
5143
|
const ref = updateOptions?.tag || updateOptions?.branch || "HEAD";
|
|
5125
|
-
const backupDir =
|
|
5126
|
-
await fs3.copy(targetPath,
|
|
5144
|
+
const backupDir = path17.join(projectPath, `.backup-${Date.now()}`);
|
|
5145
|
+
await fs3.copy(targetPath, path17.join(backupDir, targetDir));
|
|
5127
5146
|
logger.info(`\u5DF2\u521B\u5EFA\u5907\u4EFD: ${backupDir}`);
|
|
5128
5147
|
if (updateOptions?.dryRun) {
|
|
5129
5148
|
logger.info("[Dry Run] \u5C06\u4F1A\u66F4\u65B0\u5230\u4EE5\u4E0B\u7248\u672C:");
|
|
@@ -5133,7 +5152,7 @@ async function performUpdate(projectPath, updates) {
|
|
|
5133
5152
|
continue;
|
|
5134
5153
|
}
|
|
5135
5154
|
try {
|
|
5136
|
-
const tempDir =
|
|
5155
|
+
const tempDir = path17.join(projectPath, `.template-update-${Date.now()}`);
|
|
5137
5156
|
await execa4("git", ["clone", "--depth=1", "--branch", ref, info.repository, tempDir], {
|
|
5138
5157
|
stdio: "pipe"
|
|
5139
5158
|
});
|
|
@@ -5150,7 +5169,7 @@ async function performUpdate(projectPath, updates) {
|
|
|
5150
5169
|
const currentFiles = await FileUtils.findFiles("*", targetPath);
|
|
5151
5170
|
for (const file of currentFiles) {
|
|
5152
5171
|
if (!keepFiles.includes(file)) {
|
|
5153
|
-
const filePath =
|
|
5172
|
+
const filePath = path17.join(targetPath, file);
|
|
5154
5173
|
try {
|
|
5155
5174
|
await fs3.remove(filePath);
|
|
5156
5175
|
} catch {
|
|
@@ -5172,7 +5191,7 @@ async function performUpdate(projectPath, updates) {
|
|
|
5172
5191
|
logger.error(`\u66F4\u65B0\u5931\u8D25: ${error.message}`);
|
|
5173
5192
|
logger.info("\u6B63\u5728\u6062\u590D\u5907\u4EFD...");
|
|
5174
5193
|
await fs3.remove(targetPath);
|
|
5175
|
-
await fs3.copy(
|
|
5194
|
+
await fs3.copy(path17.join(backupDir, targetDir), targetPath);
|
|
5176
5195
|
await fs3.remove(backupDir);
|
|
5177
5196
|
logger.info("\u5DF2\u6062\u590D\u5230\u66F4\u65B0\u524D\u7684\u72B6\u6001");
|
|
5178
5197
|
}
|
|
@@ -5295,7 +5314,7 @@ var init_update = __esm({
|
|
|
5295
5314
|
import { Command as Command14 } from "commander";
|
|
5296
5315
|
import inquirer10 from "inquirer";
|
|
5297
5316
|
import chalk2 from "chalk";
|
|
5298
|
-
var
|
|
5317
|
+
var setTokenCommand, showConfigCommand, removeConfigCommand, validateTokenCommand, configCommand;
|
|
5299
5318
|
var init_config = __esm({
|
|
5300
5319
|
"src/commands/config.ts"() {
|
|
5301
5320
|
"use strict";
|
|
@@ -5303,7 +5322,6 @@ var init_config = __esm({
|
|
|
5303
5322
|
init_user_config();
|
|
5304
5323
|
init_gitlab_api();
|
|
5305
5324
|
init_logger();
|
|
5306
|
-
configCommand = new Command14("config").description("\u7BA1\u7406 GitLab \u914D\u7F6E").addCommand(setTokenCommand).addCommand(showConfigCommand).addCommand(removeConfigCommand).addCommand(validateTokenCommand);
|
|
5307
5325
|
setTokenCommand = new Command14("set-token").description("\u8BBE\u7F6E GitLab Access Token").option("-t, --token <token>", "Access Token").option("-u, --url <url>", "GitLab Base URL", "https://gitlab.com").action(async (options) => {
|
|
5308
5326
|
try {
|
|
5309
5327
|
logger.header("GitLab Access Token \u914D\u7F6E");
|
|
@@ -5470,6 +5488,7 @@ var init_config = __esm({
|
|
|
5470
5488
|
process.exit(1);
|
|
5471
5489
|
}
|
|
5472
5490
|
});
|
|
5491
|
+
configCommand = new Command14("config").description("\u7BA1\u7406 GitLab \u914D\u7F6E").addCommand(setTokenCommand).addCommand(showConfigCommand).addCommand(removeConfigCommand).addCommand(validateTokenCommand);
|
|
5473
5492
|
}
|
|
5474
5493
|
});
|
|
5475
5494
|
|
|
@@ -5854,7 +5873,7 @@ var init_index = __esm({
|
|
|
5854
5873
|
init_config();
|
|
5855
5874
|
init_diff();
|
|
5856
5875
|
program = new Command16();
|
|
5857
|
-
program.name("team-cli").description("AI-Native \u56E2\u961F\u7814\u53D1\u811A\u624B\u67B6").version("2.
|
|
5876
|
+
program.name("team-cli").description("AI-Native \u56E2\u961F\u7814\u53D1\u811A\u624B\u67B6").version("2.1.2");
|
|
5858
5877
|
program.option("-v, --verbose", "\u8BE6\u7EC6\u8F93\u51FA\u6A21\u5F0F").option("--debug", "\u8C03\u8BD5\u6A21\u5F0F");
|
|
5859
5878
|
program.addCommand(initCommand);
|
|
5860
5879
|
program.addCommand(splitPrdCommand);
|