@stalfh233/omc-cli 0.6.4 → 0.6.5
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-contract.js +18 -2
- package/dist/support.js +2 -2
- package/dist/tool-types.js +24 -1
- package/package.json +3 -3
package/dist/cli-contract.js
CHANGED
|
@@ -272,15 +272,31 @@ export function classifyResult(result) {
|
|
|
272
272
|
const suffix = candidates.length > 0 ? `;did you mean: ${candidates.join("、")}` : ";用 `omc commands --json --compact --lane <lane>` 或 `omc next` 定位工具";
|
|
273
273
|
return { status: "error", error: withNext({ code: "invalid-input", message: `unknown tool ${String(result.tool ?? "")}${suffix}`, retryable: false }), exitCode: CLI_EXIT_CODES.invalidInput };
|
|
274
274
|
}
|
|
275
|
-
|
|
275
|
+
// r25 探针实证(2026-11-04):`blocker: "invalid-input"` 有 8 处产出点
|
|
276
|
+
// (workflow/runtime-data/compound-writes),但这里只认 `tool-input-*`——于是
|
|
277
|
+
// 它们全落到函数末尾的 internal 分支:`error.code=internal` + exit 15,被调用方
|
|
278
|
+
// 读成"CLI 内部故障",而实际是**自己传错了参数**(探针原话:
|
|
279
|
+
// 「rejected ✓, but error.code=internal (should be invalid-input), and no nextCommand」)。
|
|
280
|
+
// 入参形状错误一律 exit 10,并给出下一步。
|
|
281
|
+
const inputShapeBlocker = result.blocker === "tool-input-invalid"
|
|
282
|
+
|| result.blocker === "tool-input-unknown-keys"
|
|
283
|
+
|| result.blocker === "invalid-input";
|
|
284
|
+
if (inputShapeBlocker) {
|
|
285
|
+
// `invalid-input` 也可能是 CLI 层参数校验(compound-writes 的 --schema 必填),
|
|
286
|
+
// 那时没有 tool 字段——别硬拼一条指向不存在的工具的 describe。
|
|
287
|
+
const toolName = typeof result.tool === "string" && result.tool ? result.tool : undefined;
|
|
288
|
+
const nextCommand = typeof result.nextCommand === "string"
|
|
289
|
+
? result.nextCommand
|
|
290
|
+
: toolName !== undefined ? `omc describe ${toolName}` : undefined;
|
|
276
291
|
return {
|
|
277
292
|
status: "error",
|
|
278
293
|
error: {
|
|
279
294
|
...withNext({ code: "invalid-input", message: String(result.message ?? "tool input is invalid"), retryable: false }),
|
|
280
|
-
nextCommand
|
|
295
|
+
...(nextCommand !== undefined ? { nextCommand } : {}),
|
|
281
296
|
},
|
|
282
297
|
exitCode: CLI_EXIT_CODES.invalidInput,
|
|
283
298
|
};
|
|
299
|
+
}
|
|
284
300
|
if (status === "uncertain")
|
|
285
301
|
return { status, error: withNext({ code: "uncertain", message: String(result.message ?? result.reason ?? "outcome is uncertain"), retryable: true }), exitCode: CLI_EXIT_CODES.uncertain };
|
|
286
302
|
if (status === "refused") {
|
package/dist/support.js
CHANGED
|
@@ -126,8 +126,8 @@ export function applicationScopeHint(scope, noun) {
|
|
|
126
126
|
export function applicationScopeNotice(scope) {
|
|
127
127
|
const count = scope.applicationCount ?? 1;
|
|
128
128
|
const where = scope.source === "first-tenant-application" && count > 1
|
|
129
|
-
?
|
|
130
|
-
:
|
|
129
|
+
? `租户首个应用「${scope.code}」(租户共 ${count} 个应用)`
|
|
130
|
+
: `应用「${scope.code}」`;
|
|
131
131
|
return `本次只在${where}内扫描(source=${scope.source})——结果被应用边界裁剪,不代表租户全集;跨应用先 app.list 取 applicationCode 再传 applicationCode。`;
|
|
132
132
|
}
|
|
133
133
|
export function flattenTreeRows(rows) {
|
package/dist/tool-types.js
CHANGED
|
@@ -50,6 +50,23 @@ const KEY_SYNONYMS = Object.freeze({
|
|
|
50
50
|
code: ["schemaCode", "sheetCode", "workflowCode"],
|
|
51
51
|
ruleCode: ["code"],
|
|
52
52
|
});
|
|
53
|
+
/**
|
|
54
|
+
* r25 沙盒实证(2026-11-04):探针给 `configure_form` 传了 `publish:true`,
|
|
55
|
+
* 得到「未知键 publish。最接近的合法键:publish→(无相近键)」——写面 fail-closed
|
|
56
|
+
* 是对的,但**意图没被接住**:配置与发布本来就是两步,用户真正要的是
|
|
57
|
+
* `form.publish`。同类还有「配完字段就发布」(`field.publish`)与
|
|
58
|
+
* 「配完列表视图」(无需发布)。这里按工具给出可执行的两步指引,
|
|
59
|
+
* 比「无相近键」有用得多;代价是探针少花一轮(21→22 实测)。
|
|
60
|
+
*/
|
|
61
|
+
const TWO_STEP_GUIDANCE = Object.freeze({
|
|
62
|
+
configure_form: Object.freeze({
|
|
63
|
+
publish: "表单的配置与发布是两步:本工具只写草稿,发布用 `omc call form.publish --args '{\"schemaCode\":\"<模型>\",\"sheetCode\":\"<槽位>\"}'`(也可在本工具的成功回执后紧接着跑)。",
|
|
64
|
+
publishNow: "同上:本工具不负责发布,用 `omc call form.publish`。",
|
|
65
|
+
}),
|
|
66
|
+
configure_model: Object.freeze({
|
|
67
|
+
publish: "模型/字段的配置与发布是两步:字段建好后用 `omc call field.publish --args '{\"schemaCode\":\"<模型>\"}'` 发布;模型本身不需要单独发布。",
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
53
70
|
/**
|
|
54
71
|
* Per-tool input aliases: a synonym the caller may send INSTEAD of the canonical
|
|
55
72
|
* key. Applied in `parseToolInput` BEFORE validation (fill canonical from an
|
|
@@ -152,11 +169,17 @@ export function parseToolInput(tool, input) {
|
|
|
152
169
|
const unknown = Object.keys(normalized).filter((key) => !schemaKeys.has(key));
|
|
153
170
|
if (unknown.length > 0) {
|
|
154
171
|
const suggestions = unknown.map((key) => `${key}→${closestSchemaKey(key, schemaKeys) ?? "(无相近键,omc describe <tool> 看参数表)"}`);
|
|
172
|
+
// r25 实证:`publish→(无相近键)` 等于没说——配置与发布是两步,用户要的是
|
|
173
|
+
// 另一个工具。有语义指引时优先给可执行的下一步。
|
|
174
|
+
const twoStep = unknown
|
|
175
|
+
.map((key) => TWO_STEP_GUIDANCE[tool.name]?.[key])
|
|
176
|
+
.filter((hint) => typeof hint === "string" && hint.length > 0);
|
|
155
177
|
throw new ToolInputError({
|
|
156
178
|
status: "error",
|
|
157
179
|
blocker: "tool-input-unknown-keys",
|
|
158
180
|
tool: tool.name,
|
|
159
|
-
message: `写面工具不接受未知键(会被静默丢弃):${unknown.join("、")}
|
|
181
|
+
message: `写面工具不接受未知键(会被静默丢弃):${unknown.join("、")}。${twoStep.length > 0 ? twoStep.join(" ") : `最接近的合法键:${suggestions.join(";")}。参数表:omc describe ${tool.name}`}`,
|
|
182
|
+
...(twoStep.length > 0 ? { nextCommand: `omc describe ${tool.name}` } : {}),
|
|
160
183
|
issues: unknown.map((key) => ({ path: [key], code: "unrecognized_key", message: `unknown key; closest: ${closestSchemaKey(key, schemaKeys) ?? "none"}` })),
|
|
161
184
|
});
|
|
162
185
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stalfh233/omc-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "CloudPivot 8.6 configuration capability CLI — governed, fail-closed, coverage-manifest bounded.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"access": "public"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@stalfh233/omc-fake-platform": "0.6.
|
|
55
|
+
"@stalfh233/omc-fake-platform": "0.6.5",
|
|
56
56
|
"commander": "14.0.3",
|
|
57
|
-
"omc-core": "0.6.
|
|
57
|
+
"omc-core": "0.6.5",
|
|
58
58
|
"proper-lockfile": "4.1.2",
|
|
59
59
|
"write-file-atomic": "6.0.0",
|
|
60
60
|
"zod": "^3.23.8",
|