@stalfh233/omc-cli 0.5.0 → 0.5.2

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 (226) 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 +0 -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 +9 -1
  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 +75 -7
  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 +29 -29
  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 +0 -0
  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 +14 -29
  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 +2 -2
  162. package/dist/model-record.js +40 -0
  163. package/dist/model-scaffold.js +0 -0
  164. package/dist/omc-core-lazy.js +0 -0
  165. package/dist/online-js-layout.js +0 -0
  166. package/dist/online-js-source.js +28 -28
  167. package/dist/package-tool.js +0 -0
  168. package/dist/package.js +0 -0
  169. package/dist/path-projection.js +0 -0
  170. package/dist/plan.js +0 -0
  171. package/dist/read.js +0 -0
  172. package/dist/recipes/b2-registration.js +0 -0
  173. package/dist/recipes/businessrule.js +0 -0
  174. package/dist/recipes/datarule.js +0 -0
  175. package/dist/recipes/dictionary.js +0 -0
  176. package/dist/recipes/field.js +0 -0
  177. package/dist/recipes/form.js +0 -0
  178. package/dist/recipes/list-view.js +0 -0
  179. package/dist/recipes/model.js +0 -0
  180. package/dist/recipes/online-js.js +0 -0
  181. package/dist/recipes/runtime-data.js +0 -0
  182. package/dist/recipes/shared.js +0 -0
  183. package/dist/recipes/workflow.js +0 -0
  184. package/dist/redact.js +0 -0
  185. package/dist/refusal-guidance.js +0 -0
  186. package/dist/rollback-spec.js +0 -0
  187. package/dist/rollback.js +0 -0
  188. package/dist/rule-support.js +5 -11
  189. package/dist/rule-when.js +0 -0
  190. package/dist/runtime-support.js +0 -0
  191. package/dist/script.js +0 -0
  192. package/dist/server.js +92 -0
  193. package/dist/service-doctor.js +0 -0
  194. package/dist/session-manager.js +0 -0
  195. package/dist/session.js +12 -0
  196. package/dist/skills.js +12 -2
  197. package/dist/sqlite-warning-filter.js +0 -0
  198. package/dist/support.js +0 -0
  199. package/dist/token-cache.js +0 -0
  200. package/dist/tool-types.js +0 -0
  201. package/dist/tools.js +0 -0
  202. package/dist/usage-log.js +0 -0
  203. package/dist/wire.js +0 -0
  204. package/dist/workflow-support.js +0 -0
  205. package/dist/write-lease.js +0 -0
  206. package/dist/write-lock.js +0 -0
  207. package/dist/write.js +0 -0
  208. package/dist/zip.js +0 -0
  209. package/docs/images/omc-nixi/README.md +41 -41
  210. package/docs/omc-introduction.md +851 -851
  211. package/docs/tool-surface-map.md +42 -42
  212. package/package.json +4 -4
  213. package/skills/omc-acceptance-criteria.md +50 -50
  214. package/skills/omc-business-configuration.md +334 -334
  215. package/skills/omc-capabilities.md +214 -214
  216. package/skills/omc-capability-scouting.md +55 -55
  217. package/skills/omc-config-draft-review.md +175 -175
  218. package/skills/omc-five-piece-flow.md +35 -35
  219. package/skills/omc-glossary.md +86 -86
  220. package/skills/omc-refusals.md +127 -127
  221. package/skills/omc-requirement-analysis.md +161 -161
  222. package/skills/omc-requirement-vocabulary.md +61 -61
  223. package/skills/omc-start-here.md +106 -106
  224. package/skills/omc-tool-selection.md +119 -119
  225. package/skills/omc-write-hazards.md +200 -200
  226. package/dist/lanes/organization-coverage.js +0 -27
package/dist/graph.js CHANGED
@@ -452,30 +452,30 @@ export async function publishGraphPull(session, concurrency = DEFAULT_PULL_CONCU
452
452
  // D-state in folio_wait_bit_common). One transaction + memory journal
453
453
  // + synchronous=OFF makes the build effectively free.
454
454
  db.exec("PRAGMA journal_mode=MEMORY; PRAGMA synchronous=OFF;");
455
- db.exec(`BEGIN;
456
- CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);
457
- CREATE TABLE rules (
458
- schema_code TEXT NOT NULL,
459
- rule_code TEXT NOT NULL,
460
- name TEXT,
461
- enabled INTEGER,
462
- status TEXT,
463
- default_rule INTEGER,
464
- row_id TEXT NOT NULL,
465
- graph_sha256 TEXT NOT NULL,
466
- PRIMARY KEY (schema_code, rule_code)
467
- );
468
- CREATE TABLE edges (
469
- kind TEXT NOT NULL,
470
- code TEXT NOT NULL,
471
- schema_code TEXT NOT NULL,
472
- rule_code TEXT NOT NULL,
473
- node_code TEXT,
474
- node_type TEXT,
475
- via TEXT NOT NULL
476
- );
477
- CREATE INDEX edges_lookup ON edges(kind, code);
478
- CREATE TABLE gaps (kind TEXT NOT NULL, ref TEXT NOT NULL, note TEXT);
455
+ db.exec(`BEGIN;
456
+ CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);
457
+ CREATE TABLE rules (
458
+ schema_code TEXT NOT NULL,
459
+ rule_code TEXT NOT NULL,
460
+ name TEXT,
461
+ enabled INTEGER,
462
+ status TEXT,
463
+ default_rule INTEGER,
464
+ row_id TEXT NOT NULL,
465
+ graph_sha256 TEXT NOT NULL,
466
+ PRIMARY KEY (schema_code, rule_code)
467
+ );
468
+ CREATE TABLE edges (
469
+ kind TEXT NOT NULL,
470
+ code TEXT NOT NULL,
471
+ schema_code TEXT NOT NULL,
472
+ rule_code TEXT NOT NULL,
473
+ node_code TEXT,
474
+ node_type TEXT,
475
+ via TEXT NOT NULL
476
+ );
477
+ CREATE INDEX edges_lookup ON edges(kind, code);
478
+ CREATE TABLE gaps (kind TEXT NOT NULL, ref TEXT NOT NULL, note TEXT);
479
479
  `);
480
480
  const insertMeta = db.prepare("INSERT INTO meta (key, value) VALUES (?, ?)");
481
481
  for (const [key, value] of Object.entries(data.meta))
@@ -491,9 +491,9 @@ export async function publishGraphPull(session, concurrency = DEFAULT_PULL_CONCU
491
491
  insertGap.run(gap.kind, gap.ref, gap.note ?? null);
492
492
  // FTS5 mirrors rules (code+name) for `graph search`; one rebuild after
493
493
  // the bulk insert is cheaper than per-row triggers on a wholesale rebuild.
494
- db.exec(`
495
- CREATE VIRTUAL TABLE rules_fts USING fts5(rule_code, name, content='rules', content_rowid='rowid');
496
- INSERT INTO rules_fts(rules_fts) VALUES('rebuild');
494
+ db.exec(`
495
+ CREATE VIRTUAL TABLE rules_fts USING fts5(rule_code, name, content='rules', content_rowid='rowid');
496
+ INSERT INTO rules_fts(rules_fts) VALUES('rebuild');
497
497
  `);
498
498
  db.exec("COMMIT;");
499
499
  }
@@ -618,8 +618,8 @@ export function searchGraphRules(term, limit = 20) {
618
618
  if (tokens.length > 0) {
619
619
  const quoted = tokens.map((token, index) => `"${token.replaceAll('"', '""')}"${index === tokens.length - 1 ? "*" : ""}`).join(" ");
620
620
  const rows = db
621
- .prepare(`SELECT r.schema_code, r.rule_code, r.name, r.enabled, r.status
622
- FROM rules_fts JOIN rules r ON r.rowid = rules_fts.rowid
621
+ .prepare(`SELECT r.schema_code, r.rule_code, r.name, r.enabled, r.status
622
+ FROM rules_fts JOIN rules r ON r.rowid = rules_fts.rowid
623
623
  WHERE rules_fts MATCH ? ORDER BY bm25(rules_fts), r.schema_code, r.rule_code LIMIT ?`)
624
624
  .all(quoted, limit);
625
625
  const refsFor = db.prepare("SELECT kind, code FROM edges WHERE schema_code = ? AND rule_code = ? ORDER BY kind, code");
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
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
@@ -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
@@ -14,6 +14,7 @@ import { writeTool } from "../write.js";
14
14
  import { registerPackageTool } from "../package-tool.js";
15
15
  import { defineTool, ToolInputError, ToolRefusalError } from "../tool-types.js";
16
16
  import { wireCall, wireRows, WireError } from "../wire.js";
17
+ import { readModelRecord } from "../model-record.js";
17
18
  import { MODEL_CREATE_BODY_DEFAULTS, MODEL_LANE_CONTRACT } from "./model-contract.js";
18
19
  const MODEL_LANE = MODEL_LANE_CONTRACT.lane;
19
20
  const MODEL_TOOLS = MODEL_LANE_CONTRACT.tools;
@@ -48,7 +49,7 @@ function modelRollbackSpec(toolName) {
48
49
  target: (args) => `model:${String(args.schemaCode ?? args.code ?? "")}`,
49
50
  read: async (session, args) => {
50
51
  const resolved = await resolveModelTreeNode(session, String(args.schemaCode ?? args.code));
51
- const record = (await wireCall(session, { path: ENDPOINTS.modelGet, query: { schemaCode: String(args.schemaCode ?? args.code) } })).data;
52
+ const record = await readModelRecord(session, String(args.schemaCode ?? args.code));
52
53
  if (!resolved.node && !record)
53
54
  return null;
54
55
  return { node: resolved.node ?? null, record: record ?? null };
@@ -386,7 +387,7 @@ export function registerModelLane(tools) {
386
387
  // bizmodels/get_all is keyed by the query, so a non-null object IS the
387
388
  // model (an absent one answers a business errcode — wireCall throws and
388
389
  // we fall through to create).
389
- const record = (await wireCall(session, { path: ENDPOINTS.modelGet, query: { schemaCode: args.code } })).data;
390
+ const record = await readModelRecord(session, args.code);
390
391
  if (record !== null && typeof record === "object") {
391
392
  throw new ToolRefusalError({
392
393
  status: "refused",
@@ -461,7 +462,7 @@ export function registerModelLane(tools) {
461
462
  async function modelDeleteDryRun(session, args) {
462
463
  const record = await (async () => {
463
464
  try {
464
- return (await wireCall(session, { path: ENDPOINTS.modelGet, query: { schemaCode: args.schemaCode } })).data ?? null;
465
+ return readModelRecord(session, args.schemaCode);
465
466
  }
466
467
  catch (error) {
467
468
  if (error instanceof WireError && error.kind === "business")
@@ -510,17 +511,7 @@ export function registerModelLane(tools) {
510
511
  writeTool(tools, "model.delete", MODEL_LANE, MODEL_TOOLS["model.delete"].scope, MODEL_TOOLS["model.delete"].description, { schemaCode: z.string().min(1), applicationCode: z.string().optional() }, async (session, args) => {
511
512
  // authoritative model record (bizmodels/get_all); the app-tree node id
512
513
  // may lag behind and is cleaned best-effort.
513
- const readRecord = async () => {
514
- try {
515
- const result = await wireCall(session, { path: ENDPOINTS.modelGet, query: { schemaCode: args.schemaCode } });
516
- return result.data ?? null;
517
- }
518
- catch (error) {
519
- if (error instanceof WireError && error.kind === "business")
520
- return null;
521
- throw error;
522
- }
523
- };
514
+ const readRecord = () => readModelRecord(session, args.schemaCode);
524
515
  const record = await readRecord();
525
516
  // Ticket 68: resolve the app-tree node across applications (the tree row
526
517
  // id IS the AppFunction id physically_delete needs). Never fall back to
@@ -673,17 +664,7 @@ export function registerModelLane(tools) {
673
664
  // every existing model in that single request after prechecking each
674
665
  // target's inbound references — a referenced model refuses the whole
675
666
  // batch with per-target evidence and ZERO side effects.
676
- const readRecord = async (schemaCode) => {
677
- try {
678
- const result = await wireCall(session, { path: ENDPOINTS.modelGet, query: { schemaCode } });
679
- return result.data ?? null;
680
- }
681
- catch (error) {
682
- if (error instanceof WireError && error.kind === "business")
683
- return null;
684
- throw error;
685
- }
686
- };
667
+ const readRecord = (schemaCode) => readModelRecord(session, schemaCode);
687
668
  const applicationCode = await resolveApplicationCode(session, args.applicationCode).catch(() => "");
688
669
  const targets = [...new Set(args.schemaCodes)];
689
670
  const alreadyAbsent = [];
@@ -885,8 +866,10 @@ export function registerModelLane(tools) {
885
866
  // NOT migrated by this endpoint (probe evidence).
886
867
  const after = await resolveModelTreeNode(session, args.schemaCode);
887
868
  const nodeAfter = after.node;
888
- const record = await wireCall(session, { path: ENDPOINTS.modelGet, query: { schemaCode: args.schemaCode } });
889
- const recordName = (record.data ?? {}).name ?? null;
869
+ // Informational only: the app-tree node is the authoritative face for a
870
+ // rename, so an unreadable record face must not fail the whole call.
871
+ const record = await readModelRecord(session, args.schemaCode).catch(() => null);
872
+ const recordName = record?.name ?? null;
890
873
  const nodeName = typeof nodeAfter?.name === "string" ? nodeAfter.name : null;
891
874
  return {
892
875
  performed: { errcode: performed.errcode },
@@ -1120,8 +1103,9 @@ export function registerModelLane(tools) {
1120
1103
  for (const row of wireRows((await wireCall(session, { path: ENDPOINTS.fieldList, query: { schemaCode: args.code, isPublish } })).data))
1121
1104
  existingFields.set(String(row.code ?? row.propertyCode ?? ""), row);
1122
1105
  }
1106
+ const configureTargetVersion = session.detectedVersion();
1123
1107
  for (const entry of entries) {
1124
- const input = fieldChangeInputOf(args.code, entry);
1108
+ const input = fieldChangeInputOf(args.code, entry, configureTargetVersion);
1125
1109
  failed = await run(results.length, "field.create", async () => {
1126
1110
  const existing = existingFields.get(entry.code);
1127
1111
  if (existing !== undefined) {
@@ -1237,12 +1221,13 @@ function fieldEntriesOf(args) {
1237
1221
  assertFieldFamilyAllowed(legacy);
1238
1222
  return [legacy];
1239
1223
  }
1240
- function fieldChangeInputOf(schemaCode, entry) {
1224
+ function fieldChangeInputOf(schemaCode, entry, targetVersion) {
1241
1225
  return {
1242
1226
  schemaCode,
1243
1227
  code: entry.code,
1244
1228
  name: entry.name,
1245
1229
  propertyType: entry.propertyType,
1230
+ ...(targetVersion ? { targetVersion } : {}),
1246
1231
  ...(entry.options ? { options: entry.options } : {}),
1247
1232
  ...(entry.choices ? { choices: entry.choices } : {}),
1248
1233
  ...(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
@@ -27,6 +27,7 @@ import { CLI_EXIT_CODES, classifyResult, envelope, refusalText, requestId } from
27
27
  import { writeEnvelope } from "./cli-output.js";
28
28
  import { ENDPOINTS } from "./endpoints.js";
29
29
  import { wireCall, wireRows } from "./wire.js";
30
+ import { readModelRecord } from "./model-record.js";
30
31
  import { SessionManager } from "./session-manager.js";
31
32
  import { ConfigStore, defaultPaths } from "./config-store.js";
32
33
  async function sessionFor(environment) {
@@ -43,8 +44,7 @@ export async function planPurge(options, injected) {
43
44
  const session = injected ?? (await sessionFor(options.environment));
44
45
  let modelExists = true;
45
46
  try {
46
- const record = (await wireCall(session, { path: ENDPOINTS.modelGet, query: { schemaCode: options.schemaCode } })).data;
47
- modelExists = record !== null && record !== undefined;
47
+ modelExists = (await readModelRecord(session, options.schemaCode)) !== null;
48
48
  }
49
49
  catch {
50
50
  modelExists = false;
@@ -0,0 +1,40 @@
1
+ import { ENDPOINTS } from "./endpoints.js";
2
+ import { wireCall, wireRows, WireError } from "./wire.js";
3
+ /**
4
+ * Authoritative biz-model record, across platform versions.
5
+ *
6
+ * 8.6 serves `/api/api/app/bizmodels/get_all` (BizSchemaController resolves
7
+ * getBizSchemaBySchemaCode and answers 10011 on a miss). 8.0/8.1 deployments
8
+ * answer **HTTP 404** for that path (field report 2026-10-30, 8.1.108 /
9
+ * 上海电建) and expose the same rows through `/bizmodels/list_schema`, filtered
10
+ * by `schemaCode`. Pinning the 8.6 path made model.*, rule.* and the purge
11
+ * precheck die with a raw 404 before any of their own logic ran.
12
+ *
13
+ * Reads the primary face first; only a 404 (endpoint absent) falls back, so a
14
+ * genuine 401/500/transport failure still surfaces as itself. Returns null when
15
+ * the model is not there (business "not found" on either face).
16
+ */
17
+ export async function readModelRecord(session, schemaCode) {
18
+ try {
19
+ const result = await wireCall(session, { path: ENDPOINTS.modelGet, query: { schemaCode } });
20
+ return result.data ?? null;
21
+ }
22
+ catch (error) {
23
+ if (error instanceof WireError && error.kind === "business")
24
+ return null;
25
+ const endpointAbsent = error instanceof WireError && error.kind === "http-status" && error.diagnostic?.httpStatus === 404;
26
+ if (!endpointAbsent)
27
+ throw error;
28
+ }
29
+ try {
30
+ const rows = wireRows((await wireCall(session, { path: ENDPOINTS.modelList, query: { schemaCode } })).data);
31
+ const match = rows.find((row) => String(row.schemaCode ?? row.code ?? "") === schemaCode);
32
+ return match ?? null;
33
+ }
34
+ catch (error) {
35
+ if (error instanceof WireError && error.kind === "business")
36
+ return null;
37
+ throw error;
38
+ }
39
+ }
40
+ //# sourceMappingURL=model-record.js.map
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes