dsh-agy-link 0.4.78 → 0.4.80

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/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.80 (2026-10-29)
4
+
5
+ ### English
6
+
7
+ - **Security(doctor): redact OIDC/JWT id_tokens and more provider secret shapes in `/agy doctor`.**
8
+ - `redactLine()` already stripped `ya29.*`, `1//0…` refresh tokens, `AIza…` keys, `Bearer` headers, `4/` codes and proxy credentials, but a Google `id_token` (a JWT `header.payload.signature`), `sk-…` provider keys, and `GOCSPX-…` OAuth client secrets passed through verbatim when agy echoed them into the log ring buffer. All three are now redacted; ordinary text is preserved. Adds regression tests.
9
+
10
+ ### 中文
11
+
12
+ - **安全(doctor):`/agy doctor` 额外脱敏 OIDC/JWT id_token 及更多密钥形态。**
13
+ - `redactLine()` 原本已脱敏 `ya29.*`、`1//0…` refresh token、`AIza…` key、`Bearer` 头、`4/` 授权码与代理凭证,但 Google `id_token`(JWT `header.payload.signature`)、`sk-…` 提供方密钥、`GOCSPX-…` OAuth client secret 在 agy 回显进日志环时仍会原样落入报告。现三类均已脱敏,普通文本保持不变。补充回归测试。
14
+
15
+ **Full Changelog**: https://github.com/amlyczz/dsh-agy-link/compare/v0.4.79...v0.4.80
16
+
17
+ ## 0.4.79 (2026-10-29)
18
+
19
+ ### English
20
+
21
+ - **Fix(mcp): never silently drop tools whose names collide after MCP normalization.**
22
+ - `toMcpName()` maps any non-`[A-Za-z0-9_-]` character to `_`, so distinct DSH tools like `a.b` and `a_b` normalized to the same MCP name and the second was silently removed from `/tools` — hiding a real, possibly allowlisted, tool from the agent. Colliding names are now disambiguated with a stable `__<n>` suffix; `bridge.mjs` still calls back by the exact `_dshName`, so execution is unaffected. Adds a regression test.
23
+
24
+ ### 中文
25
+
26
+ - **修复(mcp):名称经 MCP 归一化后撞名的工具不再被静默丢弃。**
27
+ - `toMcpName()` 会把非 `[A-Za-z0-9_-]` 字符替换成 `_`,于是 `a.b` 与 `a_b` 这类不同工具会归一化成同一个 MCP 名,第二个被从 `/tools` 静默删除,导致一个真实(且可能已加入 allowlist 的)工具对 agent 不可见。现在撞名会加稳定的 `__<n>` 后缀消歧;`bridge.mjs` 仍按精确 `_dshName` 回调,执行不受影响。补充回归测试。
28
+
29
+ **Full Changelog**: https://github.com/amlyczz/dsh-agy-link/compare/v0.4.78...v0.4.79
30
+
3
31
  ## 0.4.78 (2026-10-29)
4
32
 
5
33
  ### English
package/dist/index.js CHANGED
@@ -32399,6 +32399,9 @@ function redactLine(line) {
32399
32399
  out = out.replace(/Bearer\s+\S+/gi, "Bearer <redacted>");
32400
32400
  out = out.replace(/\b1\/\/0[A-Za-z0-9._-]{10,}/g, "<oauth-refresh-token-redacted>");
32401
32401
  out = out.replace(/\bAIza[0-9A-Za-z_-]{30,}\b/g, "<api-key-redacted>");
32402
+ out = out.replace(/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\b/g, "<jwt-redacted>");
32403
+ out = out.replace(/\bsk-[A-Za-z0-9_-]{16,}\b/g, "<api-key-redacted>");
32404
+ out = out.replace(/\bGOCSPX-[A-Za-z0-9_-]{10,}\b/g, "<api-key-redacted>");
32402
32405
  out = out.replace(/\b(?:https?|socks[45]):\/\/[^\s/]*:[^\s/@]*@[^\s]+/gi, "<proxy-url-redacted>");
32403
32406
  return out;
32404
32407
  }
@@ -34773,22 +34776,22 @@ function startMcpBridge(opts) {
34773
34776
  }
34774
34777
  const allow = opts.allowlist().split(",").map((s) => s.trim()).filter(Boolean);
34775
34778
  const allowSet = new Set(allow);
34776
- const seen = /* @__PURE__ */ new Set();
34777
- sendJson(res, 200, { tools: svc.schemas().filter((t) => allow.length === 0 || allowSet.has(t.name)).filter((t) => {
34778
- if (INTERNAL_TOOL_NAMES.has(t.name)) return false;
34779
- const mapped = toMcpName(t.name);
34780
- if (seen.has(mapped)) return false;
34781
- seen.add(mapped);
34782
- return true;
34783
- }).map((t) => ({
34784
- name: toMcpName(t.name),
34785
- dshName: t.name,
34786
- description: t.description,
34787
- inputSchema: {
34788
- type: "object",
34789
- ...t.parameters
34790
- }
34791
- })) });
34779
+ const used = /* @__PURE__ */ new Set();
34780
+ sendJson(res, 200, { tools: svc.schemas().filter((t) => allow.length === 0 || allowSet.has(t.name)).filter((t) => !INTERNAL_TOOL_NAMES.has(t.name)).map((t) => {
34781
+ const base = toMcpName(t.name);
34782
+ let name = base;
34783
+ for (let i = 2; used.has(name); i++) name = base + "__" + i;
34784
+ used.add(name);
34785
+ return {
34786
+ name,
34787
+ dshName: t.name,
34788
+ description: t.description,
34789
+ inputSchema: {
34790
+ type: "object",
34791
+ ...t.parameters
34792
+ }
34793
+ };
34794
+ }) });
34792
34795
  return;
34793
34796
  }
34794
34797
  if (req.method === "POST" && (url === "/call" || url === "/mcp/call")) {
@@ -120,6 +120,9 @@ reference-counted slot is the strongest isolation the plugin can provide.
120
120
  loopback endpoint also caps request bodies (8 MiB → HTTP 413) and compares the
121
121
  bearer token in constant time, so a token-holding but prompt-injected child
122
122
  cannot OOM the host with an unbounded body or probe the token via timing.
123
+ Distinct DSH tool names that normalize to the same MCP name (e.g. `a.b`
124
+ and `a_b`) are disambiguated with a stable suffix instead of being silently
125
+ dropped, so every real tool stays reachable.
123
126
  Every bridged call is audit-logged as `mcp call <tool> [<outcome>] <ms>` with
124
127
  the caller class and the failure text (never the arguments), so a failed run
125
128
  is visible in journald instead of only in transcripts.
@@ -42,8 +42,10 @@ choice, not a fallback applied by this plugin.
42
42
  ## Report hygiene
43
43
 
44
44
  `/agy doctor` writes its report with redaction: Google auth URLs,
45
- `4/...` authorization codes, `ya29.*` tokens, and `Bearer` headers are
46
- stripped before the file hits disk. Still read it before attaching.
45
+ `4/...` authorization codes, `ya29.*` access tokens, `1//0…` refresh tokens,
46
+ OIDC/JWT `id_token`s, `AIza…`/`sk-…`/`GOCSPX-…` API keys, credentialed proxy
47
+ URLs, and `Bearer` headers are stripped before the file hits disk. Still read it
48
+ before attaching.
47
49
 
48
50
  ## HTTP surfaces and request-body caps
49
51
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-agy-link",
3
- "version": "0.4.78",
3
+ "version": "0.4.80",
4
4
  "description": "Google Antigravity (agy CLI) models for DeepSeek Harness — stream Gemini/Claude/GPT-OSS subscriptions into DSH with thinking, tool activity, token usage and in-GUI Google OAuth login.",
5
5
  "type": "module",
6
6
  "license": "MIT",