@coze-arch/cli 0.0.1-alpha.ee5d83 → 0.0.1-alpha.f626fa

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.
@@ -1,4 +1,4 @@
1
- ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
1
+ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
2
2
  PREVIEW_DIR="${COZE_PREVIEW_DIR:-/source/preview}"
3
3
  LOG_DIR="${COZE_LOG_DIR:-$ROOT_DIR/logs}"
4
4
  LOG_FILE="$LOG_DIR/app.log"
@@ -111,14 +111,14 @@ wait_port_connectable() {
111
111
  start_expo() {
112
112
  local offline="${1:-0}"
113
113
 
114
- pushd ./client
114
+ pushd "$ROOT_DIR/client"
115
115
 
116
116
  if [ "$offline" = "1" ]; then
117
117
  ( EXPO_OFFLINE=1 EXPO_NO_DOCTOR=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" \
118
- nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "../logs/client.log" ) &
118
+ nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "$ROOT_DIR/logs/client.log" ) &
119
119
  else
120
120
  ( EXPO_NO_DOCTOR=1 EXPO_PUBLIC_BACKEND_BASE_URL="$EXPO_PUBLIC_BACKEND_BASE_URL" EXPO_PACKAGER_PROXY_URL="$EXPO_PACKAGER_PROXY_URL" \
121
- nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "../logs/client.log" ) &
121
+ nohup npx expo start --clear --port "$EXPO_PORT" 2>&1 | pipe_to_log "CLIENT" "$ROOT_DIR/logs/client.log" ) &
122
122
  fi
123
123
  EXPO_PID=$!
124
124
  disown $EXPO_PID 2>/dev/null || true
@@ -129,7 +129,7 @@ start_expo() {
129
129
  detect_expo_fetch_failed() {
130
130
  local timeout="${1:-8}"
131
131
  local waited=0
132
- local log_file="logs/client.log"
132
+ local log_file="$ROOT_DIR/logs/client.log"
133
133
  while [ "$waited" -lt "$timeout" ]; do
134
134
  if [ -f "$log_file" ] && grep -q "TypeError: fetch failed" "$log_file" 2>/dev/null; then
135
135
  return 0
@@ -159,15 +159,15 @@ check_command "pnpm"
159
159
  check_command "lsof"
160
160
  check_command "bash"
161
161
 
162
- echo "准备日志目录:logs"
163
- mkdir -p logs
162
+ echo "准备日志目录:$ROOT_DIR/logs"
163
+ mkdir -p "$ROOT_DIR/logs"
164
164
  # 端口占用预检查与处理
165
165
  ensure_port SERVER_PORT "$SERVER_PORT"
166
166
  ensure_port EXPO_PORT "$EXPO_PORT"
167
167
 
168
168
  echo "==================== 启动 server 服务 ===================="
169
- echo "正在执行:npm run dev"
170
- ( PORT="$SERVER_PORT" nohup npm run dev --prefix ./server 2>&1 | pipe_to_log "SERVER" "logs/server.log" ) &
169
+ echo "正在执行:pnpm run dev (server)"
170
+ ( pushd "$ROOT_DIR/server" > /dev/null && SERVER_PORT="$SERVER_PORT" nohup pnpm run dev; popd > /dev/null ) &
171
171
  SERVER_PID=$!
172
172
  disown $SERVER_PID 2>/dev/null || true
173
173
  if [ -z "${SERVER_PID}" ]; then
@@ -181,7 +181,7 @@ start_expo 0
181
181
  if detect_expo_fetch_failed 8; then
182
182
  echo "Expo 启动检测到网络错误:TypeError: fetch failed,启用离线模式重试"
183
183
  if [ -n "${EXPO_PID}" ]; then kill -9 "$EXPO_PID" 2>/dev/null || true; fi
184
- : > logs/client.log
184
+ : > "$ROOT_DIR/logs/client.log"
185
185
  start_expo 1
186
186
  fi
187
187
  # 输出以下环境变量,确保 Expo 项目能正确连接到 Server 服务
@@ -40,8 +40,8 @@ fi
40
40
  info "==================== 依赖安装完成!====================\n"
41
41
 
42
42
  info "==================== dist打包 ===================="
43
- info "开始执行:npm run build --prefix server"
44
- (cd "$ROOT_DIR" && npm run build --prefix ./server) || error "dist打包失败"
43
+ info "开始执行:pnpm run build (server)"
44
+ (pushd "$ROOT_DIR/server" > /dev/null && pnpm run build; popd > /dev/null) || error "dist打包失败"
45
45
  info "==================== dist打包完成!====================\n"
46
46
 
47
47
  info "下一步:执行 ./prod_run.sh 启动服务"
@@ -29,6 +29,6 @@ check_command() {
29
29
  check_command "pnpm"
30
30
  check_command "npm"
31
31
 
32
- info "开始执行:npm run start"
33
- (cd "$ROOT_DIR" && PORT="$PORT" npm run start --prefix ./server) || error "服务启动失败"
32
+ info "开始执行:pnpm run start (server)"
33
+ (pushd "$ROOT_DIR/server" > /dev/null && PORT="$PORT" pnpm run start; popd > /dev/null) || error "服务启动失败"
34
34
  info "服务启动完成!\n"
@@ -0,0 +1,45 @@
1
+ #!/bin/bash
2
+
3
+ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
4
+ SERVER_DIR="$ROOT_DIR/server"
5
+ LOG_DIR="$ROOT_DIR/logs"
6
+ LOG_FILE="$LOG_DIR/server.log"
7
+ SERVER_PORT="${SERVER_PORT:-9091}"
8
+
9
+ mkdir -p "$LOG_DIR"
10
+
11
+ pipe_to_log() {
12
+ local source="${1:-SERVER}"
13
+ local raw_log="${2:-}"
14
+ local line
15
+ while IFS= read -r line || [ -n "$line" ]; do
16
+ if [ -n "$raw_log" ]; then
17
+ echo "$line" >> "$raw_log"
18
+ fi
19
+ line=$(echo "[$source] $line" | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\x1b\[[0-9;]*m//g')
20
+ echo "$line"
21
+ done
22
+ }
23
+
24
+ kill_old_server() {
25
+ if command -v lsof &> /dev/null; then
26
+ local pids
27
+ pids=$(lsof -t -i tcp:"$SERVER_PORT" -sTCP:LISTEN 2>/dev/null || true)
28
+ if [ -n "$pids" ]; then
29
+ echo "正在关闭旧的 server 进程:$pids"
30
+ kill -9 $pids 2>/dev/null || echo "关闭进程失败:$pids"
31
+ sleep 1
32
+ fi
33
+ fi
34
+ }
35
+
36
+ echo "==================== Server Dev Run ===================="
37
+ echo "Server 目录:$SERVER_DIR"
38
+ echo "Server 端口:$SERVER_PORT"
39
+ echo "日志文件:$LOG_FILE"
40
+
41
+ kill_old_server
42
+
43
+ echo "启动 server 服务..."
44
+ cd "$SERVER_DIR"
45
+ NODE_ENV=development PORT="$SERVER_PORT" npx tsx ./src/index.ts 2>&1 | pipe_to_log "SERVER" "$LOG_FILE"
@@ -14,20 +14,20 @@ LogBox.ignoreLogs([
14
14
  export default function RootLayout() {
15
15
  return (
16
16
  <AuthProvider>
17
- <GestureHandlerRootView style={{ flex: 1 }}>
18
- <StatusBar style="dark"></StatusBar>
19
- <Stack screenOptions={{
20
- // 设置所有页面的切换动画为从右侧滑入,适用于iOS 和 Android
21
- animation: 'slide_from_right',
22
- gestureEnabled: true,
23
- gestureDirection: 'horizontal',
24
- // 隐藏自带的头部
25
- headerShown: false
26
- }}>
27
- <Stack.Screen name="index" options={{ title: "" }} />
28
- </Stack>
29
- <Toast />
30
- </GestureHandlerRootView>
17
+ <GestureHandlerRootView style={{ flex: 1 }}>
18
+ <StatusBar style="dark"></StatusBar>
19
+ <Stack screenOptions={{
20
+ // 设置所有页面的切换动画为从右侧滑入,适用于iOS 和 Android
21
+ animation: 'slide_from_right',
22
+ gestureEnabled: true,
23
+ gestureDirection: 'horizontal',
24
+ // 隐藏自带的头部
25
+ headerShown: false
26
+ }}>
27
+ <Stack.Screen name="index" options={{ title: "" }} />
28
+ </Stack>
29
+ <Toast />
30
+ </GestureHandlerRootView>
31
31
  </AuthProvider>
32
32
  );
33
33
  }
@@ -1 +1 @@
1
- export { default } from './home'
1
+ export { default } from '@/screens/demo';
@@ -1,7 +1,8 @@
1
1
  import { ExpoConfig, ConfigContext } from 'expo/config';
2
2
 
3
- const appName = 'My App';
4
- const slugAppName = 'my-app';
3
+ const appName = process.env.EXPO_PUBLIC_COZE_PROJECT_NAME || '应用';
4
+ const projectId = process.env.EXPO_PUBLIC_COZE_PROJECT_ID;
5
+ const slugAppName = projectId ? `app${projectId}` : 'myapp';
5
6
 
6
7
  export default ({ config }: ConfigContext): ExpoConfig => {
7
8
  return {
@@ -22,7 +23,7 @@ export default ({ config }: ConfigContext): ExpoConfig => {
22
23
  "foregroundImage": "./assets/images/adaptive-icon.png",
23
24
  "backgroundColor": "#ffffff"
24
25
  },
25
- "package": "com.anonymous.myapp"
26
+ "package": `com.anonymous.x${projectId || '0'}`
26
27
  },
27
28
  "web": {
28
29
  "bundler": "metro",
@@ -0,0 +1,5 @@
1
+ // declarations.d.ts
2
+
3
+ declare module 'expo-file-system/legacy' {
4
+ export * from 'expo-file-system';
5
+ }
@@ -5,7 +5,7 @@ import { useTheme } from '@/hooks/useTheme';
5
5
  import { Screen } from '@/components/Screen';
6
6
  import { styles } from './styles';
7
7
 
8
- export default function HomeScreen() {
8
+ export default function DemoPage() {
9
9
  const { theme, isDark } = useTheme();
10
10
 
11
11
  return (
@@ -38,6 +38,7 @@ try {
38
38
  const ignoreFilePatterns = [
39
39
  /template\.config\.(ts|js)$/, // 模板配置文件
40
40
  /\.template\./, // 其他模板文件
41
+ /declarations\.d\.ts$/, // 项目配置文件
41
42
  ];
42
43
 
43
44
  // 过滤包:排除内部别名和只被模板文件引用的包
@@ -1,9 +1,31 @@
1
+ import { Platform } from 'react-native';
1
2
  import dayjs from 'dayjs';
2
3
  import utc from 'dayjs/plugin/utc';
3
4
  dayjs.extend(utc);
4
5
 
5
6
  const API_BASE = (process.env.EXPO_PUBLIC_API_BASE ?? '').replace(/\/$/, '');
6
7
 
8
+ /**
9
+ * 创建跨平台兼容的文件对象,用于 FormData.append()
10
+ * - Web 端返回 File 对象
11
+ * - 移动端返回 { uri, type, name } 对象(RN fetch 会自动处理)
12
+ * @param fileUri Expo 媒体库(如 expo-image-picker、expo-camera)返回的 uri
13
+ * @param fileName 上传时的文件名,如 'photo.jpg'
14
+ * @param mimeType 文件 MIME 类型,如 'image/jpeg'、'audio/mpeg'
15
+ */
16
+ export async function createFormDataFile(
17
+ fileUri: string,
18
+ fileName: string,
19
+ mimeType: string
20
+ ): Promise<File | { uri: string; type: string; name: string }> {
21
+ if (Platform.OS === 'web') {
22
+ const response = await fetch(fileUri);
23
+ const blob = await response.blob();
24
+ return new File([blob], fileName, { type: mimeType });
25
+ }
26
+ return { uri: fileUri, type: mimeType, name: fileName };
27
+ }
28
+
7
29
  /**
8
30
  * 构建文件或图片完整的URL
9
31
  * @param url 相对或绝对路径
@@ -0,0 +1,21 @@
1
+ import * as esbuild from 'esbuild';
2
+ import { createRequire } from 'module';
3
+
4
+ const require = createRequire(import.meta.url);
5
+ const pkg = require('./package.json');
6
+ const dependencies = pkg.dependencies || {};
7
+ const externalList = Object.keys(dependencies).filter(dep => dep !== 'dayjs');
8
+ try {
9
+ await esbuild.build({
10
+ entryPoints: ['src/index.ts'],
11
+ bundle: true,
12
+ platform: 'node',
13
+ format: 'esm',
14
+ outdir: 'dist',
15
+ external: externalList,
16
+ });
17
+ console.log('⚡ Build complete!');
18
+ } catch (e) {
19
+ console.error(e);
20
+ process.exit(1);
21
+ }
@@ -4,8 +4,8 @@
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "preinstall": "npx only-allow pnpm",
7
- "dev": "NODE_ENV=development tsx ./src/index.ts",
8
- "build": "pnpm exec esbuild src/index.ts --platform=node --packages=external --bundle --format=esm --outdir=dist",
7
+ "dev": "bash ../.cozeproj/scripts/server_dev_run.sh",
8
+ "build": "node build.js",
9
9
  "start": "NODE_ENV=production PORT=${PORT:-5000} node dist/index.js"
10
10
  },
11
11
  "dependencies": {
@@ -2,14 +2,14 @@ import type { NextConfig } from 'next';
2
2
  import path from 'path';
3
3
 
4
4
  const nextConfig: NextConfig = {
5
- outputFileTracingRoot: path.resolve(__dirname, '../../'),
5
+ // outputFileTracingRoot: path.resolve(__dirname, '../../'),
6
6
  /* config options here */
7
7
  allowedDevOrigins: ['*.dev.coze.site'],
8
8
  images: {
9
9
  remotePatterns: [
10
10
  {
11
11
  protocol: 'https',
12
- hostname: 'lf3-static.bytednsdoc.com',
12
+ hostname: 'lf-coze-web-cdn.coze.cn',
13
13
  pathname: '/**',
14
14
  },
15
15
  ],
@@ -15,11 +15,11 @@ export default function Home() {
15
15
  {/* 头部:Logo 和 产品名称 */}
16
16
  <div className="flex items-center gap-3">
17
17
  <Image
18
- className="dark:invert"
19
- src="https://lf3-static.bytednsdoc.com/obj/eden-cn/hkpzboz/coze_logo.png"
18
+ src="https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/favicon.svg"
20
19
  alt="扣子编程 Logo"
21
20
  width={40}
22
21
  height={40}
22
+ unoptimized
23
23
  />
24
24
  <span className="text-xl font-bold tracking-tight text-foreground dark:text-foreground">
25
25
  扣子编程
@@ -13,8 +13,7 @@ export function initApp(): void {
13
13
  <!-- 头部:Logo 和 产品名称 -->
14
14
  <div class="flex items-center gap-3">
15
15
  <img
16
- class="dark:invert"
17
- src="https://lf3-static.bytednsdoc.com/obj/eden-cn/hkpzboz/coze_logo.png"
16
+ src="https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/favicon.svg"
18
17
  alt="扣子编程 Logo"
19
18
  width="40"
20
19
  height="40"
package/lib/cli.js CHANGED
@@ -1748,13 +1748,20 @@ const runGitInit = (projectPath) => {
1748
1748
  /**
1749
1749
  * 运行开发服务器(后台模式)
1750
1750
  * 启动后台子进程运行开发服务器,父进程可以直接退出
1751
+ * 使用 CLI 自己的 dev 命令(定义在 run.ts)而不是直接运行 npm run dev
1751
1752
  */
1752
- const runNpmDev = (projectPath) => {
1753
+ const runDev = (projectPath) => {
1753
1754
  logger.info('\nStarting development server in background...');
1754
- logger.info(`Executing: npm run dev in ${projectPath}`);
1755
+
1756
+ // 获取当前 CLI 的可执行文件路径
1757
+ // process.argv[0] 是 node,process.argv[1] 是 CLI 入口文件
1758
+ const cliPath = process.argv[1];
1759
+
1760
+ logger.info(`Executing: ${cliPath} dev in ${projectPath}`);
1755
1761
 
1756
1762
  // 使用通用的后台执行函数启动开发服务器
1757
- const pid = spawnDetached('npm', ['run', 'dev'], {
1763
+ // 调用 CLI 自己的 dev 命令
1764
+ const pid = spawnDetached(process.argv[0], [cliPath, 'dev'], {
1758
1765
  cwd: projectPath,
1759
1766
  verbose: false, // 不输出额外的进程信息,由 logger 统一处理
1760
1767
  });
@@ -1830,7 +1837,7 @@ const executeInit = async (
1830
1837
 
1831
1838
  // 如果没有跳过 dev,则启动开发服务器
1832
1839
  if (!skipDev) {
1833
- runNpmDev(absoluteOutputPath);
1840
+ runDev(absoluteOutputPath);
1834
1841
  timer.logPhase('Dev server startup');
1835
1842
  } else {
1836
1843
  // 只有跳过 dev 时才显示 Next steps
@@ -1844,7 +1851,7 @@ const executeInit = async (
1844
1851
  ' git init && git add . && git commit -m "initial commit"',
1845
1852
  );
1846
1853
  }
1847
- logger.info(' npm run dev');
1854
+ logger.info(' coze dev');
1848
1855
  }
1849
1856
 
1850
1857
  // 输出总耗时
@@ -1878,7 +1885,7 @@ const registerCommand = program => {
1878
1885
  });
1879
1886
  };
1880
1887
 
1881
- var version = "0.0.1-alpha.ee5d83";
1888
+ var version = "0.0.1-alpha.f626fa";
1882
1889
  var packageJson = {
1883
1890
  version: version};
1884
1891
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coze-arch/cli",
3
- "version": "0.0.1-alpha.ee5d83",
3
+ "version": "0.0.1-alpha.f626fa",
4
4
  "private": false,
5
5
  "description": "coze coding devtools cli",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- export { default } from '@/screens/home'