openyida 2026.9.17 → 2026.9.18

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.
@@ -1795,6 +1795,7 @@ Options:
1795
1795
  configuring_process: 'Configuring and publishing process',
1796
1796
  configure_failed: 'Failed to configure process',
1797
1797
  retry_hint: 'Process configuration failed, but the form was created. Fix the process definition and retry with this command:',
1798
+ preserve_existing_form: 'The original form exists. Inspect its state and failure cause using the returned formUuid and preserve it. Do not remove --formUuid, recreate the form, or create a same-name replacement to recover. Never retry writes when noWriteRetry=true.',
1798
1799
  fields_not_found: 'Fields definition file not found',
1799
1800
  process_def_not_found: 'Process definition file not found',
1800
1801
  done: 'Process form creation completed',
@@ -1125,6 +1125,7 @@ openyida - 宜搭命令行工具
1125
1125
  configuring_process: '配置并发布流程',
1126
1126
  configure_failed: '流程配置失败',
1127
1127
  retry_hint: '流程配置失败,但表单已创建。请修复流程定义后,使用以下命令复用该表单重试:',
1128
+ preserve_existing_form: '原表单已存在。先只读核实该 formUuid 的状态和失败原因,保留原表;禁止移除 --formUuid、再次创建表单或另建同名表来恢复。noWriteRetry=true 时禁止写重试。',
1128
1129
  fields_not_found: '字段定义文件不存在',
1129
1130
  process_def_not_found: '流程定义文件不存在',
1130
1131
  done: '流程表单创建完成',
@@ -76,6 +76,28 @@ function parseArgs(args) {
76
76
  };
77
77
  }
78
78
 
79
+ function quoteCommandArgument(value, shell) {
80
+ const text = String(value);
81
+ const safePattern = shell === 'powershell'
82
+ ? /^[a-zA-Z0-9_./:\\-]+$/
83
+ : /^[a-zA-Z0-9_./:-]+$/;
84
+ if (safePattern.test(text)) {
85
+ return text;
86
+ }
87
+ if (shell === 'powershell') {
88
+ return "'" + text.replace(/'/g, "''") + "'";
89
+ }
90
+ return "'" + text.replace(/'/g, "'\"'\"'") + "'";
91
+ }
92
+
93
+ function buildRetryCommand({ appType, formUuid, processDefinitionFile, replace, platform = process.platform }) {
94
+ const shell = platform === 'win32' ? 'powershell' : 'posix';
95
+ return ['openyida', 'create-process', appType, '--formUuid', formUuid,
96
+ processDefinitionFile, ...(replace ? ['--replace'] : [])]
97
+ .map(value => quoteCommandArgument(value, shell))
98
+ .join(' ');
99
+ }
100
+
79
101
  // ── 主流程 ───────────────────────────────────────────
80
102
 
81
103
  async function run(args) {
@@ -100,9 +122,13 @@ async function run(args) {
100
122
  }, extra || {});
101
123
  }
102
124
 
103
- function buildRetryCommand() {
104
- return 'openyida create-process ' + appType + ' --formUuid ' + formUuid + ' '
105
- + path.basename(processDefinitionFile) + (replace ? ' --replace' : '');
125
+ function recoveryRetryCommand() {
126
+ return buildRetryCommand({
127
+ appType,
128
+ formUuid,
129
+ processDefinitionFile,
130
+ replace,
131
+ });
106
132
  }
107
133
 
108
134
  function isTerminalSafetyError(error) {
@@ -118,7 +144,16 @@ async function run(args) {
118
144
 
119
145
  function buildConfigureFailureDetails(configError) {
120
146
  const terminalSafetyError = isTerminalSafetyError(configError);
121
- const retryCommand = terminalSafetyError ? null : buildRetryCommand();
147
+ const retryCommand = terminalSafetyError ? null : recoveryRetryCommand();
148
+ const recovery = {
149
+ action: 'inspect_existing_form',
150
+ appType,
151
+ formUuid,
152
+ processDefinitionFile,
153
+ doNotCreateNewForm: true,
154
+ noWriteRetry: terminalSafetyError,
155
+ instruction: t('create_process.preserve_existing_form'),
156
+ };
122
157
  const failureContext = { processCode };
123
158
  if (retryCommand) {
124
159
  failureContext.retryCommand = retryCommand;
@@ -128,6 +163,7 @@ async function run(args) {
128
163
  cause: configError,
129
164
  nextStep: terminalSafetyError ? terminalSafetyNextStep() : undefined,
130
165
  });
166
+ outerDetails.recovery = recovery;
131
167
  const innerDetails = configError && configError.isCliError && configError.details && configError.details.stage
132
168
  ? configError.details
133
169
  : null;
@@ -303,7 +339,7 @@ async function run(args) {
303
339
  // 仅对已知、可安全重试的配置失败提供复用表单命令。
304
340
  warn('');
305
341
  warn(' 💡 ' + t('create_process.retry_hint'));
306
- warn(' ' + buildRetryCommand());
342
+ warn(' ' + recoveryRetryCommand());
307
343
  warn('');
308
344
  }
309
345
  const failureOutput = {
@@ -318,6 +354,8 @@ async function run(args) {
318
354
  completedStages: failureDetails.completedStages,
319
355
  nextStep: failureDetails.nextStep,
320
356
  configureProcess: failureDetails.configureProcess,
357
+ recovery: failureDetails.recovery,
358
+ noWriteRetry: terminalSafetyError,
321
359
  };
322
360
  if (!terminalSafetyError && failureDetails.context && failureDetails.context.retryCommand) {
323
361
  failureOutput.retryCommand = failureDetails.context.retryCommand;
@@ -361,4 +399,5 @@ async function run(args) {
361
399
  module.exports = {
362
400
  run,
363
401
  parseArgs,
402
+ buildRetryCommand,
364
403
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openyida",
3
- "version": "2026.9.17",
3
+ "version": "2026.9.18",
4
4
  "description": "OpenYida CLI - 宜搭低代码 AI 开发工具(安装即用,零配置)",
5
5
  "bin": {
6
6
  "openyida": "bin/yida.js",
@@ -35,6 +35,13 @@ description: 流程表单一体化创建(创建表单 → 转流程 → 配置
35
35
  - 创建或转换任何远程资源前,CLI 必须先完成字段和流程定义的纯本地编译;本地编译失败时远程写入数必须为 0
36
36
  - 复用普通表单时由 `configure-process` 统一执行表单模式只读 preflight、必要转换、发布与平台 view 回读,不要在外层先手动转换表单
37
37
 
38
+ ## 配置失败后的原表恢复
39
+
40
+ - `create-process` 返回 `success:false` 且包含 `formUuid` 时,该表单已经存在,失败的是后续配置;新建模式与复用模式均适用。保存返回的 `appType/formUuid`,禁止去掉 `--formUuid`、再次 `create-form` 或另建同名表作为恢复手段。
41
+ - 先按错误中的 `stage`、`nextStep` 和 `recovery` 检查原表状态及权限。修正明确原因后只能复用原 `formUuid`,使用返回的完整 `retryCommand`;不得自动补 `--replace` 绕过已绑定流程的保护。
42
+ - `noWriteRetry:true`、`NON_IDEMPOTENT_RESULT_UNKNOWN` 或 `PUBLISHED_UNVERIFIED` 表示远程结果未确认:只读核实原表/流程,不能执行写重试,也不能新建替代资源。
43
+ - 无法安全恢复时保留原表,并向用户报告原表链接、失败阶段和需处理的问题;不要宣称流程已完成。
44
+
38
45
  ## 适用场景
39
46
 
40
47
  用户需要"创建审批流程"、"新建流程表单"、"搭建审批系统",且 resource context 没有既有流程/表单目标时使用。