yg-team-cli 2.3.5 → 2.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1491,7 +1491,7 @@ var initCommand = new Command("init").argument("[project-name]", "\u9879\u76EE\u
1491
1491
  logger.error("\u9879\u76EE\u540D\u79F0\u53EA\u80FD\u5305\u542B\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u8FDE\u5B57\u7B26");
1492
1492
  process.exit(1);
1493
1493
  }
1494
- logger.header("\u521D\u59CB\u5316\u9879\u76EE");
1494
+ logger.header("AI-Native \u56E2\u961F\u7814\u53D1\u811A\u624B\u67B6 - \u9879\u76EE\u521D\u59CB\u5316");
1495
1495
  logger.newLine();
1496
1496
  const hasClaude = await claudeAI.checkInstalled();
1497
1497
  if (!hasClaude) {
@@ -1520,44 +1520,20 @@ var initCommand = new Command("init").argument("[project-name]", "\u9879\u76EE\u
1520
1520
  const tasks = new Listr(
1521
1521
  [
1522
1522
  {
1523
- title: "\u68C0\u67E5\u73AF\u5883",
1524
- task: async () => {
1525
- const version = await claudeAI.getVersion();
1526
- logger.info(`Claude \u7248\u672C: ${version}`);
1527
- }
1528
- },
1529
- {
1530
- title: "\u521B\u5EFA\u9879\u76EE\u76EE\u5F55",
1523
+ title: "\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u7ED3\u6784",
1531
1524
  task: async () => {
1532
1525
  await FileUtils.ensureDir(projectPath);
1533
- await FileUtils.ensureDir(path7.join(projectPath, "frontend"));
1534
- await FileUtils.ensureDir(path7.join(projectPath, "backend"));
1535
1526
  await FileUtils.ensureDir(path7.join(projectPath, "docs/specs"));
1536
1527
  await FileUtils.ensureDir(path7.join(projectPath, "docs/api"));
1537
1528
  await FileUtils.ensureDir(path7.join(projectPath, "docs/sessions"));
1538
1529
  }
1539
1530
  },
1540
1531
  {
1541
- title: "\u751F\u6210\u6280\u672F\u6808\u6587\u6863",
1532
+ title: "\u751F\u6210\u6280\u672F\u6587\u6863 (Tech Stack, Conventions, Memory)",
1542
1533
  task: async () => {
1543
1534
  await generateTechStack(projectPath);
1544
- }
1545
- },
1546
- {
1547
- title: "\u751F\u6210\u5F00\u53D1\u89C4\u8303\u6587\u6863",
1548
- task: async () => {
1549
1535
  await generateConventions(projectPath);
1550
- }
1551
- },
1552
- {
1553
- title: "\u751F\u6210 AI Memory",
1554
- task: async () => {
1555
1536
  await generateAIMemory(projectPath, projectName);
1556
- }
1557
- },
1558
- {
1559
- title: "\u751F\u6210 Spec \u6A21\u677F",
1560
- task: async () => {
1561
1537
  await generateSpecTemplate(projectPath);
1562
1538
  }
1563
1539
  },
@@ -1583,85 +1559,75 @@ var initCommand = new Command("init").argument("[project-name]", "\u9879\u76EE\u
1583
1559
  });
1584
1560
  }
1585
1561
  },
1586
- ...options.docker ? [
1587
- {
1588
- title: "\u751F\u6210 Docker \u914D\u7F6E",
1589
- task: async () => {
1590
- await generateDockerFiles();
1591
- }
1592
- }
1593
- ] : [],
1594
- ...options.git ? [
1595
- {
1596
- title: "\u521D\u59CB\u5316 Git",
1597
- task: async () => {
1598
- await initGit(projectPath, projectName);
1599
- }
1600
- }
1601
- ] : [],
1602
- {
1603
- title: "\u6CE8\u518C\u8FDC\u7A0B MCP \u670D\u52A1",
1604
- task: async () => {
1605
- const hasRemoteModule = selectedModules.some(
1606
- (id) => ModuleManager.getModuleById(id)?.type === "remote"
1607
- );
1608
- if (hasRemoteModule) {
1609
- const mcpCmd = 'claude_m2 mcp add --transport sse --header "Authorization: Bearer mcp_00557dabb71297b4f9ac5fe748395f2c" -- api-metadata https://api-metadata.yungu.org/sse';
1610
- const { execaCommand } = await import("execa");
1611
- try {
1612
- await execaCommand(mcpCmd);
1613
- logger.info("\u8FDC\u7A0B MCP \u670D\u52A1 api-metadata \u5DF2\u6CE8\u518C");
1614
- } catch (err) {
1615
- logger.warn("\u8FDC\u7A0B MCP \u670D\u52A1\u6CE8\u518C\u5931\u8D25\uFF0C\u53EF\u80FD\u5DF2\u5B58\u5728\u6216\u6743\u9650\u4E0D\u8DB3");
1616
- }
1617
- }
1618
- }
1619
- },
1620
1562
  {
1621
- title: "\u6CE8\u5165\u901A\u7528\u6A21\u5757",
1563
+ title: "\u6CE8\u5165\u9009\u5B9A\u7684\u901A\u7528\u6A21\u5757",
1622
1564
  task: async () => {
1623
1565
  if (selectedModules.length === 0) return;
1624
1566
  const templatesDir = path7.resolve(FileUtils.getDirName(import.meta.url), "../templates");
1625
1567
  for (const moduleId of selectedModules) {
1626
1568
  await ModuleManager.injectModule(projectPath, moduleId, templatesDir);
1627
- logger.info(`\u6CE8\u5165\u6A21\u5757: ${moduleId}`);
1628
1569
  }
1629
1570
  }
1630
1571
  },
1631
- {
1632
- title: "\u6267\u884C\u8FDC\u7A0B\u6A21\u5757\u4EE3\u7801\u751F\u6210",
1633
- task: async () => {
1634
- const remoteModules = selectedModules.map((id) => ModuleManager.getModuleById(id)).filter((m) => m?.type === "remote");
1635
- if (remoteModules.length === 0) return;
1636
- const { execaCommand } = await import("execa");
1637
- for (const module of remoteModules) {
1638
- if (!module) continue;
1639
- logger.info(`\u6B63\u5728\u4E3A\u60A8\u751F\u6210 ${module.name} \u7684\u8FDC\u7A0B\u8C03\u7528\u4EE3\u7801...`);
1640
- const prompt = `\u4F7F\u7528 api-metadata MCP \u5DE5\u5177\u83B7\u53D6\u6240\u6709\u4E0E "${module.id.replace("-remote", "")}" \u76F8\u5173\u7684 API \u5143\u6570\u636E\u3002
1641
- \u7136\u540E\u5728\u9879\u76EE\u8DEF\u5F84 \`${projectPath}\` \u7684\u540E\u7AEF\u76EE\u5F55\u4E2D\uFF0C\u76F4\u63A5\u751F\u6210\u5BF9\u5E94\u7684 Java \u8C03\u7528\u4EE3\u7801\uFF08\u5982 Feign Client \u6216 RestTemplate \u5C01\u88C5\uFF09\u3002
1642
- \u8BF7\u786E\u4FDD\u4EE3\u7801\u7B26\u5408 \`CONVENTIONS.md\` \u4E2D\u7684\u89C4\u8303\u3002
1643
- \u751F\u6210\u5B8C\u6210\u540E\uFF0C\u8BF7\u7B80\u8981\u5217\u51FA\u751F\u6210\u7684\u6587\u4EF6\u3002`;
1644
- try {
1645
- await execaCommand(`claude_m2 -p "${prompt}" --add-dir ${projectPath}`, {
1646
- stdio: "inherit",
1647
- timeout: 3e5
1648
- // 5分钟超时
1649
- });
1650
- } catch (err) {
1651
- logger.error(`${module.name} \u4EE3\u7801\u751F\u6210\u5931\u8D25\uFF0C\u60A8\u53EF\u4EE5\u7A0D\u540E\u5728\u5F00\u53D1\u6A21\u5F0F\u4E0B\u624B\u52A8\u8FD0\u884C\u3002`);
1652
- }
1572
+ ...options.docker ? [
1573
+ {
1574
+ title: "\u751F\u6210 Docker \u90E8\u7F72\u914D\u7F6E",
1575
+ task: async () => {
1576
+ await generateDockerFiles(projectPath, projectName);
1653
1577
  }
1654
1578
  }
1655
- }
1579
+ ] : []
1656
1580
  ],
1657
- {
1658
- concurrent: false,
1659
- exitOnError: true
1660
- }
1581
+ { concurrent: false, exitOnError: true }
1661
1582
  );
1662
1583
  await tasks.run();
1584
+ const remoteModules = selectedModules.map((id) => ModuleManager.getModuleById(id)).filter((m) => m?.type === "remote");
1585
+ if (remoteModules.length > 0) {
1586
+ logger.newLine();
1587
+ logger.header("\u5904\u7406\u8FDC\u7A0B\u6A21\u5757");
1588
+ const { execa: e } = await import("execa");
1589
+ try {
1590
+ logger.info("\u6B63\u5728\u6CE8\u518C\u8FDC\u7A0B MCP \u670D\u52A1 api-metadata...");
1591
+ await e("claude", [
1592
+ "mcp",
1593
+ "add",
1594
+ "--transport",
1595
+ "sse",
1596
+ "--header",
1597
+ "Authorization: Bearer mcp_00557dabb71297b4f9ac5fe748395f2c",
1598
+ "--",
1599
+ "api-metadata",
1600
+ "https://api-metadata.yungu.org/sse"
1601
+ ]);
1602
+ logger.success("\u8FDC\u7A0B MCP \u670D\u52A1\u6CE8\u518C\u6210\u529F");
1603
+ } catch (err) {
1604
+ logger.warn("\u8FDC\u7A0B MCP \u670D\u52A1\u6CE8\u518C\u63D0\u793A: \u53EF\u80FD\u5DF2\u5B58\u5728\u6216\u624B\u52A8\u6CE8\u518C");
1605
+ }
1606
+ for (const module of remoteModules) {
1607
+ if (!module) continue;
1608
+ logger.newLine();
1609
+ logger.info(`\u6B63\u5728\u4E3A\u60A8\u751F\u6210 [${module.name}] \u7684\u8FDC\u7A0B\u8C03\u7528\u4EE3\u7801...`);
1610
+ const prompt = `\u4F7F\u7528 api-metadata MCP \u5DE5\u5177\u83B7\u53D6\u6240\u6709\u4E0E "${module.id.replace("-remote", "")}" \u76F8\u5173\u7684 API \u5143\u6570\u636E\u3002
1611
+ \u7136\u540E\u5728\u9879\u76EE\u8DEF\u5F84 \`${projectPath}\` \u7684\u540E\u7AEF\u76EE\u5F55\u4E2D\uFF0C\u76F4\u63A5\u751F\u6210\u5BF9\u5E94\u7684 Java \u8C03\u7528\u4EE3\u7801\uFF08\u5982 Feign Client \u6216 RestTemplate \u5C01\u88C5\uFF09\u3002
1612
+ \u8BF7\u786E\u4FDD\u4EE3\u7801\u7B26\u5408 \`CONVENTIONS.md\` \u4E2D\u7684\u89C4\u8303\u3002
1613
+ \u751F\u6210\u5B8C\u6210\u540E\uFF0C\u68C0\u67E5\u5E76\u4FEE\u590D\u4EFB\u4F55\u7F16\u8BD1\u9519\u8BEF\uFF0C\u6700\u540E\u7B80\u8981\u5217\u51FA\u751F\u6210\u7684\u6587\u4EF6\u3002`;
1614
+ try {
1615
+ await e("claude", ["-p", prompt, "--add-dir", projectPath], {
1616
+ stdio: "inherit",
1617
+ timeout: 6e5
1618
+ });
1619
+ logger.success(`[${module.name}] \u4EE3\u7801\u751F\u6210\u5B8C\u6210`);
1620
+ } catch (err) {
1621
+ logger.error(`[${module.name}] \u4EE3\u7801\u751F\u6210\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u624B\u52A8\u91CD\u8BD5`);
1622
+ }
1623
+ }
1624
+ }
1625
+ if (!options.noGit) {
1626
+ logger.newLine();
1627
+ await initGit(projectPath, projectName);
1628
+ }
1663
1629
  logger.newLine();
1664
- logger.success(`\u9879\u76EE ${projectName} \u521D\u59CB\u5316\u5B8C\u6210\uFF01`);
1630
+ logger.success(`\u9879\u76EE ${projectName} \u521D\u59CB\u5316\u6210\u529F\uFF01`);
1665
1631
  logger.newLine();
1666
1632
  logger.info("\u4E0B\u4E00\u6B65:");
1667
1633
  logger.step(`cd ${projectName}`);
@@ -2309,8 +2275,48 @@ async function cloneFrontendTemplate(projectPath, versionOptions = {}) {
2309
2275
  await FileUtils.ensureDir(path7.join(frontendPath, "src/components"));
2310
2276
  }
2311
2277
  }
2312
- async function generateDockerFiles() {
2313
- logger.info("Docker \u914D\u7F6E\u751F\u6210\u5F85\u5B9E\u73B0");
2278
+ async function generateDockerFiles(projectPath, projectName) {
2279
+ const backendPath = path7.join(projectPath, "backend");
2280
+ if (!await FileUtils.exists(backendPath)) {
2281
+ logger.warn("\u672A\u627E\u5230 backend \u76EE\u5F55\uFF0C\u8DF3\u8FC7 Docker \u914D\u7F6E\u751F\u6210");
2282
+ return;
2283
+ }
2284
+ const dockerfile = `FROM openjdk:17-jdk-slim
2285
+ WORKDIR /app
2286
+ COPY build/libs/*.jar app.jar
2287
+ EXPOSE 8080
2288
+ ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
2289
+ `;
2290
+ const deploySh = `#!/bin/bash
2291
+ # yg-team-cli \u81EA\u52A8\u751F\u6210\u7684\u90E8\u7F72\u811A\u672C
2292
+ # \u504F\u597D\uFF1AAliyun \u955C\u50CF\u4ED3\u5E93, Gradle \u6784\u5EFA, \u5237\u65B0\u4F9D\u8D56, \u8DF3\u8FC7\u6D4B\u8BD5
2293
+
2294
+ PROJECT_NAME="${projectName}"
2295
+ TIMESTAMP=$(date +%Y%m%d%H%M%S)
2296
+ REGISTRY="registry.cn-hangzhou.aliyuncs.com/yungu-app"
2297
+ IMAGE_TAG="\${PROJECT_NAME}:\${TIMESTAMP}"
2298
+
2299
+ echo "\u{1F418} \u5F00\u59CB Gradle \u6784\u5EFA (\u8DF3\u8FC7\u6D4B\u8BD5, \u5237\u65B0\u4F9D\u8D56)..."
2300
+ ./gradlew clean build -x test --refresh-dependencies
2301
+
2302
+ if [ $? -ne 0 ]; then
2303
+ echo "\u274C \u6784\u5EFA\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u4EE3\u7801"
2304
+ exit 1
2305
+ fi
2306
+
2307
+ echo "\u{1F433} \u6784\u5EFA Docker \u955C\u50CF..."
2308
+ docker build -t \${REGISTRY}/\${IMAGE_TAG} .
2309
+ docker tag \${REGISTRY}/\${IMAGE_TAG} \${REGISTRY}/\${PROJECT_NAME}:latest
2310
+
2311
+ echo "\u{1F680} \u63A8\u9001\u955C\u50CF\u5230\u963F\u91CC\u4E91..."
2312
+ docker push \${REGISTRY}/\${IMAGE_TAG}
2313
+ docker push \${REGISTRY}/\${PROJECT_NAME}:latest
2314
+
2315
+ echo "\u2705 \u90E8\u7F72\u5B8C\u6210! \u955C\u50CF\u5730\u5740: \${REGISTRY}/\${IMAGE_TAG}"
2316
+ `;
2317
+ await fs4.writeFile(path7.join(backendPath, "Dockerfile"), dockerfile);
2318
+ await fs4.writeFile(path7.join(backendPath, "deploy.sh"), deploySh);
2319
+ await fs4.chmod(path7.join(backendPath, "deploy.sh"), 493);
2314
2320
  }
2315
2321
  async function initGit(projectPath, projectName) {
2316
2322
  try {