openyida 2026.8.5 → 2026.8.12

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 CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  OpenYida connects AI coding agents with Yida's low-code platform, so developers can create apps, forms, workflows, custom pages, reports, integrations, and deployment configuration from a normal chat-driven development workflow.
10
10
 
11
- [Quick Start](#quick-start) · [Help Center](https://xmtrf1.aliwork.com/o/openyida/help?lang=en) · [Capabilities](#capabilities) · [Full Capability List](./docs/capabilities.md) · [CLI Reference](#cli-reference) · [Examples](#examples) · [Contributing](./CONTRIBUTING.md) · [Changelog](./CHANGELOG.md)
11
+ [Quick Start](#quick-start) · [帮助网站&文档](https://demo.aliwork.com/o/openyida/helpCenter) · [Capabilities](#capabilities) · [Full Capability List](https://demo.aliwork.com/o/openyida/helpCenter?openyidaPath=capabilities) · [CLI Reference](https://demo.aliwork.com/o/openyida/helpCenter?openyidaPath=features/skills) · [Examples](https://demo.aliwork.com/o/openyida/helpCenter?openyidaRoute=showcase) · [Contributing](./CONTRIBUTING.md) · [Changelog](https://demo.aliwork.com/o/openyida/helpCenter?openyidaRoute=changelog)
12
12
 
13
13
  [![npm version](https://img.shields.io/npm/v/openyida?color=brightgreen&label=npm)](https://www.npmjs.com/package/openyida)
14
14
  [![npm downloads](https://img.shields.io/npm/dm/openyida?color=blue)](https://www.npmjs.com/package/openyida)
@@ -16,7 +16,7 @@ OpenYida connects AI coding agents with Yida's low-code platform, so developers
16
16
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
17
17
  [![Node.js >=18](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
18
18
 
19
- **Help Center:** [简体中文](https://xmtrf1.aliwork.com/o/openyida/help?lang=zh) · [繁體中文(中國台灣)](https://xmtrf1.aliwork.com/o/openyida/help?lang=zh-Hant) · [繁體中文(中國香港)](https://xmtrf1.aliwork.com/o/openyida/help?lang=zh-HK) · [English](https://xmtrf1.aliwork.com/o/openyida/help?lang=en) · [日本語](https://xmtrf1.aliwork.com/o/openyida/help?lang=ja) · [한국어](https://xmtrf1.aliwork.com/o/openyida/help?lang=ko) · [Tiếng Việt](https://xmtrf1.aliwork.com/o/openyida/help?lang=vi) · [ไทย](https://xmtrf1.aliwork.com/o/openyida/help?lang=th) · [Bahasa Indonesia](https://xmtrf1.aliwork.com/o/openyida/help?lang=id) · [Bahasa Melayu](https://xmtrf1.aliwork.com/o/openyida/help?lang=ms) · [Français](https://xmtrf1.aliwork.com/o/openyida/help?lang=fr) · [Português](https://xmtrf1.aliwork.com/o/openyida/help?lang=pt) · [Türkçe](https://xmtrf1.aliwork.com/o/openyida/help?lang=tr) · [Español](https://xmtrf1.aliwork.com/o/openyida/help?lang=es) · [Русский](https://xmtrf1.aliwork.com/o/openyida/help?lang=ru)
19
+ **帮助网站&文档:** [帮助网站&文档](https://demo.aliwork.com/o/openyida/helpCenter)
20
20
 
21
21
  [English README](./README.md) · [简体中文 README](./README_zhCN.md)
22
22
 
@@ -163,7 +163,7 @@ openyida/
163
163
 
164
164
  ## Capabilities
165
165
 
166
- For a user-facing list of supported features and matching CLI commands, see [OpenYida 功能完整列表](./docs/capabilities.md).
166
+ For a user-facing list of supported features and matching CLI commands, see [OpenYida 功能完整列表](https://demo.aliwork.com/o/openyida/helpCenter?openyidaPath=capabilities).
167
167
 
168
168
  ### Application and Form Management
169
169
 
@@ -194,6 +194,8 @@ Custom page source is authored directly from PRD and design guidance. Code Canva
194
194
 
195
195
  For member, department, attachment, and image upload components, choose the page chain first. Code Canvas pages should follow `yida-canvas-custom-page/references/native-components-bridge.md` for feature detection, fallback, and value normalization. 普通自定义页面 JSX/Jsx pages should use `.oyd.jsx`, read `yida-custom-page/references/component-jsx-guide.md`, and read `attachment-upload-guide.md` when upload fields are involved.
196
196
 
197
+ For the current AI custom page native-component support matrix, see [Yida native components supported by AI custom pages](https://demo.aliwork.com/o/openyida/sample/canvas-native-components).
198
+
197
199
  ### Workflow, Data, and Permissions
198
200
 
199
201
  ```bash
@@ -369,6 +371,8 @@ Run `openyida --help` or `openyida <command> --help` for detailed usage.
369
371
  | `openyida corp-efficiency [overview\|details\|detail\|groups\|notify] [options] [--open\|--no-open]` | Query enterprise efficiency overview and detail reports |
370
372
  | `openyida create-app "<name>"\|--name <name> [options] [--locale zh_CN\|en_US\|ja_JP] [--open\|--no-open]` | Create a Yida app |
371
373
  | `openyida update-app <appType> [--name "..."] [--layout slide\|ver] [--theme deepBlue]` | Update app info |
374
+ | `openyida app-online <appType> [--to-ding-app-center] [--show-app-center]` | Enable a Yida app |
375
+ | `openyida app-offline <appType> [--to-ding-app-center] [--show-app-center]` | Disable a Yida app |
372
376
  | `openyida nav-group <list\|create\|rename\|delete\|move\|order\|auto-order\|hide\|show> <appType> ...` | Manage app sidebar navigation groups |
373
377
  | `openyida app-permission <get\|set\|add\|remove\|search-user> ...` | Manage app primary, data, and developer admins |
374
378
  | `openyida i18n <overview\|config\|languages\|list\|upsert\|delete\|translate\|translate-all\|upgrade> <appType> ...` | Manage app multilingual copy and language config |
package/bin/yida.js CHANGED
@@ -143,7 +143,7 @@ function printHelp() {
143
143
  console.log(` ${DIM}${RESET} openyida create-form create APP_XXX "${t('help.quickstart_form_name')}" .cache/openyida/forms/fields.json`);
144
144
  console.log(` ${DIM}${RESET} openyida dws contact user search --keyword "张三"`);
145
145
  console.log('');
146
- console.log(` ${DIM}${t('help.docs')} https://xmtrf1.aliwork.com/o/openyida/help · https://github.com/openyida/openyida${RESET}`);
146
+ console.log(` ${DIM}${t('help.docs')} https://demo.aliwork.com/o/openyida/helpCenter · https://github.com/openyida/openyida${RESET}`);
147
147
  console.log('');
148
148
  }
149
149
 
@@ -841,6 +841,13 @@ async function main() {
841
841
  break;
842
842
  }
843
843
 
844
+ case 'app-online':
845
+ case 'app-offline': {
846
+ const { run: runAppLifecycle } = require('../lib/app/app-lifecycle');
847
+ await runAppLifecycle(command === 'app-online' ? 'online' : 'offline', args);
848
+ break;
849
+ }
850
+
844
851
  case 'nav-group':
845
852
  case 'group': {
846
853
  const { run: runNavGroup } = require('../lib/app/nav-group');
@@ -0,0 +1,128 @@
1
+ /**
2
+ * app-lifecycle.js - 启用或停用宜搭应用
3
+ *
4
+ * 用法:
5
+ * openyida app-online <appType> [--to-ding-app-center] [--show-app-center]
6
+ * openyida app-offline <appType> [--to-ding-app-center] [--show-app-center]
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const querystring = require('querystring');
12
+ const { httpPost, requestWithAutoLogin } = require('../core/utils');
13
+ const { createAuthRef } = require('../core/yida-client');
14
+ const { t } = require('../core/i18n');
15
+ const { throwCommandError, throwUsage } = require('../core/command-errors');
16
+
17
+ const ACTIONS = Object.freeze({
18
+ online: Object.freeze({ endpoint: 'onlineApp', api: 'App.goOnline' }),
19
+ offline: Object.freeze({ endpoint: 'offlineApp', api: 'App.goOffline' }),
20
+ });
21
+
22
+ function parseArgs(args = []) {
23
+ const params = {
24
+ appType: null,
25
+ toDingAppCenter: false,
26
+ showAppCenter: false,
27
+ help: false,
28
+ };
29
+
30
+ for (const arg of args) {
31
+ if (arg === '--help' || arg === '-h') {
32
+ params.help = true;
33
+ } else if (arg === '--to-ding-app-center') {
34
+ params.toDingAppCenter = true;
35
+ } else if (arg === '--show-app-center') {
36
+ params.showAppCenter = true;
37
+ } else if (!arg.startsWith('-') && !params.appType) {
38
+ params.appType = arg;
39
+ } else {
40
+ throwUsage(t('app_lifecycle.invalid_argument', arg));
41
+ }
42
+ }
43
+
44
+ return params;
45
+ }
46
+
47
+ function buildRequestPath(action, appType, stamp = Date.now()) {
48
+ const config = ACTIONS[action];
49
+ if (!config) {
50
+ throw new Error(t('app_lifecycle.invalid_action', action));
51
+ }
52
+ return `/dingtalk/web/${encodeURIComponent(appType)}/query/app/${config.endpoint}.json` +
53
+ `?_api=${encodeURIComponent(config.api)}&_mock=false&_stamp=${stamp}`;
54
+ }
55
+
56
+ function buildPostData(params, authRef) {
57
+ return querystring.stringify({
58
+ _csrf_token: authRef.csrfToken || '',
59
+ _locale_time_zone_offset: '28800000',
60
+ isToDingAppCenter: params.toDingAppCenter ? 'y' : 'n',
61
+ showAppCenter: params.showAppCenter ? 'y' : 'n',
62
+ });
63
+ }
64
+
65
+ async function changeAppLifecycle(action, params, authRef = createAuthRef()) {
66
+ const response = await requestWithAutoLogin((auth) => httpPost(
67
+ auth.baseUrl,
68
+ buildRequestPath(action, params.appType),
69
+ buildPostData(params, auth),
70
+ auth.cookies
71
+ ), authRef);
72
+
73
+ if (!response || response.success !== true || response.content !== true) {
74
+ const errorMsg = response && (response.errorMsg || response.message || response.errorCode);
75
+ throwCommandError(errorMsg || t('app_lifecycle.request_failed'), {
76
+ code: action === 'online' ? 'APP_ONLINE_FAILED' : 'APP_OFFLINE_FAILED',
77
+ details: { action, appType: params.appType },
78
+ });
79
+ }
80
+
81
+ return {
82
+ success: true,
83
+ action,
84
+ appType: params.appType,
85
+ isToDingAppCenter: params.toDingAppCenter,
86
+ showAppCenter: params.showAppCenter,
87
+ };
88
+ }
89
+
90
+ function printUsage(action) {
91
+ const { usage } = require('../core/chalk');
92
+ usage(t(`app_lifecycle.${action}_usage`), t(`app_lifecycle.${action}_example`));
93
+ }
94
+
95
+ async function run(action, args = []) {
96
+ if (!ACTIONS[action]) {
97
+ throwCommandError(t('app_lifecycle.invalid_action', action), {
98
+ code: 'APP_LIFECYCLE_INVALID_ACTION',
99
+ });
100
+ }
101
+
102
+ const params = parseArgs(args);
103
+ if (params.help) {
104
+ printUsage(action);
105
+ return { success: true, help: true };
106
+ }
107
+ if (!params.appType) {
108
+ printUsage(action);
109
+ throwUsage(t('app_lifecycle.missing_app_type'), t(`app_lifecycle.${action}_usage`), {
110
+ code: 'APP_LIFECYCLE_USAGE',
111
+ });
112
+ }
113
+
114
+ const output = await changeAppLifecycle(action, params);
115
+ const { result } = require('../core/chalk');
116
+ result(true, t(`app_lifecycle.${action}_success`), [['appType', params.appType]]);
117
+ console.log(JSON.stringify(output));
118
+ return output;
119
+ }
120
+
121
+ module.exports = {
122
+ ACTIONS,
123
+ buildPostData,
124
+ buildRequestPath,
125
+ changeAppLifecycle,
126
+ parseArgs,
127
+ run,
128
+ };
@@ -187,6 +187,117 @@ function buildComponentAliasMaps(schemaResult) {
187
187
  return { aliasByFieldId, fieldIdByAlias };
188
188
  }
189
189
 
190
+ function parseJsonObject(value) {
191
+ if (typeof value !== 'string') {
192
+ return value && typeof value === 'object' ? value : null;
193
+ }
194
+ try {
195
+ const parsed = JSON.parse(value);
196
+ return parsed && typeof parsed === 'object' ? parsed : null;
197
+ } catch {
198
+ return null;
199
+ }
200
+ }
201
+
202
+ function resolveSchemaContent(schemaResult) {
203
+ if (!schemaResult) {
204
+ return null;
205
+ }
206
+ const content = schemaResult.content !== undefined ? schemaResult.content : schemaResult;
207
+ return parseJsonObject(content);
208
+ }
209
+
210
+ function addImportedModules(target, value) {
211
+ let modules = value;
212
+ if (typeof modules === 'string') {
213
+ const trimmed = modules.trim();
214
+ if (!trimmed) {
215
+ return;
216
+ }
217
+ try {
218
+ modules = JSON.parse(trimmed);
219
+ } catch {
220
+ modules = [trimmed];
221
+ }
222
+ }
223
+ if (!Array.isArray(modules)) {
224
+ return;
225
+ }
226
+ modules
227
+ .map(item => String(item || '').trim())
228
+ .filter(Boolean)
229
+ .forEach((item) => {
230
+ if (!target.includes(item)) {
231
+ target.push(item);
232
+ }
233
+ });
234
+ }
235
+
236
+ function codeBytes(value) {
237
+ return typeof value === 'string' ? Buffer.byteLength(value, 'utf8') : 0;
238
+ }
239
+
240
+ function isComponentInstance(node) {
241
+ return !!(node && typeof node === 'object' && (node.id || node.props || node.children));
242
+ }
243
+
244
+ function extractDisplayPageSummary(schemaResult) {
245
+ const content = resolveSchemaContent(schemaResult);
246
+ if (!content || typeof content !== 'object') {
247
+ return null;
248
+ }
249
+
250
+ const displayPage = {
251
+ hasYidaCodeCanvas: false,
252
+ hasNativeJsx: false,
253
+ runtimeCodeBytes: 0,
254
+ sourceCodeBytes: 0,
255
+ compiledCodeBytes: 0,
256
+ importedModules: [],
257
+ componentCount: 0,
258
+ };
259
+
260
+ function traverse(node) {
261
+ if (!node) {
262
+ return;
263
+ }
264
+ if (Array.isArray(node)) {
265
+ node.forEach(traverse);
266
+ return;
267
+ }
268
+ if (typeof node !== 'object') {
269
+ return;
270
+ }
271
+
272
+ if (node.componentName === 'YidaCodeCanvas' && isComponentInstance(node)) {
273
+ const props = node.props || {};
274
+ displayPage.hasYidaCodeCanvas = true;
275
+ displayPage.componentCount++;
276
+ displayPage.runtimeCodeBytes += codeBytes(props.runtimeCode);
277
+ displayPage.sourceCodeBytes += codeBytes(props.code);
278
+ addImportedModules(displayPage.importedModules, props.importedModules);
279
+ } else if (node.componentName === 'Jsx' && isComponentInstance(node)) {
280
+ displayPage.hasNativeJsx = true;
281
+ displayPage.componentCount++;
282
+ }
283
+
284
+ Object.keys(node).forEach((key) => traverse(node[key]));
285
+ }
286
+
287
+ traverse(content.pages || content);
288
+
289
+ const module = content.actions && content.actions.module;
290
+ if (displayPage.hasNativeJsx && module && typeof module === 'object') {
291
+ displayPage.sourceCodeBytes += codeBytes(module.source);
292
+ displayPage.compiledCodeBytes += codeBytes(module.compiled);
293
+ }
294
+
295
+ if (!displayPage.hasYidaCodeCanvas && !displayPage.hasNativeJsx) {
296
+ return null;
297
+ }
298
+ return displayPage;
299
+ }
300
+
190
301
  function parsePositiveInt(value, fallback, min, max) {
191
302
  const parsed = Number.parseInt(value, 10);
192
303
  if (!Number.isFinite(parsed) || parsed < min) {
@@ -402,7 +513,7 @@ function printFieldSummary(result) {
402
513
 
403
514
  function buildSchemaSummary(appType, formUuid, schemaResult, meta = {}) {
404
515
  const fields = extractFieldSummary(schemaResult);
405
- return {
516
+ const summary = {
406
517
  success: true,
407
518
  appType,
408
519
  formUuid,
@@ -410,6 +521,11 @@ function buildSchemaSummary(appType, formUuid, schemaResult, meta = {}) {
410
521
  fieldCount: fields.length,
411
522
  fields,
412
523
  };
524
+ const displayPage = extractDisplayPageSummary(schemaResult);
525
+ if (displayPage) {
526
+ summary.displayPage = displayPage;
527
+ }
528
+ return summary;
413
529
  }
414
530
 
415
531
  function filterForms(forms, keyword) {
@@ -454,7 +570,7 @@ async function fetchSchemaRecord(appType, form, authRef, retries) {
454
570
  try {
455
571
  const result = await fetchSchema(appType, form.formUuid, authRef);
456
572
  if (isSuccessfulSchemaResult(result)) {
457
- return {
573
+ const record = {
458
574
  formUuid: form.formUuid,
459
575
  formName: form.formName,
460
576
  formType: form.formType,
@@ -464,6 +580,11 @@ async function fetchSchemaRecord(appType, form, authRef, retries) {
464
580
  fieldSummary: extractFieldSummary(result),
465
581
  schema: result,
466
582
  };
583
+ const displayPage = extractDisplayPageSummary(result);
584
+ if (displayPage) {
585
+ record.displayPage = displayPage;
586
+ }
587
+ return record;
467
588
  }
468
589
  lastError = new Error(result ? result.errorMsg || t('common.unknown_error') : t('common.request_failed'));
469
590
  } catch (error) {
@@ -430,6 +430,8 @@ const COMMAND_SIDE_EFFECTS = new Map([
430
430
 
431
431
  ...sideEffectEntries([
432
432
  'add-validation',
433
+ 'app-offline',
434
+ 'app-online',
433
435
  'append-chart',
434
436
  'cdn-refresh',
435
437
  'cdn-upload',
@@ -596,7 +598,7 @@ const COMMAND_SIDE_EFFECTS = new Map([
596
598
  mutates_yida: true,
597
599
  mutates_local: false,
598
600
  read_actions: ['list'],
599
- mutating_actions: ['create', 'rename', 'delete', 'move', 'order', 'hide', 'show'],
601
+ mutating_actions: ['create', 'rename', 'delete', 'move', 'order', 'auto-order', 'hide', 'show'],
600
602
  })],
601
603
  ['org', sideEffect('mixed', {
602
604
  mutates_yida: false,
@@ -667,6 +669,7 @@ const COMMAND_PERMISSIONS = new Map([
667
669
 
668
670
  ...permissionEntries([
669
671
  'add-validation',
672
+ 'app-online',
670
673
  'append-chart',
671
674
  'build-page',
672
675
  'cdn-config',
@@ -727,10 +730,11 @@ const COMMAND_PERMISSIONS = new Map([
727
730
  })),
728
731
 
729
732
  ...permissionEntries([
733
+ 'app-offline',
730
734
  'connector.delete',
731
735
  'connector.delete-action',
732
736
  ], permission('ask', 'destructive', {
733
- reason: 'Deletes or removes existing configuration.',
737
+ reason: 'Deletes, removes, or disables existing remote state.',
734
738
  })),
735
739
 
736
740
  ...permissionEntries([
@@ -884,7 +888,7 @@ const COMMAND_PERMISSIONS = new Map([
884
888
  ...permissionEntries([
885
889
  'nav-group',
886
890
  ], actionDependentPermission({
887
- preauthorized_actions: ['create', 'rename', 'move', 'order', 'hide', 'show'],
891
+ preauthorized_actions: ['create', 'rename', 'move', 'order', 'auto-order', 'hide', 'show'],
888
892
  ask_actions: ['delete'],
889
893
  })),
890
894
 
@@ -1032,6 +1036,8 @@ const COMMAND_GROUPS = [
1032
1036
  }),
1033
1037
  command('create-app', ['create-app'], 'create-app "<name>"|--name <name> [options] [--locale zh_CN|en_US|ja_JP] [--open|--no-open]', 'help.cmd_create_app'),
1034
1038
  command('update-app', ['update-app'], 'update-app <appType> [--name "..."] [--layout slide|ver] [--theme deepBlue]', 'help.cmd_update_app'),
1039
+ command('app-online', ['app-online'], 'app-online <appType> [--to-ding-app-center] [--show-app-center]', 'help.cmd_app_online'),
1040
+ command('app-offline', ['app-offline'], 'app-offline <appType> [--to-ding-app-center] [--show-app-center]', 'help.cmd_app_offline'),
1035
1041
  command('nav-group', ['nav-group'], 'nav-group <list|create|rename|delete|move|order|auto-order|hide|show> <appType> ...', 'help.cmd_nav_group', {
1036
1042
  output: 'json',
1037
1043
  aliases: ['group'],
@@ -23,6 +23,8 @@ module.exports = {
23
23
  cmd_corp_efficiency: 'Query enterprise efficiency overview and detail reports',
24
24
  cmd_create_app: 'Create a Yida app',
25
25
  cmd_update_app: 'Update app info',
26
+ cmd_app_online: 'Enable a Yida app',
27
+ cmd_app_offline: 'Disable a Yida app',
26
28
  cmd_nav_group: 'Manage app sidebar navigation groups',
27
29
  cmd_app_permission: 'Manage app primary, data, and developer admins',
28
30
  cmd_i18n: 'Manage app multilingual copy and language config',
@@ -960,6 +962,19 @@ Examples:
960
962
  layout_notice: 'Note: layoutDirection is consumed by the Yida app shell during creation/refresh. If the top action bar does not recover immediately after a backend switch, reopen the workbench or recreate the app with the target layout.',
961
963
  },
962
964
 
965
+ app_lifecycle: {
966
+ online_usage: 'Usage: openyida app-online <appType> [--to-ding-app-center] [--show-app-center]',
967
+ online_example: 'Example: openyida app-online APP_XXX',
968
+ offline_usage: 'Usage: openyida app-offline <appType> [--to-ding-app-center] [--show-app-center]',
969
+ offline_example: 'Example: openyida app-offline APP_XXX',
970
+ missing_app_type: 'Error: missing appType argument',
971
+ invalid_argument: 'Unsupported argument: {0}',
972
+ invalid_action: 'Unsupported app lifecycle action: {0}',
973
+ request_failed: 'App lifecycle operation failed',
974
+ online_success: 'App enabled',
975
+ offline_success: 'App disabled',
976
+ },
977
+
963
978
  // ── lib/update-form-config.js ──────────────────────
964
979
  update_form_config: {
965
980
  usage: 'Usage: openyida update-form-config <appType> <formUuid> <isRenderNav> <title>',
@@ -23,6 +23,8 @@ module.exports = {
23
23
  cmd_corp_efficiency: '查询企业效能概览和明细报表',
24
24
  cmd_create_app: '创建宜搭应用',
25
25
  cmd_update_app: '更新应用信息',
26
+ cmd_app_online: '启用宜搭应用',
27
+ cmd_app_offline: '停用宜搭应用',
26
28
  cmd_nav_group: '管理应用左侧导航分组',
27
29
  cmd_app_permission: '管理应用主管理员、数据管理员和开发成员',
28
30
  cmd_i18n: '管理应用多语言文案和语言配置',
@@ -889,6 +891,19 @@ openyida - 宜搭命令行工具
889
891
  layout_notice: '提示:layoutDirection 由宜搭应用外壳在创建/刷新时消费;若后台切换后顶部操作栏未立即恢复,请重新打开工作台或使用目标 layout 重新创建应用。',
890
892
  },
891
893
 
894
+ app_lifecycle: {
895
+ online_usage: '用法: openyida app-online <appType> [--to-ding-app-center] [--show-app-center]',
896
+ online_example: '示例: openyida app-online APP_XXX',
897
+ offline_usage: '用法: openyida app-offline <appType> [--to-ding-app-center] [--show-app-center]',
898
+ offline_example: '示例: openyida app-offline APP_XXX',
899
+ missing_app_type: '错误: 缺少 appType 参数',
900
+ invalid_argument: '不支持的参数: {0}',
901
+ invalid_action: '不支持的应用生命周期操作: {0}',
902
+ request_failed: '应用生命周期操作失败',
903
+ online_success: '应用已启用',
904
+ offline_success: '应用已停用',
905
+ },
906
+
892
907
  // ── lib/process/create-process.js ─────────────────
893
908
  create_process: {
894
909
  title: '宜搭流程表单一体化创建',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openyida",
3
- "version": "2026.8.5",
3
+ "version": "2026.8.12",
4
4
  "description": "OpenYida CLI - 宜搭低代码 AI 开发工具(安装即用,零配置)",
5
5
  "bin": {
6
6
  "openyida": "bin/yida.js",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: openyida
3
3
  description: >
4
- 宜搭应用开发总入口技能。通过具备代码生成能力的智能体(悟空/Claude/Open Code 等)+ 宜搭低代码平台,实现一句话搭建或修改完整应用。
4
+ 宜搭应用开发总入口技能。通过具备代码生成能力的智能体(千问办公/Claude/Open Code 等)+ 宜搭低代码平台,实现一句话搭建或修改完整应用。
5
5
  包含资源上下文解析、应用创建/复用、表单设计/更新、自定义页面开发、页面发布、登录态管理等完整开发流程。
6
6
  当用户提到“宜搭”、“yida”、“低代码”、“创建应用”、“创建表单”、“发布页面”、“搭建”、“系统”等关键词时,使用此技能;以下情况不要触发:只是讨论通用前端/后端代码、非宜搭平台产品、或只需要解释概念而不操作宜搭资源。
7
7
  重要路由规则:当用户首次创建完整应用/系统/平台时,如帮我搭建一个管理应用或者创建一个管理系统等,必须先加载 yida-app 子技能作为唯一编排入口,禁止直接调用 create-app/create-form/create-page 等子命令手动拼接。已有 app 且已有自定义页面的补齐或修改按常规路由即可。
@@ -9,7 +9,7 @@ description: >
9
9
 
10
10
  # 宜搭应用开发指南
11
11
 
12
- 通过具备代码生成能力的智能体(悟空/Claude/Open Code 等)+ 宜搭低代码平台,实现一句话搭建或修改完整应用。所有操作通过 **`openyida`** CLI 统一执行。登录态分流必须以 `openyida agent-capabilities --summary-json` 或 `openyida login --check-only --json` 返回的 OpenYida auth snapshot 为准;只有 snapshot 明确返回 `login.auth_source=env` 或 `failure_reason=env_token_missing` 时,才按运行环境注入 token 模式处理。其他未登录 token 场景走默认 OAuth token 登录,不要根据 agent 名称、运行环境类型或手写环境判断自行分流;禁止读取 `.cache/cookies*.json`。
12
+ 通过具备代码生成能力的智能体(千问办公/Claude/Open Code 等)+ 宜搭低代码平台,实现一句话搭建或修改完整应用。所有操作通过 **`openyida`** CLI 统一执行。登录态分流必须以 `openyida agent-capabilities --summary-json` 或 `openyida login --check-only --json` 返回的 OpenYida auth snapshot 为准;只有 snapshot 明确返回 `login.auth_source=env` 或 `failure_reason=env_token_missing` 时,才按运行环境注入 token 模式处理。其他未登录 token 场景走默认 OAuth token 登录,不要根据 agent 名称、运行环境类型或手写环境判断自行分流;禁止读取 `.cache/cookies*.json`。
13
13
 
14
14
  ---
15
15
 
@@ -165,7 +165,7 @@ OpenYida builder 默认使用 `create-app / create-form / create-page / publish`
165
165
  | 大类目录 | 第一层意图信号 | 子技能 |
166
166
  |------|------|------|
167
167
  | `yida-skills/context` | 登录、退出、切换组织、组织版本/容量、Schema、fieldId、只读预检 | `yida-login`、`yida-logout`、`yida-basic-info`、`yida-get-schema`、`yida-corp-efficiency` |
168
- | `yida-skills/app` | 从零搭应用、完整系统、应用导航、多语言 | `yida-app`、`yida-create-app`、`yida-nav-group`、`yida-i18n` |
168
+ | `yida-skills/app` | 从零搭应用、完整系统、应用启停、应用导航、多语言 | `yida-app`、`yida-create-app`、`yida-app-lifecycle`、`yida-nav-group`、`yida-i18n` |
169
169
  | `yida-skills/design` | 完整应用产品设计、单页 UI 改造、主页面视觉设计、应用主题色、全局换肤、PRD 和 design.md | `yida-design` |
170
170
  | `yida-skills/form` | 表单字段、公式、校验、业务关联规则、详情页、批量录入、数据记录 | `yida-create-form-page`、`yida-formula`、`yida-formula-evaluate`、`yida-business-rule`、`yida-form-detail`、`yida-canvas-table-form`、`yida-table-form`、`yida-data-management` |
171
171
  | `yida-skills/process` | 审批、流程表单、流程规则、节点/分支/字段权限、流程代理 | `yida-create-process`、`yida-process-rule`、`yida-agent-center` |
@@ -186,6 +186,7 @@ OpenYida builder 默认使用 `create-app / create-form / create-page / publish`
186
186
  | 用户给 taskUuid 并要求转 PRD | 先用 `yida-tingji` 读取听记内容,再把已有内容交给 `yida-flash-note-to-prd` 生成 PRD |
187
187
  | 已有会议纪要/闪记内容转 PRD | `yida-flash-note-to-prd`,只处理已有内容,不负责按 taskUuid 拉取听记 |
188
188
  | 只创建应用壳并拿 appType | `yida-create-app`;创建成功后把真实 `appType` 交给 `yida-design` 生成或更新 `prd/<项目名>/prd.md` 和 `prd/<项目名>/design.md`,后续表单、流程、页面和发布都消费这两份文件 |
189
+ | 启用/上线或停用/下线已有应用 | `yida-app-lifecycle`;只有用户明确要求时执行,`app-offline` 执行前需再次确认目标应用 |
189
190
  | 创建自定义展示页资源 | `yida-create-page`,之后默认接 `yida-canvas-custom-page` 和 `yida-publish-page` |
190
191
  | 开发表单字段结构 / 增删改字段 | 先加载 `yida-form-detail` 做表单视觉引导并合并 Divider 分割线,再用 `yida-create-form-page` 落地字段结构 |
191
192
  | 创建带审批的流程表单 | `yida-create-process` |
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: yida-app-lifecycle
3
+ description: 宜搭应用启用与停用。仅当用户明确要求启用、停用、上线或下线某个已有应用时使用;不用于创建应用、发布页面或发布到钉钉应用中心。
4
+ ---
5
+
6
+ # 宜搭应用启用与停用
7
+
8
+ ## 严格要求 (MUST DO)
9
+
10
+ - 只有用户明确说“启用应用 / 上线应用 / 停用应用 / 下线应用”时,才允许调用本技能的远程写命令;不得从“发布页面”“更新应用”“应用不可用”等间接描述推断执行。
11
+ - 执行前必须确认唯一的 `appType` 和当前登录组织;目标不明确时先询问用户。
12
+ - `app-offline` 会让现有应用停止服务,执行前必须向用户展示目标 `appType` 与完整命令并获得确认。
13
+ - 默认保持 `isToDingAppCenter=n`、`showAppCenter=n`。只有用户明确要求同步钉钉应用中心或显示应用中心时,才添加对应开关。
14
+ - 命令失败后完整展示错误并停止;不得无修改连续重试,也不得改用浏览器抓包中的 Cookie、token 或 `sec-*` header 绕过认证。
15
+
16
+ ## 严格禁止 (NEVER DO)
17
+
18
+ - 不得把首次创建应用、表单/页面发布、应用信息更新自动升级为应用启用。
19
+ - 不得把“暂时隐藏页面”“禁用集成自动化”“关闭公开访问”路由为应用停用。
20
+ - 不得在测试、评测或默认 shared real E2E 中执行真实启用/停用。
21
+ - 不得把本能力扩展为钉钉应用中心完整发布流程。
22
+
23
+ ## 意图与命令
24
+
25
+ 启用或上线已有应用:
26
+
27
+ ```bash
28
+ openyida app-online <appType>
29
+ ```
30
+
31
+ 停用或下线已有应用(需确认):
32
+
33
+ ```bash
34
+ openyida app-offline <appType>
35
+ ```
36
+
37
+ 仅在用户明确要求应用中心相关行为时使用:
38
+
39
+ ```bash
40
+ openyida app-online <appType> --to-ding-app-center --show-app-center
41
+ openyida app-offline <appType> --to-ding-app-center --show-app-center
42
+ ```
43
+
44
+ ## 完成条件
45
+
46
+ - CLI 返回 `success: true`,且返回的 `action` 与用户意图一致。
47
+ - 向用户说明目标 `appType` 已启用或已停用;失败时不得宣称状态已改变。
48
+
49
+ ## 异常处理
50
+
51
+ | 异常场景 | 处理方式 |
52
+ |---------|----------|
53
+ | 缺少或存在多个 appType 候选 | 停止并要求用户确认唯一目标 |
54
+ | 登录态失效 / 组织不符 | 重新登录或切换到目标组织后再执行 |
55
+ | 权限不足 | 停止并提示使用具备应用管理权限的账号 |
56
+ | 平台返回 `success: false` 或 `content: false` | 展示 `errorMsg` / `errorCode`,不得重试或宣称成功 |
@@ -1,7 +1,7 @@
1
1
  # 素材工作流:官网 / 品牌页的真实图片如何落地
2
2
 
3
3
  > 官网、品牌首页、活动落地页需要**大 Hero 图和真实产品/场景图**才好看。但绝不能编造图片 URL。
4
- > 本文档告诉本地智能体(Claude / 悟空等):**怎么拿到真实图片、怎么校验、怎么回填进页面**,以及拿不到时怎么诚实标注草稿。
4
+ > 本文档告诉本地智能体(Claude / 千问办公等):**怎么拿到真实图片、怎么校验、怎么回填进页面**,以及拿不到时怎么诚实标注草稿。
5
5
 
6
6
  ---
7
7
 
@@ -1,8 +1,8 @@
1
1
  # 生成 design.md 规则
2
2
 
3
- 本文件用于在 Step 5 为完整应用生成一份应用级 `prd/<项目名>/design.md`。生成流程必须先从业务上下文推演用户任务、信息拓扑和必需视觉 DNA,再选择唯一一个内置 `style-designs/*.md` 作为基础视觉母体,最后按主题色适配模板并输出自包含的 `design.md`。
3
+ 本文件用于在 Step 5 为完整应用生成一份应用级 `prd/<项目名>/design.md`。生成流程必须先从业务上下文判断内容兼容性,再推演视觉策略,选择唯一一个内置 `style-designs/*.md` 作为基础视觉母体,最后按主题色适配模板并输出自包含的 `design.md`。
4
4
 
5
- 业务对象、字段、表单、流程、导航、权限和页面结构都从当前 PRD 读取;模板只提供视觉 DNA、布局机制、组件机制、质量锚点和主题换肤规则,不提供业务内容。
5
+ 业务对象、字段、表单、流程、导航、权限和页面结构都从当前 PRD 读取;模板只提供视觉 DNA、布局机制、组件机制、质量锚点和主题换肤规则,不提供业务内容。指标卡、图表、表格、待办、筛选器、右侧栏、状态标签、快捷入口、时间线等常见内容组件只能判断模板是否可承载,不得作为风格模板的强匹配理由。
6
6
  `style-designs/_design-md-template.md` 是最终结构模板,只约束章节结构、字段完整度和描述粒度;内置 style-design 模板只提供可复用视觉母体。真实项目的配色、业务内容、资源关系、页面结构和实现交接必须从当前 PRD、应用主题和用户要求生成。
7
7
 
8
8
  ## 何时使用
@@ -23,7 +23,10 @@
23
23
  | --- | --- |
24
24
  | 用户任务 | 判断状态、处理待办、追踪阶段、分析趋势、管理明细、展示成果、汇报经营 |
25
25
  | 业务对象 | 订单、客户、库存、项目、任务、审批、线索、合同、员工、门店 |
26
- | 信息拓扑 | 摘要优先、图表优先、表格优先、时间轴优先、右侧上下文优先、深色焦点区优先 |
26
+ | 内容兼容性 | 当前页面是否需要指标、图表、表格、待办、筛选、右侧栏、时间线、卡片目录、媒体卡片 |
27
+ | 布局兼容性 | 均衡工作台、重点舞台、右栏工作区、指挥台、趋势看板、进度叙事、目录网格 |
28
+ | 视觉策略 | 柔和办公、深色重点舞台、蓝色洞察、规整边框、清爽右栏、高能指挥、进度叙事、目录浏览 |
29
+ | 视觉强调 | 所有模块均衡、核心指标强强调、行动队列强强调、趋势图强强调、右侧洞察强强调、目录筛选强强调 |
27
30
  | 交互重心 | 搜索筛选、待办处理、下钻详情、多入口跳转、趋势比较、异常处置 |
28
31
  | 数据形态 | KPI、队列、趋势、排行、明细表、日程、快捷入口、预警、阶段节点 |
29
32
  | 页面区块 | 顶部概览、搜索筛选、表格、图表、右侧详情、表单入口、空态 |
@@ -34,32 +37,48 @@
34
37
 
35
38
  1. 读取 [style-designs/registry.md](style-designs/registry.md),了解可选模板和选择规则。
36
39
  2. 读取 [style-designs/_design-md-template.md](style-designs/_design-md-template.md),用它作为最终 `design.md` 的结构基准。
37
- 3. 从业务上下文推演 `inferredUserTask`、`inferredInformationTopology` 和 `interactionFocus`。用户通常不会主动描述视觉结构,agent 必须自行推演。
38
- 4. 基于业务对象和信息拓扑推演 `requiredVisualDNA`,例如多指标摘要命中指标拼图、阶段节点命中时间轴、待办提醒命中右侧明细流、结构化记录命中圆角明细表。
39
- 5. 对 registry 中的模板做硬过滤:纯表单、长文、品牌营销、移动端单任务、未要求暗色时,不选择明显不合适的分析工作台模板或深色模板。
40
- 6. `业务任务匹配 30% + 信息拓扑匹配 25% + 视觉 DNA 命中 30% + 实现稳定性 10% - 风险扣分 5%` 选择唯一模板。
41
- 7. 读取被选中的 `style-designs/*.md`,抽取 `visual_dna`、`theme_adaptation`、`layout_stability`、`quality_anchors`、`components` `modules`。
42
- 8. 根据 Step 2 的主题色来源和主题色输入,按模板 `theme_adaptation` 执行换肤:替换 `replace_tokens`,派生 `derive_tokens`,保留 `preserve_tokens` `visual_dna.invariant`。
43
- 9. 读取 [visual-scaffold-recipes.md](visual-scaffold-recipes.md),把当前页面组合映射到统一 `visualScaffold` 规则。
44
- 10. 读取 [page-quality-gates.md](page-quality-gates.md),把质量门禁补进 `acceptanceChecks`。
45
- 11. 需要判断详略时参考 `_design-md-template.md` 的字段粒度、registry 的输出记录和所选模板的质量锚点;只学习“写到多细”,不复制示例业务、色盘、字段、页面顺序或组件组合。
46
- 12. 根据行业、品牌、业务情绪、应用主题和用户偏好生成配色。不要固定使用蓝色、绿色、紫色或任何预置色,也不要复用历史样例色盘。
47
- 13. 写入 `densityRule`、`breathingRule`、`spacing` 和 `rounded` 的具体数值。默认业务工具页使用 high density + 圆润形状 + 有呼吸感的分组节奏:页面边距 20-28px,卡片与卡片 gap 12-18px 且必须小于 20px,卡片 padding 默认 22-28px 且必须大于 20px,卡片圆角范围 0-32px;只有品牌展示、官网或用户明确要求舒展时才降低密度。
48
- 14. 写入 `surfaceContrast`:页面背景与卡片背景必须形成明显层次对比,不可相近或相同;默认浅色背景保持清爽,但必须按“白色/浅色背景 + 有边框卡片、浅灰背景(如 `#F3F4F6`)+ 白色无边框卡片、浅彩色背景 + 白色无边框卡片、渐变背景 + 玻璃感卡片”四类方案选择。
49
- 15. 写入 `emptyStateRecipe` 和 `acceptanceChecks`:空态必须是薄行、面板内提示或右侧上下文,不使用 160px 以上大白卡;状态摘要不能是横跨整页且内容稀疏的空矩形。
50
- 16. 如果平台导航可见,页面主按钮、链接、选中态、重点标签和图表主序列默认跟随应用主题;自定义色盘只能作为辅助色、浅背景、图表第二序列或页面级独立主题。
51
-
52
- ## 视觉 DNA 推演规则
53
-
54
- | 业务信号 | 推荐 DNA |
40
+ 3. 从业务上下文推演 `inferredUserTask`、`contentCompatibility`、`layoutCompatibility`、`visualStyleIntent`、`visualEmphasis` 和 `interactionFocus`。用户通常不会主动描述视觉风格,agent 必须自行推演。
41
+ 4. 先用内容组件做兼容性筛选:模板必须能承载当前页面已有内容,但不得因为“有指标卡 / 有图表 / 有表格 / 有右侧栏 / 有时间线”等公共组件直接胜出。
42
+ 5. 再用视觉策略选择模板:判断页面需要柔和均衡、重点舞台、趋势洞察、行动指挥、常驻右栏、规整边框、进度叙事、目录浏览还是视觉陈列。
43
+ 6. registry 中的模板做硬过滤:纯表单、长文、品牌营销、移动端单任务等页面不选择明显不合适的分析工作台模板。不要因用户未明确说“深色”而过滤 `dark-stage-analytic-dashboard`;它是浅色画布上的局部深色重点舞台,不等于全页面深色沉浸。
44
+ 7. `视觉策略 45% + 视觉强调与密度 15% + 布局兼容性 15% + 内容兼容性 15% + 多样性或用户偏好 10%` 选择唯一模板。内容和布局合计不得超过 30%,避免常见工作台内容把结果塌缩到通用模板。
45
+ 8. 做内部近邻比较:生成 `design.md` 前必须在工作记忆中比较最相近的 2-4 个模板;选择 `soft-analytic-workbench` 时必须确认其他更强视觉策略证据不足。近邻比较是选择校验,不默认写入最终 `design.md`。
46
+ 9. 读取被选中的 `style-designs/*.md`,抽取 `visual_dna`、`theme_adaptation`、`layout_stability`、`quality_anchors`、`components` 和 `modules`。
47
+ 10. 根据 Step 2 的主题色来源和主题色输入,按模板 `theme_adaptation` 执行换肤:替换 `replace_tokens`,派生 `derive_tokens`,保留 `preserve_tokens` 和 `visual_dna.invariant`。
48
+ 11. 读取 [visual-scaffold-recipes.md](visual-scaffold-recipes.md),把当前页面组合映射到统一 `visualScaffold` 规则。
49
+ 12. 读取 [page-quality-gates.md](page-quality-gates.md),把质量门禁补进 `acceptanceChecks`。
50
+ 13. 需要判断详略时参考 `_design-md-template.md` 的字段粒度、registry 的输出记录和所选模板的质量锚点;只学习“写到多细”,不复制示例业务、色盘、字段、页面顺序或组件组合。
51
+ 14. 根据行业、品牌、业务情绪、应用主题和用户偏好生成配色。不要固定使用蓝色、绿色、紫色或任何预置色,也不要复用历史样例色盘。
52
+ 15. 写入 `densityRule`、`breathingRule`、`spacing` 和 `rounded` 的具体数值。默认业务工具页使用 high density + 圆润形状 + 有呼吸感的分组节奏:页面边距 20-28px,卡片与卡片 gap 12-18px 且必须小于 20px,卡片 padding 默认 22-28px 且必须大于 20px,卡片圆角范围 0-32px;只有品牌展示、官网或用户明确要求舒展时才降低密度。
53
+ 16. 写入 `surfaceContrast`:页面背景与卡片背景必须形成明显层次对比,不可相近或相同;默认浅色背景保持清爽,但必须按“白色/浅色背景 + 有边框卡片、浅灰背景(如 `#F3F4F6`)+ 白色无边框卡片、浅彩色背景 + 白色无边框卡片、渐变背景 + 玻璃感卡片”四类方案选择。
54
+ 17. 写入 `emptyStateRecipe` 和 `acceptanceChecks`:空态必须是薄行、面板内提示或右侧上下文,不使用 160px 以上大白卡;状态摘要不能是横跨整页且内容稀疏的空矩形。
55
+ 18. 如果平台导航可见,页面主按钮、链接、选中态、重点标签和图表主序列默认跟随应用主题;自定义色盘只能作为辅助色、浅背景、图表第二序列或页面级独立主题。
56
+
57
+ ## 内容兼容与视觉策略
58
+
59
+ 公共内容组件只判断模板是否可承载,不决定最终风格。最终模板必须由视觉策略、视觉强调和近邻比较决定。
60
+
61
+ | 常见内容信号 | 只能用于判断 | 不得直接推出 |
62
+ | --- | --- | --- |
63
+ | 指标卡 / KPI | 是否需要状态摘要、核心舞台、趋势入口、行动队列入口 | `soft-analytic-workbench` |
64
+ | 图表 | 是否需要轻量分布、大趋势图、进度图、纹理化洞察 | dashboard 模板 |
65
+ | 表格 / 明细 | 是否需要主工作区、详情沉淀、搜索结果、记录日志 | analytic 模板 |
66
+ | 右侧栏 | 是辅助上下文、常驻洞察栏还是行动队列 | rail 模板 |
67
+ | 时间线 / 阶段 | 是核心叙事骨架还是普通进度提示 | timeline 模板 |
68
+ | 筛选器 / 标签 | 是主导航还是表格辅助条件 | catalog 模板 |
69
+
70
+ | 视觉策略 | 适用判断 |
55
71
  | --- | --- |
56
- | 3 个以上核心指标、需要快速比较状态 | 指标拼图、等高指标卡、深色摘要舞台 |
57
- | 趋势、周期、对比、分布或进度数据 | 轻网格图表、图表洞察面板、纹理化对比图 |
58
- | 待办、提醒、异常、审批、消息或事件流 | 右侧明细流、右侧洞察栏、侧向洞察摘要栈 |
59
- | 订单、客户、库存、任务、交易或结构化记录 | 圆角明细表、图标化行、工具化表格壳 |
60
- | 阶段、里程碑、日程、流程节点或周期追踪 | 时间轴节点、左侧指标栈、趋势面板 |
61
- | 管理层汇报、核心指标焦点、用户明确深色或高对比 | 深色指标舞台、玻璃态指标卡、数据纹理 |
62
- | 搜索、筛选、导出、时间范围或全局命令频繁出现 | 顶部轻量命令栏、标签筛选、紧凑工具栏 |
72
+ | `soft_neutral` | 低噪声、均衡、朴素办公感;没有强主舞台、强趋势、强指挥或强目录诉求 |
73
+ | `dark_accent_stage` | 浅色页面中需要一个局部深色重点舞台,突出核心判断、风险、目标或经营结果 |
74
+ | `blue_insight` | 需要更强分析感、趋势感、数据洞察感,主图表或趋势面板应成为记忆点 |
75
+ | `bordered_enterprise` | 需要规整、边界清晰、系统化的管理后台气质 |
76
+ | `teal_fresh_rail` | 需要清爽、服务感或常驻右侧洞察栏,右栏是页面稳定结构而非临时补充 |
77
+ | `action_command` | 需要今日行动、命令入口、推荐处理、任务队列或高能量指挥感 |
78
+ | `progress_narrative` | 需要阶段推进、周期节奏、服务进度或里程碑叙事 |
79
+ | `catalog_browse` | 需要以筛选、比较、挑选、卡片目录或视觉浏览作为主体验 |
80
+
81
+ 选择 `soft_neutral` / `soft-analytic-workbench` 时必须满足:其他视觉策略都没有更强证据。它是均衡办公风格,不是所有工作台的默认答案。
63
82
 
64
83
  ## 主题色应用规则
65
84
 
@@ -89,7 +108,7 @@ Step 5 生成 `design.md`,并让 PRD 的每个自定义展示页只引用它
89
108
  | 字段 | 写入位置 | 写法 |
90
109
  | --- | --- | --- |
91
110
  | baseDesignSource | design.md | `references/style-designs/<selected-template>.md`;所有模板不适用时才写 `generated-from-business-context` |
92
- | styleDesignSelection | design.md | 记录用户任务、信息拓扑、必需 DNA、选中模板、拒绝模板和置信度 |
111
+ | styleDesignSelection | design.md | 只记录模板来源、视觉策略、视觉强调、选中模板、实现约束和置信度;候选比较和拒绝理由默认不写入 |
93
112
  | themeAdaptationResult | design.md | 记录输入主题色、换肤策略、替换 token、保留 DNA 和保留机制 |
94
113
  | designFile | PRD pageSpecHandoff | `prd/<项目名>/design.md` |
95
114
  | designRefs | PRD pageSpecHandoff | 当前页面引用 design.md 的章节 ID |
@@ -1,6 +1,6 @@
1
1
  # style-design 内置模板注册表
2
2
 
3
- 本目录提供 `yida-design` Step 5 生成 `prd/<项目名>/design.md` 时可选择的内置视觉 DNA 模板。生成 `design.md` 时必须先基于业务任务、信息拓扑和视觉 DNA 选择唯一一个 `style-designs/*.md` 作为基础视觉母体,再结合主题色和当前 PRD 生成最终自包含的 `design.md`。
3
+ 本目录提供 `yida-design` Step 5 生成 `prd/<项目名>/design.md` 时可选择的内置视觉 DNA 模板。生成 `design.md` 时必须先判断内容兼容性,再根据视觉策略选择唯一一个 `style-designs/*.md` 作为基础视觉母体,最后结合主题色和当前 PRD 生成最终自包含的 `design.md`。
4
4
 
5
5
  `_design-md-template.md` 仍是结构模板;它不参与视觉风格选择。实现阶段只读取当前项目的 `prd.md` 和 `design.md`,不回读本目录。
6
6
 
@@ -14,23 +14,23 @@
14
14
 
15
15
  ## 可选 style-design 模板
16
16
 
17
- | 模板 | 适合任务 | 信息拓扑 | 关键视觉 DNA | 避免场景 |
17
+ | 模板 | 视觉策略 | 可承载内容 | 强选择触发 | 近邻边界 |
18
18
  | --- | --- | --- | --- | --- |
19
- | `soft-analytic-workbench.md` | 通用数据工作台、运营首页、管理后台首页、分析列表页 | 摘要 + 图表 + 右侧列表 + 明细表均衡承载 | `metric_mosaic_header`、`light_analytic_charts`、`side_detail_stream`、`rounded_table_detail` | 品牌叙事页、沉浸大屏、低信息展示页 |
20
- | `soft-bordered-analytic-workbench.md` | 运营控制台、需要搜索筛选和全局命令的工作台 | 顶部命令栏 + 深色摘要舞台 + 图表洞察 + 明细承载 | `command_toolbar`、`dark_summary_stage`、`chart_with_side_insights`、`split_detail_surface` | 营销落地页、长文页、强图片展示页 |
21
- | `soft-modular-analytic-workbench.md` | 模块多、指标多、趋势和明细并重的复杂工作台 | 模块化网格 + 大摘要 + 指标拼图 + 内嵌洞察 + 明细表 | `airy_page_shell`、`mixed_scale_summary_grid`、`contained_insight_panel`、`refined_detail_table` | 单一步骤表单、内容阅读页、低密展示页 |
22
- | `soft-progress-analytics-workbench.md` | 进度追踪、周期分析、任务概览、明细管理工作台 | 左侧优先级指标栈 + 右侧时序节点 + 趋势面板 + 明细表 | `left_priority_metric_stack`、`floating_milestone_timeline`、`crafted_trend_panel`、`rounded_utility_detail_table` | 无阶段/周期语义的普通后台、单一表单、图片优先页面 |
23
- | `soft-timeline-analytics-workbench.md` | 进度追踪、阶段管理、周期分析、里程碑工作台 | 左侧指标栈 + 时间轴节点 + 趋势面板 + 明细表 | `left_metric_stack`、`floating_timeline_panel`、`refined_trend_panel`、`rounded_detail_table` | 没有时间/阶段语义的普通后台、图片优先页面 |
24
- | `teal-rail-analytics-workbench.md` | 需要常驻右侧洞察栏的运营分析、排行提醒、状态追踪 | 左宽主工作区 + 右侧洞察栏 + 标签筛选 + 明细表 | `split_main_with_right_insight_rail`、`layered_chart_analytics_panel`、`tabbed_toolbar_detail_table` | 移动端单任务页、沉浸大屏、低信息展示页 |
25
- | `dark-stage-analytic-dashboard.md` | 管理层看板、核心指标展示、明确要求深色焦点或高对比 | 深色指标舞台 + 白底分析面板 + 数据纹理 + 宽松明细表 | `dark_metric_stage`、`glass_metric_cards`、`micro_texture_visualization`、`rounded_detail_table` | 纯表单、长文阅读、普通移动流程、用户未要求的暗色沉浸 |
26
- | `contrast-command-analytics-workbench.md` | 命令入口、日程协同、分析图表和明细记录并存的工作台 | 大标题 + 分段表现图 + 事件流 + 深色命令面板 + 媒体化明细表 | `oversized_identity_bar`、`segmented_performance_panel`、`dark_assistant_command_panel`、`refined_record_table` | 纯表单、单一表格、低信息展示页 |
27
- | `blue-productivity-insight-workbench.md` | 任务中心、周期分析、行动跟进、记录管理工作台 | 指标横排 + 大幅柱状图 + 右侧行动栏 + 工具化记录表 | `command_filter_header`、`bordered_metric_row`、`large_bar_analytics_panel`、`stacked_action_rail` | 图片优先页面、单一长表单、无行动队列页面 |
28
- | `aqua-service-progress-dashboard.md` | 服务门户、进度追踪、资源状态、媒体和上下文混合概览 | 宽松状态头 + 左侧时间轴 + 中心进度评分 + 渐变状态卡 + 媒体/上下文卡 | `airy_status_header`、`schedule_or_timeline_column`、`progress_score_panel`、`gradient_status_chart_card` | 密集表格后台、暗色大屏、高压交易页面 |
29
- | `blue-insight-operations-dashboard.md` | 运营概览、管理看板、团队状态、活动追踪页 | 火花线指标卡 + 主面积趋势图 + 右侧洞察卡 + 活动表 + 进度列表 | `sparkline_metric_cards`、`primary_area_trend_panel`、`pastel_insight_stack`、`activity_table_panel` | 图片展示页、纯表单、低信息门户 |
30
- | `green-timeline-progress-workbench.md` | 进度追踪、阶段管理、周期任务和明细记录工作台 | 左侧主摘要指标栈 + 右侧浮动时间轴 + 趋势图 + 全宽明细表 | `green_priority_summary_stack`、`floating_date_timeline`、`polished_line_trend_panel`、`full_width_detail_table` | 无时间/阶段语义页面、纯表单、图片优先页面 |
31
- | `filterable-card-catalog.md` | 筛选目录页、搜索结果页、资源选择页、卡片列表页 | 左侧筛选栏 + 顶部结果工具条 + 条件胶囊 + 等高卡片矩阵 | `left_filter_rail`、`result_toolbar_with_chips`、`uniform_media_card_grid`、`compact_value_and_meta`、`small_area_accent_actions` | 纯表单、长文阅读、深色大屏、复杂图表分析工作台 |
32
- | `soft-curated-filter-gallery.md` | 视觉型目录页、候选对象浏览页、分类筛选页、资源挑选页 | 大标题 + 胶囊分类切换 + 柔和筛选面板 + 大图卡片画廊 | `headline_tabs_toolbar`、`soft_filter_canvas`、`oversized_visual_cards`、`corner_badges_and_favorites`、`visual_range_histogram` | 高密表格后台、复杂图表看板、流程表单、长文阅读 |
33
- | `command-filter-card-console.md` | 资源管理目录、对象管理控制台、可搜索卡片库、状态筛选列表 | 边框筛选面板 + 状态标签工具条 + 紧凑管理卡片 + 底部分页 | `bordered_filter_drawer_panel`、`command_toolbar_status_tabs`、`compact_admin_card_grid`、`bottom_pagination_bar`、`swatch_and_range_filters` | 强视觉陈列、品牌展示页、长流程表单、沉浸媒体页 |
19
+ | `soft-analytic-workbench.md` | `soft_neutral` 均衡办公 | 指标、轻图表、右侧辅助列表、明细表、普通入口 | 用户明确需要低噪声、均衡、朴素办公感;所有模块视觉优先级接近 | 通用兜底,有泛化惩罚;若需要重点舞台、趋势洞察、行动队列、常驻右栏或规整边框,应输给对应模板 |
20
+ | `soft-bordered-analytic-workbench.md` | `bordered_enterprise` 规整控制台 | 命令栏、深色摘要区、图表洞察、分区明细 | 页面需要边界清晰、系统化、控制台感,搜索筛选和全局命令是稳定入口 | 若只是均衡办公输给 `soft-analytic`;若深色舞台是主记忆点输给 `dark-stage` |
21
+ | `soft-modular-analytic-workbench.md` | `bordered_enterprise` 模块化复杂工作台 | 多模块、多指标、趋势、洞察卡、明细表 | 页面模块很多,需要规整网格和混合尺度承载,不希望单一大舞台主导 | 若模块少且均衡输给 `soft-analytic`;若趋势图是主视觉输给 `blue-insight` |
22
+ | `soft-progress-analytics-workbench.md` | `progress_narrative` 进度分析 | 优先级指标、周期节点、趋势、明细表 | 阶段、周期、进度是核心体验,但整体仍偏分析工作台 | 若没有阶段推进语义输给非进度模板;若服务资源和媒体上下文更强输给 `aqua-service` |
23
+ | `soft-timeline-analytics-workbench.md` | `progress_narrative` 时间轴工作台 | 指标栈、时间轴、趋势、明细表 | 时间轴本身是页面骨架,用户需要按阶段/里程碑阅读 | 若时间轴只是辅助提示输给 `soft-progress` 或非进度模板 |
24
+ | `teal-rail-analytics-workbench.md` | `teal_fresh_rail` 常驻洞察右栏 | 左侧主工作区、右侧洞察栏、标签筛选、明细表 | 右侧洞察栏是持续结构,用于提醒、排名、状态、上下文,而非普通补充列表 | 若右栏只是辅助列表输给 `soft-analytic`;若行动队列更强输给 `blue-productivity` |
25
+ | `dark-stage-analytic-dashboard.md` | `dark_accent_stage` 局部深色重点舞台 | 指标、图表、表格、待办、右侧上下文 | 浅色页面中需要一个强记忆点,突出核心判断、风险、目标完成度或经营结果 | 不要求用户明确说深色;若只是全模块均衡扫描输给 `soft-analytic`,若命令处理更强输给 `contrast-command` |
26
+ | `contrast-command-analytics-workbench.md` | `action_command` 高对比指挥 | 大标题、表现图、事件流、深色命令面板、媒体化明细 | 页面需要指挥感、推荐处理、助手面板、日程协同或高能量主操作 | 若只是待办列表输给 `blue-productivity`;若只是核心指标舞台输给 `dark-stage` |
27
+ | `blue-productivity-insight-workbench.md` | `action_command` 生产力行动队列 | 指标、柱状图、右侧行动栏、记录表 | 指标之后立刻驱动今日处理、待办、跟进、确认、分派等动作 | 若主图表洞察更强输给 `blue-insight`;若右栏是洞察而非行动输给 `teal-rail` |
28
+ | `aqua-service-progress-dashboard.md` | `progress_narrative` 服务进度 | 状态头、时间轴、进度评分、渐变状态卡、媒体/上下文卡 | 服务、资源、场地、设备、交付进度或上下文媒体共同构成体验 | 若是密集后台或纯表格处理输给工作台模板;若只是阶段管理输给 timeline/progress 模板 |
29
+ | `blue-insight-operations-dashboard.md` | `blue_insight` 趋势洞察 | 火花线指标、主趋势图、洞察卡、活动表、进度列表 | 主要记忆点是趋势、分析、经营洞察,图表不只是轻量状态分布 | 若数据不足以支撑趋势图输给 `soft-analytic`;若行动队列更强输给 `blue-productivity` |
30
+ | `green-timeline-progress-workbench.md` | `progress_narrative` 清爽阶段推进 | 主摘要指标栈、浮动日期时间轴、趋势图、全宽表格 | 阶段推进明确,同时希望气质更清爽、轻运营、低压 | 若没有时间/阶段语义输给非进度模板;若需要更中性时间轴输给 `soft-timeline` |
31
+ | `filterable-card-catalog.md` | `catalog_browse` 高密筛选目录 | 左筛选栏、结果工具条、条件胶囊、等高卡片矩阵 | 主体验是搜索、筛选、比较、选择对象;卡片比表格更适合承载结果 | 若只是工作台里的辅助筛选输给 analytic 模板;若需要大图陈列输给 `soft-curated-filter-gallery` |
32
+ | `soft-curated-filter-gallery.md` | `catalog_browse` 视觉精选画廊 | 大标题、分类切换、柔和筛选、大图卡片、收藏/徽标 | 主体验是视觉浏览、候选挑选、精选展示,图片或视觉对象重要 | 若需要高密管理和批量操作输给 `command-filter-card-console` `filterable-card-catalog` |
33
+ | `command-filter-card-console.md` | `catalog_browse` 管理型卡片控制台 | 边框筛选、状态标签、紧凑管理卡片、分页 | 主体验是对象管理、状态筛选、批量查看,卡片是管理单元而非展示物 | 若偏视觉陈列输给 `soft-curated-filter-gallery`;若偏普通结果浏览输给 `filterable-card-catalog` |
34
34
 
35
35
  ## 消费硬规则
36
36
 
@@ -43,40 +43,65 @@
43
43
 
44
44
  ## 选择原则
45
45
 
46
- 1. 先从业务需求推演用户任务、业务对象、信息拓扑和交互重心,再匹配模板视觉 DNA;不要按行业或主题色直接选模板。
46
+ 1. 先从业务需求判断内容兼容性,再推演视觉策略、视觉强调、密度气质和交互重心;不要按行业、主题色或公共内容组件直接选模板。
47
47
  2. 主题色只作为所选模板的 `theme_adaptation` 输入,用于替换强调色 token;主题色不是选择模板的主要依据。
48
- 3. 用户一般不会主动描述视觉结构,agent 必须从 PRD 和 Step 1-4 产物中推演 `requiredVisualDNA`。
48
+ 3. 指标卡、图表、表格、待办、筛选器、右侧栏、状态标签、快捷入口、时间线等公共组件只用于判断 `contentCompatibility`,不得作为模板强匹配理由。
49
49
  4. 每次必须选择唯一一个 `style-designs/*.md` 作为 `baseDesignSource`。若所有模板都不适合,仍读取 `_design-md-template.md` 输出 `baseDesignSource=generated-from-business-context`,并在 `styleDesignSelection.rejectedStyleDesigns` 说明原因。
50
50
  5. 不得为了套模板凭空创造 PRD 未要求的图表、右侧栏、时间轴、深色舞台或快捷入口;模板只能决定已有业务内容的视觉承载方式。
51
- 6. 最终 `design.md` 必须自包含:包含模板来源、选择依据、主题换肤结果、视觉 DNA、token、组件、状态、响应式、可访问性和实现契约。
51
+ 6. `dark-stage-analytic-dashboard` 是局部深色重点舞台,不是全页面深色沉浸。不得仅以“用户未要求深色”为理由拒绝它;只能在页面不需要强视觉焦点时拒绝。
52
+ 7. `soft-analytic-workbench` 是 `soft_neutral` 均衡办公风格,不是所有工作台的默认答案。选择它时必须在内部选择草稿中确认其他更强视觉策略证据不足。
53
+ 8. 最终 `design.md` 必须自包含:包含模板来源、选择依据、主题换肤结果、视觉 DNA、token、组件、状态、响应式、可访问性和实现契约。
52
54
 
53
55
  ## 选择评分建议
54
56
 
55
57
  | 维度 | 权重 | 判断方法 |
56
58
  | --- | --- | --- |
57
- | 业务任务匹配 | 30% | 页面主要用于判断、处理、追踪、分析、展示还是汇报 |
58
- | 信息拓扑匹配 | 25% | 摘要、图表、明细表、时间轴、右侧上下文、深色焦点区哪个最关键 |
59
- | 视觉 DNA 命中 | 30% | 模板 `visual_dna` 是否能承载当前业务结构 |
60
- | 实现稳定性 | 10% | 是否能在 PC/移动端、平台导航和 Code Canvas 中稳定落地 |
61
- | 风险扣分 | -5% | 是否会强行制造不存在的模块、过度依赖图表、右侧栏、时间轴或深色舞台 |
59
+ | 视觉策略匹配 | 45% | 页面需要 `soft_neutral`、`dark_accent_stage`、`blue_insight`、`bordered_enterprise`、`teal_fresh_rail`、`action_command`、`progress_narrative` 还是 `catalog_browse` |
60
+ | 视觉强调与密度 | 15% | 首屏是均衡扫描、核心舞台、趋势洞察、行动队列、常驻右栏、阶段推进还是目录筛选;密度是高密、规整、舒展还是展示型 |
61
+ | 布局兼容性 | 15% | 当前页面是否能稳定承载该模板的舞台、右栏、命令栏、进度骨架、目录网格或趋势面板 |
62
+ | 内容兼容性 | 15% | 模板是否支持当前已有指标、图表、表格、待办、筛选、右栏、时间线、卡片和媒体内容 |
63
+ | 多样性或用户偏好 | 10% | 用户语气、品牌气质、应用主题和候选分差接近时,避免所有工作台都落到 `soft-analytic-workbench` |
64
+ | 风险扣分 | -5% | 是否会强行制造不存在的模块、过度依赖图表、右侧栏、时间轴、深色舞台或图片素材 |
65
+
66
+ 内容兼容性和布局兼容性合计不得超过 30%。如果多个模板都能承载相同内容,必须让视觉策略、视觉强调和近邻边界决定最终选择。
62
67
 
63
68
  ## 输出记录
64
69
 
65
- 最终 `design.md` 必须记录:
70
+ 生成 `design.md` 前必须先形成内部选择草稿,用来防止公共组件误导模板选择。内部选择草稿不写入最终 `design.md`,除非用户要求调试或评估选择过程。
71
+
72
+ ```yaml
73
+ selectionScratchpad:
74
+ topCandidates:
75
+ - name: <template-name>
76
+ evidence: <短句或枚举,不写长解释>
77
+ rejectedCloseNeighbors:
78
+ - name: <template-name>
79
+ evidence: <短句或枚举>
80
+ softAnalyticCheck:
81
+ strongerVisualStrategyExists: <true / false>
82
+ result: <select_soft_analytic / choose_stronger_strategy>
83
+ ```
84
+
85
+ 最终 `design.md` 只记录可交接给实现阶段的精简选择摘要:
66
86
 
67
87
  ```yaml
68
88
  baseDesignSource: references/style-designs/<selected-template>.md
69
89
  styleDesignSelection:
70
90
  inferredUserTask: <判断 / 处理 / 追踪 / 分析 / 展示 / 汇报>
71
- inferredInformationTopology: <摘要优先 + 趋势承接 + 明细落地>
91
+ contentCompatibility:
92
+ supports: [<metrics / charts / tables / todos / filters / side_panel / timeline / catalog_cards / media_cards>]
93
+ commonComponentsAreWeakSignals: true
94
+ layoutCompatibility: <balanced_workbench / stage_workbench / rail_workspace / command_console / insight_dashboard / progress_narrative / catalog_grid>
95
+ visualStyleIntent: <soft_neutral / dark_accent_stage / blue_insight / bordered_enterprise / teal_fresh_rail / action_command / progress_narrative / catalog_browse>
96
+ visualEmphasis: <均衡扫描 / 核心舞台 / 趋势洞察 / 行动队列 / 常驻右栏 / 阶段推进 / 目录筛选>
72
97
  requiredVisualDNA:
73
98
  - <dna-id>
74
99
  selectedStyleDesign:
75
100
  name: <template-name>
76
101
  source: references/style-designs/<template>.md
77
- reason: <为什么该模板最适合当前业务>
78
- rejectedStyleDesigns:
79
- - <template-name>: <为什么不选>
102
+ implementationConstraints:
103
+ - <必须保留的视觉约束,例如局部深色舞台 / 常驻右栏 / 行动队列 / 大趋势面板>
104
+ selectionNotes: <可选,一句话以内;默认省略>
80
105
  selectionConfidence: <high / medium / low>
81
106
  ```
82
107
 
@@ -86,6 +111,7 @@ styleDesignSelection:
86
111
 
87
112
  - front matter 中的 `template_type: visual_dna_preset`。
88
113
  - `selection.best_for`、`selection.user_intent`、`selection.visual_tone`、`selection.avoid_for`。
114
+ - registry 中必须为新模板补充 `视觉策略`、`可承载内容`、`强选择触发` 和 `近邻边界`,避免只写宽泛适用场景。
89
115
  - 2-5 个可稳定复用的 `visual_dna`,每个 DNA 要有 `id`、`hooks`、`invariant`、`variable`。
90
116
  - `theme_adaptation`,明确 `replace_tokens`、`derive_tokens`、`preserve_tokens` 和换肤规则。
91
117
  - `quality_anchors`、`layout_stability`、`components` 和 `modules`,让最终 `design.md` 能抽取为可实现规则。
@@ -102,6 +102,40 @@
102
102
  "应用权限"
103
103
  ]
104
104
  },
105
+ {
106
+ "name": "yida-app-lifecycle",
107
+ "path": "skills/yida-app-lifecycle/SKILL.md",
108
+ "display_name": "应用启用与停用",
109
+ "description": "宜搭应用启用与停用。仅当用户明确要求启用、停用、上线或下线某个已有应用时使用;不用于创建应用、发布页面或发布到钉钉应用中心。",
110
+ "category": "yida-skills/app",
111
+ "tags": [
112
+ "启用应用",
113
+ "停用应用",
114
+ "上线应用",
115
+ "下线应用"
116
+ ],
117
+ "aliases": [
118
+ "应用生命周期",
119
+ "应用上下线"
120
+ ],
121
+ "positive_signals": [
122
+ "启用应用",
123
+ "停用应用",
124
+ "上线应用",
125
+ "下线应用"
126
+ ],
127
+ "negative_signals": [
128
+ "发布页面",
129
+ "更新应用信息",
130
+ "禁用集成自动化",
131
+ "关闭公开访问"
132
+ ],
133
+ "command_ids": [
134
+ "app-online",
135
+ "app-offline"
136
+ ],
137
+ "done_when": "CLI 返回 success:true 且 action 与用户明确意图一致;app-offline 执行前已确认目标 appType,失败时不得宣称状态改变。"
138
+ },
105
139
  {
106
140
  "name": "yida-basic-info",
107
141
  "path": "skills/yida-basic-info/SKILL.md",
@@ -1160,6 +1194,10 @@
1160
1194
  "创建应用",
1161
1195
  "完整应用",
1162
1196
  "管理系统",
1197
+ "启用应用",
1198
+ "停用应用",
1199
+ "上线应用",
1200
+ "下线应用",
1163
1201
  "导航分组",
1164
1202
  "多语言"
1165
1203
  ]