openyida 2026.3.28-2 → 2026.4.2-beta.0
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/README.md +1 -1
- package/bin/yida.js +4 -3
- package/lib/app/create-app.js +8 -4
- package/lib/app/create-form.js +1 -0
- package/lib/app/get-schema.js +8 -6
- package/lib/app/publish.js +10 -4
- package/lib/core/check-update.js +5 -2
- package/lib/core/doctor.js +119 -72
- package/lib/core/locales/ar.js +3 -0
- package/lib/core/locales/de.js +3 -0
- package/lib/core/locales/en.js +1 -1
- package/lib/core/locales/es.js +3 -0
- package/lib/core/locales/fr.js +3 -0
- package/lib/core/locales/hi.js +3 -0
- package/lib/core/locales/ja.js +1 -1
- package/lib/core/locales/ko.js +3 -0
- package/lib/core/locales/pt.js +3 -0
- package/lib/core/locales/vi.js +3 -0
- package/lib/core/locales/zh-TW.js +1 -1
- package/lib/core/locales/zh.js +1 -1
- package/lib/core/utils.js +1 -1
- package/lib/flash-note/flash-to-prd.js +26 -15
- package/lib/report/chart-builder.js +134 -956
- package/lib/report/data-model.js +380 -0
- package/lib/report/field-utils.js +208 -0
- package/lib/report/filter-builder.js +376 -0
- package/lib/report/index.js +17 -6
- package/package.json +4 -3
- package/scripts/postinstall.js +33 -1
- package/yida-skills/SKILL.md +87 -91
- package/yida-skills/references/edition-features-guide.md +382 -0
- package/yida-skills/skills/yida-app/SKILL.md +20 -8
- package/yida-skills/skills/yida-chart/SKILL.md +26 -21
- package/yida-skills/skills/yida-connector/SKILL.md +22 -0
- package/yida-skills/skills/yida-create-app/SKILL.md +44 -2
- package/yida-skills/skills/yida-create-form-page/SKILL.md +22 -0
- package/yida-skills/skills/yida-create-page/SKILL.md +21 -0
- package/yida-skills/skills/yida-create-process/SKILL.md +22 -0
- package/yida-skills/skills/yida-custom-page/SKILL.md +31 -0
- package/yida-skills/skills/yida-custom-page/references/assets-guide.md +2 -2
- package/yida-skills/skills/yida-data-management/SKILL.md +34 -0
- package/yida-skills/skills/yida-density/SKILL.md +27 -14
- package/yida-skills/skills/yida-export-conversation/SKILL.md +16 -0
- package/yida-skills/skills/yida-flash-note-to-prd/SKILL.md +25 -28
- package/yida-skills/skills/yida-form-permission/SKILL.md +25 -0
- package/yida-skills/skills/yida-formula/SKILL.md +24 -7
- package/yida-skills/skills/yida-get-schema/SKILL.md +24 -0
- package/yida-skills/skills/yida-integration/SKILL.md +22 -16
- package/yida-skills/skills/yida-login/SKILL.md +25 -17
- package/yida-skills/skills/yida-logout/SKILL.md +19 -0
- package/yida-skills/skills/yida-page-config/SKILL.md +23 -0
- package/yida-skills/skills/yida-ppt-slider/SKILL.md +28 -16
- package/yida-skills/skills/yida-process-rule/SKILL.md +22 -16
- package/yida-skills/skills/yida-publish-page/SKILL.md +20 -0
- package/yida-skills/skills/yida-report/SKILL.md +25 -16
- package/yida-skills/skills/yida-table-form/SKILL.md +26 -14
- package/yida-skills/skills/yida-chatbot/SKILL.md +0 -237
- package/yida-skills/skills/yida-create-report/SKILL.md +0 -738
- /package/{yida-skills/skills/yida-flash-note-to-prd → lib/flash-note}/build-flash-note-prompt.js +0 -0
- /package/{yida-skills/skills/yida-create-report/build-yida-report-schema.js → lib/report/schema-template.js} +0 -0
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**Build Yida low-code apps with AI — zero config, instant deploy.**
|
|
10
10
|
|
|
11
|
-
[Get Started](#get-started) · [CLI Commands](#cli-commands) · [Demo](
|
|
11
|
+
[Get Started](#get-started) · [CLI Commands](#cli-commands) · [Demo](https://www.aliwork.com/o/OpenYidaAppShowcase) · [Contributing](./CONTRIBUTING.md) · [Changelog](./CHANGELOG.md)
|
|
12
12
|
|
|
13
13
|
[](https://www.npmjs.com/package/openyida)
|
|
14
14
|
[](https://www.npmjs.com/package/openyida)
|
package/bin/yida.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* openyida auth logout 退出登录
|
|
17
17
|
* openyida org list 列出可访问的组织
|
|
18
18
|
* openyida org switch --corp-id <corpId> 切换组织(无需重新登录)
|
|
19
|
-
* openyida create-app "<名称>" [desc] [icon] [color] [
|
|
19
|
+
* openyida create-app "<名称>" [desc] [icon] [color] [colour] [navTheme] [layout] 创建应用
|
|
20
20
|
* openyida create-page <appType> "<页面名>" 创建自定义页面
|
|
21
21
|
* openyida create-form create <appType> "<表单名>" <字段JSON> [--layout <布局>] [--theme <主题>] [--label-align <对齐>] 创建表单页面
|
|
22
22
|
* openyida create-form update <appType> <formUuid> <修改JSON> 更新表单页面
|
|
@@ -76,7 +76,7 @@ openyida - 宜搭命令行工具
|
|
|
76
76
|
copy [--force] 复制 project 工作目录到当前 AI 工具环境
|
|
77
77
|
login 登录态管理(优先缓存,否则扫码)
|
|
78
78
|
logout 退出登录 / 切换账号
|
|
79
|
-
create-app "<名称>" [描述] [图标] [颜色] [主题色]
|
|
79
|
+
create-app "<名称>" [描述] [图标] [颜色] [主题色] [导航风格] [布局] 创建应用,输出 appType
|
|
80
80
|
create-page <appType> "<页面名>" 创建自定义页面,输出 pageId
|
|
81
81
|
create-form create <appType> "<表单名>" <字段JSON> [--layout <布局>] [--theme <主题>] [--label-align <对齐>] 创建表单页面
|
|
82
82
|
create-form update <appType> <formUuid> <修改JSON> 更新表单页面
|
|
@@ -132,7 +132,8 @@ openyida - 宜搭命令行工具
|
|
|
132
132
|
openyida login
|
|
133
133
|
openyida logout
|
|
134
134
|
openyida create-app "考勤管理"
|
|
135
|
-
openyida create-app "考勤管理" "员工考勤系统" "xian-daka" "#00B853" "
|
|
135
|
+
openyida create-app "考勤管理" "员工考勤系统" "xian-daka" "#00B853" "deepBlue" "dark" "slide"
|
|
136
|
+
openyida create-app "党建管理" "党员管理系统" "xian-zhengfu" "#FF4D4F" "red" "light" "ver"
|
|
136
137
|
openyida create-page APP_XXX "游戏主页"
|
|
137
138
|
openyida create-form create APP_XXX "员工信息" fields.json
|
|
138
139
|
openyida create-form update APP_XXX FORM-XXX '[{"action":"add","field":{"type":"TextField","label":"备注"}}]'
|
package/lib/app/create-app.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* create-app.js - 宜搭应用创建命令
|
|
3
3
|
*
|
|
4
|
-
* 用法:yidacli create-app "<appName>" [description] [icon] [iconColor]
|
|
4
|
+
* 用法:yidacli create-app "<appName>" [description] [icon] [iconColor] [colour] [navTheme] [layoutDirection]
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
@@ -93,7 +93,9 @@ async function run(args) {
|
|
|
93
93
|
const description = args[1] || appName;
|
|
94
94
|
const icon = args[2] || 'xian-yingyong';
|
|
95
95
|
const iconColor = args[3] || '#0089FF';
|
|
96
|
-
const
|
|
96
|
+
const colour = args[4] || 'deepBlue';
|
|
97
|
+
const navTheme = args[5] || 'dark';
|
|
98
|
+
const layoutDirection = args[6] || 'slide';
|
|
97
99
|
|
|
98
100
|
const SEP = '='.repeat(50);
|
|
99
101
|
console.error(SEP);
|
|
@@ -102,7 +104,7 @@ async function run(args) {
|
|
|
102
104
|
console.error(t('create_app.app_name', appName));
|
|
103
105
|
console.error(t('create_app.app_desc', description));
|
|
104
106
|
console.error(t('create_app.app_icon', icon, iconColor));
|
|
105
|
-
console.error(t('create_app.app_theme',
|
|
107
|
+
console.error(t('create_app.app_theme', colour, navTheme, layoutDirection));
|
|
106
108
|
|
|
107
109
|
// Step 1: 读取登录态
|
|
108
110
|
console.error(t('common.step_login', 1));
|
|
@@ -150,7 +152,9 @@ async function run(args) {
|
|
|
150
152
|
description: JSON.stringify({ zh_CN: description, en_US: description, type: 'i18n' }),
|
|
151
153
|
icon: iconValue,
|
|
152
154
|
iconUrl: iconValue,
|
|
153
|
-
colour
|
|
155
|
+
colour,
|
|
156
|
+
navTheme,
|
|
157
|
+
layoutDirection,
|
|
154
158
|
defaultLanguage: 'zh_CN',
|
|
155
159
|
openExclusive: openExclusive,
|
|
156
160
|
openPhysicColumn: openPhysicColumn,
|
package/lib/app/create-form.js
CHANGED
|
@@ -1337,6 +1337,7 @@ function buildFormSchema(formTitle, fields, formUuid, corpId, appType, layout, t
|
|
|
1337
1337
|
compiled: constructorCode,
|
|
1338
1338
|
source: constructorCode,
|
|
1339
1339
|
},
|
|
1340
|
+
componentDidMount: { name: 'didMount', id: 'didMount', params: {}, type: 'actionRef' },
|
|
1340
1341
|
},
|
|
1341
1342
|
hidden: false,
|
|
1342
1343
|
title: '',
|
package/lib/app/get-schema.js
CHANGED
|
@@ -35,11 +35,6 @@ function extractFieldSummary(schemaResult) {
|
|
|
35
35
|
return fields;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const tree = pages[0].componentsTree && pages[0].componentsTree[0];
|
|
39
|
-
if (!tree) {
|
|
40
|
-
return fields;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
38
|
const FIELD_COMPONENT_NAMES = new Set([
|
|
44
39
|
'TextField', 'TextareaField', 'SelectField', 'DateField', 'NumberField',
|
|
45
40
|
'RadioField', 'CheckboxField', 'EmployeeField', 'PhoneField', 'EmailField',
|
|
@@ -69,7 +64,14 @@ function extractFieldSummary(schemaResult) {
|
|
|
69
64
|
}
|
|
70
65
|
}
|
|
71
66
|
|
|
72
|
-
|
|
67
|
+
// 遍历所有页面,避免多页面表单遗漏字段
|
|
68
|
+
for (const page of pages) {
|
|
69
|
+
const tree = page.componentsTree && page.componentsTree[0];
|
|
70
|
+
if (tree) {
|
|
71
|
+
traverse(tree);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
73
75
|
return fields;
|
|
74
76
|
}
|
|
75
77
|
|
package/lib/app/publish.js
CHANGED
|
@@ -205,10 +205,15 @@ function compileSource(sourcePath) {
|
|
|
205
205
|
|
|
206
206
|
// ── ID 生成工具 ──────────────────────────────────────
|
|
207
207
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
208
|
+
/**
|
|
209
|
+
* 创建一个独立的 nodeId 生成器,每次调用 buildSchemaContent 时应创建新实例,
|
|
210
|
+
* 避免模块级全局计数器在多次调用时累加导致 ID 不可预期。
|
|
211
|
+
*/
|
|
212
|
+
function createNodeIdGenerator() {
|
|
213
|
+
let counter = 1;
|
|
214
|
+
return function nextNodeId() {
|
|
215
|
+
return 'node_oc' + Date.now().toString(36) + (counter++).toString(36);
|
|
216
|
+
};
|
|
212
217
|
}
|
|
213
218
|
|
|
214
219
|
function generateSuffix() {
|
|
@@ -219,6 +224,7 @@ function generateSuffix() {
|
|
|
219
224
|
|
|
220
225
|
function buildSchemaContent(sourceCode, compiledCode, formUuid) {
|
|
221
226
|
console.error(t('publish.building_schema'));
|
|
227
|
+
const nextNodeId = createNodeIdGenerator();
|
|
222
228
|
|
|
223
229
|
// 构造函数代码(固定模板)
|
|
224
230
|
const constructorCode = "function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}";
|
package/lib/core/check-update.js
CHANGED
|
@@ -37,10 +37,13 @@ function fetchLatestVersion() {
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* 比较版本号,返回 latestVersion 是否比 currentVersion 更新。
|
|
40
|
-
*
|
|
40
|
+
* 支持 semver 格式(major.minor.patch),pre-release 标签(如 -beta.1)会被忽略,
|
|
41
|
+
* 仅比较数字部分。
|
|
41
42
|
*/
|
|
42
43
|
function isNewer(currentVersion, latestVersion) {
|
|
43
|
-
|
|
44
|
+
// 截取 '-' 前的纯数字版本部分,兼容 pre-release 格式(如 1.2.3-beta.1)
|
|
45
|
+
const parseStableVersion = (v) => (v || '').split('-')[0];
|
|
46
|
+
const parseParts = (v) => parseStableVersion(v).split('.').map((n) => parseInt(n, 10) || 0);
|
|
44
47
|
const [cMajor, cMinor, cPatch] = parseParts(currentVersion);
|
|
45
48
|
const [lMajor, lMinor, lPatch] = parseParts(latestVersion);
|
|
46
49
|
|
package/lib/core/doctor.js
CHANGED
|
@@ -148,10 +148,7 @@ class EnvironmentChecker {
|
|
|
148
148
|
this.checkNodeVersion(),
|
|
149
149
|
this.checkNpmVersion(),
|
|
150
150
|
this.checkPlaywrightInstalled(),
|
|
151
|
-
this.checkGhCli(),
|
|
152
|
-
this.checkGhAuth(),
|
|
153
151
|
this.checkConfig(),
|
|
154
|
-
this.checkSkills(),
|
|
155
152
|
this.checkLoginStatus(),
|
|
156
153
|
await this.checkNetwork(),
|
|
157
154
|
];
|
|
@@ -220,51 +217,6 @@ class EnvironmentChecker {
|
|
|
220
217
|
}
|
|
221
218
|
}
|
|
222
219
|
|
|
223
|
-
checkGhCli() {
|
|
224
|
-
try {
|
|
225
|
-
const ghVersion = execSync('gh --version 2>&1', { encoding: 'utf-8' }).split('\n')[0].trim();
|
|
226
|
-
return {
|
|
227
|
-
id: 'env-gh',
|
|
228
|
-
label: ghVersion,
|
|
229
|
-
passed: true,
|
|
230
|
-
severity: Severity.INFO,
|
|
231
|
-
fixType: null,
|
|
232
|
-
};
|
|
233
|
-
} catch {
|
|
234
|
-
return {
|
|
235
|
-
id: 'env-gh',
|
|
236
|
-
label: 'gh CLI 安装检测',
|
|
237
|
-
passed: false,
|
|
238
|
-
severity: Severity.ERROR,
|
|
239
|
-
message: 'gh CLI 未安装,请安装:https://cli.github.com/',
|
|
240
|
-
fixType: null,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
checkGhAuth() {
|
|
246
|
-
try {
|
|
247
|
-
execSync('gh auth status 2>&1', { encoding: 'utf-8', stdio: 'pipe' });
|
|
248
|
-
return {
|
|
249
|
-
id: 'env-gh-auth',
|
|
250
|
-
label: 'gh CLI 已登录',
|
|
251
|
-
passed: true,
|
|
252
|
-
severity: Severity.INFO,
|
|
253
|
-
fixType: null,
|
|
254
|
-
};
|
|
255
|
-
} catch {
|
|
256
|
-
return {
|
|
257
|
-
id: 'env-gh-auth',
|
|
258
|
-
label: 'gh CLI 登录状态',
|
|
259
|
-
passed: false,
|
|
260
|
-
severity: Severity.WARNING,
|
|
261
|
-
message: 'gh CLI 未登录',
|
|
262
|
-
fixType: FixType.COMMAND,
|
|
263
|
-
fixCommand: 'gh auth login',
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
220
|
checkConfig() {
|
|
269
221
|
const configPath = path.join(this.projectRoot, 'config.json');
|
|
270
222
|
if (!fs.existsSync(configPath)) {
|
|
@@ -301,30 +253,6 @@ class EnvironmentChecker {
|
|
|
301
253
|
}
|
|
302
254
|
}
|
|
303
255
|
|
|
304
|
-
checkSkills() {
|
|
305
|
-
const skillsPath = path.join(this.projectRoot, '.claude', 'skills', 'skills');
|
|
306
|
-
if (fs.existsSync(skillsPath)) {
|
|
307
|
-
const skills = fs.readdirSync(skillsPath).filter((name) =>
|
|
308
|
-
fs.statSync(path.join(skillsPath, name)).isDirectory()
|
|
309
|
-
);
|
|
310
|
-
return {
|
|
311
|
-
id: 'env-skills',
|
|
312
|
-
label: `Skills 已安装(${skills.length} 个)`,
|
|
313
|
-
passed: true,
|
|
314
|
-
severity: Severity.INFO,
|
|
315
|
-
fixType: null,
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
return {
|
|
319
|
-
id: 'env-skills',
|
|
320
|
-
label: 'Skills 安装检测',
|
|
321
|
-
passed: false,
|
|
322
|
-
severity: Severity.WARNING,
|
|
323
|
-
message: 'Skills 未安装,运行 bash install-skills.sh 安装',
|
|
324
|
-
fixType: FixType.MANUAL,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
|
|
328
256
|
checkLoginStatus() {
|
|
329
257
|
const cookiePath = path.join(this.projectRoot, '.cache', 'cookies.json');
|
|
330
258
|
if (!fs.existsSync(cookiePath)) {
|
|
@@ -399,6 +327,121 @@ class EnvironmentChecker {
|
|
|
399
327
|
}
|
|
400
328
|
}
|
|
401
329
|
|
|
330
|
+
// ── VersionChecker ───────────────────────────────────
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* openyida 版本检查器。
|
|
334
|
+
* 检测当前安装版本是否与 SKILL.md 中的 metadata.version 一致,
|
|
335
|
+
* 不一致时在 --fix 模式下自动升级到最新版。
|
|
336
|
+
*/
|
|
337
|
+
class VersionChecker {
|
|
338
|
+
constructor({ projectRoot } = {}) {
|
|
339
|
+
this.projectRoot = projectRoot || findProjectRoot();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* 读取 SKILL.md 中 metadata.version 字段。
|
|
344
|
+
* @returns {string|null}
|
|
345
|
+
*/
|
|
346
|
+
readSkillVersion() {
|
|
347
|
+
const skillPaths = [
|
|
348
|
+
path.join(this.projectRoot, 'yida-skills', 'SKILL.md'),
|
|
349
|
+
path.join(require('os').homedir(), '.claude', 'yida-skills', 'SKILL.md'),
|
|
350
|
+
path.join(require('os').homedir(), '.aone_copilot', 'yida-skills', 'SKILL.md'),
|
|
351
|
+
];
|
|
352
|
+
for (const skillPath of skillPaths) {
|
|
353
|
+
if (!fs.existsSync(skillPath)) {continue;}
|
|
354
|
+
const content = fs.readFileSync(skillPath, 'utf-8');
|
|
355
|
+
const match = content.match(/^metadata:\s*\n\s*version:\s*(.+)$/m);
|
|
356
|
+
if (match) {return match[1].trim();}
|
|
357
|
+
}
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* 获取当前安装的 openyida 版本。
|
|
363
|
+
* @returns {string|null}
|
|
364
|
+
*/
|
|
365
|
+
getInstalledVersion() {
|
|
366
|
+
try {
|
|
367
|
+
return execSync('openyida -v 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
368
|
+
} catch {
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
async check() {
|
|
374
|
+
const skillVersion = this.readSkillVersion();
|
|
375
|
+
const installedVersion = this.getInstalledVersion();
|
|
376
|
+
|
|
377
|
+
if (!skillVersion) {
|
|
378
|
+
return [{
|
|
379
|
+
id: 'version-skill',
|
|
380
|
+
label: 'openyida 版本检测',
|
|
381
|
+
passed: true,
|
|
382
|
+
severity: Severity.INFO,
|
|
383
|
+
message: '无法读取 SKILL.md 版本,跳过版本比对',
|
|
384
|
+
fixType: null,
|
|
385
|
+
}];
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (!installedVersion) {
|
|
389
|
+
return [{
|
|
390
|
+
id: 'version-installed',
|
|
391
|
+
label: 'openyida 版本检测',
|
|
392
|
+
passed: false,
|
|
393
|
+
severity: Severity.ERROR,
|
|
394
|
+
message: 'openyida 未安装,请运行:npm install -g openyida',
|
|
395
|
+
fixType: FixType.COMMAND,
|
|
396
|
+
fixCommand: 'npm install -g openyida@latest',
|
|
397
|
+
}];
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// 比较主版本号(忽略 -beta.x 等预发布后缀)
|
|
401
|
+
const installedMain = installedVersion.replace(/-.+$/, '');
|
|
402
|
+
const skillMain = skillVersion.replace(/-.+$/, '');
|
|
403
|
+
const passed = installedMain === skillMain;
|
|
404
|
+
|
|
405
|
+
return [{
|
|
406
|
+
id: 'version-match',
|
|
407
|
+
label: `openyida 版本:${installedVersion}(SKILL 期望:${skillVersion})`,
|
|
408
|
+
passed,
|
|
409
|
+
severity: passed ? Severity.INFO : Severity.WARNING,
|
|
410
|
+
message: passed ? null : `版本不匹配,建议升级到最新版`,
|
|
411
|
+
fixType: passed ? null : FixType.COMMAND,
|
|
412
|
+
fixCommand: passed ? null : 'npm install -g openyida@latest',
|
|
413
|
+
}];
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// ── ProjectInitChecker ────────────────────────────────
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* project 工作目录初始化检查器。
|
|
421
|
+
* 检测 project/ 目录是否存在,不存在时在 --fix 模式下自动执行 openyida copy。
|
|
422
|
+
*/
|
|
423
|
+
class ProjectInitChecker {
|
|
424
|
+
constructor({ projectRoot } = {}) {
|
|
425
|
+
this.projectRoot = projectRoot || findProjectRoot();
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
async check() {
|
|
429
|
+
const projectDir = path.join(this.projectRoot, 'project');
|
|
430
|
+
const configPath = path.join(projectDir, 'config.json');
|
|
431
|
+
const passed = fs.existsSync(projectDir) && fs.existsSync(configPath);
|
|
432
|
+
|
|
433
|
+
return [{
|
|
434
|
+
id: 'project-init',
|
|
435
|
+
label: passed ? 'project/ 工作目录已初始化' : 'project/ 工作目录检测',
|
|
436
|
+
passed,
|
|
437
|
+
severity: passed ? Severity.INFO : Severity.WARNING,
|
|
438
|
+
message: passed ? null : 'project/ 目录未初始化,将自动执行 openyida copy',
|
|
439
|
+
fixType: passed ? null : FixType.COMMAND,
|
|
440
|
+
fixCommand: passed ? null : 'openyida copy',
|
|
441
|
+
}];
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
402
445
|
// ── ApplicationChecker ────────────────────────────────
|
|
403
446
|
|
|
404
447
|
/**
|
|
@@ -1410,6 +1453,8 @@ async function run(args) {
|
|
|
1410
1453
|
|
|
1411
1454
|
// ── 主诊断流程 ──
|
|
1412
1455
|
const engine = new DiagnosticEngine({ projectRoot });
|
|
1456
|
+
engine.registerChecker(new VersionChecker({ projectRoot }));
|
|
1457
|
+
engine.registerChecker(new ProjectInitChecker({ projectRoot }));
|
|
1413
1458
|
engine.registerChecker(new EnvironmentChecker({ projectRoot }));
|
|
1414
1459
|
engine.registerChecker(new ApplicationChecker({ projectRoot, appId: options.app }));
|
|
1415
1460
|
|
|
@@ -1451,6 +1496,8 @@ async function run(args) {
|
|
|
1451
1496
|
|
|
1452
1497
|
module.exports = {
|
|
1453
1498
|
DiagnosticEngine,
|
|
1499
|
+
VersionChecker,
|
|
1500
|
+
ProjectInitChecker,
|
|
1454
1501
|
EnvironmentChecker,
|
|
1455
1502
|
ApplicationChecker,
|
|
1456
1503
|
FixEngine,
|
package/lib/core/locales/ar.js
CHANGED
|
@@ -42,6 +42,9 @@ module.exports = {
|
|
|
42
42
|
example: 'مثال: openyida create-app "تطبيقي"',
|
|
43
43
|
title: ' create-app - أداة إنشاء تطبيق Yida',
|
|
44
44
|
app_name: '\n اسم التطبيق: {0}',
|
|
45
|
+
app_desc: ' الوصف: {0}',
|
|
46
|
+
app_icon: ' الأيقونة: {0} ({1})',
|
|
47
|
+
app_theme: ' السمة: colour={0} navTheme={1} layout={2}',
|
|
45
48
|
step_create: '\n🚀 جارٍ إنشاء التطبيق...',
|
|
46
49
|
sending_request: ' جارٍ إرسال طلب createApp...',
|
|
47
50
|
success: ' ✅ تم إنشاء التطبيق بنجاح!',
|
package/lib/core/locales/de.js
CHANGED
|
@@ -42,6 +42,9 @@ module.exports = {
|
|
|
42
42
|
example: 'Beispiel: openyida create-app "Meine App"',
|
|
43
43
|
title: ' create-app - Yida-App-Erstellungstool',
|
|
44
44
|
app_name: '\n App-Name: {0}',
|
|
45
|
+
app_desc: ' Beschreibung: {0}',
|
|
46
|
+
app_icon: ' Symbol: {0} ({1})',
|
|
47
|
+
app_theme: ' Thema: colour={0} navTheme={1} layout={2}',
|
|
45
48
|
step_create: '\n🚀 App wird erstellt...',
|
|
46
49
|
sending_request: ' createApp-Anfrage wird gesendet...',
|
|
47
50
|
success: ' ✅ App erfolgreich erstellt!',
|
package/lib/core/locales/en.js
CHANGED
|
@@ -230,7 +230,7 @@ Examples:
|
|
|
230
230
|
app_name: ' App name: {0}',
|
|
231
231
|
app_desc: ' Description: {0}',
|
|
232
232
|
app_icon: ' Icon: {0} ({1})',
|
|
233
|
-
app_theme: ' Theme: {0}',
|
|
233
|
+
app_theme: ' Theme: colour={0} navTheme={1} layout={2}',
|
|
234
234
|
step_create: '\n📦 Step 2: Create App\n',
|
|
235
235
|
success: ' ✅ App created successfully!',
|
|
236
236
|
app_type_label: ' appType: {0}',
|
package/lib/core/locales/es.js
CHANGED
|
@@ -42,6 +42,9 @@ module.exports = {
|
|
|
42
42
|
example: 'Ejemplo: openyida create-app "Mi App"',
|
|
43
43
|
title: ' create-app - Herramienta de creación de aplicaciones Yida',
|
|
44
44
|
app_name: '\n Nombre de la app: {0}',
|
|
45
|
+
app_desc: ' Descripción: {0}',
|
|
46
|
+
app_icon: ' Icono: {0} ({1})',
|
|
47
|
+
app_theme: ' Tema: colour={0} navTheme={1} layout={2}',
|
|
45
48
|
step_create: '\n🚀 Creando la aplicación...',
|
|
46
49
|
sending_request: ' Enviando solicitud createApp...',
|
|
47
50
|
success: ' ✅ ¡Aplicación creada exitosamente!',
|
package/lib/core/locales/fr.js
CHANGED
|
@@ -42,6 +42,9 @@ module.exports = {
|
|
|
42
42
|
example: 'Exemple : openyida create-app "Mon App"',
|
|
43
43
|
title: " create-app - Outil de création d'application Yida",
|
|
44
44
|
app_name: "\n Nom de l'app : {0}",
|
|
45
|
+
app_desc: ' Description : {0}',
|
|
46
|
+
app_icon: ' Icône : {0} ({1})',
|
|
47
|
+
app_theme: ' Thème : colour={0} navTheme={1} layout={2}',
|
|
45
48
|
step_create: "\n🚀 Création de l'application...",
|
|
46
49
|
sending_request: ' Envoi de la requête createApp...',
|
|
47
50
|
success: ' ✅ Application créée avec succès !',
|
package/lib/core/locales/hi.js
CHANGED
|
@@ -42,6 +42,9 @@ module.exports = {
|
|
|
42
42
|
example: 'उदाहरण: openyida create-app "मेरा ऐप"',
|
|
43
43
|
title: ' create-app - Yida ऐप निर्माण टूल',
|
|
44
44
|
app_name: '\n ऐप नाम: {0}',
|
|
45
|
+
app_desc: ' विवरण: {0}',
|
|
46
|
+
app_icon: ' आइकॉन: {0} ({1})',
|
|
47
|
+
app_theme: ' थीम: colour={0} navTheme={1} layout={2}',
|
|
45
48
|
step_create: '\n🚀 ऐप बनाया जा रहा है...',
|
|
46
49
|
sending_request: ' createApp अनुरोध भेजा जा रहा है...',
|
|
47
50
|
success: ' ✅ ऐप सफलतापूर्वक बनाया गया!',
|
package/lib/core/locales/ja.js
CHANGED
|
@@ -215,7 +215,7 @@ openyida - Yida CLI ツール
|
|
|
215
215
|
app_name: ' アプリ名: {0}',
|
|
216
216
|
app_desc: ' 説明: {0}',
|
|
217
217
|
app_icon: ' アイコン: {0} ({1})',
|
|
218
|
-
app_theme: '
|
|
218
|
+
app_theme: ' テーマ: colour={0} navTheme={1} layout={2}',
|
|
219
219
|
step_create: '\n📦 Step 2: アプリを作成\n',
|
|
220
220
|
success: ' ✅ アプリが正常に作成されました!',
|
|
221
221
|
app_type_label: ' appType: {0}',
|
package/lib/core/locales/ko.js
CHANGED
|
@@ -42,6 +42,9 @@ module.exports = {
|
|
|
42
42
|
example: '예시: openyida create-app "내 앱"',
|
|
43
43
|
title: ' create-app - Yida 앱 생성 도구',
|
|
44
44
|
app_name: '\n 앱 이름: {0}',
|
|
45
|
+
app_desc: ' 설명: {0}',
|
|
46
|
+
app_icon: ' 아이콘: {0} ({1})',
|
|
47
|
+
app_theme: ' 테마: colour={0} navTheme={1} layout={2}',
|
|
45
48
|
step_create: '\n🚀 앱 생성 중...',
|
|
46
49
|
sending_request: ' createApp 요청 전송 중...',
|
|
47
50
|
success: ' ✅ 앱 생성 성공!',
|
package/lib/core/locales/pt.js
CHANGED
|
@@ -42,6 +42,9 @@ module.exports = {
|
|
|
42
42
|
example: 'Exemplo: openyida create-app "Meu App"',
|
|
43
43
|
title: ' create-app - Ferramenta de criação de aplicativos Yida',
|
|
44
44
|
app_name: '\n Nome do app: {0}',
|
|
45
|
+
app_desc: ' Descrição: {0}',
|
|
46
|
+
app_icon: ' Ícone: {0} ({1})',
|
|
47
|
+
app_theme: ' Tema: colour={0} navTheme={1} layout={2}',
|
|
45
48
|
step_create: '\n🚀 Criando o aplicativo...',
|
|
46
49
|
sending_request: ' Enviando requisição createApp...',
|
|
47
50
|
success: ' ✅ Aplicativo criado com sucesso!',
|
package/lib/core/locales/vi.js
CHANGED
|
@@ -42,6 +42,9 @@ module.exports = {
|
|
|
42
42
|
example: 'Ví dụ: openyida create-app "Ứng dụng của tôi"',
|
|
43
43
|
title: ' create-app - Công cụ tạo ứng dụng Yida',
|
|
44
44
|
app_name: '\n Tên ứng dụng: {0}',
|
|
45
|
+
app_desc: ' Mô tả: {0}',
|
|
46
|
+
app_icon: ' Biểu tượng: {0} ({1})',
|
|
47
|
+
app_theme: ' Chủ đề: colour={0} navTheme={1} layout={2}',
|
|
45
48
|
step_create: '\n🚀 Đang tạo ứng dụng...',
|
|
46
49
|
sending_request: ' Đang gửi yêu cầu createApp...',
|
|
47
50
|
success: ' ✅ Tạo ứng dụng thành công!',
|
|
@@ -222,7 +222,7 @@ openyida - 宜搭命令列工具
|
|
|
222
222
|
app_name: ' 應用名稱:{0}',
|
|
223
223
|
app_desc: ' 應用描述:{0}',
|
|
224
224
|
app_icon: ' 圖示: {0} ({1})',
|
|
225
|
-
app_theme: '
|
|
225
|
+
app_theme: ' 主題: colour={0} navTheme={1} layout={2}',
|
|
226
226
|
step_create: '\n📦 Step 2:建立應用\n',
|
|
227
227
|
success: ' ✅ 應用建立成功!',
|
|
228
228
|
app_type_label: ' appType:{0}',
|
package/lib/core/locales/zh.js
CHANGED
|
@@ -222,7 +222,7 @@ openyida - 宜搭命令行工具
|
|
|
222
222
|
app_name: ' 应用名称: {0}',
|
|
223
223
|
app_desc: ' 应用描述: {0}',
|
|
224
224
|
app_icon: ' 图标: {0} ({1})',
|
|
225
|
-
app_theme: '
|
|
225
|
+
app_theme: ' 主题: colour={0} navTheme={1} layout={2}',
|
|
226
226
|
step_create: '\n📦 Step 2: 创建应用\n',
|
|
227
227
|
success: ' ✅ 应用创建成功!',
|
|
228
228
|
app_type_label: ' appType: {0}',
|
package/lib/core/utils.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* findProjectRoot() - 查找项目根目录(兼容悟空环境)
|
|
6
6
|
* extractInfoFromCookies() - 从 Cookie 列表中提取 csrf_token / corp_id / user_id
|
|
7
7
|
* loadCookieData() - 读取 .cache/cookies.json 登录态缓存
|
|
8
|
-
* triggerLogin() -
|
|
8
|
+
* triggerLogin() - 触发登录
|
|
9
9
|
* refreshCsrfToken() - 刷新 csrf_token
|
|
10
10
|
* resolveBaseUrl() - 从 cookieData 中解析 base_url
|
|
11
11
|
* isLoginExpired() - 检测响应体是否表示登录过期
|
|
@@ -24,6 +24,19 @@ const {
|
|
|
24
24
|
} = require('../core/utils');
|
|
25
25
|
const { t } = require('../core/i18n');
|
|
26
26
|
|
|
27
|
+
// ── 路径常量 ──────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
/** Prompt 构建模块文件名(与本文件同目录) */
|
|
30
|
+
const PROMPT_BUILDER_FILE = 'build-flash-note-prompt.js';
|
|
31
|
+
|
|
32
|
+
/** 闪记转 PRD 技能在工作目录软链中的相对路径(用户自定义覆盖场景) */
|
|
33
|
+
const FLASH_NOTE_SKILL_RELATIVE_PATH = path.join(
|
|
34
|
+
'yida-skills', 'skills', 'yida-flash-note-to-prd', PROMPT_BUILDER_FILE
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
/** PRD 输出目录名(相对于项目工作目录) */
|
|
38
|
+
const PRD_OUTPUT_DIR = 'prd';
|
|
39
|
+
|
|
27
40
|
// ── 参数解析 ──────────────────────────────────────────
|
|
28
41
|
|
|
29
42
|
function parseArgs(args) {
|
|
@@ -117,28 +130,26 @@ function extractProjectNameFromPrd(prdContent) {
|
|
|
117
130
|
// ── Prompt 构建模块加载 ───────────────────────────────
|
|
118
131
|
|
|
119
132
|
function loadPromptBuilder() {
|
|
133
|
+
// 优先:与本文件同目录的内置模块(npm 包安装后的标准路径)
|
|
134
|
+
const builtinModulePath = path.join(__dirname, PROMPT_BUILDER_FILE);
|
|
135
|
+
|
|
136
|
+
// 备用:用户工作目录下的 yida-skills 软链(openyida copy -skills 创建的软链)
|
|
120
137
|
const projectRoot = findProjectRoot();
|
|
121
|
-
const
|
|
122
|
-
__dirname, '..', '..', 'yida-skills', 'skills',
|
|
123
|
-
'yida-flash-note-to-prd', 'build-flash-note-prompt.js'
|
|
124
|
-
);
|
|
125
|
-
const localModulePath = path.join(
|
|
126
|
-
projectRoot, 'skills', 'yida-flash-note-to-prd', 'build-flash-note-prompt.js'
|
|
127
|
-
);
|
|
138
|
+
const linkedModulePath = path.join(projectRoot, FLASH_NOTE_SKILL_RELATIVE_PATH);
|
|
128
139
|
|
|
129
|
-
if (fs.existsSync(
|
|
140
|
+
if (fs.existsSync(builtinModulePath)) {
|
|
130
141
|
console.error(t('flashNote.toPrd.module_loaded_builtin'));
|
|
131
|
-
return require(
|
|
142
|
+
return require(builtinModulePath);
|
|
132
143
|
}
|
|
133
144
|
|
|
134
|
-
if (fs.existsSync(
|
|
135
|
-
console.error(t('flashNote.toPrd.module_loaded_local',
|
|
136
|
-
return require(
|
|
145
|
+
if (fs.existsSync(linkedModulePath)) {
|
|
146
|
+
console.error(t('flashNote.toPrd.module_loaded_local', linkedModulePath));
|
|
147
|
+
return require(linkedModulePath);
|
|
137
148
|
}
|
|
138
149
|
|
|
139
150
|
console.error(t('flashNote.toPrd.module_not_found'));
|
|
140
|
-
console.error(t('flashNote.toPrd.module_path_tried', '1',
|
|
141
|
-
console.error(t('flashNote.toPrd.module_path_tried', '2',
|
|
151
|
+
console.error(t('flashNote.toPrd.module_path_tried', '1', builtinModulePath));
|
|
152
|
+
console.error(t('flashNote.toPrd.module_path_tried', '2', linkedModulePath));
|
|
142
153
|
process.exit(1);
|
|
143
154
|
}
|
|
144
155
|
|
|
@@ -268,7 +279,7 @@ async function run(args) {
|
|
|
268
279
|
const projectName = parsed.name || extractProjectNameFromPrd(prdContent);
|
|
269
280
|
const safeFileName = projectName.replace(/[<>:"/\\|?*\s]/g, '-').replace(/-+/g, '-');
|
|
270
281
|
const projectRoot = findProjectRoot();
|
|
271
|
-
const prdDir = path.join(projectRoot,
|
|
282
|
+
const prdDir = path.join(projectRoot, PRD_OUTPUT_DIR);
|
|
272
283
|
|
|
273
284
|
if (!fs.existsSync(prdDir)) {
|
|
274
285
|
fs.mkdirSync(prdDir, { recursive: true });
|