@stalfh233/omc-cli 0.4.102 → 0.5.1

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.
Files changed (225) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +359 -359
  3. package/coverage/m1-coverage-manifest-v1.json +1414 -1414
  4. package/dist/approval-flow.js +0 -0
  5. package/dist/approval-token.js +102 -0
  6. package/dist/args.js +0 -0
  7. package/dist/artifacts.js +0 -0
  8. package/dist/batch-call.js +0 -0
  9. package/dist/bench/call-face-eval.js +0 -0
  10. package/dist/bench/context-attribution.js +0 -0
  11. package/dist/bench/discovery-cost-eval.js +2 -0
  12. package/dist/bench/driver.js +0 -0
  13. package/dist/bench/evals.js +0 -0
  14. package/dist/bench/fake-http-server.js +65 -0
  15. package/dist/bench/instrument.js +0 -0
  16. package/dist/bench/intent-face-eval.js +40 -40
  17. package/dist/bench/run.js +0 -0
  18. package/dist/bench/scenario.js +0 -0
  19. package/dist/bench/types.js +0 -0
  20. package/dist/bi-wire.js +0 -0
  21. package/dist/bizservice-config.js +0 -0
  22. package/dist/call.js +0 -0
  23. package/dist/capability-absences.js +0 -0
  24. package/dist/capability-overview.js +0 -0
  25. package/dist/capability-shape.js +0 -0
  26. package/dist/cli-contract.js +38 -1
  27. package/dist/cli-output.js +8 -2
  28. package/dist/cli.js +147 -5
  29. package/dist/closest-match.js +0 -0
  30. package/dist/code-rules.js +0 -0
  31. package/dist/command-transport.js +0 -0
  32. package/dist/compound-writes.js +0 -0
  33. package/dist/compute.js +0 -0
  34. package/dist/config-store.js +0 -0
  35. package/dist/context.js +0 -0
  36. package/dist/contract-consistency.js +0 -0
  37. package/dist/contract-resources.js +0 -0
  38. package/dist/coverage-consistency.js +0 -0
  39. package/dist/coverage-registry.js +0 -0
  40. package/dist/coverage.js +0 -0
  41. package/dist/data-list-filter.js +0 -0
  42. package/dist/describe-cache.js +0 -0
  43. package/dist/discovery.js +0 -0
  44. package/dist/endpoints.js +0 -0
  45. package/dist/environment-policy.js +0 -0
  46. package/dist/execution-metadata.js +0 -0
  47. package/dist/fake/app.js +45 -0
  48. package/dist/fake/b2-registration.js +594 -0
  49. package/dist/fake/businessrule.js +242 -0
  50. package/dist/fake/datarule.js +72 -0
  51. package/dist/fake/dictionary.js +108 -0
  52. package/dist/fake/environment.js +30 -0
  53. package/dist/fake/field.js +167 -0
  54. package/dist/fake/form.js +101 -0
  55. package/dist/fake/index.js +121 -0
  56. package/dist/fake/list-view.js +289 -0
  57. package/dist/fake/model.js +136 -0
  58. package/dist/fake/online-js.js +18 -0
  59. package/dist/fake/report.js +253 -0
  60. package/dist/fake/routes.js +47 -0
  61. package/dist/fake/rule-lifecycle.js +37 -0
  62. package/dist/fake/runtime-data.js +367 -0
  63. package/dist/fake/state.js +67 -0
  64. package/dist/fake/workflow.js +364 -0
  65. package/dist/field-change.js +86 -2
  66. package/dist/field-families.js +59 -9
  67. package/dist/form-default.js +0 -0
  68. package/dist/form-layout.js +0 -0
  69. package/dist/form-support.js +0 -0
  70. package/dist/formula-lint.js +0 -0
  71. package/dist/goal-routes.js +16 -16
  72. package/dist/governed-execution.js +0 -0
  73. package/dist/graph.js +734 -0
  74. package/dist/human-summary.js +0 -0
  75. package/dist/identity.js +0 -0
  76. package/dist/intent/baseline.js +0 -0
  77. package/dist/intent/capabilities/bizservice.js +0 -0
  78. package/dist/intent/capabilities/businessrule.js +0 -0
  79. package/dist/intent/capabilities/datarule.js +0 -0
  80. package/dist/intent/capabilities/field.js +0 -0
  81. package/dist/intent/capabilities/form.js +0 -0
  82. package/dist/intent/capabilities/index.js +0 -0
  83. package/dist/intent/capabilities/listview.js +0 -0
  84. package/dist/intent/capabilities/model.js +0 -0
  85. package/dist/intent/capabilities/onlinejs.js +0 -0
  86. package/dist/intent/capabilities/report.js +0 -0
  87. package/dist/intent/capabilities/workflow.js +0 -0
  88. package/dist/intent/capability.js +0 -0
  89. package/dist/intent/cli.js +0 -0
  90. package/dist/intent/compare.js +0 -0
  91. package/dist/intent/compiler.js +0 -0
  92. package/dist/intent/dsl.js +0 -0
  93. package/dist/intent/plan-apply.js +0 -0
  94. package/dist/intent/plan-file.js +0 -0
  95. package/dist/intent/readback.js +0 -0
  96. package/dist/intent/schema.js +0 -0
  97. package/dist/intent/validation.js +0 -0
  98. package/dist/intent/yaml.js +0 -0
  99. package/dist/journal.js +0 -0
  100. package/dist/json-column.js +0 -0
  101. package/dist/lanes/app-contract.js +0 -0
  102. package/dist/lanes/app-coverage.js +0 -0
  103. package/dist/lanes/app.js +0 -0
  104. package/dist/lanes/apply-changes.js +0 -0
  105. package/dist/lanes/b2-registration-contract.js +0 -0
  106. package/dist/lanes/b2-registration-coverage.js +0 -0
  107. package/dist/lanes/b2-registration.js +0 -0
  108. package/dist/lanes/businessrule-contract.js +0 -0
  109. package/dist/lanes/businessrule-coverage.js +0 -0
  110. package/dist/lanes/businessrule.js +7 -1
  111. package/dist/lanes/contract-support.js +0 -0
  112. package/dist/lanes/coverage-declaration.js +0 -0
  113. package/dist/lanes/custom-page.js +0 -0
  114. package/dist/lanes/datarule-contract.js +0 -0
  115. package/dist/lanes/datarule-coverage.js +0 -0
  116. package/dist/lanes/datarule-protocol.js +0 -0
  117. package/dist/lanes/datarule.js +0 -0
  118. package/dist/lanes/dictionary-contract.js +0 -0
  119. package/dist/lanes/dictionary-coverage.js +0 -0
  120. package/dist/lanes/dictionary.js +0 -0
  121. package/dist/lanes/environment-contract.js +0 -0
  122. package/dist/lanes/environment-coverage.js +0 -0
  123. package/dist/lanes/environment.js +0 -0
  124. package/dist/lanes/field-contract.js +0 -0
  125. package/dist/lanes/field-coverage.js +0 -0
  126. package/dist/lanes/field.js +6 -1
  127. package/dist/lanes/folder-contract.js +0 -0
  128. package/dist/lanes/folder-coverage.js +0 -0
  129. package/dist/lanes/folder.js +0 -0
  130. package/dist/lanes/form-contract.js +0 -0
  131. package/dist/lanes/form-coverage.js +0 -0
  132. package/dist/lanes/form.js +0 -0
  133. package/dist/lanes/lane-ids.js +0 -0
  134. package/dist/lanes/list-view-contract.js +0 -0
  135. package/dist/lanes/list-view-coverage.js +0 -0
  136. package/dist/lanes/list-view-shapes.js +0 -0
  137. package/dist/lanes/list-view.js +0 -0
  138. package/dist/lanes/meta-contract.js +0 -0
  139. package/dist/lanes/meta.js +6 -0
  140. package/dist/lanes/model-contract.js +0 -0
  141. package/dist/lanes/model-coverage.js +0 -0
  142. package/dist/lanes/model.js +4 -2
  143. package/dist/lanes/online-js-contract.js +0 -0
  144. package/dist/lanes/online-js-coverage.js +0 -0
  145. package/dist/lanes/online-js.js +0 -0
  146. package/dist/lanes/org-tree.js +0 -0
  147. package/dist/lanes/organization.js +0 -0
  148. package/dist/lanes/report-contract.js +0 -0
  149. package/dist/lanes/report-coverage.js +0 -0
  150. package/dist/lanes/report.js +0 -0
  151. package/dist/lanes/rule-graph.js +0 -0
  152. package/dist/lanes/rule-lifecycle-contract.js +0 -0
  153. package/dist/lanes/rule-lifecycle-coverage.js +0 -0
  154. package/dist/lanes/rule-lifecycle.js +0 -0
  155. package/dist/lanes/runtime-data-contract.js +0 -0
  156. package/dist/lanes/runtime-data-coverage.js +0 -0
  157. package/dist/lanes/runtime-data.js +0 -0
  158. package/dist/lanes/workflow-contract.js +0 -0
  159. package/dist/lanes/workflow-coverage.js +0 -0
  160. package/dist/lanes/workflow.js +0 -0
  161. package/dist/model-purge.js +0 -0
  162. package/dist/model-scaffold.js +0 -0
  163. package/dist/omc-core-lazy.js +0 -0
  164. package/dist/online-js-layout.js +0 -0
  165. package/dist/online-js-source.js +28 -28
  166. package/dist/package-tool.js +0 -0
  167. package/dist/package.js +0 -0
  168. package/dist/path-projection.js +0 -0
  169. package/dist/plan.js +0 -0
  170. package/dist/read.js +0 -0
  171. package/dist/recipes/b2-registration.js +0 -0
  172. package/dist/recipes/businessrule.js +0 -0
  173. package/dist/recipes/datarule.js +0 -0
  174. package/dist/recipes/dictionary.js +0 -0
  175. package/dist/recipes/field.js +55 -1
  176. package/dist/recipes/form.js +0 -0
  177. package/dist/recipes/list-view.js +0 -0
  178. package/dist/recipes/model.js +0 -0
  179. package/dist/recipes/online-js.js +0 -0
  180. package/dist/recipes/runtime-data.js +0 -0
  181. package/dist/recipes/shared.js +0 -0
  182. package/dist/recipes/workflow.js +0 -0
  183. package/dist/redact.js +0 -0
  184. package/dist/refusal-guidance.js +0 -0
  185. package/dist/rollback-spec.js +0 -0
  186. package/dist/rollback.js +0 -0
  187. package/dist/rule-support.js +0 -0
  188. package/dist/rule-when.js +0 -0
  189. package/dist/runtime-support.js +0 -0
  190. package/dist/script.js +0 -0
  191. package/dist/server.js +92 -0
  192. package/dist/service-doctor.js +0 -0
  193. package/dist/session-manager.js +0 -0
  194. package/dist/session.js +12 -0
  195. package/dist/skills.js +12 -2
  196. package/dist/sqlite-warning-filter.js +0 -0
  197. package/dist/support.js +0 -0
  198. package/dist/token-cache.js +0 -0
  199. package/dist/tool-types.js +0 -0
  200. package/dist/tools.js +0 -0
  201. package/dist/usage-log.js +0 -0
  202. package/dist/wire.js +0 -0
  203. package/dist/workflow-support.js +0 -0
  204. package/dist/write-lease.js +0 -0
  205. package/dist/write-lock.js +0 -0
  206. package/dist/write.js +0 -0
  207. package/dist/zip.js +0 -0
  208. package/docs/images/omc-nixi/README.md +41 -41
  209. package/docs/omc-introduction.md +851 -851
  210. package/docs/tool-surface-map.md +42 -42
  211. package/package.json +7 -5
  212. package/skills/omc-acceptance-criteria.md +50 -50
  213. package/skills/omc-business-configuration.md +334 -334
  214. package/skills/omc-capabilities.md +214 -214
  215. package/skills/omc-capability-scouting.md +55 -55
  216. package/skills/omc-config-draft-review.md +175 -175
  217. package/skills/omc-five-piece-flow.md +35 -35
  218. package/skills/omc-glossary.md +86 -86
  219. package/skills/omc-refusals.md +127 -127
  220. package/skills/omc-requirement-analysis.md +161 -161
  221. package/skills/omc-requirement-vocabulary.md +61 -61
  222. package/skills/omc-start-here.md +106 -106
  223. package/skills/omc-tool-selection.md +119 -119
  224. package/skills/omc-write-hazards.md +200 -199
  225. package/dist/lanes/organization-coverage.js +0 -27
File without changes
package/dist/identity.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/dist/journal.js CHANGED
File without changes
File without changes
File without changes
File without changes
package/dist/lanes/app.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -4,6 +4,7 @@ import { capabilityArg, environmentArg } from "../args.js";
4
4
  import { governedRead } from "../read.js";
5
5
  import { writeTool } from "../write.js";
6
6
  import { decodeJsonColumn, JSON_COLUMN_NULL_COALESCE } from "../json-column.js";
7
+ import { flattenTreeRows, resolveApplicationCode } from "../support.js";
7
8
  import { executeRuleSaveWrite, ruleNodeGraphArg } from "../rule-support.js";
8
9
  import { defineTool, ToolInputError, ToolRefusalError } from "../tool-types.js";
9
10
  import { resolveRuleRowId } from "../identity.js";
@@ -135,8 +136,13 @@ export function registerBusinessRuleLane(tools) {
135
136
  // schema×ruleCode 组合(171 次 rule.get / 229KB)。没有引用检索面时,
136
137
  // 全库枚举是理性选择——所以给它一个。客户端聚合:模型清单 → 每模型
137
138
  // rule.list → 每规则 rule.get → 图内匹配,一次调用、只回命中行。
139
+ // Model enumeration mirrors `model.list`: the bare modelList endpoint
140
+ // returns EMPTY rows on a real platform (live 2026-10-29: a full scan
141
+ // "found" 0 models → false zero-hit), so walk the application tree.
138
142
  const scoped = args.schemaCodes === undefined
139
- ? wireRows((await wireCall(session, { path: ENDPOINTS.modelList })).data).map((row) => String(row.schemaCode ?? "")).filter((code) => code !== "")
143
+ ? flattenTreeRows(wireRows((await wireCall(session, { path: ENDPOINTS.applicationTree, query: { appCode: await resolveApplicationCode(session, undefined).catch(() => "") } })).data))
144
+ .filter((row) => row.type === "BizModel" && typeof row.code === "string" && row.code !== "")
145
+ .map((row) => String(row.code))
140
146
  : (Array.isArray(args.schemaCodes) ? args.schemaCodes : [args.schemaCodes]);
141
147
  const wanted = args.code;
142
148
  const matches = [];
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -412,7 +412,10 @@ export function registerFieldLane(tools) {
412
412
  // wire body (src/field-change.ts), so configure_model and intent share it.
413
413
  assertNoSelfSchemaAggregation(args, published);
414
414
  await assertNoChildSchemaAggregation(session, args.schemaCode, args.propertyType, args.options ?? {});
415
- const prepared = prepareFieldChange(args);
415
+ // 目标版本决定 optionsSet 形状:8.2 以下要补 optionStructure/treeSelect
416
+ // (cpdocs issue #8:缺键让设计器选项弹窗硬崩)。
417
+ const targetVersion = session.detectedVersion();
418
+ const prepared = prepareFieldChange({ ...args, ...(targetVersion ? { targetVersion } : {}) });
416
419
  let performed;
417
420
  try {
418
421
  performed = await wireCall(session, { path: ENDPOINTS.fieldCreate, method: "POST", body: fieldChangeWireBody(args, prepared) });
@@ -515,10 +518,12 @@ async function runFieldUpdate(session, args) {
515
518
  assertNoSelfSchemaAggregation({ schemaCode: args.schemaCode, propertyType: record.type ?? record.propertyType, options: args.options }, publishedRows);
516
519
  await assertNoChildSchemaAggregation(session, args.schemaCode, record.type ?? record.propertyType, args.options);
517
520
  }
521
+ const targetVersion = session.detectedVersion();
518
522
  const update = {
519
523
  schemaCode: args.schemaCode,
520
524
  code: args.code,
521
525
  base: record,
526
+ ...(targetVersion ? { targetVersion } : {}),
522
527
  ...(args.name !== undefined ? { name: args.name } : {}),
523
528
  ...(args.name_i18n !== undefined ? { name_i18n: args.name_i18n } : {}),
524
529
  ...(args.options !== undefined ? { options: args.options } : {}),
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -239,6 +239,12 @@ export function registerMetaLane(tools) {
239
239
  const session = await ctx.sessions.session(args.environment);
240
240
  const version = session.detectedVersion();
241
241
  steps.push({ step: "登录", ok: true, enterpriseId: session.enterpriseId(), administrator: session.administrator() });
242
+ // A deployment whose system/config carries an unusual/absent `client`
243
+ // blob still logs in (client_secret is optional). Report it as a WARN
244
+ // instead of letting it read as a failed self-check.
245
+ const loginNotes = session.loginNotes();
246
+ if (loginNotes.length > 0)
247
+ steps.push({ step: "OAuth 客户端配置", ok: null, notes: loginNotes });
242
248
  const familyOk = version ? version.startsWith(ctx.manifest.version_family + ".") : null;
243
249
  steps.push({
244
250
  step: "版本族",
File without changes
File without changes
@@ -1120,8 +1120,9 @@ export function registerModelLane(tools) {
1120
1120
  for (const row of wireRows((await wireCall(session, { path: ENDPOINTS.fieldList, query: { schemaCode: args.code, isPublish } })).data))
1121
1121
  existingFields.set(String(row.code ?? row.propertyCode ?? ""), row);
1122
1122
  }
1123
+ const configureTargetVersion = session.detectedVersion();
1123
1124
  for (const entry of entries) {
1124
- const input = fieldChangeInputOf(args.code, entry);
1125
+ const input = fieldChangeInputOf(args.code, entry, configureTargetVersion);
1125
1126
  failed = await run(results.length, "field.create", async () => {
1126
1127
  const existing = existingFields.get(entry.code);
1127
1128
  if (existing !== undefined) {
@@ -1237,12 +1238,13 @@ function fieldEntriesOf(args) {
1237
1238
  assertFieldFamilyAllowed(legacy);
1238
1239
  return [legacy];
1239
1240
  }
1240
- function fieldChangeInputOf(schemaCode, entry) {
1241
+ function fieldChangeInputOf(schemaCode, entry, targetVersion) {
1241
1242
  return {
1242
1243
  schemaCode,
1243
1244
  code: entry.code,
1244
1245
  name: entry.name,
1245
1246
  propertyType: entry.propertyType,
1247
+ ...(targetVersion ? { targetVersion } : {}),
1246
1248
  ...(entry.options ? { options: entry.options } : {}),
1247
1249
  ...(entry.choices ? { choices: entry.choices } : {}),
1248
1250
  ...(entry.relativeCode ? { relativeCode: entry.relativeCode } : {}),
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -15,34 +15,34 @@ import { ToolRefusalError } from "./tool-types.js";
15
15
  * to replace it.
16
16
  */
17
17
  export const PLATFORM_LIFECYCLE_WRAPPER_MARKER = "(function(form)";
18
- export const PLATFORM_DEFAULT_LIFECYCLE_SCRIPT = `/**
19
- * 用户自定义JS区域;
20
- * 注:外部链接的JS统一放置在HTML中,原有script标签下的js统一放置在当前编码区域
21
- * 使用环境变量,可通过"$env("唤醒提示框,并通过$env(分类名称.变量名称)的方式使用
22
- */
23
- (function(form){
24
- /**
25
- * 事件绑定,form.on
26
- * @param eventType 事件类型
27
- * @params function 事件
28
- * @param cover true, false 是否覆盖root的生命周期 默认不覆盖
29
- */
30
- //数据加载后,渲染之前,this为window
31
- form.on('onLoad',function(data, dataPermission){},'cover');
32
- //渲染完成后
33
- form.on('onRendered',function(data){});
34
- //内置校验完成后,返回false阻止提交
35
- form.on('onValidate',function(action,data){});
36
- //操作前(包含自定义按钮)执行,返回false阻止按钮操作
37
- form.on('onPreAction',function(action,data){});
38
- //自定义按钮执行
39
- form.on('onCustomAction',function(action,data){});
40
- //操作完成后执行
41
- form.on('onActionDone',function(action,data,httpRes){});
42
- //表单字段打印数据格式扩展,可自行定义调用打印模板时,表单字段对应所打印数据的内容
43
- form.on('onPrintFormDataHandle',function(vm, printData, sourceData, formValues, key, locale, printTemplateCode, control, dataType, sheetData){});
44
- //流程日志打印数据格式扩展,可自行定义调用打印模板时,流程日志对应所打印数据的内容
45
- form.on('onPrintWorkflowLogDataHandle',function(vm, sourceData, printData, locale, printTemplateCode){});
18
+ export const PLATFORM_DEFAULT_LIFECYCLE_SCRIPT = `/**
19
+ * 用户自定义JS区域;
20
+ * 注:外部链接的JS统一放置在HTML中,原有script标签下的js统一放置在当前编码区域
21
+ * 使用环境变量,可通过"$env("唤醒提示框,并通过$env(分类名称.变量名称)的方式使用
22
+ */
23
+ (function(form){
24
+ /**
25
+ * 事件绑定,form.on
26
+ * @param eventType 事件类型
27
+ * @params function 事件
28
+ * @param cover true, false 是否覆盖root的生命周期 默认不覆盖
29
+ */
30
+ //数据加载后,渲染之前,this为window
31
+ form.on('onLoad',function(data, dataPermission){},'cover');
32
+ //渲染完成后
33
+ form.on('onRendered',function(data){});
34
+ //内置校验完成后,返回false阻止提交
35
+ form.on('onValidate',function(action,data){});
36
+ //操作前(包含自定义按钮)执行,返回false阻止按钮操作
37
+ form.on('onPreAction',function(action,data){});
38
+ //自定义按钮执行
39
+ form.on('onCustomAction',function(action,data){});
40
+ //操作完成后执行
41
+ form.on('onActionDone',function(action,data,httpRes){});
42
+ //表单字段打印数据格式扩展,可自行定义调用打印模板时,表单字段对应所打印数据的内容
43
+ form.on('onPrintFormDataHandle',function(vm, printData, sourceData, formValues, key, locale, printTemplateCode, control, dataType, sheetData){});
44
+ //流程日志打印数据格式扩展,可自行定义调用打印模板时,流程日志对应所打印数据的内容
45
+ form.on('onPrintWorkflowLogDataHandle',function(vm, sourceData, printData, locale, printTemplateCode){});
46
46
  })`;
47
47
  /** The lifecycle events the platform dispatches; anything else is a typo the runtime silently drops (or throws on). */
48
48
  export const ONLINE_JS_EVENTS = new Set([
File without changes
package/dist/package.js CHANGED
File without changes
File without changes
package/dist/plan.js CHANGED
File without changes
package/dist/read.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -277,8 +277,62 @@ const formulaAggregationCrossModel = Object.freeze({
277
277
  requiresEnvironmentDerivedIds: true,
278
278
  prerequisiteData: { source: "field.list(published:true) ×2(来源模型 + 目标模型)", fields: ["source.model", "source.dataItemCode", "source.matchField", "target.matchField"] },
279
279
  });
280
+ /**
281
+ * r29(2026-10-29 中冶终轮)+ 用户领域知识:外部数据(企查查/NC 等)在表单上
282
+ * 「填表时即带出」的标准模式——两段式组合。此前三轮探针(r24/r28b/r29)都发明
283
+ * 了「按钮触发规则回写」的重方案,因为没人知道标准模式;r29 实证 GetList 规则
284
+ * 实时调接口替换数据源在 1.1.25 不成立(CREATE 节点被校验器禁止指向本模型),
285
+ * 但「数据段落表 + 表单段关联下拉查表带出」完全成立且是平台正解。
286
+ *
287
+ * 2026-10-29 用户定案修正:GetList/Load 规则**实时调接口也是成立的**——触发点是
288
+ * 填表时**前端发起**的关联控件查询链(接口方法配 frontEndExtensionEnable:true,
289
+ * 前端直调);r29 判「不成立」是因为用 data.list(后端 REST 查询)验证,该链不
290
+ * 执行 BIZ_ACTION 出参替换。验证必须走门户填表(关键字回车→候选→选中带出)。
291
+ */
292
+ const externalLookupModel = Object.freeze({
293
+ id: "external-lookup-model",
294
+ title: "外部数据映射模型:接口数据落表 + 关联单选下拉带出(填表时即映射)",
295
+ aliases: ["外部数据源", "接口映射模型", "企查查下拉", "关联带出", "映射模型", "外部数据带出"],
296
+ status: "requires-prior-readback",
297
+ tool: "field.create",
298
+ args: {
299
+ environment,
300
+ schemaCode: model,
301
+ code: "ext_lookup_ref",
302
+ name: "外部数据引用",
303
+ propertyType: "WORK_SHEET",
304
+ options: {
305
+ schemaCode: "<映射模型code>",
306
+ queryCode: "<映射模型code>",
307
+ displayField: "<映射模型显示字段>",
308
+ mappings: [{ source: "<映射模型.业务字段>", target: "<本模型.落点字段>" }],
309
+ },
310
+ },
311
+ preconditions: [
312
+ "映射模型已建且字段与接口返回字段一一对应(如 qcc_company: company_name/credit_code)",
313
+ "数据段已通:接口数据已能落进映射模型表(见 conditionalRequirements 第 1 条的三个已验证组合)",
314
+ ],
315
+ conditionalRequirements: [
316
+ "**数据段首选(平台标准模式,2026-10-29 playwright 门户实证定案)**:映射模型的 GetList/Load 规则挂 BIZ_ACTION 实时调接口(接口方法配 frontEndExtensionEnable:true)——门户关联控件**打开即触发**前端查询链→GetList 规则→BIZ_ACTION 实时调外部接口(引擎日志 bizBusService.invoke + 外部网关日志双侧铁证)。**验证必须走门户填表;data.list 后端查询不反映此链,别用它判死**(r29 曾据此误判不成立)。配置侧三个收尾点:① WORK_SHEET 字段必须带 relativeCode(仅 options.schemaCode 发布表单会 301015 关联业务模型为空);② GetList 规则的 BIZ_ACTION 入参映射要接前端搜索词(实测未配词时 invoke 参数为空 {});③ 出参→列表行的映射配完候选才回显(未配时弹窗 Total 0 但接口已调)。「下拉框形态(输关键字回车查询)」是表单 attributes 层的控件形态设置,默认弹窗形态。备选(不需要实时时):预置 Create/Update 规则落映射表 / TIMING 定时同步。图内「BIZ_ACTION→CREATE 落表→再查」回环在 1.1.25 不可表达,不要走这条岔路。",
317
+ "**表单段是平台原生能力**:关联单选指向映射模型后,门户上输入关键字回车即查映射表、选中即 mappings 带出——前台填表时映射自然出现,无需按钮/脚本。",
318
+ "下拉框形态(输入关键字回车查询而非弹窗选择)在表单 attributes 层配置(form.draft 改控件形态),不在字段 options。",
319
+ "映射模型表要有数据下拉才有选项——空表=空下拉;数据段先通再配表单段。",
320
+ ],
321
+ priorToolReferences: [
322
+ { tool: "model.create", args: { environment }, purpose: "建映射模型(字段与接口返回一一对应)" },
323
+ { tool: "rule.save", args: { environment }, purpose: "数据段规则(三选一,见 conditionalRequirements)" },
324
+ ],
325
+ dryRun: { supported: true, command: `omc call field.create --env ${environment} --dry-run --args '<recipe.args>'`, notes: "校验 WORK_SHEET options 与 mappings 形状" },
326
+ expectedReadback: { readback: { field: { propertyType: "WORK_SHEET", options: { mappings: [{ source: "<映射模型.业务字段>" }] } } }, next: ["field.publish", "form.draft(控件形态配下拉框)", "form.publish", "门户填表验证:输关键字回车→选中→字段带出"] },
327
+ refusalRecovery: [
328
+ { code: "field-family-options-invalid", action: "WORK_SHEET options 必带 schemaCode/queryCode/displayField;mappings 用数组或 JSON 字符串均可(CLI 就地归一)" },
329
+ ...commonRecovery,
330
+ ],
331
+ notes: "r29 终轮定案:此模式是「外部数据填表带出」的平台正解;按钮触发回写是下策(多一次交互且体验差)。映射模型数据段的三个组合全部基于已验证的出参回写三前提(平铺端点/预置规则上下文/data 触发)。",
332
+ requiresEnvironmentDerivedIds: true,
333
+ });
280
334
  export const FIELD_METADATA = Object.freeze({
281
335
  "field.update": Object.freeze({ recipes: [fieldSerialNumber, formConditionalRequired, formAlwaysReadonly, formConditionalReadonly], relatedTools: ["field.list", "field.publish", "form.draft", "form.publish"] }),
282
- "field.create": Object.freeze({ recipes: [numericTwoDecimals, dictionarySelection, childTable, businessModelDropdown, formulaAggregationCrossModel], relatedTools: ["dictionary.names", "dictionary.records", "discover_environment", "field.list", "field.publish", "form.draft", "configure_form", "form.publish"] }),
336
+ "field.create": Object.freeze({ recipes: [numericTwoDecimals, dictionarySelection, childTable, businessModelDropdown, formulaAggregationCrossModel, externalLookupModel], relatedTools: ["dictionary.names", "dictionary.records", "discover_environment", "field.list", "field.publish", "form.draft", "configure_form", "form.publish"] }),
283
337
  });
284
338
  //# sourceMappingURL=field.js.map
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/dist/redact.js CHANGED
File without changes
File without changes
File without changes
package/dist/rollback.js CHANGED
File without changes
File without changes
package/dist/rule-when.js CHANGED
File without changes
File without changes
package/dist/script.js CHANGED
File without changes
package/dist/server.js ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { randomBytes } from "node:crypto";
5
+ import { realpathSync } from "node:fs";
6
+ import { fileURLToPath } from "node:url";
7
+ import { buildToolRegistry, makeToolContext } from "./tools.js";
8
+ import { SessionManager } from "./session-manager.js";
9
+ import { redact, redactError } from "./redact.js";
10
+ import { ConfigStore } from "./config-store.js";
11
+ import { contractMarkdown, contractResourceUri, LANE_CONTRACTS, shortToolDescription } from "./contract-resources.js";
12
+ import { listSkills, readSkill } from "./skills.js";
13
+ export function createMcpServer(options = {}) {
14
+ const context = makeToolContext({
15
+ sessions: options.sessions ?? new SessionManager(new ConfigStore()),
16
+ artifactsDir: options.artifactsDir,
17
+ tokenKey: options.tokenKey ?? randomBytes(32).toString("base64"),
18
+ tokenTtlMs: options.tokenTtlMs,
19
+ });
20
+ const secrets = options.secrets ?? (() => []);
21
+ const server = new McpServer({ name: "omc-cli", version: "0.1.0" }, {
22
+ capabilities: { tools: {}, resources: {} },
23
+ instructions: "Governed CloudPivot 8.6 configuration server. Tool schemas are self-describing (field families, relation options, rule nodeGraph, workflow template, formData, and the two-step approval flow). Methodology is served as MCP resources under omc://skills/ (five-piece flow, tool selection, acceptance criteria, requirement analysis, capability scouting, glossary, config draft review); read them with resources/list + resources/read rather than reading repository source. Before ANY write, read omc://skills/omc-config-draft-review: present the design (exact names/codes/types, layout, rule graph, view) as a plain-language draft and get explicit human approval first — the conversational human gate (approval granularity is the enumerated change package; an interrupted package loses its approval and resuming needs a fresh draft and go-ahead). Then: call without approvalToken to preview the plan, approval.request to get a token (the machine gate — it carries no human check), re-call with it. Production environments refuse writes by default (dual-key grant). Deliver ONE closing report per run — never interrupt per step.",
24
+ });
25
+ const register = server.tool.bind(server);
26
+ for (const definition of buildToolRegistry()) {
27
+ register(definition.name, shortToolDescription(definition.name, definition.kind, definition.lane) ?? definition.description, definition.inputSchema, async (args) => {
28
+ try {
29
+ const result = await definition.handler(context, args, definition);
30
+ return { content: [{ type: "text", text: redact(result, secrets()) }] };
31
+ }
32
+ catch (error) {
33
+ const refusal = error.payload;
34
+ if (refusal)
35
+ return { content: [{ type: "text", text: redact(refusal, secrets()) }] };
36
+ const redacted = redactError(error, secrets());
37
+ return { content: [{ type: "text", text: redact({ status: "error", message: redacted.message }, secrets()) }], isError: true };
38
+ }
39
+ });
40
+ }
41
+ registerSkillResources(server);
42
+ registerContractResources(server);
43
+ return { server, context };
44
+ }
45
+ /**
46
+ * Serve the package's methodology notes as MCP resources so any client can
47
+ * read them on demand (host-agnostic) instead of the agent globbing the
48
+ * filesystem for them. Each skill file's YAML frontmatter supplies its name
49
+ * and description.
50
+ */
51
+ function registerSkillResources(server) {
52
+ for (const entry of listSkills()) {
53
+ const document = readSkill(entry.name);
54
+ if (document === undefined)
55
+ continue;
56
+ server.registerResource(entry.name, entry.uri, { title: entry.name, description: entry.description, mimeType: "text/markdown" }, async (uri) => ({ contents: [{ uri: uri.href, mimeType: "text/markdown", text: document.content }] }));
57
+ }
58
+ }
59
+ function registerContractResources(server) {
60
+ for (const contract of LANE_CONTRACTS) {
61
+ const text = contractMarkdown(contract);
62
+ server.registerResource(`contract-${contract.lane}`, contractResourceUri(contract), {
63
+ title: `${contract.lane} contract`,
64
+ description: `CloudPivot ${contract.family} contract for ${contract.lane}; reference ${contract.referenceVersion}`,
65
+ mimeType: "text/markdown",
66
+ }, async (uri) => ({ contents: [{ uri: uri.href, mimeType: "text/markdown", text }] }));
67
+ }
68
+ }
69
+ export async function runStdioServer(options = {}) {
70
+ const { server } = createMcpServer(options);
71
+ const transport = new StdioServerTransport();
72
+ await server.connect(transport);
73
+ }
74
+ function isProcessEntryPoint() {
75
+ const entry = process.argv[1];
76
+ if (!entry)
77
+ return false;
78
+ try {
79
+ return realpathSync(entry) === fileURLToPath(import.meta.url);
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ if (isProcessEntryPoint()) {
86
+ runStdioServer().catch((error) => {
87
+ console.error(error instanceof Error ? error.message : String(error));
88
+ process.exit(1);
89
+ });
90
+ }
91
+ export { buildToolRegistry, makeToolContext };
92
+ //# sourceMappingURL=server.js.map
File without changes
File without changes