@stalfh233/omc-cli 0.4.38 → 0.4.40
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.
- package/dist/cli.js +35 -12
- package/dist/execution-metadata.js +4 -3
- package/dist/lanes/field.js +3 -1
- package/dist/lanes/runtime-data.js +1 -1
- package/dist/recipes/runtime-data.js +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// T04:SQLite 警告过滤器必须保持第一个 import(先于任何拉起 omc-core/node:sqlite 的模块)。
|
|
3
3
|
import "./sqlite-warning-filter.js";
|
|
4
|
+
import { spawnSync } from "node:child_process";
|
|
4
5
|
import { createInterface } from "node:readline/promises";
|
|
5
6
|
import { stdin, argv } from "node:process";
|
|
6
7
|
import { createRequire } from "node:module";
|
|
@@ -113,6 +114,23 @@ async function cmdDoctor(store, environment, serviceCode) {
|
|
|
113
114
|
const manifest = loadCoverageManifest();
|
|
114
115
|
const steps = [];
|
|
115
116
|
let ok = true;
|
|
117
|
+
// r45 Windows 实测:PowerShell 管道按 GBK(936) 解码 CLI 的 UTF-8 输出 → 全屏乱码,
|
|
118
|
+
// 且用户常误判为「OMC 输出坏了」。doctor 是入口体检,顺手检测活动代码页。
|
|
119
|
+
if (process.platform === "win32") {
|
|
120
|
+
try {
|
|
121
|
+
const chcp = spawnSync("chcp.com", [], { encoding: "utf8" });
|
|
122
|
+
const active = /([0-9]{3,5})\s*$/.exec((chcp.stdout || "").trim().split("\n").pop() ?? "")?.[1];
|
|
123
|
+
if (active && active !== "65001") {
|
|
124
|
+
steps.push(`编码 ⚠ 活动代码页 ${active}(非 65001)——PowerShell 管道会把 CLI 的 UTF-8 中文输出解成乱码;这是终端解码问题不是 OMC 故障。先 \`chcp 65001\` + \`[Console]::OutputEncoding=[Text.Encoding]::UTF8\` 再读 CLI 输出`);
|
|
125
|
+
}
|
|
126
|
+
else if (active === "65001") {
|
|
127
|
+
steps.push("编码 ok 活动代码页 65001(UTF-8,中文输出无乱码风险)");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// chcp 不可用(非传统控制台等)——跳过,不阻塞体检
|
|
132
|
+
}
|
|
133
|
+
}
|
|
116
134
|
try {
|
|
117
135
|
const resolved = store.resolveEnvironment(environment);
|
|
118
136
|
steps.push(`配置 ok 环境=${resolved.name}(来源 ${resolved.source})`);
|
|
@@ -367,32 +385,35 @@ function resolvedDefaultEnvironment(store) {
|
|
|
367
385
|
return "default";
|
|
368
386
|
}
|
|
369
387
|
}
|
|
370
|
-
/**
|
|
371
|
-
* Bounded JSON-path projection for `artifact get --jq`. Supports dotted
|
|
372
|
-
* (`content.activities.0.name`) and slashed (`content/activities/0/name`)
|
|
373
|
-
* segments. Not a general jq: a path walk only, so it can never evaluate code.
|
|
374
|
-
*/
|
|
375
388
|
function projectJsonPath(value, path) {
|
|
376
|
-
const
|
|
389
|
+
const normalized = path
|
|
390
|
+
.trim()
|
|
391
|
+
.replace(/^[.\/]+/, "")
|
|
392
|
+
.replace(/\[(\d+)\]/g, ".$1")
|
|
393
|
+
.replace(/\[(?:"([^"]+)"|'([^']+)')\]/g, (_all, dq, sq) => `.${dq || sq}`)
|
|
394
|
+
.replace(/\.{2,}/g, ".");
|
|
395
|
+
const segments = normalized.split(/[./]/).filter((segment) => segment.length > 0);
|
|
377
396
|
let current = value;
|
|
378
397
|
for (const segment of segments) {
|
|
379
398
|
if (Array.isArray(current)) {
|
|
380
399
|
const index = Number(segment);
|
|
381
400
|
if (!Number.isInteger(index) || index < 0 || index >= current.length)
|
|
382
|
-
return
|
|
401
|
+
return { missed: true, at: segment, available: `数组长度 ${current.length}(下标 0-${Math.max(current.length - 1, 0)})` };
|
|
383
402
|
current = current[index];
|
|
384
403
|
}
|
|
385
404
|
else if (current && typeof current === "object") {
|
|
386
405
|
const record = current;
|
|
387
|
-
if (!Object.prototype.hasOwnProperty.call(record, segment))
|
|
388
|
-
|
|
406
|
+
if (!Object.prototype.hasOwnProperty.call(record, segment)) {
|
|
407
|
+
const keys = Object.keys(record);
|
|
408
|
+
return { missed: true, at: segment, available: keys.length > 0 ? keys.slice(0, 12) : "(该层是空对象)" };
|
|
409
|
+
}
|
|
389
410
|
current = record[segment];
|
|
390
411
|
}
|
|
391
412
|
else {
|
|
392
|
-
return undefined;
|
|
413
|
+
return { missed: true, at: segment, available: `路径在第 ${segments.indexOf(segment) + 1} 段之前已到标量/undefined(前段类型 ${current === null ? "null" : typeof current})` };
|
|
393
414
|
}
|
|
394
415
|
}
|
|
395
|
-
return current;
|
|
416
|
+
return { missed: false, value: current };
|
|
396
417
|
}
|
|
397
418
|
async function cmdArtifactGet(id, transport, options = {}) {
|
|
398
419
|
try {
|
|
@@ -443,7 +464,9 @@ async function cmdArtifactGet(id, transport, options = {}) {
|
|
|
443
464
|
}
|
|
444
465
|
if (options.jq !== undefined) {
|
|
445
466
|
const projected = projectJsonPath(artifact.content.toString("utf8") === "" ? undefined : content, options.jq);
|
|
446
|
-
return emitTransportResult(
|
|
467
|
+
return emitTransportResult(projected.missed
|
|
468
|
+
? { status: "ok", artifactId: id, sha256: artifact.sha256, path: options.jq, content: null, pathMiss: true, missedAt: projected.at, available: projected.available, hint: `路径未命中段 "${projected.at}"——available 是该层可用的键/范围;方括号下标(a[0])与点式(a.0)等价` }
|
|
469
|
+
: { status: "ok", artifactId: id, sha256: artifact.sha256, path: options.jq, content: projected.value ?? null }, transport);
|
|
447
470
|
}
|
|
448
471
|
const result = { status: "ok", artifactId: id, sha256: artifact.sha256, content };
|
|
449
472
|
if (Buffer.byteLength(JSON.stringify(result), "utf8") > transport.maxOutputBytes)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
// 配方按 lane 分居维护(src/recipes/<lane>.ts
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// 配方按 lane 分居维护(src/recipes/<lane>.ts);本文件是聚合接缝:按 lane 分组顺序
|
|
2
|
+
// 合并(非原中央表字面量序——已核实全仓零 Object.keys/entries 枚举消费者,消费方一律
|
|
3
|
+
// 按工具名查找,键序无行为影响),并在模块加载时对重复工具键 fail-fast
|
|
4
|
+
// (lane 各自注册后静默覆盖是拆分最大风险)。
|
|
4
5
|
import { MODEL_METADATA } from "./recipes/model.js";
|
|
5
6
|
import { FORM_METADATA } from "./recipes/form.js";
|
|
6
7
|
import { FIELD_METADATA } from "./recipes/field.js";
|
package/dist/lanes/field.js
CHANGED
|
@@ -135,7 +135,9 @@ export function registerFieldLane(tools) {
|
|
|
135
135
|
});
|
|
136
136
|
return {
|
|
137
137
|
schemaCode: args.schemaCode,
|
|
138
|
-
|
|
138
|
+
// r45: 这是"本次查询的面选择器"回显(draft/published),不是字段发布状态——
|
|
139
|
+
// 曾被误读为"字段未发布"。改名 face 消歧义;要查发布态用 field.publish 回读或详情面。
|
|
140
|
+
face: args.published === true ? "published" : "draft",
|
|
139
141
|
...(selector.length > 0 ? { selected: selector } : {}),
|
|
140
142
|
...(args.all !== true ? { businessOnly: true } : {}),
|
|
141
143
|
fields: projected,
|
|
@@ -524,7 +524,7 @@ export function registerRuntimeDataLane(tools) {
|
|
|
524
524
|
inputSchema: {
|
|
525
525
|
environment: environmentArg,
|
|
526
526
|
schemaCode: z.string(),
|
|
527
|
-
bizObjectId: z.string({ required_error: "bizObjectId
|
|
527
|
+
bizObjectId: z.string({ required_error: "bizObjectId 必填(参数名就是 bizObjectId——不是 id 也不是 objectId,r44 两个 agent 都猜了 objectId;取值来自 data.submit 读回的 objectId/sequenceNo 或 data.list 的 row.bizObjectId)" }),
|
|
528
528
|
full: z.boolean().optional().describe("返回未裁剪的完整业务对象(含 owner/creater 等系统字段;默认返回业务字段+身份的精简记录)"),
|
|
529
529
|
capability: capabilityArg,
|
|
530
530
|
},
|
|
@@ -38,7 +38,7 @@ const plainSubmit = Object.freeze({
|
|
|
38
38
|
{ code: "submit-biz-object-absent", action: "bizObjectId 在平台无行(304001)——回 data.save 重建草稿后再直提" },
|
|
39
39
|
{ code: "invalid-input", action: "带了 workItemId/workflowInstanceId 时必须同时带 bizObjectId(fail-closed)" },
|
|
40
40
|
],
|
|
41
|
-
notes: "r23 复盘修正:本配方曾教先 save 再 submit 两步——正确路径是无 id 一调(业务约定:正式数据一律 data.submit)。Create/Update 规则只在 COMPLETED 分发(DomainServiceImpl.java:240-248);规则效果以提交读回/data.load
|
|
41
|
+
notes: "r23 复盘修正:本配方曾教先 save 再 submit 两步——正确路径是无 id 一调(业务约定:正式数据一律 data.submit)。Create/Update 规则只在 COMPLETED 分发(DomainServiceImpl.java:240-248);规则效果以提交读回/data.load 为准(data.load 参数名=bizObjectId,直接用提交读回的 objectId)。data.save 定位=草稿/暂存",
|
|
42
42
|
requiresEnvironmentDerivedIds: true,
|
|
43
43
|
});
|
|
44
44
|
const workflowSubmit = Object.freeze({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stalfh233/omc-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.40",
|
|
4
4
|
"description": "CloudPivot 8.6 configuration capability CLI — governed, fail-closed, coverage-manifest bounded.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@stalfh233/omc-fake-platform": "0.4.
|
|
53
|
+
"@stalfh233/omc-fake-platform": "0.4.40",
|
|
54
54
|
"commander": "14.0.3",
|
|
55
|
-
"omc-core": "0.4.
|
|
55
|
+
"omc-core": "0.4.40",
|
|
56
56
|
"proper-lockfile": "4.1.2",
|
|
57
57
|
"write-file-atomic": "6.0.0",
|
|
58
58
|
"zod": "^3.23.8",
|