@stalfh233/omc-cli 0.4.13 → 0.4.15

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/README.md CHANGED
@@ -246,12 +246,12 @@ src/ args/support/plan/read/write/package/context(治理管道)
246
246
 
247
247
  ## npm 分发
248
248
 
249
- 本包(`@stalfh233/omc-cli`,可执行命令仍是 `omc`)通过公共 npm registry 分发。`omc-core` 是 `omc-cli` 的内部依赖,发布时先发 `omc-core`,再发 `omc-cli`;两者版本保持一致。当前版本为 `0.4.13`,尚未宣称 `1.0.0` 稳定契约。
249
+ 本包(`@stalfh233/omc-cli`,可执行命令仍是 `omc`)通过公共 npm registry 分发。`omc-core` 是 `omc-cli` 的内部依赖,发布时先发 `omc-core`,再发 `omc-cli`;两者版本保持一致。当前版本为 `0.4.15`,尚未宣称 `1.0.0` 稳定契约。
250
250
 
251
251
  ### 使用已发布包
252
252
 
253
253
  ```bash
254
- npm install -g @stalfh233/omc-cli@0.4.13
254
+ npm install -g @stalfh233/omc-cli@0.4.15
255
255
  omc setup
256
256
  omc doctor
257
257
  omc help omc-write-hazards
@@ -272,7 +272,7 @@ npm publish --workspace packages/omc-cli
272
272
 
273
273
  ### 输出编码
274
274
 
275
- stdout 是机器解析的 JSON:Windows 上默认把非 ASCII 转义成 `\uXXXX`(纯 ASCII,在 GBK 控制台也不会乱码,等价于 Python `json.dumps(ensure_ascii=True)`),Linux/macOS 保持原始 UTF-8。UTF-8 终端想要可读中文时设 `OMC_ASCII_STDOUT=0`。`--out` 文件、artifact、stderr、CloudPivot 请求体始终是原始 UTF-8。
275
+ stdout 是机器解析的 JSON,编码按消费方选择:**终端**(`isTTY`)写原始 UTF-8(Windows 上 Node 走 `WriteConsoleW`,中文正常显示);**管道/重定向/捕获**写 ASCII 安全 JSON(非 ASCII 转义成 `\uXXXX`,任何代码页都能正确解析,等价于 Python `json.dumps(ensure_ascii=True)`)。Linux/macOS 始终原始 UTF-8;`--out` 文件、artifact、stderr、CloudPivot 请求体始终原始 UTF-8。强制用 `OMC_ASCII_STDOUT=1|0`。
276
276
 
277
277
  ### 版本策略
278
278
 
@@ -13,21 +13,24 @@ export function envelope(status, result, requestId, error = null) {
13
13
  /**
14
14
  * The single stdout serialization for every envelope.
15
15
  *
16
- * stdout is machine-parsed JSON, so it must decode identically for ANY consumer
17
- * regardless of the ambient console code page. On zh-CN Windows the console is
18
- * GBK (cp936), and a native process's bytes are decoded with that code page — by
19
- * the terminal for direct output, and by PowerShell's `[Console]::OutputEncoding`
20
- * for `$x = omc …` / `omc … > f` / `omc … | …`. Raw UTF-8 Chinese is mangled
21
- * there (verified on Windows PowerShell 5.1 AND PowerShell 7.6). Escaping every
22
- * non-ASCII code unit to `\uXXXX` makes stdout pure ASCII, so it survives any
23
- * code page and still `JSON.parse`s back to the original string. This is the
24
- * same conservative default as Python's `json.dumps(ensure_ascii=True)`.
16
+ * Encoding is chosen by the CONSUMER, because "correct" differs by context:
25
17
  *
26
- * Escaping is ON by default only on win32; POSIX keeps its smaller raw UTF-8
27
- * bytes. Override with `OMC_ASCII_STDOUT=1|0` (set `0` on a UTF-8 terminal to
28
- * get readable Chinese). `--out` files, artifacts, stderr, and the CloudPivot
29
- * wire stay raw UTF-8 — they are not a code-page-bound console stream. See
30
- * `CONTEXT.md` → Agent-facing CLI.
18
+ * - A real terminal (stdout.isTTY) renders UTF-8 correctly on Windows: Node
19
+ * writes UTF-16 through the console API (WriteConsoleW), which bypasses the
20
+ * console code page entirely. So there we emit raw UTF-8 and a human sees
21
+ * readable Chinese.
22
+ * - A PIPE / redirect / capture (not a TTY) is decoded by the consumer with its
23
+ * own ambient code page. On zh-CN Windows that is GBK (cp936) and raw UTF-8 is
24
+ * mangled by the terminal AND by PowerShell's `[Console]::OutputEncoding`
25
+ * (verified on Windows PowerShell 5.1 and PowerShell 7.6) for `$x = omc …`,
26
+ * `omc … > f`, and the `.ps1` shim pipe. There we escape every non-ASCII code
27
+ * unit to `\uXXXX`: stdout stays pure ASCII, survives any code page, and
28
+ * still `JSON.parse`s back to the original string — the same conservative
29
+ * default as Python's `json.dumps(ensure_ascii=True)`.
30
+ *
31
+ * POSIX always keeps raw UTF-8. `OMC_ASCII_STDOUT=1|0` forces either mode. `--out`
32
+ * files, artifacts, stderr, and the CloudPivot wire stay raw UTF-8 — they are
33
+ * not a code-page-bound console stream. See `CONTEXT.md` → Agent-facing CLI.
31
34
  */
32
35
  export function asciiStdout() {
33
36
  const override = process.env.OMC_ASCII_STDOUT;
@@ -35,7 +38,9 @@ export function asciiStdout() {
35
38
  return true;
36
39
  if (override === "0")
37
40
  return false;
38
- return process.platform === "win32";
41
+ if (process.platform !== "win32")
42
+ return false;
43
+ return process.stdout.isTTY !== true;
39
44
  }
40
45
  export function serializeEnvelope(value) {
41
46
  const json = JSON.stringify(value);
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createInterface } from "node:readline/promises";
3
3
  import { stdin, argv } from "node:process";
4
+ import { createRequire } from "node:module";
4
5
  import { Command, CommanderError } from "commander";
5
6
  import { ConfigStore, defaultPaths, removedProfileKeys } from "./config-store.js";
6
7
  import { loadCoverageManifest, versionFamilyNotice } from "./coverage.js";
@@ -1309,6 +1310,15 @@ async function main() {
1309
1310
  let commandExitCode = 0;
1310
1311
  beginUsage(argv);
1311
1312
  const command = new Command();
1313
+ const ownPackageVersion = () => {
1314
+ try {
1315
+ // ESM 下读自身包根的 package.json(安装形态与源码形态都成立)
1316
+ return String(createRequire(import.meta.url)("../package.json").version);
1317
+ }
1318
+ catch {
1319
+ return "unknown";
1320
+ }
1321
+ };
1312
1322
  try {
1313
1323
  configureOutput(argv);
1314
1324
  }
@@ -1320,6 +1330,13 @@ async function main() {
1320
1330
  command.exitOverride();
1321
1331
  command.configureOutput({ writeOut: (text) => process.stderr.write(text), writeErr: (text) => process.stderr.write(text) });
1322
1332
  command.name("omc").showHelpAfterError().showSuggestionAfterError(true);
1333
+ // --version 短路:commander 的 version 走 process.exit,会被 exitOverride 包成
1334
+ // invalid-input 信封(exit 10);cpdocs --omc-global 的探测要干净的 exit 0。
1335
+ const bare = argv.slice(2).filter((a) => a !== "--");
1336
+ if (bare.includes("--version") || bare.includes("-V")) {
1337
+ process.stdout.write(`${ownPackageVersion()}\n`);
1338
+ return 0;
1339
+ }
1323
1340
  command.addHelpText("after", `\n${onboardingHelp()}\n`);
1324
1341
  // No command at all: guide the agent (help text + onboarding), exit 0. This
1325
1342
  // is a benign "show me the surface" invocation, not a failure.
@@ -1388,7 +1405,9 @@ function finish(code) {
1388
1405
  }
1389
1406
  const request = requestId();
1390
1407
  main().then((code) => {
1391
- if (argv[2] === "call" || argv[2] === "artifact" || argv[2] === "commands" || argv[2] === "describe" || argv[2] === "contract" || argv[2] === "capabilities" || argv[2] === "capability" || argv[2] === "next" || argv[2] === "usage" || argv[2] === "intent" || argv[2] === "help") {
1408
+ // Commands that own their stdout never grow a trailing envelope. `--version`/
1409
+ // `-V` are here because their short-circuit already wrote the bare version.
1410
+ if (argv[2] === "call" || argv[2] === "artifact" || argv[2] === "commands" || argv[2] === "describe" || argv[2] === "contract" || argv[2] === "capabilities" || argv[2] === "capability" || argv[2] === "next" || argv[2] === "usage" || argv[2] === "intent" || argv[2] === "help" || argv[2] === "--version" || argv[2] === "-V") {
1392
1411
  completeUsage(code);
1393
1412
  finish(code);
1394
1413
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stalfh233/omc-cli",
3
- "version": "0.4.13",
3
+ "version": "0.4.15",
4
4
  "description": "CloudPivot 8.6 configuration capability CLI — governed, fail-closed, coverage-manifest bounded.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "commander": "14.0.3",
54
- "omc-core": "0.4.13",
54
+ "omc-core": "0.4.15",
55
55
  "proper-lockfile": "4.1.2",
56
56
  "write-file-atomic": "6.0.0",
57
57
  "zod": "^3.23.8",