@cnwenf/occ 2.1.338 → 2.1.339

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 (3) hide show
  1. package/README.md +5 -5
  2. package/dist/cli.js +74 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![npm version](https://img.shields.io/npm/v/@cnwenf/occ.svg)](https://www.npmjs.com/package/@cnwenf/occ)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
7
7
  [![Runtime: Bun](https://img.shields.io/badge/Runtime-Bun-%23000000.svg)](https://bun.sh/)
8
- [![Tracks: Claude Code 2.1.273](https://img.shields.io/badge/Tracks-Claude%20Code%202.1.273-blueviolet.svg)](https://docs.anthropic.com/en/docs/claude-code)
8
+ [![Tracks: Claude Code 2.1.274](https://img.shields.io/badge/Tracks-Claude%20Code%202.1.274-blueviolet.svg)](https://docs.anthropic.com/en/docs/claude-code)
9
9
 
10
10
  [简体中文](./README.zh-CN.md) · **English**
11
11
 
@@ -13,7 +13,7 @@
13
13
 
14
14
  ## What is OCC
15
15
 
16
- **Open C Code (OCC)** is an open-source coding agent. Its capabilities are aligned with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (currently tracking `2.1.273` — 2.1.270 fully aligned; 2.1.271–2.1.273 partial: the OCC-127 catch-up round landed the 2.1.273 gateway-hint request headers (default on for the first-party api.anthropic.com endpoint, off for third-party/custom endpoints; tri-bool `CLAUDE_CODE_GATEWAY_HINT_HEADERS` override), the spinner doubled-ellipsis guard, the shell-mode `!` insert fix, and the round's security centerpiece — the subshell-hidden dangerous-`rm` bypass fix (per-segment analysis in the always-on catastrophic-rm deny guard), per `docs/upstream-version-gap-occ127.md`; remaining 2.1.273 entries are triaged there as NO-OP (surfaces OCC trims) or STAGED (per-site forensics needed); still not landed from the 2.1.270→2.1.272 delta: `/config` panel fullscreen mouse support (PORTABLE-LARGE scope) and the spinner status ladder "deep in thought"/"picking the thought back up" (STAGED), plus the pre-existing sandbox per-command `allowed_domains` gap; prior alignment through 2.1.270 landed via OCC-122/OCC-123/OCC-84/OCC-124/OCC-85/OCC-125/OCC-126). The code is fully open, auditable, backdoor-free, and your data stays under your control.
16
+ **Open C Code (OCC)** is an open-source coding agent. Its capabilities are aligned with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (currently tracking `2.1.274` — 2.1.270 fully aligned; 2.1.271–2.1.274 partial: the latest OCC-127 round landed the 2.1.274 MCP auth-stub description secret-leak fix — the byte-verified display-sanitizer family (NFKC + invisible-character stripping, quote/angle-bracket neutralization, bearer/token-family redaction, code-point-safe truncation) with the origin-only unexpanded endpoint — and confirmed NO-OP with behavioral tests for the 2.1.274 bash special-variable assignment/loop and worktree nested-expansion hardening (OCC's existing guards already ask/refuse every risky vector, byte-verified parity with the official); prior rounds landed the 2.1.273 gateway-hint request headers (default on for the first-party api.anthropic.com endpoint, off for third-party/custom endpoints; tri-bool `CLAUDE_CODE_GATEWAY_HINT_HEADERS` override), the spinner doubled-ellipsis guard, the shell-mode `!` insert fix, and the subshell-hidden dangerous-`rm` bypass fix (per-segment analysis in the always-on catastrophic-rm deny guard), per `docs/upstream-version-gap-occ127.md`; remaining 2.1.273/2.1.274 entries are triaged there as NO-OP (surfaces OCC trims) or STAGED (per-site forensics needed); still not landed from the 2.1.270→2.1.272 delta: `/config` panel fullscreen mouse support (PORTABLE-LARGE scope) and the spinner status ladder "deep in thought"/"picking the thought back up" (STAGED), plus the pre-existing sandbox per-command `allowed_domains` gap; prior alignment through 2.1.270 landed via OCC-122/OCC-123/OCC-84/OCC-124/OCC-85/OCC-125/OCC-126). The code is fully open, auditable, backdoor-free, and your data stays under your control.
17
17
 
18
18
  If you worry that a closed-source CLI might hide backdoors, or that your code and credentials are uploaded to unauditable services, OCC is for you: all source is open and unobfuscated, the build is reproducible from source, and API credentials are sent only to endpoints you configure.
19
19
 
@@ -62,7 +62,7 @@ Requires a valid Anthropic API Key (or AWS Bedrock / Google Vertex / Azure Found
62
62
  | **Auditability** | Line-by-line reviewable | No |
63
63
  | **Telemetry** | Minimal (analytics stubbed) | Standard |
64
64
  | **Data sovereignty** | Credentials stay on your machine; requests only to endpoints you configure | Anthropic endpoints |
65
- | **Capability parity** | Tracks CC `2.1.273` (2.1.270 fully aligned; 2.1.271–2.1.273 partial) | Reference implementation |
65
+ | **Capability parity** | Tracks CC `2.1.274` (2.1.270 fully aligned; 2.1.271–2.1.274 partial) | Reference implementation |
66
66
  | **Providers** | Anthropic Direct, Bedrock, Vertex, Azure | Anthropic, Bedrock, Vertex |
67
67
  | **Cost** | Free & open-source (MIT) | Subscription |
68
68
  | **Build** | Reproducible from source | N/A |
@@ -143,7 +143,7 @@ Requires [Bun](https://bun.sh/) >= 1.3.11 (use `bun upgrade` — older Bun cause
143
143
 
144
144
  ```bash
145
145
  bun install
146
- bun run dev # run from source; version prints 2.1.273 (dev polyfill; build overrides with pkg.version) when working
146
+ bun run dev # run from source; version prints 2.1.274 (dev polyfill; build overrides with pkg.version) when working
147
147
  bun run build # output: dist/cli.js (~26 MB, single-file bundle)
148
148
  bun test # test suite (Bun test runner)
149
149
  bun run lint # Biome lint (formatter disabled to avoid large diffs)
@@ -157,7 +157,7 @@ For architecture, entry/bootstrap, tool system, UI layer, and module-status deta
157
157
 
158
158
  ## Status
159
159
 
160
- - Tracks Claude Code **`2.1.273`** (2.1.270 fully aligned; 2.1.271–2.1.273 partial — the OCC-127 catch-up round landed the gateway-hint request headers, the spinner doubled-ellipsis guard, the shell-mode `!` insert fix, and the subshell-hidden dangerous-`rm` bypass fix — see `docs/upstream-version-gap-occ127.md`; remaining 2.1.273 entries are triaged there as NO-OP or STAGED; still not landed from the 2.1.270→2.1.272 delta: `/config` fullscreen mouse support (PORTABLE-LARGE) and the spinner status ladder (STAGED), plus the pre-existing sandbox per-command `allowed_domains` gap; prior alignment through 2.1.270 landed via OCC-122/OCC-123/OCC-84, OCC-124 + OCC-85, OCC-125, and OCC-126 — see `docs/upstream-version-gap-occ124.md`, `docs/upstream-version-gap-occ125.md`, and `docs/upstream-version-gap-occ126.md`).
160
+ - Tracks Claude Code **`2.1.274`** (2.1.270 fully aligned; 2.1.271–2.1.274 partial — the latest OCC-127 round landed the 2.1.274 MCP auth-stub description secret-leak fix (byte-verified display-sanitizer family port) and verified the 2.1.274 bash special-variable and worktree nested-expansion hardening as NO-OP with behavioral tests; prior rounds landed the 2.1.273 gateway-hint request headers, the spinner doubled-ellipsis guard, the shell-mode `!` insert fix, and the subshell-hidden dangerous-`rm` bypass fix — see `docs/upstream-version-gap-occ127.md`; remaining 2.1.273/2.1.274 entries are triaged there as NO-OP or STAGED; still not landed from the 2.1.270→2.1.272 delta: `/config` fullscreen mouse support (PORTABLE-LARGE) and the spinner status ladder (STAGED), plus the pre-existing sandbox per-command `allowed_domains` gap; prior alignment through 2.1.270 landed via OCC-122/OCC-123/OCC-84, OCC-124 + OCC-85, OCC-125, and OCC-126 — see `docs/upstream-version-gap-occ124.md`, `docs/upstream-version-gap-occ125.md`, and `docs/upstream-version-gap-occ126.md`).
161
161
  - Published to npm as [`@cnwenf/occ`](https://www.npmjs.com/package/@cnwenf/occ).
162
162
  - Many modules are intentionally stubbed or feature-flagged off — see "Disabled / stubbed" above.
163
163
 
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- globalThis.MACRO={"VERSION":"2.1.338","BINARY_NAME":"occ","BUILD_TIME":"2026-09-16T23:15:11.887Z","FEEDBACK_CHANNEL":"","ISSUES_EXPLAINER":"","NATIVE_PACKAGE_URL":"","PACKAGE_URL":"@cnwenf/occ","VERSION_CHANGELOG":""};
2
+ globalThis.MACRO={"VERSION":"2.1.339","BINARY_NAME":"occ","BUILD_TIME":"2026-09-17T03:37:58.902Z","FEEDBACK_CHANNEL":"","ISSUES_EXPLAINER":"","NATIVE_PACKAGE_URL":"","PACKAGE_URL":"@cnwenf/occ","VERSION_CHANGELOG":""};
3
3
  // @bun
4
4
  var __create = Object.create;
5
5
  var __getProtoOf = Object.getPrototypeOf;
@@ -628459,17 +628459,78 @@ var init_auth11 = __esm(() => {
628459
628459
  };
628460
628460
  });
628461
628461
 
628462
+ // src/services/mcp/displaySanitize.ts
628463
+ function stripInvisibleForDisplay(input2) {
628464
+ if (typeof input2 !== "string")
628465
+ return "";
628466
+ return (input2.length > 4096 ? input2.slice(0, 4096) : input2).replace(SURROGATE_PATTERN, (match) => match.length === 2 ? match : " ").replace(INVISIBLE_PATTERN, " ");
628467
+ }
628468
+ function sanitizeLoneSurrogatesFallback(value) {
628469
+ const chunks = [];
628470
+ for (let i6 = 0;i6 < value.length; i6 += 8192) {
628471
+ const end = Math.min(i6 + 8192, value.length);
628472
+ const codes = new Uint16Array(end - i6);
628473
+ for (let a6 = i6;a6 < end; a6++)
628474
+ codes[a6 - i6] = value.charCodeAt(a6);
628475
+ chunks.push(String.fromCharCode(...codes));
628476
+ }
628477
+ return chunks.join("");
628478
+ }
628479
+ function sanitizeLoneSurrogates(value) {
628480
+ if (typeof Buffer < "u")
628481
+ return Buffer.from(value, "utf16le").toString("utf16le");
628482
+ return sanitizeLoneSurrogatesFallback(value);
628483
+ }
628484
+ function truncateToDisplayLength(value, max2) {
628485
+ if (max2 <= 0)
628486
+ return "";
628487
+ if (value.length <= max2)
628488
+ return value;
628489
+ const head = value.slice(0, max2);
628490
+ const lastUnit = head.charCodeAt(max2 - 1);
628491
+ return sanitizeLoneSurrogates(lastUnit >= 55296 && lastUnit <= 56319 ? head.slice(0, -1) : head);
628492
+ }
628493
+ function redactSecretsForDisplay(value, mode = "all") {
628494
+ function replacer(match, label, secret) {
628495
+ return /[0-9._~+/=%-]/.test(secret) ? `${label} [redacted]` : match;
628496
+ }
628497
+ if (mode === "none")
628498
+ return value;
628499
+ return value.replace(/(?:\b|(?<=\\[A-Za-z"']))(bearer|basic)[\s:=\uFF1A\uFF1D]+(?:(?:\\*["']|\\+)\s*)?([A-Za-z0-9._~+/=%-]{8,})/gi, replacer).replace(/(?:\b|(?<=\\[A-Za-z"']))((?:access[-_ ]?|refresh[-_ ]?|id[-_ ]?|client[-_ ]?|api[-_ ]?|x[-_]api[-_ ]?|session[-_ ]?|auth[-_ ]?)?(?:token|key|secret|password|authorization|credential)s?)(?:\\*["']|\\+)?\s*[:=\uFF1A\uFF1D]\s*(?:\\*["']|\\+)?\s*([A-Za-z0-9._~+/=%-]{8,})/gi, replacer);
628500
+ }
628501
+ function sanitizeForDisplay(input2, max2 = DEFAULT_DISPLAY_MAX, redact = "all") {
628502
+ if (typeof input2 !== "string")
628503
+ return "";
628504
+ const cleaned = stripInvisibleForDisplay(input2.normalize("NFKC")).replaceAll(/[<>";\u2018\u2019\u201A\u201C\u201D\u201E\u00AB\u20BB\u2039\u203A\u2329\u232A\u27E8\u27E9\u27EA\u27EB\u3008\u3009\u300A\u300B]/g, " ").replaceAll(/\s+/g, " ").trim();
628505
+ const scanMax = Math.max(REDACT_SCAN_MAX, max2 + REDACT_SCAN_SLACK);
628506
+ const overflow = cleaned.length > scanMax;
628507
+ const redacted = redactSecretsForDisplay(overflow ? truncateToDisplayLength(cleaned, scanMax) : cleaned, redact);
628508
+ return overflow || redacted.length > max2 ? `${truncateToDisplayLength(redacted, max2)}\u2026` : redacted;
628509
+ }
628510
+ function sanitizeDisplayUrl(url3, max2 = 1024) {
628511
+ return sanitizeForDisplay(url3, max2);
628512
+ }
628513
+ function sanitizeServerNameForDisplay(name3, max2 = 64) {
628514
+ if (typeof name3 !== "string")
628515
+ return "";
628516
+ return sanitizeForDisplay(name3.normalize("NFKC").replace(/['`]/g, " "), max2, "none");
628517
+ }
628518
+ var SURROGATE_PATTERN, INVISIBLE_PATTERN, DEFAULT_DISPLAY_MAX = 200, REDACT_SCAN_MAX = 2000, REDACT_SCAN_SLACK = 512;
628519
+ var init_displaySanitize = __esm(() => {
628520
+ SURROGATE_PATTERN = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF]|[\uDC00-\uDFFF]/g;
628521
+ INVISIBLE_PATTERN = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}\p{Default_Ignorable_Code_Point}\u2800]|(?!\u0020)\p{Zs}/gu;
628522
+ });
628523
+
628462
628524
  // src/tools/McpAuthTool/McpAuthTool.ts
628463
- function getConfigUrl(config7) {
628464
- if ("url" in config7)
628465
- return config7.url;
628466
- return;
628525
+ function buildMcpAuthToolDescription(serverName, config7, resolveUnexpanded = resolveUnexpandedMcpServers) {
628526
+ const transport = config7.type ?? "stdio";
628527
+ const displayOrigin = getMcpErrorEndpoint(serverName, config7, { detail: "origin" }, resolveUnexpanded);
628528
+ const location = displayOrigin && displayOrigin !== transport ? `${transport} at ${sanitizeDisplayUrl(displayOrigin, 256)}` : transport;
628529
+ return `The "${sanitizeServerNameForDisplay(serverName)}" MCP server (${location}) is installed but requires authentication. ` + `Call this tool to start the OAuth flow \u2014 you'll receive an authorization URL to share with the user. ` + `Once the user completes authorization in their browser, the server's real tools will become available automatically.`;
628467
628530
  }
628468
- function createMcpAuthTool(serverName, config7) {
628469
- const url3 = getConfigUrl(config7);
628531
+ function createMcpAuthTool(serverName, config7, resolveUnexpanded = resolveUnexpandedMcpServers) {
628470
628532
  const transport = config7.type ?? "stdio";
628471
- const location = url3 ? `${transport} at ${url3}` : transport;
628472
- const description = `The \`${serverName}\` MCP server (${location}) is installed but requires authentication. ` + `Call this tool to start the OAuth flow \u2014 you'll receive an authorization URL to share with the user. ` + `Once the user completes authorization in their browser, the server's real tools will become available automatically.`;
628533
+ const description = buildMcpAuthToolDescription(serverName, config7, resolveUnexpanded);
628473
628534
  return {
628474
628535
  name: buildMcpToolName(serverName, "authenticate"),
628475
628536
  isMcp: true,
@@ -628590,7 +628651,10 @@ var init_McpAuthTool = __esm(() => {
628590
628651
  init_v4();
628591
628652
  init_auth11();
628592
628653
  init_client12();
628654
+ init_displaySanitize();
628593
628655
  init_mcpStringUtils();
628656
+ init_redaction();
628657
+ init_utils9();
628594
628658
  init_errors();
628595
628659
  init_log3();
628596
628660
  inputSchema45 = lazySchema(() => exports_external.object({}));
@@ -831870,7 +831934,7 @@ var _FEATURE_ALLOWLIST = new Set([
831870
831934
  var feature2 = (name3) => _FEATURE_ALLOWLIST.has(name3);
831871
831935
  if (typeof globalThis.MACRO === "undefined") {
831872
831936
  globalThis.MACRO = {
831873
- VERSION: "2.1.273",
831937
+ VERSION: "2.1.274",
831874
831938
  BINARY_NAME: "occ",
831875
831939
  BUILD_TIME: new Date().toISOString(),
831876
831940
  FEEDBACK_CHANNEL: "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cnwenf/occ",
3
- "version": "2.1.338",
3
+ "version": "2.1.339",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "bin": {