@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
package/dist/read.js ADDED
@@ -0,0 +1,144 @@
1
+ import { assertWithinCoverage } from "./coverage.js";
2
+ import { wireErrorKind, isUncertainWireError, jsonBytes, refusalFromCoverage, sha256, summarizeValue, writeArtifact } from "./support.js";
3
+ import { plannableArgsRaw } from "./plan.js";
4
+ import { WireError } from "./wire.js";
5
+ /**
6
+ * `full:true` used to bypass every diet gate and inline the raw platform body.
7
+ * For `workflow.get_draft` that is a 30–75 KB native blob (btnConfigList,
8
+ * propertyPermissions, eight lifecycle callbacks, geometry, a duplicated
9
+ * originateActivity) of which the editable shape is <1.5 KB. Round 9 (sandbox
10
+ * 40): 8 `workflow.get_* full:true` calls were 147 KB = 24% of the task, and the
11
+ * blob is re-read on every later turn.
12
+ *
13
+ * So the raw body is only inlined below this ceiling. Above it the caller gets
14
+ * the tool's compact semantic projection (which holds everything an edit needs)
15
+ * plus the artifact reference and a targeted-fetch hint. This does NOT change
16
+ * any platform write: write tools read the stored row server-side, never from
17
+ * the agent's readback (workflow.update/publish, field.update, form.publish,
18
+ * onlinejs.compose, service.update/method.update all self-read).
19
+ */
20
+ const FULL_INLINE_CEILING_BYTES = 8192;
21
+ /**
22
+ * Run composed sibling reads without the `unchanged` short-circuit, so a
23
+ * composite tool (model.inspect) receives their real payloads even after an
24
+ * identical standalone read primed the cache. Re-entrant via a counter, so
25
+ * nesting is safe. Only the short-circuit is skipped; results are still cached
26
+ * normally, and the cache is process-local (a fresh CLI process starts empty).
27
+ */
28
+ export async function withoutReadbackCache(ctx, run) {
29
+ ctx.readbackCacheBypass += 1;
30
+ try {
31
+ return await run();
32
+ }
33
+ finally {
34
+ ctx.readbackCacheBypass -= 1;
35
+ }
36
+ }
37
+ export async function governedRead(ctx, tool, args, execute, options = {}) {
38
+ const lane = args.capability ?? tool.lane;
39
+ if (lane) {
40
+ try {
41
+ assertWithinCoverage(ctx.manifest, lane, tool.scope ?? "");
42
+ }
43
+ catch (error) {
44
+ return refusalFromCoverage(error);
45
+ }
46
+ }
47
+ try {
48
+ const session = await ctx.sessions.session(args.environment);
49
+ const environmentFingerprint = safeFingerprint(session);
50
+ const result = await execute(session);
51
+ if (result.status === "refused" || result.status === "uncertain")
52
+ return { ...result, environmentFingerprint };
53
+ const target = options.target ?? `${tool.name}:${JSON.stringify(plannableArgsRaw(args))}`;
54
+ const targetFingerprint = sha256(result);
55
+ const cached = ctx.readbackCache.get(target);
56
+ if (ctx.readbackCacheBypass === 0 && cached && cached.environmentFingerprint === environmentFingerprint && cached.targetFingerprint === targetFingerprint && options.full !== true)
57
+ return { status: "ok", unchanged: true, detailFile: cached.detailFile, detailSha256: cached.detailSha256, environmentFingerprint };
58
+ const detail = { status: "ok", ...result, environmentFingerprint };
59
+ const large = jsonBytes(result) > 4096;
60
+ const fileName = `${tool.name.replace(/[^a-zA-Z0-9._-]/g, "_")}-${sha256(target).slice(0, 16)}.json`;
61
+ const artifactRef = writeArtifact(ctx, fileName, detail);
62
+ ctx.readbackCache.set(target, { environmentFingerprint, targetFingerprint, detailFile: artifactRef.detailFile, detailSha256: artifactRef.detailSha256 });
63
+ if (options.full === true) {
64
+ const rawBytes = jsonBytes(result);
65
+ // Small raw bodies keep the old inline behaviour; large ones are dieted
66
+ // (see FULL_INLINE_CEILING_BYTES). The raw body stays fully reachable via
67
+ // the artifact, so no capability is lost — only the inline copy is skipped.
68
+ if (rawBytes <= FULL_INLINE_CEILING_BYTES)
69
+ return { ...detail, detailFile: artifactRef.detailFile, detailSha256: artifactRef.detailSha256 };
70
+ const compact = options.compact ? options.compact(result, session) : compactReadback(result);
71
+ return {
72
+ status: "ok",
73
+ ...passthroughScalars(result),
74
+ ...compact,
75
+ full: true,
76
+ fullOmitted: true,
77
+ fullBytes: rawBytes,
78
+ fullArtifactHint: `--full 的原生正文 ${rawBytes}B 超过内联上限 ${FULL_INLINE_CEILING_BYTES}B,已外置到 artifact;上面的语义投影含编辑所需字段,需要原生字段用 \`omc artifact get <detailArtifactId>\`(可 --jq <path> / --keys)定向取回,勿全量读入。`,
79
+ environmentFingerprint,
80
+ detailFile: artifactRef.detailFile,
81
+ detailSha256: artifactRef.detailSha256,
82
+ };
83
+ }
84
+ if (!large)
85
+ return { status: "ok", ...result, environmentFingerprint };
86
+ const compact = options.compact ? options.compact(result, session) : compactReadback(result);
87
+ return { status: "ok", ...passthroughScalars(result), ...compact, environmentFingerprint, detailFile: artifactRef.detailFile, detailSha256: artifactRef.detailSha256 };
88
+ }
89
+ catch (error) {
90
+ if (isUncertainWireError(error))
91
+ return { status: "uncertain", frozen: true, reason: `wire-transport:${wireErrorKind(error)}`, detail: error.message };
92
+ if (error instanceof WireError)
93
+ return { status: "refused", blocker: `wire-${error.kind}`, errcode: error.errcode, message: error.message, ...(error.diagnostic ? { diagnostic: error.diagnostic } : {}) };
94
+ throw error;
95
+ }
96
+ }
97
+ function compactReadback(result) {
98
+ const compact = {};
99
+ for (const [key, value] of Object.entries(result)) {
100
+ if (BULKY_READ_KEYS.has(key)) {
101
+ compact[`${key}Count`] = Array.isArray(value) ? value.length : value && typeof value === "object" ? Object.keys(value).length : 0;
102
+ }
103
+ else {
104
+ compact[key] = summarizeValue(value);
105
+ }
106
+ }
107
+ return compact;
108
+ }
109
+ /**
110
+ * Keys whose values are the bulk a compact projection replaces with a count.
111
+ * Everything else is a small facet identity/decision fields (workflowCode,
112
+ * exists, published, id, code, schemaCode, note, …).
113
+ */
114
+ const BULKY_READ_KEYS = new Set(["data", "nodes", "routes", "items", "rules", "applications", "foldersAndModels", "models"]);
115
+ /**
116
+ * Carry the handler's small top-level facets through a compact projection.
117
+ *
118
+ * A lane's compact function reduces the result to its own summary shape and can
119
+ * drop scalar identity/decision keys the handler set at the top level — e.g.
120
+ * `workflow.get_draft` returns `{ workflowCode, exists, published, data }`, but
121
+ * `workflowCompactProjection` emitted only `workflowSummary`, so a caller reading
122
+ * `result.workflowCode` got `undefined` (round 10: live demo). Pass the scalar
123
+ * (non-bulky) top-level keys through; the compact's own keys still win.
124
+ */
125
+ function passthroughScalars(result) {
126
+ const carried = {};
127
+ for (const [key, value] of Object.entries(result)) {
128
+ if (key === "status" || BULKY_READ_KEYS.has(key))
129
+ continue;
130
+ const type = typeof value;
131
+ if (value === null || type === "string" || type === "number" || type === "boolean")
132
+ carried[key] = value;
133
+ }
134
+ return carried;
135
+ }
136
+ function safeFingerprint(session) {
137
+ try {
138
+ return session.environmentFingerprint();
139
+ }
140
+ catch {
141
+ return "unavailable";
142
+ }
143
+ }
144
+ //# sourceMappingURL=read.js.map
package/dist/redact.js ADDED
@@ -0,0 +1,28 @@
1
+ const PLACEHOLDER = "[REDACTED]";
2
+ export function redact(value, secrets) {
3
+ let text = JSON.stringify(value ?? null);
4
+ for (const secret of secrets) {
5
+ if (!secret.value)
6
+ continue;
7
+ text = text.split(secret.value).join(PLACEHOLDER);
8
+ }
9
+ return text;
10
+ }
11
+ export function redactText(text, secrets) {
12
+ let out = text;
13
+ for (const secret of secrets) {
14
+ if (!secret.value)
15
+ continue;
16
+ out = out.split(secret.value).join(PLACEHOLDER);
17
+ }
18
+ return out;
19
+ }
20
+ /** Error messages must never embed secret material either. */
21
+ export function redactError(error, secrets) {
22
+ const message = redactText(error instanceof Error ? error.message : String(error), secrets);
23
+ const redacted = new Error(message);
24
+ if (error instanceof Error && error.stack)
25
+ redacted.stack = redactText(error.stack, secrets);
26
+ return redacted;
27
+ }
28
+ //# sourceMappingURL=redact.js.map