@coze-arch/cli 0.0.1-alpha.db1c06 → 0.0.1-alpha.dcc485

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.
Files changed (132) hide show
  1. package/README.md +1 -0
  2. package/lib/__templates__/expo/_npmrc +1 -0
  3. package/lib/__templates__/expo/client/components/Screen.tsx +2 -2
  4. package/lib/__templates__/expo/client/eslint.config.mjs +7 -0
  5. package/lib/__templates__/expo/client/scripts/install-missing-deps.js +10 -10
  6. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/index.js +9 -0
  7. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/rule.js +112 -0
  8. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/tech.md +94 -0
  9. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/index.js +9 -0
  10. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/rule.js +120 -0
  11. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/tech.md +58 -0
  12. package/lib/__templates__/nextjs/AGENTS.md +54 -0
  13. package/lib/__templates__/nextjs/README.md +5 -0
  14. package/lib/__templates__/nextjs/eslint.config.mjs +5 -0
  15. package/lib/__templates__/nextjs/next.config.ts +1 -2
  16. package/lib/__templates__/nextjs/package.json +2 -5
  17. package/lib/__templates__/nextjs/pnpm-lock.yaml +1028 -5
  18. package/lib/__templates__/nextjs/scripts/build.sh +4 -1
  19. package/lib/__templates__/nextjs/scripts/dev.sh +8 -2
  20. package/lib/__templates__/nextjs/scripts/start.sh +7 -1
  21. package/lib/__templates__/nextjs/src/app/layout.tsx +1 -1
  22. package/lib/__templates__/nextjs/src/app/page.tsx +1 -2
  23. package/lib/__templates__/nextjs/src/server.ts +35 -0
  24. package/lib/__templates__/nextjs/tsconfig.json +1 -1
  25. package/lib/__templates__/nuxt-vue/.coze +12 -0
  26. package/lib/__templates__/nuxt-vue/AGENTS.md +42 -0
  27. package/lib/__templates__/nuxt-vue/README.md +73 -0
  28. package/lib/__templates__/nuxt-vue/_gitignore +24 -0
  29. package/lib/__templates__/nuxt-vue/_npmrc +23 -0
  30. package/lib/__templates__/nuxt-vue/app/app.vue +6 -0
  31. package/lib/__templates__/nuxt-vue/app/pages/index.vue +23 -0
  32. package/lib/__templates__/nuxt-vue/assets/css/main.css +24 -0
  33. package/lib/__templates__/nuxt-vue/nuxt.config.ts +116 -0
  34. package/lib/__templates__/nuxt-vue/package.json +35 -0
  35. package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +8759 -0
  36. package/lib/__templates__/nuxt-vue/postcss.config.mjs +8 -0
  37. package/lib/__templates__/nuxt-vue/public/favicon.ico +0 -0
  38. package/lib/__templates__/nuxt-vue/public/robots.txt +2 -0
  39. package/lib/__templates__/nuxt-vue/scripts/build.sh +14 -0
  40. package/lib/__templates__/nuxt-vue/scripts/dev.sh +39 -0
  41. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +14 -0
  42. package/lib/__templates__/nuxt-vue/scripts/start.sh +21 -0
  43. package/lib/__templates__/nuxt-vue/server/api/hello.ts +10 -0
  44. package/lib/__templates__/nuxt-vue/server/middleware/logger.ts +10 -0
  45. package/lib/__templates__/nuxt-vue/server/routes/health.ts +10 -0
  46. package/lib/__templates__/nuxt-vue/tailwind.config.js +13 -0
  47. package/lib/__templates__/nuxt-vue/template.config.js +87 -0
  48. package/lib/__templates__/nuxt-vue/tsconfig.json +18 -0
  49. package/lib/__templates__/taro/README.md +57 -45
  50. package/lib/__templates__/taro/config/index.ts +106 -41
  51. package/lib/__templates__/taro/config/prod.ts +4 -5
  52. package/lib/__templates__/taro/eslint.config.mjs +62 -6
  53. package/lib/__templates__/taro/package.json +19 -4
  54. package/lib/__templates__/taro/patches/@tarojs__plugin-mini-ci@4.1.9.patch +30 -0
  55. package/lib/__templates__/taro/pnpm-lock.yaml +912 -206
  56. package/lib/__templates__/taro/src/app.css +140 -36
  57. package/lib/__templates__/taro/src/components/ui/accordion.tsx +159 -0
  58. package/lib/__templates__/taro/src/components/ui/alert-dialog.tsx +260 -0
  59. package/lib/__templates__/taro/src/components/ui/alert.tsx +60 -0
  60. package/lib/__templates__/taro/src/components/ui/aspect-ratio.tsx +36 -0
  61. package/lib/__templates__/taro/src/components/ui/avatar.tsx +84 -0
  62. package/lib/__templates__/taro/src/components/ui/badge.tsx +37 -0
  63. package/lib/__templates__/taro/src/components/ui/breadcrumb.tsx +117 -0
  64. package/lib/__templates__/taro/src/components/ui/button-group.tsx +83 -0
  65. package/lib/__templates__/taro/src/components/ui/button.tsx +67 -0
  66. package/lib/__templates__/taro/src/components/ui/calendar.tsx +394 -0
  67. package/lib/__templates__/taro/src/components/ui/card.tsx +108 -0
  68. package/lib/__templates__/taro/src/components/ui/carousel.tsx +228 -0
  69. package/lib/__templates__/taro/src/components/ui/checkbox.tsx +58 -0
  70. package/lib/__templates__/taro/src/components/ui/code-block.tsx +169 -0
  71. package/lib/__templates__/taro/src/components/ui/collapsible.tsx +71 -0
  72. package/lib/__templates__/taro/src/components/ui/command.tsx +385 -0
  73. package/lib/__templates__/taro/src/components/ui/context-menu.tsx +614 -0
  74. package/lib/__templates__/taro/src/components/ui/dialog.tsx +256 -0
  75. package/lib/__templates__/taro/src/components/ui/drawer.tsx +192 -0
  76. package/lib/__templates__/taro/src/components/ui/dropdown-menu.tsx +561 -0
  77. package/lib/__templates__/taro/src/components/ui/field.tsx +228 -0
  78. package/lib/__templates__/taro/src/components/ui/hover-card.tsx +282 -0
  79. package/lib/__templates__/taro/src/components/ui/input-group.tsx +197 -0
  80. package/lib/__templates__/taro/src/components/ui/input-otp.tsx +136 -0
  81. package/lib/__templates__/taro/src/components/ui/input.tsx +56 -0
  82. package/lib/__templates__/taro/src/components/ui/label.tsx +24 -0
  83. package/lib/__templates__/taro/src/components/ui/menubar.tsx +595 -0
  84. package/lib/__templates__/taro/src/components/ui/navigation-menu.tsx +264 -0
  85. package/lib/__templates__/taro/src/components/ui/pagination.tsx +118 -0
  86. package/lib/__templates__/taro/src/components/ui/popover.tsx +291 -0
  87. package/lib/__templates__/taro/src/components/ui/portal.tsx +19 -0
  88. package/lib/__templates__/taro/src/components/ui/progress.tsx +28 -0
  89. package/lib/__templates__/taro/src/components/ui/radio-group.tsx +64 -0
  90. package/lib/__templates__/taro/src/components/ui/resizable.tsx +346 -0
  91. package/lib/__templates__/taro/src/components/ui/scroll-area.tsx +34 -0
  92. package/lib/__templates__/taro/src/components/ui/select.tsx +438 -0
  93. package/lib/__templates__/taro/src/components/ui/separator.tsx +30 -0
  94. package/lib/__templates__/taro/src/components/ui/sheet.tsx +262 -0
  95. package/lib/__templates__/taro/src/components/ui/skeleton.tsx +17 -0
  96. package/lib/__templates__/taro/src/components/ui/slider.tsx +203 -0
  97. package/lib/__templates__/taro/src/components/ui/sonner.tsx +1 -0
  98. package/lib/__templates__/taro/src/components/ui/switch.tsx +55 -0
  99. package/lib/__templates__/taro/src/components/ui/table.tsx +142 -0
  100. package/lib/__templates__/taro/src/components/ui/tabs.tsx +114 -0
  101. package/lib/__templates__/taro/src/components/ui/textarea.tsx +54 -0
  102. package/lib/__templates__/taro/src/components/ui/toast.tsx +517 -0
  103. package/lib/__templates__/taro/src/components/ui/toggle-group.tsx +120 -0
  104. package/lib/__templates__/taro/src/components/ui/toggle.tsx +77 -0
  105. package/lib/__templates__/taro/src/components/ui/tooltip.tsx +455 -0
  106. package/lib/__templates__/taro/src/lib/hooks/use-keyboard-offset.ts +37 -0
  107. package/lib/__templates__/taro/src/lib/measure.ts +115 -0
  108. package/lib/__templates__/taro/src/lib/platform.ts +12 -0
  109. package/lib/__templates__/taro/src/lib/utils.ts +6 -0
  110. package/lib/__templates__/taro/src/presets/dev-debug.ts +23 -0
  111. package/lib/__templates__/taro/src/presets/h5-container.tsx +15 -0
  112. package/lib/__templates__/taro/src/presets/h5-navbar.tsx +97 -30
  113. package/lib/__templates__/taro/src/presets/h5-styles.ts +192 -5
  114. package/lib/__templates__/taro/src/presets/index.tsx +4 -4
  115. package/lib/__templates__/templates.json +32 -0
  116. package/lib/__templates__/vite/AGENTS.md +41 -0
  117. package/lib/__templates__/vite/README.md +190 -11
  118. package/lib/__templates__/vite/_gitignore +1 -0
  119. package/lib/__templates__/vite/eslint.config.mjs +6 -1
  120. package/lib/__templates__/vite/package.json +10 -3
  121. package/lib/__templates__/vite/pnpm-lock.yaml +755 -15
  122. package/lib/__templates__/vite/scripts/build.sh +4 -1
  123. package/lib/__templates__/vite/scripts/dev.sh +9 -2
  124. package/lib/__templates__/vite/scripts/start.sh +9 -3
  125. package/lib/__templates__/vite/server/routes/index.ts +31 -0
  126. package/lib/__templates__/vite/server/server.ts +65 -0
  127. package/lib/__templates__/vite/server/vite.ts +67 -0
  128. package/lib/__templates__/vite/tsconfig.json +4 -3
  129. package/lib/__templates__/vite/vite.config.ts +4 -0
  130. package/lib/cli.js +99 -92
  131. package/package.json +6 -3
  132. package/lib/__templates__/taro/src/presets/wx-debug.ts +0 -23
@@ -8,7 +8,10 @@ cd "${COZE_WORKSPACE_PATH}"
8
8
  echo "Installing dependencies..."
9
9
  pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
10
10
 
11
- echo "Building the project..."
11
+ echo "Building frontend with Vite..."
12
12
  npx vite build
13
13
 
14
+ echo "Bundling server with tsup..."
15
+ npx tsup server/server.ts --format cjs --platform node --target node20 --outDir dist-server --no-splitting --no-minify --external vite
16
+
14
17
  echo "Build completed successfully!"
@@ -1,9 +1,16 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
3
 
4
+ <% if (process.env.NODE_ENV === 'test') { %>
5
+ # 测试环境:支持环境变量覆盖端口
6
+ PORT="${PORT:-<%= port %>}"
7
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
8
+ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
9
+ <% } else { %>
4
10
  PORT=<%= port %>
5
11
  COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
6
12
  DEPLOY_RUN_PORT=<%= port %>
13
+ <% } %>
7
14
 
8
15
  cd "${COZE_WORKSPACE_PATH}"
9
16
 
@@ -27,6 +34,6 @@ kill_port_if_listening() {
27
34
 
28
35
  echo "Clearing port ${PORT} before start."
29
36
  kill_port_if_listening
30
- echo "Starting HTTP service on port ${PORT} for dev..."
37
+ echo "Starting express + Vite dev server on port ${PORT}..."
31
38
 
32
- npx vite --port $PORT
39
+ PORT=$PORT npx tsx watch server/server.ts
@@ -2,14 +2,20 @@
2
2
  set -Eeuo pipefail
3
3
 
4
4
  COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
5
+ <% if (process.env.NODE_ENV === 'test') { %>
6
+ # 测试环境:支持环境变量覆盖端口
7
+ PORT="${PORT:-<%= port %>}"
8
+ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
9
+ <% } else { %>
5
10
  PORT=<%= port %>
6
11
  DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-$PORT}"
12
+ <% } %>
7
13
 
8
14
  start_service() {
9
15
  cd "${COZE_WORKSPACE_PATH}"
10
- echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for deploy..."
11
- npx vite preview --port $DEPLOY_RUN_PORT
16
+ echo "Starting express production server on port ${DEPLOY_RUN_PORT}..."
17
+ PORT=$DEPLOY_RUN_PORT node dist-server/server.js
12
18
  }
13
19
 
14
- echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for deploy..."
20
+ echo "Starting express production server on port ${DEPLOY_RUN_PORT}..."
15
21
  start_service
@@ -0,0 +1,31 @@
1
+ import { Router } from 'express';
2
+
3
+ const router = Router();
4
+
5
+ // API 路由示例
6
+ router.get('/api/hello', (req, res) => {
7
+ res.json({
8
+ message: 'Hello from Express + Vite!',
9
+ timestamp: new Date().toISOString(),
10
+ });
11
+ });
12
+
13
+ router.post('/api/data', (req, res) => {
14
+ const requestData = req.body;
15
+ res.json({
16
+ success: true,
17
+ data: requestData,
18
+ receivedAt: new Date().toISOString(),
19
+ });
20
+ });
21
+
22
+ // 健康检查接口
23
+ router.get('/api/health', (req, res) => {
24
+ res.json({
25
+ status: 'ok',
26
+ env: process.env.COZE_PROJECT_ENV,
27
+ timestamp: new Date().toISOString(),
28
+ });
29
+ });
30
+
31
+ export default router;
@@ -0,0 +1,65 @@
1
+ // ABOUTME: Express server with Vite integration
2
+ // ABOUTME: Handles API routes and serves frontend in dev/prod modes
3
+
4
+ import { createServer, type Server } from 'http';
5
+ import express from 'express';
6
+ import router from './routes/index';
7
+ import { setupVite } from './vite';
8
+
9
+ const isDev = process.env.COZE_PROJECT_ENV !== 'PROD';
10
+ const port = parseInt(process.env.PORT || '<%= port %>', 10);
11
+ const hostname = process.env.HOSTNAME || 'localhost';
12
+ const app = express();
13
+ // 使用 http.createServer 包装 Express app,以便支持 WebSocket 等协议升级
14
+ const server = createServer(app);
15
+
16
+ async function startServer(): Promise<Server> {
17
+ // 请求日志(仅开发环境)
18
+ if (isDev) {
19
+ app.use((req, res, next) => {
20
+ const start = Date.now();
21
+ res.on('finish', () => {
22
+ const ms = Date.now() - start;
23
+ console.log(`${req.method} ${req.url} - ${ms}ms`);
24
+ });
25
+ next();
26
+ });
27
+ }
28
+
29
+ // 添加请求体解析
30
+ app.use(express.json());
31
+ app.use(express.urlencoded({ extended: true }));
32
+
33
+ // 注册 API 路由
34
+ app.use(router);
35
+
36
+ // 集成 Vite(开发模式)或静态文件服务(生产模式)
37
+ await setupVite(app);
38
+
39
+ // 全局错误处理
40
+ app.use((err: Error, req: express.Request, res: express.Response) => {
41
+ console.error('Server error:', err);
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ const status = 'status' in err ? (err as any).status || 500 : 500;
44
+ res.status(status).json({
45
+ error: err.message || 'Internal server error',
46
+ });
47
+ });
48
+
49
+ server.once('error', err => {
50
+ console.error('Server error:', err);
51
+ process.exit(1);
52
+ });
53
+
54
+ server.listen(port, () => {
55
+ console.log(`\n✨ Server running at http://${hostname}:${port}`);
56
+ console.log(`📝 Environment: ${isDev ? 'development' : 'production'}\n`);
57
+ });
58
+
59
+ return server;
60
+ }
61
+
62
+ startServer().catch(err => {
63
+ console.error('Failed to start server:', err);
64
+ process.exit(1);
65
+ });
@@ -0,0 +1,67 @@
1
+ // ABOUTME: Vite integration for Express server
2
+ // ABOUTME: Handles dev middleware and production static file serving
3
+
4
+ import type { Application, Request, Response } from 'express';
5
+ import express from 'express';
6
+ import path from 'path';
7
+ import fs from 'fs';
8
+ import { createServer as createViteServer } from 'vite';
9
+ import viteConfig from '../vite.config';
10
+
11
+ const isDev = process.env.COZE_PROJECT_ENV !== 'PROD';
12
+
13
+ /**
14
+ * 集成 Vite 开发服务器(中间件模式)
15
+ */
16
+ export async function setupViteMiddleware(app: Application) {
17
+ const vite = await createViteServer({
18
+ ...viteConfig,
19
+ server: {
20
+ ...viteConfig.server,
21
+ middlewareMode: true,
22
+ },
23
+ appType: 'spa',
24
+ });
25
+
26
+ // 使用 Vite middleware
27
+ app.use(vite.middlewares);
28
+
29
+ console.log('🚀 Vite dev server initialized');
30
+ }
31
+
32
+ /**
33
+ * 设置生产环境静态文件服务
34
+ */
35
+ export function setupStaticServer(app: Application) {
36
+ const distPath = path.resolve(process.cwd(), 'dist');
37
+
38
+ if (!fs.existsSync(distPath)) {
39
+ console.error('❌ dist folder not found. Please run "pnpm build" first.');
40
+ process.exit(1);
41
+ }
42
+
43
+ // 1. 服务静态文件(如果存在对应文件则直接返回)
44
+ app.use(express.static(distPath));
45
+
46
+ // 2. SPA fallback - 所有未处理的请求返回 index.html
47
+ // 到达这里的请求说明:
48
+ // - 不是 API 请求(已被前面注册的路由处理)
49
+ // - 不是静态文件(express.static 未找到对应文件)
50
+ // - 需要返回 index.html 让前端路由处理
51
+ app.use((_req: Request, res: Response) => {
52
+ res.sendFile(path.join(distPath, 'index.html'));
53
+ });
54
+
55
+ console.log('📦 Serving static files from dist/');
56
+ }
57
+
58
+ /**
59
+ * 根据环境设置 Vite
60
+ */
61
+ export async function setupVite(app: Application) {
62
+ if (isDev) {
63
+ await setupViteMiddleware(app);
64
+ } else {
65
+ setupStaticServer(app);
66
+ }
67
+ }
@@ -3,14 +3,15 @@
3
3
  "target": "ES2020",
4
4
  "lib": ["ES2020", "DOM", "DOM.Iterable"],
5
5
  "module": "ESNext",
6
- "moduleResolution": "bundler",
6
+ "moduleResolution": "node",
7
7
  "strict": true,
8
8
  "esModuleInterop": true,
9
9
  "skipLibCheck": true,
10
10
  "forceConsistentCasingInFileNames": true,
11
11
  "resolveJsonModule": true,
12
12
  "isolatedModules": true,
13
- "noEmit": true
13
+ "noEmit": true,
14
+ "types": ["node"]
14
15
  },
15
- "include": ["src"]
16
+ "include": ["src", "server"]
16
17
  }
@@ -12,5 +12,9 @@ export default defineConfig({
12
12
  clientPort: 443,
13
13
  timeout: 30000,
14
14
  },
15
+ watch: {
16
+ usePolling: true,
17
+ interval: 100,
18
+ }
15
19
  },
16
20
  });
package/lib/cli.js CHANGED
@@ -1722,38 +1722,6 @@ const collectFilesToRender = async (options
1722
1722
 
1723
1723
  return filesToWrite;
1724
1724
  };
1725
-
1726
- /**
1727
- * 检测文件冲突
1728
- *
1729
- * @param outputPath - 输出目录路径
1730
- * @param filesToWrite - 将要写入的文件路径列表
1731
- * @returns 冲突的文件路径列表
1732
- */
1733
- const detectFileConflicts = (
1734
- outputPath,
1735
- filesToWrite,
1736
- ) => {
1737
- logger.verbose('\nChecking for file conflicts...');
1738
-
1739
- const conflicts = [];
1740
-
1741
- for (const file of filesToWrite) {
1742
- const fullPath = path.join(outputPath, file);
1743
- if (fs.existsSync(fullPath)) {
1744
- conflicts.push(file);
1745
- logger.verbose(` ⚠ Conflict detected: ${file}`);
1746
- }
1747
- }
1748
-
1749
- if (conflicts.length === 0) {
1750
- logger.verbose(' ✓ No conflicts detected');
1751
- } else {
1752
- logger.verbose(` ⚠ ${conflicts.length} conflicts detected`);
1753
- }
1754
-
1755
- return conflicts;
1756
- };
1757
1725
  // end_aigc
1758
1726
 
1759
1727
  // ABOUTME: Main file processing orchestration for template rendering
@@ -1809,7 +1777,7 @@ const processSingleFile = async (options
1809
1777
  * 1. 验证模板目录
1810
1778
  * 2. 扫描所有模板文件
1811
1779
  * 3. Dry-run:收集将要写入的文件列表(考虑 hooks 影响)
1812
- * 4. 冲突检测:检查是否有文件会被覆盖
1780
+ * 4. 冲突检测:检查是否有文件会被覆盖(可通过 force 跳过)
1813
1781
  * 5. 实际写入:渲染并写入所有文件
1814
1782
  * 6. 复制 node_modules(如果存在)
1815
1783
  *
@@ -1820,8 +1788,9 @@ const processTemplateFiles = async (options
1820
1788
 
1821
1789
 
1822
1790
 
1791
+
1823
1792
  ) => {
1824
- const { templatePath, outputPath, context, templateConfig } = options;
1793
+ const { templatePath, outputPath, context, templateConfig} = options;
1825
1794
  logger.verbose('Processing template files:');
1826
1795
  logger.verbose(` - Template path: ${templatePath}`);
1827
1796
  logger.verbose(` - Output path: ${outputPath}`);
@@ -1853,23 +1822,17 @@ const processTemplateFiles = async (options
1853
1822
  }
1854
1823
 
1855
1824
  // 阶段 2: Dry-run - 收集所有将要写入的文件
1856
- const filesToWrite = await collectFilesToRender({
1825
+ await collectFilesToRender({
1857
1826
  files,
1858
1827
  templatePath,
1859
1828
  context,
1860
1829
  templateConfig,
1861
1830
  });
1862
1831
 
1863
- // 阶段 3: 冲突检测
1864
- const conflicts = detectFileConflicts(outputPath, filesToWrite);
1865
-
1866
- if (conflicts.length > 0) {
1867
- // 有冲突,抛出详细的错误信息
1868
- const conflictList = conflicts.map(f => ` - ${f}`).join('\n');
1869
- throw new Error(
1870
- `File conflicts detected in output directory: ${outputPath}\n\n` +
1871
- `The following files already exist and would be overwritten:\n${conflictList}\n\n` +
1872
- 'Please remove these files or use a different output directory.',
1832
+ // 阶段 3: 冲突检测(force 为 true 时跳过)
1833
+ {
1834
+ logger.verbose(
1835
+ ' - Force mode enabled, skipping conflict detection. Existing files will be overwritten.',
1873
1836
  );
1874
1837
  }
1875
1838
 
@@ -1902,6 +1865,7 @@ const processTemplateFiles = async (options
1902
1865
 
1903
1866
 
1904
1867
 
1868
+
1905
1869
  /**
1906
1870
  * 加载模板元数据和路径
1907
1871
  */
@@ -2011,7 +1975,7 @@ const prepareOutputDirectory = (outputPath) => {
2011
1975
  const execute = async (
2012
1976
  options,
2013
1977
  ) => {
2014
- const { templateName, outputPath, command } = options;
1978
+ const { templateName, outputPath, command} = options;
2015
1979
 
2016
1980
  // 1. 加载模板
2017
1981
  const { templatePath } = await loadTemplateMetadata(templateName);
@@ -2035,8 +1999,7 @@ const execute = async (
2035
1999
  templatePath,
2036
2000
  outputPath: absoluteOutputPath,
2037
2001
  context,
2038
- templateConfig,
2039
- });
2002
+ templateConfig});
2040
2003
 
2041
2004
  // 7. 执行 onAfterRender 钩子
2042
2005
  await executeAfterRenderHook(templateConfig, context, absoluteOutputPath);
@@ -2087,7 +2050,40 @@ const runPnpmInstall = (projectPath) => {
2087
2050
  };
2088
2051
 
2089
2052
  /**
2090
- * 初始化 git 仓库并创建初始提交
2053
+ * 运行 git 命令的辅助函数
2054
+ */
2055
+ const runGitCommand = (command, projectPath) => {
2056
+ logger.info(`Executing: ${command}`);
2057
+
2058
+ const result = shelljs.exec(command, {
2059
+ cwd: projectPath,
2060
+ silent: true,
2061
+ });
2062
+
2063
+ // 输出命令的结果
2064
+ if (result.stdout) {
2065
+ process.stdout.write(result.stdout);
2066
+ }
2067
+
2068
+ if (result.stderr) {
2069
+ process.stderr.write(result.stderr);
2070
+ }
2071
+
2072
+ if (result.code !== 0) {
2073
+ const errorMessage = [
2074
+ `${command} failed with exit code ${result.code}`,
2075
+ result.stderr ? `\nStderr:\n${result.stderr}` : '',
2076
+ result.stdout ? `\nStdout:\n${result.stdout}` : '',
2077
+ ]
2078
+ .filter(Boolean)
2079
+ .join('');
2080
+
2081
+ throw new Error(errorMessage);
2082
+ }
2083
+ };
2084
+
2085
+ /**
2086
+ * 初始化 git 仓库
2091
2087
  * 如果目录中已存在 .git,则跳过初始化
2092
2088
  */
2093
2089
  const runGitInit = (projectPath) => {
@@ -2100,46 +2096,9 @@ const runGitInit = (projectPath) => {
2100
2096
  return;
2101
2097
  }
2102
2098
 
2103
- const runGitCommand = (command) => {
2104
- logger.info(`Executing: ${command}`);
2105
-
2106
- const result = shelljs.exec(command, {
2107
- cwd: projectPath,
2108
- silent: true,
2109
- });
2110
-
2111
- // 输出命令的结果
2112
- if (result.stdout) {
2113
- process.stdout.write(result.stdout);
2114
- }
2115
-
2116
- if (result.stderr) {
2117
- process.stderr.write(result.stderr);
2118
- }
2119
-
2120
- if (result.code !== 0) {
2121
- const errorMessage = [
2122
- `${command} failed with exit code ${result.code}`,
2123
- result.stderr ? `\nStderr:\n${result.stderr}` : '',
2124
- result.stdout ? `\nStdout:\n${result.stdout}` : '',
2125
- ]
2126
- .filter(Boolean)
2127
- .join('');
2128
-
2129
- throw new Error(errorMessage);
2130
- }
2131
- };
2132
-
2133
2099
  try {
2134
2100
  logger.info('\nInitializing git repository...');
2135
- runGitCommand('git init');
2136
-
2137
- logger.info('Adding files to git...');
2138
- runGitCommand('git add .');
2139
-
2140
- logger.info('Creating initial commit...');
2141
- runGitCommand('git commit -m "chore: initial commit"');
2142
-
2101
+ runGitCommand('git init', projectPath);
2143
2102
  logger.success('Git repository initialized successfully!');
2144
2103
  } catch (error) {
2145
2104
  // Git 初始化失败不应该导致整个流程失败
@@ -2150,6 +2109,35 @@ const runGitInit = (projectPath) => {
2150
2109
  }
2151
2110
  };
2152
2111
 
2112
+ /**
2113
+ * 提交初始化生成的所有文件
2114
+ */
2115
+ const commitChanges = (projectPath) => {
2116
+ // 检查是否存在 .git 目录
2117
+ const gitDir = path.join(projectPath, '.git');
2118
+ if (!fs.existsSync(gitDir)) {
2119
+ logger.warn(
2120
+ '\n⚠️ Git repository does not exist, skipping commit. Run git init first.',
2121
+ );
2122
+ return;
2123
+ }
2124
+
2125
+ try {
2126
+ logger.info('\nCommitting initialized files...');
2127
+ runGitCommand('git add --all', projectPath);
2128
+ runGitCommand('git commit -m "chore: init env"', projectPath);
2129
+ logger.success('Changes committed successfully!');
2130
+ } catch (error) {
2131
+ // Commit 失败不应该导致整个流程失败
2132
+ logger.warn(
2133
+ `Git commit failed: ${error instanceof Error ? error.message : String(error)}`,
2134
+ );
2135
+ logger.info(
2136
+ 'You can manually commit later with: git add --all && git commit -m "chore: init env"',
2137
+ );
2138
+ }
2139
+ };
2140
+
2153
2141
  /**
2154
2142
  * 运行开发服务器(后台模式)
2155
2143
  * 启动后台子进程运行开发服务器,父进程可以直接退出
@@ -2191,6 +2179,8 @@ const executeInit = async (
2191
2179
 
2192
2180
 
2193
2181
 
2182
+
2183
+
2194
2184
  ,
2195
2185
  command,
2196
2186
  ) => {
@@ -2202,7 +2192,9 @@ const executeInit = async (
2202
2192
  output: outputPath,
2203
2193
  skipInstall,
2204
2194
  skipGit,
2195
+ skipCommit,
2205
2196
  skipDev,
2197
+ force,
2206
2198
  } = options;
2207
2199
 
2208
2200
  logger.info(`Initializing project with template: ${templateName}`);
@@ -2213,6 +2205,7 @@ const executeInit = async (
2213
2205
  templateName,
2214
2206
  outputPath,
2215
2207
  command,
2208
+ force,
2216
2209
  });
2217
2210
  const { outputPath: absoluteOutputPath, templateConfig, context } = result;
2218
2211
 
@@ -2245,6 +2238,12 @@ const executeInit = async (
2245
2238
  timer.logPhase('Git initialization');
2246
2239
  }
2247
2240
 
2241
+ // 如果没有跳过 commit,则提交初始化生成的文件
2242
+ if (!skipCommit) {
2243
+ commitChanges(absoluteOutputPath);
2244
+ timer.logPhase('Git commit');
2245
+ }
2246
+
2248
2247
  // 如果没有跳过 dev,则启动开发服务器
2249
2248
  if (!skipDev) {
2250
2249
  runDev(absoluteOutputPath);
@@ -2257,9 +2256,10 @@ const executeInit = async (
2257
2256
  logger.info(' pnpm install');
2258
2257
  }
2259
2258
  if (skipGit) {
2260
- logger.info(
2261
- ' git init && git add . && git commit -m "initial commit"',
2262
- );
2259
+ logger.info(' git init');
2260
+ }
2261
+ if (skipCommit) {
2262
+ logger.info(' git add --all && git commit -m "chore: init env"');
2263
2263
  }
2264
2264
  logger.info(' coze dev');
2265
2265
  }
@@ -2286,12 +2286,19 @@ const registerCommand$1 = program => {
2286
2286
  .option('-o, --output <path>', 'Output directory', process.cwd())
2287
2287
  .option('--skip-install', 'Skip automatic pnpm install', false)
2288
2288
  .option('--skip-git', 'Skip automatic git initialization', false)
2289
+ .option(
2290
+ '--skip-commit',
2291
+ 'Skip automatic git commit after initialization',
2292
+ false,
2293
+ )
2289
2294
  .option('--skip-dev', 'Skip automatic dev server start', false)
2290
2295
  .allowUnknownOption() // 允许透传参数
2291
2296
  .action(async (directory, options, command) => {
2292
2297
  // 位置参数优先级高于 --output 选项
2293
2298
  const outputPath = _nullishCoalesce(directory, () => ( options.output));
2294
- await executeInit({ ...options, output: outputPath }, command);
2299
+ // Always use force mode - overwrite existing files without conflict check
2300
+ const force = true;
2301
+ await executeInit({ ...options, output: outputPath, force }, command);
2295
2302
  });
2296
2303
  };
2297
2304
 
@@ -2591,7 +2598,7 @@ const registerCommand = program => {
2591
2598
  });
2592
2599
  };
2593
2600
 
2594
- var version = "0.0.1-alpha.db1c06";
2601
+ var version = "0.0.1-alpha.dcc485";
2595
2602
  var packageJson = {
2596
2603
  version: version};
2597
2604
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coze-arch/cli",
3
- "version": "0.0.1-alpha.db1c06",
3
+ "version": "0.0.1-alpha.dcc485",
4
4
  "private": false,
5
5
  "description": "coze coding devtools cli",
6
6
  "license": "MIT",
@@ -50,6 +50,7 @@
50
50
  "@coze-arch/vitest-config": "workspace:*",
51
51
  "@coze-coding/lambda": "workspace:*",
52
52
  "@inquirer/prompts": "^3.2.0",
53
+ "@playwright/test": "~1.55.0",
53
54
  "@types/ejs": "^3.1.5",
54
55
  "@types/iarna__toml": "^2.0.5",
55
56
  "@types/js-yaml": "^4.0.9",
@@ -57,14 +58,16 @@
57
58
  "@types/minimist": "^1.2.5",
58
59
  "@types/node": "^24",
59
60
  "@types/shelljs": "^0.10.0",
60
- "@vitest/coverage-v8": "~4.0.16",
61
+ "@vitest/coverage-v8": "~4.0.18",
61
62
  "json-schema-to-typescript": "^15.0.3",
62
63
  "minimatch": "^10.0.1",
64
+ "playwright": "~1.55.0",
63
65
  "rollup": "^4.41.1",
64
66
  "sucrase": "^3.35.0",
67
+ "tree-kill": "^1.2.2",
65
68
  "tsx": "^4.20.6",
66
69
  "vite-tsconfig-paths": "^4.2.1",
67
- "vitest": "~4.0.16"
70
+ "vitest": "~4.0.18"
68
71
  },
69
72
  "publishConfig": {
70
73
  "access": "public",
@@ -1,23 +0,0 @@
1
- import Taro from '@tarojs/taro'
2
-
3
- /**
4
- * 微信小程序调试工具
5
- * 在开发版/体验版自动开启调试模式
6
- */
7
- export function enableWxDebugIfNeeded() {
8
- // 仅在微信小程序环境执行
9
- if (Taro.getEnv() === Taro.ENV_TYPE.WEAPP) {
10
- try {
11
- const accountInfo = Taro.getAccountInfoSync()
12
- const envVersion = accountInfo.miniProgram.envVersion
13
- console.log('[Debug] envVersion:', envVersion)
14
-
15
- // 开发版/体验版自动开启调试
16
- if (envVersion !== 'release') {
17
- Taro.setEnableDebug({ enableDebug: true })
18
- }
19
- } catch (error) {
20
- console.error('[Debug] 开启调试模式失败:', error)
21
- }
22
- }
23
- }