@coze-arch/cli 0.0.1-alpha.f9be02 → 0.0.1-alpha.ff64d9
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/lib/__templates__/expo/.coze +1 -1
- package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +19 -82
- package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +62 -81
- package/lib/__templates__/expo/.cozeproj/scripts/prod_build.sh +2 -2
- package/lib/__templates__/expo/.cozeproj/scripts/prod_run.sh +2 -2
- package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +45 -0
- package/lib/__templates__/expo/README.md +66 -7
- package/lib/__templates__/expo/client/app/_layout.tsx +33 -0
- package/lib/__templates__/expo/client/app/demo.tsx +1 -0
- package/lib/__templates__/expo/client/app/index.tsx +1 -0
- package/lib/__templates__/expo/client/app.config.ts +64 -60
- package/lib/__templates__/expo/client/{src/constants → constants}/theme.ts +22 -18
- package/lib/__templates__/expo/client/declarations.d.ts +5 -0
- package/lib/__templates__/expo/client/hooks/useColorScheme.ts +34 -0
- package/lib/__templates__/expo/client/package.json +3 -2
- package/lib/__templates__/expo/client/screens/demo/index.tsx +25 -0
- package/lib/__templates__/expo/client/screens/demo/styles.ts +28 -0
- package/lib/__templates__/expo/client/tsconfig.json +1 -1
- package/lib/__templates__/expo/package.json +4 -98
- package/lib/__templates__/expo/pnpm-lock.yaml +376 -577
- package/lib/__templates__/expo/server/package.json +18 -3
- package/lib/__templates__/expo/server/src/index.ts +8 -2
- package/lib/__templates__/expo/server/tsconfig.json +24 -0
- package/lib/__templates__/expo/template.config.js +1 -0
- package/lib/__templates__/nextjs/.coze +1 -0
- package/lib/__templates__/nextjs/_npmrc +1 -0
- package/lib/__templates__/nextjs/next.config.ts +12 -0
- package/lib/__templates__/nextjs/package.json +3 -2
- package/lib/__templates__/nextjs/pnpm-lock.yaml +13 -5
- package/lib/__templates__/nextjs/scripts/prepare.sh +9 -0
- package/lib/__templates__/nextjs/src/app/globals.css +10 -2
- package/lib/__templates__/nextjs/src/app/layout.tsx +1 -12
- package/lib/__templates__/nextjs/src/app/page.tsx +35 -23
- package/lib/__templates__/nextjs/src/components/ui/resizable.tsx +29 -22
- package/lib/__templates__/nextjs/src/components/ui/sidebar.tsx +228 -230
- package/lib/__templates__/nextjs/template.config.js +30 -0
- package/lib/__templates__/templates.json +61 -43
- package/lib/__templates__/vite/.coze +1 -0
- package/lib/__templates__/vite/_npmrc +1 -0
- package/lib/__templates__/vite/eslint.config.mjs +9 -0
- package/lib/__templates__/vite/package.json +5 -1
- package/lib/__templates__/vite/pnpm-lock.yaml +3481 -14
- package/lib/__templates__/vite/scripts/prepare.sh +9 -0
- package/lib/__templates__/vite/src/main.ts +1 -2
- package/lib/__templates__/vite/template.config.js +28 -4
- package/lib/cli.js +201 -57
- package/package.json +5 -3
- package/lib/__templates__/expo/client/src/app/_layout.tsx +0 -33
- package/lib/__templates__/expo/client/src/app/index.ts +0 -1
- package/lib/__templates__/expo/client/src/hooks/useColorScheme.ts +0 -1
- package/lib/__templates__/expo/client/src/screens/home/index.tsx +0 -50
- package/lib/__templates__/expo/client/src/screens/home/styles.ts +0 -60
- package/lib/__templates__/nextjs/.vscode/settings.json +0 -121
- package/lib/__templates__/vite/.vscode/settings.json +0 -7
- /package/lib/__templates__/expo/client/{src/assets → assets}/fonts/SpaceMono-Regular.ttf +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/adaptive-icon.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/default-avatar.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/favicon.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/icon.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/partial-react-logo.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/react-logo.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/react-logo@2x.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/react-logo@3x.png +0 -0
- /package/lib/__templates__/expo/client/{src/assets → assets}/images/splash-icon.png +0 -0
- /package/lib/__templates__/expo/client/{src/components → components}/Screen.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/components → components}/SmartDateInput.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/components → components}/ThemedText.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/components → components}/ThemedView.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/contexts → contexts}/AuthContext.tsx +0 -0
- /package/lib/__templates__/expo/client/{src/hooks → hooks}/useTheme.ts +0 -0
- /package/lib/__templates__/expo/client/{src/utils → utils}/index.ts +0 -0
|
@@ -13,8 +13,7 @@ export function initApp(): void {
|
|
|
13
13
|
<!-- 头部:Logo 和 产品名称 -->
|
|
14
14
|
<div class="flex items-center gap-3">
|
|
15
15
|
<img
|
|
16
|
-
|
|
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"
|
|
@@ -37,7 +37,11 @@ export const paramsSchema = {
|
|
|
37
37
|
additionalProperties: false,
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
const description = `Vite(简单项目):\`coze init \${COZE_WORKSPACE_PATH} --template vite\`
|
|
41
|
+
- 适用:轻量级 SPA、纯前端交互、仪表盘等轻量级项目。`;
|
|
42
|
+
|
|
40
43
|
const config = {
|
|
44
|
+
description: description,
|
|
41
45
|
paramsSchema,
|
|
42
46
|
|
|
43
47
|
defaultParams: {
|
|
@@ -55,11 +59,31 @@ const config = {
|
|
|
55
59
|
|
|
56
60
|
onAfterRender: async (context, outputPath) => {
|
|
57
61
|
console.log(`\nProject created at: ${outputPath}`);
|
|
58
|
-
console.log(
|
|
59
|
-
console.log(
|
|
60
|
-
console.log(
|
|
61
|
-
console.log(
|
|
62
|
+
console.log('\nConfiguration:');
|
|
63
|
+
console.log(' - Framework: vite');
|
|
64
|
+
console.log(' - TypeScript: enabled');
|
|
65
|
+
console.log(' - App Router: enabled');
|
|
62
66
|
console.log(` - Port: ${context.port}`);
|
|
67
|
+
|
|
68
|
+
// Skip pnpm add in test environment to avoid monorepo workspace issues
|
|
69
|
+
if (process.env.NODE_ENV === 'test') {
|
|
70
|
+
console.log('⊘ Skipping dependency update in test environment');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const cmd = `pnpm add coze-coding-dev-sdk@"^0.7.0"`;
|
|
75
|
+
console.log(`${cmd}`);
|
|
76
|
+
try {
|
|
77
|
+
const projectRoot = resolve(outputPath);
|
|
78
|
+
execSync(cmd, {
|
|
79
|
+
cwd: projectRoot,
|
|
80
|
+
stdio: 'inherit',
|
|
81
|
+
});
|
|
82
|
+
console.log('✓ coze-coding-dev-sdk updated successfully');
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error('✗ Failed to update coze-coding-dev-sdk:', error);
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
63
87
|
},
|
|
64
88
|
};
|
|
65
89
|
|
package/lib/cli.js
CHANGED
|
@@ -7,10 +7,10 @@ var fs = require('fs');
|
|
|
7
7
|
var shelljs = require('shelljs');
|
|
8
8
|
var perf_hooks = require('perf_hooks');
|
|
9
9
|
var fs$1 = require('fs/promises');
|
|
10
|
+
var os = require('os');
|
|
10
11
|
var toml = require('@iarna/toml');
|
|
11
12
|
var jsYaml = require('js-yaml');
|
|
12
13
|
var child_process = require('child_process');
|
|
13
|
-
var os = require('os');
|
|
14
14
|
var addFormats = require('ajv-formats');
|
|
15
15
|
var Ajv = require('ajv');
|
|
16
16
|
var minimist = require('minimist');
|
|
@@ -826,23 +826,48 @@ const getCommandConfig = (
|
|
|
826
826
|
function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
827
827
|
|
|
828
828
|
/**
|
|
829
|
-
*
|
|
829
|
+
* 日志文件名常量
|
|
830
830
|
*/
|
|
831
|
-
const
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
831
|
+
const LOG_FILE_NAME = 'dev.log';
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* 获取日志目录
|
|
835
|
+
* 优先使用环境变量 COZE_LOG_DIR,否则使用 ~/.coze-logs
|
|
836
|
+
*/
|
|
837
|
+
const getLogDir = () =>
|
|
838
|
+
process.env.COZE_LOG_DIR || path.join(os.homedir(), '.coze-logs');
|
|
837
839
|
|
|
838
|
-
|
|
840
|
+
/**
|
|
841
|
+
* 解析日志文件路径
|
|
842
|
+
* - 如果是绝对路径,直接使用
|
|
843
|
+
* - 如果是相对路径,基于 getLogDir() + 相对路径
|
|
844
|
+
* - 如果为空,使用 getLogDir() + LOG_FILE_NAME
|
|
845
|
+
*/
|
|
846
|
+
const resolveLogFilePath = (logFile) => {
|
|
847
|
+
if (!logFile) {
|
|
848
|
+
return path.join(getLogDir(), LOG_FILE_NAME);
|
|
849
|
+
}
|
|
839
850
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
851
|
+
if (path.isAbsolute(logFile)) {
|
|
852
|
+
return logFile;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
return path.join(getLogDir(), logFile);
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* 创建日志写入流
|
|
860
|
+
*/
|
|
861
|
+
const createLogStream = (logFilePath) => {
|
|
862
|
+
const logDir = path.dirname(logFilePath);
|
|
863
|
+
|
|
864
|
+
// 确保日志目录存在
|
|
865
|
+
if (!fs.existsSync(logDir)) {
|
|
866
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// 使用 'w' 标志覆盖之前的日志
|
|
870
|
+
return fs.createWriteStream(logFilePath, { flags: 'w' });
|
|
846
871
|
};
|
|
847
872
|
|
|
848
873
|
/**
|
|
@@ -860,16 +885,15 @@ const executeRun = async (
|
|
|
860
885
|
const commandArgs = getCommandConfig(config, commandName);
|
|
861
886
|
|
|
862
887
|
// 2. 准备日志
|
|
863
|
-
const
|
|
864
|
-
const
|
|
865
|
-
const logStream = logManager.createWriteStream(logFile);
|
|
888
|
+
const logFilePath = resolveLogFilePath(options.logFile);
|
|
889
|
+
const logStream = createLogStream(logFilePath);
|
|
866
890
|
|
|
867
891
|
// 3. 执行命令
|
|
868
892
|
const commandString = commandArgs.join(' ');
|
|
869
893
|
|
|
870
894
|
logger.info(`Executing: ${commandString}`);
|
|
871
895
|
logger.info(`Working directory: ${process.cwd()}`);
|
|
872
|
-
logger.info(`Log file: ${
|
|
896
|
+
logger.info(`Log file: ${logFilePath}`);
|
|
873
897
|
|
|
874
898
|
const childProcess = shelljs.exec(commandString, {
|
|
875
899
|
async: true,
|
|
@@ -898,11 +922,11 @@ const executeRun = async (
|
|
|
898
922
|
logger.error(
|
|
899
923
|
`Command exited with code ${_nullishCoalesce$1(code, () => ( 'unknown'))}${signal ? ` and signal ${signal}` : ''}`,
|
|
900
924
|
);
|
|
901
|
-
logger.error(`Check log file for details: ${
|
|
925
|
+
logger.error(`Check log file for details: ${logFilePath}`);
|
|
902
926
|
process.exit(code || 1);
|
|
903
927
|
} else {
|
|
904
928
|
logger.success('Command completed successfully');
|
|
905
|
-
logger.info(`Log file: ${
|
|
929
|
+
logger.info(`Log file: ${logFilePath}`);
|
|
906
930
|
}
|
|
907
931
|
});
|
|
908
932
|
|
|
@@ -1248,17 +1272,139 @@ const convertDotfileName = (filePath) => {
|
|
|
1248
1272
|
};
|
|
1249
1273
|
|
|
1250
1274
|
/**
|
|
1251
|
-
*
|
|
1275
|
+
* 执行文件渲染钩子
|
|
1252
1276
|
*
|
|
1253
|
-
* @param
|
|
1254
|
-
* @param
|
|
1277
|
+
* @param templateConfig - 模板配置
|
|
1278
|
+
* @param fileInfo - 文件渲染信息
|
|
1255
1279
|
* @param context - 模板上下文
|
|
1280
|
+
* @returns 处理后的文件信息,或 null 表示跳过该文件
|
|
1256
1281
|
*/
|
|
1257
|
-
const
|
|
1258
|
-
|
|
1259
|
-
|
|
1282
|
+
const executeFileRenderHook = async (
|
|
1283
|
+
templateConfig,
|
|
1284
|
+
fileInfo,
|
|
1260
1285
|
context,
|
|
1261
1286
|
) => {
|
|
1287
|
+
if (!templateConfig.onFileRender) {
|
|
1288
|
+
return fileInfo;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
const result = await templateConfig.onFileRender(
|
|
1292
|
+
fileInfo,
|
|
1293
|
+
context,
|
|
1294
|
+
);
|
|
1295
|
+
|
|
1296
|
+
// false: 跳过文件
|
|
1297
|
+
if (result === false) {
|
|
1298
|
+
return null;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
// undefined/void: 使用默认内容
|
|
1302
|
+
if (result === undefined || result === null) {
|
|
1303
|
+
return fileInfo;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
// string: 作为 content,其他不变
|
|
1307
|
+
if (typeof result === 'string') {
|
|
1308
|
+
return {
|
|
1309
|
+
...fileInfo,
|
|
1310
|
+
content: result,
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
// FileRenderInfo: 使用新对象的信息
|
|
1315
|
+
return result;
|
|
1316
|
+
};
|
|
1317
|
+
|
|
1318
|
+
/**
|
|
1319
|
+
* 处理单个文件
|
|
1320
|
+
*/
|
|
1321
|
+
const processSingleFile = async (options
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
) => {
|
|
1328
|
+
const { file, templatePath, outputPath, context, templateConfig } = options;
|
|
1329
|
+
|
|
1330
|
+
const srcPath = path.join(templatePath, file);
|
|
1331
|
+
const destFile = convertDotfileName(file);
|
|
1332
|
+
|
|
1333
|
+
logger.verbose(
|
|
1334
|
+
` - Processing: ${file}${destFile !== file ? ` -> ${destFile}` : ''}`,
|
|
1335
|
+
);
|
|
1336
|
+
|
|
1337
|
+
// 判断是否为二进制文件
|
|
1338
|
+
const isBinary = !shouldRenderFile(srcPath);
|
|
1339
|
+
let content;
|
|
1340
|
+
let wasRendered = false;
|
|
1341
|
+
|
|
1342
|
+
if (isBinary) {
|
|
1343
|
+
// 二进制文件,读取为 buffer 然后转为 base64
|
|
1344
|
+
const buffer = await fs$1.readFile(srcPath);
|
|
1345
|
+
content = buffer.toString('base64');
|
|
1346
|
+
} else {
|
|
1347
|
+
// 文本文件,渲染后的内容
|
|
1348
|
+
content = await renderTemplate(srcPath, context);
|
|
1349
|
+
wasRendered = true;
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
// 构造文件信息对象
|
|
1353
|
+
const fileInfo = {
|
|
1354
|
+
path: file,
|
|
1355
|
+
destPath: destFile,
|
|
1356
|
+
content,
|
|
1357
|
+
isBinary,
|
|
1358
|
+
wasRendered,
|
|
1359
|
+
};
|
|
1360
|
+
|
|
1361
|
+
// 执行文件渲染钩子
|
|
1362
|
+
const processedFileInfo = await executeFileRenderHook(
|
|
1363
|
+
templateConfig,
|
|
1364
|
+
fileInfo,
|
|
1365
|
+
context,
|
|
1366
|
+
);
|
|
1367
|
+
|
|
1368
|
+
// 如果返回 null,跳过该文件
|
|
1369
|
+
if (processedFileInfo === null) {
|
|
1370
|
+
logger.verbose(' ⊘ Skipped by onFileRender hook');
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
// 使用处理后的目标路径
|
|
1375
|
+
const finalDestPath = path.join(outputPath, processedFileInfo.destPath);
|
|
1376
|
+
|
|
1377
|
+
// 确保目标目录存在
|
|
1378
|
+
await ensureDir(path.dirname(finalDestPath));
|
|
1379
|
+
|
|
1380
|
+
// 写入文件
|
|
1381
|
+
if (processedFileInfo.isBinary) {
|
|
1382
|
+
// 二进制文件:如果内容没变,直接复制;否则从 base64 解码写入
|
|
1383
|
+
if (processedFileInfo.content === content) {
|
|
1384
|
+
await fs$1.copyFile(srcPath, finalDestPath);
|
|
1385
|
+
logger.verbose(' ✓ Copied (binary)');
|
|
1386
|
+
} else {
|
|
1387
|
+
const buffer = Buffer.from(processedFileInfo.content, 'base64');
|
|
1388
|
+
await fs$1.writeFile(finalDestPath, buffer);
|
|
1389
|
+
logger.verbose(' ✓ Written (binary, modified by hook)');
|
|
1390
|
+
}
|
|
1391
|
+
} else {
|
|
1392
|
+
// 文本文件
|
|
1393
|
+
await fs$1.writeFile(finalDestPath, processedFileInfo.content, 'utf-8');
|
|
1394
|
+
logger.verbose(' ✓ Rendered and written');
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* 复制并处理模板文件到目标目录
|
|
1400
|
+
*/
|
|
1401
|
+
const processTemplateFiles = async (options
|
|
1402
|
+
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
) => {
|
|
1407
|
+
const { templatePath, outputPath, context, templateConfig } = options;
|
|
1262
1408
|
logger.verbose('Processing template files:');
|
|
1263
1409
|
logger.verbose(` - Template path: ${templatePath}`);
|
|
1264
1410
|
logger.verbose(` - Output path: ${outputPath}`);
|
|
@@ -1289,29 +1435,15 @@ const processTemplateFiles = async (
|
|
|
1289
1435
|
}
|
|
1290
1436
|
|
|
1291
1437
|
await Promise.all(
|
|
1292
|
-
files.map(
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
)
|
|
1300
|
-
|
|
1301
|
-
// 确保目标目录存在
|
|
1302
|
-
await ensureDir(path.dirname(destPath));
|
|
1303
|
-
|
|
1304
|
-
if (shouldRenderFile(srcPath)) {
|
|
1305
|
-
// 渲染文本文件
|
|
1306
|
-
const rendered = await renderTemplate(srcPath, context);
|
|
1307
|
-
await fs$1.writeFile(destPath, rendered, 'utf-8');
|
|
1308
|
-
logger.verbose(' ✓ Rendered and written');
|
|
1309
|
-
} else {
|
|
1310
|
-
// 直接复制二进制文件
|
|
1311
|
-
await fs$1.copyFile(srcPath, destPath);
|
|
1312
|
-
logger.verbose(' ✓ Copied');
|
|
1313
|
-
}
|
|
1314
|
-
}),
|
|
1438
|
+
files.map(file =>
|
|
1439
|
+
processSingleFile({
|
|
1440
|
+
file,
|
|
1441
|
+
templatePath,
|
|
1442
|
+
outputPath,
|
|
1443
|
+
context,
|
|
1444
|
+
templateConfig,
|
|
1445
|
+
}),
|
|
1446
|
+
),
|
|
1315
1447
|
);
|
|
1316
1448
|
|
|
1317
1449
|
logger.verbose('✓ All files processed successfully');
|
|
@@ -1498,7 +1630,12 @@ const execute = async (
|
|
|
1498
1630
|
const absoluteOutputPath = await prepareOutputDirectory(outputPath);
|
|
1499
1631
|
|
|
1500
1632
|
// 6. 处理模板文件
|
|
1501
|
-
await processTemplateFiles(
|
|
1633
|
+
await processTemplateFiles({
|
|
1634
|
+
templatePath,
|
|
1635
|
+
outputPath: absoluteOutputPath,
|
|
1636
|
+
context,
|
|
1637
|
+
templateConfig,
|
|
1638
|
+
});
|
|
1502
1639
|
|
|
1503
1640
|
// 7. 执行 onAfterRender 钩子
|
|
1504
1641
|
await executeAfterRenderHook(templateConfig, context, absoluteOutputPath);
|
|
@@ -1611,13 +1748,20 @@ const runGitInit = (projectPath) => {
|
|
|
1611
1748
|
/**
|
|
1612
1749
|
* 运行开发服务器(后台模式)
|
|
1613
1750
|
* 启动后台子进程运行开发服务器,父进程可以直接退出
|
|
1751
|
+
* 使用 CLI 自己的 dev 命令(定义在 run.ts)而不是直接运行 npm run dev
|
|
1614
1752
|
*/
|
|
1615
|
-
const
|
|
1753
|
+
const runDev = (projectPath) => {
|
|
1616
1754
|
logger.info('\nStarting development server in background...');
|
|
1617
|
-
|
|
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}`);
|
|
1618
1761
|
|
|
1619
1762
|
// 使用通用的后台执行函数启动开发服务器
|
|
1620
|
-
|
|
1763
|
+
// 调用 CLI 自己的 dev 命令
|
|
1764
|
+
const pid = spawnDetached(process.argv[0], [cliPath, 'dev'], {
|
|
1621
1765
|
cwd: projectPath,
|
|
1622
1766
|
verbose: false, // 不输出额外的进程信息,由 logger 统一处理
|
|
1623
1767
|
});
|
|
@@ -1693,7 +1837,7 @@ const executeInit = async (
|
|
|
1693
1837
|
|
|
1694
1838
|
// 如果没有跳过 dev,则启动开发服务器
|
|
1695
1839
|
if (!skipDev) {
|
|
1696
|
-
|
|
1840
|
+
runDev(absoluteOutputPath);
|
|
1697
1841
|
timer.logPhase('Dev server startup');
|
|
1698
1842
|
} else {
|
|
1699
1843
|
// 只有跳过 dev 时才显示 Next steps
|
|
@@ -1707,7 +1851,7 @@ const executeInit = async (
|
|
|
1707
1851
|
' git init && git add . && git commit -m "initial commit"',
|
|
1708
1852
|
);
|
|
1709
1853
|
}
|
|
1710
|
-
logger.info('
|
|
1854
|
+
logger.info(' coze dev');
|
|
1711
1855
|
}
|
|
1712
1856
|
|
|
1713
1857
|
// 输出总耗时
|
|
@@ -1741,7 +1885,7 @@ const registerCommand = program => {
|
|
|
1741
1885
|
});
|
|
1742
1886
|
};
|
|
1743
1887
|
|
|
1744
|
-
var version = "0.0.1-alpha.
|
|
1888
|
+
var version = "0.0.1-alpha.ff64d9";
|
|
1745
1889
|
var packageJson = {
|
|
1746
1890
|
version: version};
|
|
1747
1891
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coze-arch/cli",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.ff64d9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "coze coding devtools cli",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,14 +25,13 @@
|
|
|
25
25
|
"test": "vitest --run --passWithNoTests",
|
|
26
26
|
"test:all": "bash scripts/test-coverage.sh",
|
|
27
27
|
"test:cov": "vitest --run --passWithNoTests --coverage",
|
|
28
|
-
"test:e2e": "bash scripts/e2e.sh",
|
|
28
|
+
"test:e2e": "NODE_ENV=test bash scripts/e2e.sh",
|
|
29
29
|
"test:perf": "vitest bench --run --config vitest.perf.config.ts",
|
|
30
30
|
"test:perf:compare": "bash scripts/compare-perf.sh",
|
|
31
31
|
"test:perf:save": "bash scripts/run-perf-with-output.sh"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@iarna/toml": "^2.2.5",
|
|
35
|
-
"@inquirer/prompts": "^3.2.0",
|
|
36
35
|
"ajv": "^8.17.1",
|
|
37
36
|
"ajv-formats": "^3.0.1",
|
|
38
37
|
"change-case": "^5.4.4",
|
|
@@ -50,14 +49,17 @@
|
|
|
50
49
|
"@coze-arch/ts-config": "workspace:*",
|
|
51
50
|
"@coze-arch/vitest-config": "workspace:*",
|
|
52
51
|
"@coze-coding/lambda": "workspace:*",
|
|
52
|
+
"@inquirer/prompts": "^3.2.0",
|
|
53
53
|
"@types/ejs": "^3.1.5",
|
|
54
54
|
"@types/iarna__toml": "^2.0.5",
|
|
55
55
|
"@types/js-yaml": "^4.0.9",
|
|
56
|
+
"@types/minimatch": "^5.1.2",
|
|
56
57
|
"@types/minimist": "^1.2.5",
|
|
57
58
|
"@types/node": "^24",
|
|
58
59
|
"@types/shelljs": "^0.10.0",
|
|
59
60
|
"@vitest/coverage-v8": "~4.0.16",
|
|
60
61
|
"json-schema-to-typescript": "^15.0.3",
|
|
62
|
+
"minimatch": "^10.0.1",
|
|
61
63
|
"rollup": "^4.41.1",
|
|
62
64
|
"sucrase": "^3.35.0",
|
|
63
65
|
"tsx": "^4.20.6",
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
3
|
-
import { Stack } from 'expo-router';
|
|
4
|
-
import { StatusBar } from 'expo-status-bar';
|
|
5
|
-
import { LogBox } from 'react-native';
|
|
6
|
-
import Toast from 'react-native-toast-message';
|
|
7
|
-
import { AuthProvider } from "@/contexts/AuthContext";
|
|
8
|
-
|
|
9
|
-
LogBox.ignoreLogs([
|
|
10
|
-
"TurboModuleRegistry.getEnforcing(...): 'RNMapsAirModule' could not be found",
|
|
11
|
-
// 添加其它想暂时忽略的错误或警告信息
|
|
12
|
-
]);
|
|
13
|
-
|
|
14
|
-
export default function RootLayout() {
|
|
15
|
-
return (
|
|
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="(tabs)" options={{ title: "" }} />
|
|
28
|
-
</Stack>
|
|
29
|
-
<Toast />
|
|
30
|
-
</GestureHandlerRootView>
|
|
31
|
-
</AuthProvider>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from '@/screens/home'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { useColorScheme } from "react-native";
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import React, { useState, useCallback } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
Text,
|
|
5
|
-
ScrollView,
|
|
6
|
-
RefreshControl,
|
|
7
|
-
} from 'react-native';
|
|
8
|
-
import { useRouter, useFocusEffect } from 'expo-router';
|
|
9
|
-
import { FontAwesome6 } from '@expo/vector-icons';
|
|
10
|
-
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
11
|
-
import { useTheme } from "@/hooks/useTheme";
|
|
12
|
-
|
|
13
|
-
import { Screen } from '@/components/Screen';
|
|
14
|
-
|
|
15
|
-
import { styles } from './styles';
|
|
16
|
-
|
|
17
|
-
export default function HomeScreen() {
|
|
18
|
-
const insets = useSafeAreaInsets();
|
|
19
|
-
const { theme, isDark } = useTheme();
|
|
20
|
-
|
|
21
|
-
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
22
|
-
|
|
23
|
-
const loadData = useCallback(async () => {
|
|
24
|
-
}, []);
|
|
25
|
-
|
|
26
|
-
useFocusEffect(
|
|
27
|
-
useCallback(() => {
|
|
28
|
-
loadData();
|
|
29
|
-
}, [loadData])
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const handleRefresh = useCallback(() => {
|
|
33
|
-
setIsRefreshing(true);
|
|
34
|
-
loadData();
|
|
35
|
-
}, [loadData]);
|
|
36
|
-
return (
|
|
37
|
-
<Screen backgroundColor={theme.backgroundRoot} statusBarStyle={isDark ? 'light' : 'dark'}>
|
|
38
|
-
<ScrollView
|
|
39
|
-
showsVerticalScrollIndicator={false}
|
|
40
|
-
contentContainerStyle={{}}
|
|
41
|
-
refreshControl={
|
|
42
|
-
<RefreshControl refreshing={isRefreshing} onRefresh={handleRefresh} colors={['#2563EB']} />
|
|
43
|
-
}
|
|
44
|
-
>
|
|
45
|
-
<View style={[styles.header]}>
|
|
46
|
-
</View>
|
|
47
|
-
</ScrollView>
|
|
48
|
-
</Screen>
|
|
49
|
-
);
|
|
50
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { StyleSheet, Platform } from 'react-native';
|
|
2
|
-
|
|
3
|
-
export const styles = StyleSheet.create({
|
|
4
|
-
loadingContainer: {
|
|
5
|
-
flex: 1,
|
|
6
|
-
justifyContent: 'center',
|
|
7
|
-
alignItems: 'center',
|
|
8
|
-
},
|
|
9
|
-
loadingText: {
|
|
10
|
-
marginTop: 12,
|
|
11
|
-
fontSize: 14,
|
|
12
|
-
color: '#64748B',
|
|
13
|
-
},
|
|
14
|
-
errorContainer: {
|
|
15
|
-
flex: 1,
|
|
16
|
-
justifyContent: 'center',
|
|
17
|
-
alignItems: 'center',
|
|
18
|
-
paddingHorizontal: 24,
|
|
19
|
-
},
|
|
20
|
-
errorText: {
|
|
21
|
-
marginTop: 16,
|
|
22
|
-
fontSize: 16,
|
|
23
|
-
color: '#64748B',
|
|
24
|
-
},
|
|
25
|
-
header: {
|
|
26
|
-
flexDirection: 'row',
|
|
27
|
-
justifyContent: 'space-between',
|
|
28
|
-
alignItems: 'center',
|
|
29
|
-
paddingHorizontal: 16,
|
|
30
|
-
// paddingBottom: 16,
|
|
31
|
-
backgroundColor: '#FFFFFF',
|
|
32
|
-
// borderBottomWidth: 1,
|
|
33
|
-
borderBottomColor: '#E2E8F0',
|
|
34
|
-
},
|
|
35
|
-
logoContainer: {
|
|
36
|
-
width: 32,
|
|
37
|
-
height: 32,
|
|
38
|
-
backgroundColor: '#2563EB',
|
|
39
|
-
borderRadius: 8,
|
|
40
|
-
justifyContent: 'center',
|
|
41
|
-
alignItems: 'center',
|
|
42
|
-
...Platform.select({
|
|
43
|
-
ios: {
|
|
44
|
-
shadowColor: '#000',
|
|
45
|
-
shadowOffset: { width: 0, height: 1 },
|
|
46
|
-
shadowOpacity: 0.1,
|
|
47
|
-
shadowRadius: 2,
|
|
48
|
-
},
|
|
49
|
-
android: {
|
|
50
|
-
elevation: 2,
|
|
51
|
-
},
|
|
52
|
-
}),
|
|
53
|
-
},
|
|
54
|
-
logoText: {
|
|
55
|
-
fontSize: 18,
|
|
56
|
-
fontWeight: '700',
|
|
57
|
-
color: '#1E293B',
|
|
58
|
-
letterSpacing: -0.5,
|
|
59
|
-
},
|
|
60
|
-
});
|