@stalfh233/omc-cli 0.0.0-stage → 0.4.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.
Files changed (181) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +304 -3
  3. package/coverage/m1-coverage-manifest-v1.json +1278 -0
  4. package/dist/approval-token.js +102 -0
  5. package/dist/args.js +25 -0
  6. package/dist/artifacts.js +119 -0
  7. package/dist/bench/call-face-eval.js +256 -0
  8. package/dist/bench/context-attribution.js +151 -0
  9. package/dist/bench/discovery-cost-eval.js +230 -0
  10. package/dist/bench/driver.js +81 -0
  11. package/dist/bench/evals.js +236 -0
  12. package/dist/bench/fake-http-server.js +65 -0
  13. package/dist/bench/instrument.js +87 -0
  14. package/dist/bench/intent-face-eval.js +343 -0
  15. package/dist/bench/run.js +166 -0
  16. package/dist/bench/scenario.js +343 -0
  17. package/dist/bench/types.js +76 -0
  18. package/dist/bi-wire.js +41 -0
  19. package/dist/bizservice-config.js +581 -0
  20. package/dist/call.js +153 -0
  21. package/dist/capability-absences.js +23 -0
  22. package/dist/capability-overview.js +492 -0
  23. package/dist/capability-shape.js +154 -0
  24. package/dist/cli-contract.js +70 -0
  25. package/dist/cli-output.js +73 -0
  26. package/dist/cli.js +1418 -0
  27. package/dist/code-rules.js +69 -0
  28. package/dist/command-transport.js +155 -0
  29. package/dist/config-store.js +195 -0
  30. package/dist/context.js +21 -0
  31. package/dist/contract-consistency.js +66 -0
  32. package/dist/contract-resources.js +62 -0
  33. package/dist/coverage-consistency.js +62 -0
  34. package/dist/coverage-registry.js +76 -0
  35. package/dist/coverage.js +130 -0
  36. package/dist/data-list-filter.js +114 -0
  37. package/dist/discovery.js +390 -0
  38. package/dist/endpoints.js +154 -0
  39. package/dist/environment-policy.js +26 -0
  40. package/dist/execution-metadata.js +1092 -0
  41. package/dist/fake/app.js +45 -0
  42. package/dist/fake/b2-registration.js +594 -0
  43. package/dist/fake/businessrule.js +242 -0
  44. package/dist/fake/datarule.js +72 -0
  45. package/dist/fake/dictionary.js +108 -0
  46. package/dist/fake/environment.js +30 -0
  47. package/dist/fake/field.js +167 -0
  48. package/dist/fake/form.js +101 -0
  49. package/dist/fake/index.js +121 -0
  50. package/dist/fake/list-view.js +289 -0
  51. package/dist/fake/model.js +136 -0
  52. package/dist/fake/online-js.js +18 -0
  53. package/dist/fake/report.js +253 -0
  54. package/dist/fake/routes.js +47 -0
  55. package/dist/fake/rule-lifecycle.js +37 -0
  56. package/dist/fake/runtime-data.js +367 -0
  57. package/dist/fake/state.js +67 -0
  58. package/dist/fake/workflow.js +364 -0
  59. package/dist/field-change.js +200 -0
  60. package/dist/field-families.js +896 -0
  61. package/dist/form-layout.js +111 -0
  62. package/dist/form-support.js +821 -0
  63. package/dist/goal-routes.js +468 -0
  64. package/dist/governed-execution.js +87 -0
  65. package/dist/human-summary.js +212 -0
  66. package/dist/identity.js +62 -0
  67. package/dist/intent/baseline.js +57 -0
  68. package/dist/intent/capabilities/bizservice.js +274 -0
  69. package/dist/intent/capabilities/businessrule.js +493 -0
  70. package/dist/intent/capabilities/datarule.js +187 -0
  71. package/dist/intent/capabilities/field.js +545 -0
  72. package/dist/intent/capabilities/form.js +136 -0
  73. package/dist/intent/capabilities/index.js +64 -0
  74. package/dist/intent/capabilities/listview.js +157 -0
  75. package/dist/intent/capabilities/model.js +100 -0
  76. package/dist/intent/capabilities/onlinejs.js +108 -0
  77. package/dist/intent/capabilities/report.js +355 -0
  78. package/dist/intent/capabilities/workflow.js +458 -0
  79. package/dist/intent/capability.js +6 -0
  80. package/dist/intent/cli.js +91 -0
  81. package/dist/intent/compare.js +56 -0
  82. package/dist/intent/compiler.js +79 -0
  83. package/dist/intent/dsl.js +129 -0
  84. package/dist/intent/plan-file.js +63 -0
  85. package/dist/intent/readback.js +65 -0
  86. package/dist/intent/schema.js +158 -0
  87. package/dist/intent/validation.js +30 -0
  88. package/dist/intent/yaml.js +315 -0
  89. package/dist/json-column.js +68 -0
  90. package/dist/lanes/app-contract.js +95 -0
  91. package/dist/lanes/app-coverage.js +16 -0
  92. package/dist/lanes/app.js +174 -0
  93. package/dist/lanes/apply-changes.js +231 -0
  94. package/dist/lanes/b2-registration-contract.js +292 -0
  95. package/dist/lanes/b2-registration-coverage.js +48 -0
  96. package/dist/lanes/b2-registration.js +1187 -0
  97. package/dist/lanes/businessrule-contract.js +232 -0
  98. package/dist/lanes/businessrule-coverage.js +16 -0
  99. package/dist/lanes/businessrule.js +221 -0
  100. package/dist/lanes/contract-support.js +65 -0
  101. package/dist/lanes/coverage-declaration.js +9 -0
  102. package/dist/lanes/datarule-contract.js +155 -0
  103. package/dist/lanes/datarule-coverage.js +19 -0
  104. package/dist/lanes/datarule-protocol.js +308 -0
  105. package/dist/lanes/datarule.js +818 -0
  106. package/dist/lanes/dictionary-contract.js +78 -0
  107. package/dist/lanes/dictionary-coverage.js +24 -0
  108. package/dist/lanes/dictionary.js +235 -0
  109. package/dist/lanes/environment-contract.js +70 -0
  110. package/dist/lanes/environment-coverage.js +14 -0
  111. package/dist/lanes/environment.js +163 -0
  112. package/dist/lanes/field-contract.js +223 -0
  113. package/dist/lanes/field-coverage.js +27 -0
  114. package/dist/lanes/field.js +374 -0
  115. package/dist/lanes/form-contract.js +97 -0
  116. package/dist/lanes/form-coverage.js +16 -0
  117. package/dist/lanes/form.js +185 -0
  118. package/dist/lanes/lane-ids.js +34 -0
  119. package/dist/lanes/list-view-contract.js +175 -0
  120. package/dist/lanes/list-view-coverage.js +20 -0
  121. package/dist/lanes/list-view-shapes.js +1207 -0
  122. package/dist/lanes/list-view.js +578 -0
  123. package/dist/lanes/meta-contract.js +85 -0
  124. package/dist/lanes/meta.js +255 -0
  125. package/dist/lanes/model-contract.js +168 -0
  126. package/dist/lanes/model-coverage.js +20 -0
  127. package/dist/lanes/model.js +986 -0
  128. package/dist/lanes/online-js-contract.js +99 -0
  129. package/dist/lanes/online-js-coverage.js +28 -0
  130. package/dist/lanes/online-js.js +127 -0
  131. package/dist/lanes/report-contract.js +144 -0
  132. package/dist/lanes/report-coverage.js +21 -0
  133. package/dist/lanes/report.js +476 -0
  134. package/dist/lanes/rule-graph.js +1846 -0
  135. package/dist/lanes/rule-lifecycle-contract.js +92 -0
  136. package/dist/lanes/rule-lifecycle-coverage.js +20 -0
  137. package/dist/lanes/rule-lifecycle.js +176 -0
  138. package/dist/lanes/runtime-data-contract.js +264 -0
  139. package/dist/lanes/runtime-data-coverage.js +25 -0
  140. package/dist/lanes/runtime-data.js +1054 -0
  141. package/dist/lanes/workflow-contract.js +223 -0
  142. package/dist/lanes/workflow-coverage.js +40 -0
  143. package/dist/lanes/workflow.js +1813 -0
  144. package/dist/online-js-layout.js +58 -0
  145. package/dist/online-js-source.js +276 -0
  146. package/dist/package-tool.js +51 -0
  147. package/dist/package.js +73 -0
  148. package/dist/plan.js +73 -0
  149. package/dist/read.js +144 -0
  150. package/dist/redact.js +28 -0
  151. package/dist/rule-support.js +587 -0
  152. package/dist/runtime-support.js +134 -0
  153. package/dist/server.js +92 -0
  154. package/dist/session-manager.js +30 -0
  155. package/dist/session.js +149 -0
  156. package/dist/skills.js +112 -0
  157. package/dist/support.js +98 -0
  158. package/dist/tool-types.js +127 -0
  159. package/dist/tools.js +59 -0
  160. package/dist/usage-log.js +197 -0
  161. package/dist/wire.js +287 -0
  162. package/dist/workflow-support.js +99 -0
  163. package/dist/write-lease.js +26 -0
  164. package/dist/write-lock.js +109 -0
  165. package/dist/write.js +176 -0
  166. package/dist/zip.js +156 -0
  167. package/docs/tool-surface-map.md +42 -0
  168. package/package.json +71 -6
  169. package/skills/omc-acceptance-criteria.md +47 -0
  170. package/skills/omc-business-configuration.md +257 -0
  171. package/skills/omc-capabilities.md +197 -0
  172. package/skills/omc-capability-scouting.md +55 -0
  173. package/skills/omc-config-draft-review.md +171 -0
  174. package/skills/omc-five-piece-flow.md +35 -0
  175. package/skills/omc-glossary.md +86 -0
  176. package/skills/omc-refusals.md +110 -0
  177. package/skills/omc-requirement-analysis.md +161 -0
  178. package/skills/omc-requirement-vocabulary.md +51 -0
  179. package/skills/omc-start-here.md +82 -0
  180. package/skills/omc-tool-selection.md +119 -0
  181. package/skills/omc-write-hazards.md +87 -0
@@ -0,0 +1,187 @@
1
+ import { ENDPOINTS } from "../../endpoints.js";
2
+ import { assertDataRuleOptions } from "../../lanes/datarule.js";
3
+ import { wireCall, wireRows } from "../../wire.js";
4
+ import { optionalSame, sameValue } from "../compare.js";
5
+ import { isScalarString, pushError } from "../validation.js";
6
+ import { toPlain } from "../yaml.js";
7
+ import { errorDetail } from "../../tool-types.js";
8
+ const KEYS = new Set(["propertyCode", "dataRuleType", "options", "checkType", "childRule", "name", "sortKey", "absent"]);
9
+ /** Keys that describe a live rule and are meaningless on a declared-absent one. */
10
+ const PRESENT_ONLY_KEYS = ["options", "checkType", "childRule", "name", "sortKey"];
11
+ function decodeOptions(value) {
12
+ if (typeof value !== "string")
13
+ return value;
14
+ try {
15
+ return JSON.parse(value);
16
+ }
17
+ catch {
18
+ return value;
19
+ }
20
+ }
21
+ function rowOf(row) {
22
+ const codes = rowCodes(row);
23
+ return {
24
+ id: String(row.id ?? ""),
25
+ propertyCode: codes.length === 1 ? codes[0] : codes.join(","),
26
+ dataRuleType: Number(row.dataRuleType),
27
+ options: decodeOptions(row.options),
28
+ ...(row.checkType !== undefined && row.checkType !== null ? { checkType: Number(row.checkType) } : {}),
29
+ ...(row.childRule !== undefined ? { childRule: row.childRule === true } : {}),
30
+ ...(row.name !== undefined && row.name !== null ? { name: String(row.name) } : {}),
31
+ // The platform defaults an omitted sortKey to 0; an intent that omits it must
32
+ // read back equal (bench56: `sortKey:0` vs undefined produced a perpetual
33
+ // `datarule-mismatch`, so a fully-delivered apply was reported refused).
34
+ ...(row.sortKey !== undefined && row.sortKey !== null && Number(row.sortKey) !== 0 ? { sortKey: Number(row.sortKey) } : {}),
35
+ };
36
+ }
37
+ function normalizeOptions(dataRuleType, options, propertyCode) {
38
+ const normalized = { ...options };
39
+ // The tool mirrors the target field(s) into options.propertyCodes (the real
40
+ // designer shape the engine reads); declare the same here so a converged
41
+ // environment has no false drift.
42
+ if (propertyCode.length > 0 && normalized.propertyCodes === undefined)
43
+ normalized.propertyCodes = propertyCode;
44
+ if (dataRuleType === 2) {
45
+ for (const key of ["shortTextStitch", "value", "aggregation"]) {
46
+ if (normalized[key] !== undefined && typeof normalized[key] === "object")
47
+ normalized[key] = JSON.stringify(normalized[key]);
48
+ }
49
+ }
50
+ return normalized;
51
+ }
52
+ /** Stored target field codes (propertyCodes array preferred, legacy singular fallback). */
53
+ function rowCodes(row) {
54
+ if (Array.isArray(row.propertyCodes) && row.propertyCodes.length > 0)
55
+ return row.propertyCodes.map((code) => String(code));
56
+ const single = row.propertyCode;
57
+ return single !== undefined && single !== null && String(single).length > 0 ? [String(single)] : [];
58
+ }
59
+ export const dataruleCapability = {
60
+ id: "datarule",
61
+ title: "字段级控件规则",
62
+ requires: ["field"],
63
+ operations: ["create", "update"],
64
+ validate(node, draft, ctx) {
65
+ const rulesNode = node.entries.find((entry) => entry.key === "datarules")?.value;
66
+ if (rulesNode === undefined || (rulesNode.kind === "scalar" && rulesNode.value === null))
67
+ return;
68
+ if (rulesNode.kind !== "seq") {
69
+ pushError(ctx, "intent-datarules-not-a-list", "datarules 必须是列表", `${ctx.base}.datarules`, "value");
70
+ return;
71
+ }
72
+ rulesNode.items.forEach((ruleNode, index) => {
73
+ const base = `${ctx.base}.datarules[${index}]`;
74
+ if (ruleNode.kind !== "map") {
75
+ pushError(ctx, "intent-datarule-not-a-map", "datarule 必须是映射", base, "value");
76
+ return;
77
+ }
78
+ for (const entry of ruleNode.entries)
79
+ if (!KEYS.has(entry.key))
80
+ pushError(ctx, "intent-key-unknown", `datarule 不支持键 "${entry.key}"(可用:${[...KEYS].join(" / ")})`, `${base}.${entry.key}`);
81
+ const get = (key) => ruleNode.entries.find((entry) => entry.key === key)?.value;
82
+ const property = get("propertyCode");
83
+ const type = get("dataRuleType");
84
+ const options = get("options");
85
+ const checkType = get("checkType");
86
+ const childRule = get("childRule");
87
+ const name = get("name");
88
+ const sortKey = get("sortKey");
89
+ const absent = get("absent");
90
+ if (!isScalarString(property) || property.value.trim().length === 0)
91
+ pushError(ctx, "intent-datarule-property-invalid", "datarule.propertyCode 必须是非空字符串", `${base}.propertyCode`, "value");
92
+ if (type?.kind !== "scalar" || typeof type.value !== "number" || !Number.isInteger(type.value) || type.value < 1 || type.value > 5)
93
+ pushError(ctx, "intent-datarule-type-invalid", "datarule.dataRuleType 必须是 1..5", `${base}.dataRuleType`, "value");
94
+ if (absent !== undefined && (absent.kind !== "scalar" || typeof absent.value !== "boolean"))
95
+ pushError(ctx, "intent-datarule-absent-invalid", "datarule.absent 必须是布尔", `${base}.absent`, "value");
96
+ if (absent?.kind === "scalar" && absent.value === true) {
97
+ for (const key of PRESENT_ONLY_KEYS)
98
+ if (ruleNode.entries.some((entry) => entry.key === key))
99
+ pushError(ctx, "intent-datarule-absent-with-shape", `数据规则声明 absent:true 表示删除该规则,不能再声明 ${key}`, `${base}.${key}`);
100
+ if (isScalarString(property) && type?.kind === "scalar" && typeof type.value === "number")
101
+ draft.datarules.push({ propertyCode: property.value.trim(), dataRuleType: type.value, absent: true });
102
+ return;
103
+ }
104
+ if (options?.kind !== "map")
105
+ pushError(ctx, "intent-datarule-options-invalid", "datarule.options 必须是映射", `${base}.options`, "value");
106
+ if (checkType !== undefined && (checkType.kind !== "scalar" || typeof checkType.value !== "number"))
107
+ pushError(ctx, "intent-datarule-checktype-invalid", "datarule.checkType 必须是数字", `${base}.checkType`, "value");
108
+ if (childRule !== undefined && (childRule.kind !== "scalar" || typeof childRule.value !== "boolean"))
109
+ pushError(ctx, "intent-datarule-childrule-invalid", "datarule.childRule 必须是布尔", `${base}.childRule`, "value");
110
+ if (name !== undefined && (!isScalarString(name) || name.value.trim().length === 0))
111
+ pushError(ctx, "intent-datarule-name-invalid", "datarule.name 必须是非空字符串", `${base}.name`, "value");
112
+ if (sortKey !== undefined && (sortKey.kind !== "scalar" || typeof sortKey.value !== "number"))
113
+ pushError(ctx, "intent-datarule-sortkey-invalid", "datarule.sortKey 必须是数字", `${base}.sortKey`, "value");
114
+ if (!isScalarString(property) || type?.kind !== "scalar" || typeof type.value !== "number" || options?.kind !== "map")
115
+ return;
116
+ const rawOptions = options.entries ? Object.fromEntries(options.entries.map((entry) => [entry.key, entry.value.kind === "scalar" ? entry.value.value : toPlain(entry.value)])) : {};
117
+ const normalizedOptions = normalizeOptions(type.value, rawOptions, property.value.trim());
118
+ const parsedCheckType = checkType?.kind === "scalar" && typeof checkType.value === "number" ? checkType.value : undefined;
119
+ try {
120
+ assertDataRuleOptions(type.value, normalizedOptions, parsedCheckType);
121
+ }
122
+ catch (error) {
123
+ pushError(ctx, "intent-datarule-options-invalid", errorDetail(error), `${base}.options`, "value");
124
+ return;
125
+ }
126
+ const item = {
127
+ propertyCode: property.value.trim(),
128
+ dataRuleType: type.value,
129
+ options: normalizedOptions,
130
+ ...(checkType?.kind === "scalar" && typeof checkType.value === "number" ? { checkType: checkType.value } : {}),
131
+ ...(childRule?.kind === "scalar" && typeof childRule.value === "boolean" ? { childRule: childRule.value } : {}),
132
+ ...(isScalarString(name) ? { name: name.value.trim() } : {}),
133
+ ...(sortKey?.kind === "scalar" && typeof sortKey.value === "number" ? { sortKey: sortKey.value } : {}),
134
+ };
135
+ draft.datarules.push(item);
136
+ });
137
+ },
138
+ async read(session, intent, draft) {
139
+ if (!intent.datarules?.length)
140
+ return;
141
+ const rows = wireRows((await wireCall(session, { path: ENDPOINTS.dataRuleList, query: { schemaCode: draft.code } })).data);
142
+ draft.datarules = rows.filter((row) => row.schemaCode === draft.code && intent.datarules.some((rule) => rowCodes(row).includes(rule.propertyCode) && rule.dataRuleType === Number(row.dataRuleType))).map(rowOf);
143
+ },
144
+ plan(intent, baseline, emit) {
145
+ if (!intent.datarules?.length)
146
+ return;
147
+ for (const rule of intent.datarules) {
148
+ const current = (baseline.datarules ?? []).find((row) => row.propertyCode === rule.propertyCode && row.dataRuleType === rule.dataRuleType);
149
+ const resource = `datarule:${intent.code}.${rule.propertyCode}.${rule.dataRuleType}`;
150
+ if (rule.absent === true) {
151
+ if (current)
152
+ emit.change("datarule.delete", { id: current.id, schemaCode: intent.code }, resource, "datarule-declared-absent");
153
+ else
154
+ emit.skip(resource, "datarule-already-absent");
155
+ continue;
156
+ }
157
+ if (!current)
158
+ emit.change("datarule.create", { schemaCode: intent.code, ...rule }, resource, "datarule-absent");
159
+ else if (!sameValue(current.options, rule.options) || !optionalSame(current.checkType, rule.checkType) || !optionalSame(current.childRule, rule.childRule) || !optionalSame(current.name, rule.name) || !optionalSame(current.sortKey, rule.sortKey))
160
+ emit.change("datarule.update", { id: current.id, schemaCode: intent.code, ...rule }, resource, "datarule-drift");
161
+ else
162
+ emit.skip(resource, "datarule-present");
163
+ }
164
+ },
165
+ decode(baseline, draft) {
166
+ draft.datarules = (baseline.datarules ?? []).map((rule) => ({ ...rule }));
167
+ },
168
+ compare(intent, live, emit) {
169
+ if (!intent.datarules?.length)
170
+ return;
171
+ const current = live.datarules ?? [];
172
+ for (const rule of intent.datarules) {
173
+ const row = current.find((item) => item.propertyCode === rule.propertyCode && item.dataRuleType === rule.dataRuleType);
174
+ const resource = `datarule:${intent.code}.${rule.propertyCode}.${rule.dataRuleType}`;
175
+ if (rule.absent === true) {
176
+ if (row)
177
+ emit.difference("datarule-present-unexpected", resource, `字段 ${intent.code}.${rule.propertyCode} 的数据规则声明 absent:true 但仍存在`);
178
+ continue;
179
+ }
180
+ if (!row)
181
+ emit.difference("datarule-missing", resource, `字段 ${intent.code}.${rule.propertyCode} 的数据规则不存在`);
182
+ else if (!sameValue(row.options, rule.options) || !optionalSame(row.checkType, rule.checkType) || !optionalSame(row.childRule, rule.childRule) || !optionalSame(row.name, rule.name) || !optionalSame(row.sortKey, rule.sortKey))
183
+ emit.difference("datarule-mismatch", resource, `字段 ${intent.code}.${rule.propertyCode} 的数据规则不等价`);
184
+ }
185
+ },
186
+ };
187
+ //# sourceMappingURL=datarule.js.map