diff --git a/CHANGELOG.md b/CHANGELOG.md index 18d3a0b..ab5a19f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ versioning theo [SemVer](https://semver.org). **8sync rule:** mỗi PR cập nh ## [Unreleased] +## [0.110.87] — 2026-10-27 + +### Changed +- **`8sync ccc kit` tắt MCP chrome-devtools của ECC trên mọi máy, giữ skill/agent/command `ecc:*`.** Owner (2026-10-27): "Tắt MCP chrome-devtools của ECC trên mọi máy", "spam terminal ram, cpu lag". `.mcp.json` gốc của ECC chạy `npx -y chrome-devtools-mcp@1.10.1` ở mỗi phiên (4 tiến trình node/cmd mỗi phiên; máy owner có 14 phiên = 56 tiến trình) dù `plugin.json` ghi không có MCP; duyệt web đã có ego-browser. + - Kit thêm `{ "serverName": "plugin:ecc:chrome-devtools" }` vào `deniedMcpServers` trong `~/.claude/settings.json` (Claude Code nhận denylist ở settings người dùng, code.claude.com/docs/en/managed-mcp). Entry deny khác của người dùng được giữ; không thêm trùng. + - Kiểm trên Windows: trước khi deny `claude mcp list` hiện `plugin:ecc:chrome-devtools … Connected`, sau khi deny server biến mất. Phiên đang mở vẫn giữ tiến trình cũ tới khi đóng phiên. + ## [0.110.86] — 2026-10-27 ### Added diff --git a/Cargo.lock b/Cargo.lock index 38bf460..05463c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,7 +200,7 @@ dependencies = [ [[package]] name = "ccc-core" -version = "0.110.86" +version = "0.110.87" dependencies = [ "anyhow", "dirs", @@ -1503,7 +1503,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "su-code" -version = "0.110.86" +version = "0.110.87" dependencies = [ "anyhow", "axum", diff --git a/Cargo.toml b/Cargo.toml index 9c5b3ca..fffc929 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["crates/cli", "crates/ccc-core"] [workspace.package] -version = "0.110.86" +version = "0.110.87" edition = "2021" license = "PolyForm-Noncommercial-1.0.0" authors = ["8sync-dev <8sync.dev.1111@gmail.com>"] diff --git a/assets/claude/.claude-plugin/plugin.json b/assets/claude/.claude-plugin/plugin.json index b7a8c0f..7efb495 100644 --- a/assets/claude/.claude-plugin/plugin.json +++ b/assets/claude/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "8sync-kit", "displayName": "8sync kit", - "version": "0.110.86", + "version": "0.110.87", "description": "8 Sync kit for Claude Code: role-routed subagents (explore, task, quick-task, reviewer, designer, researcher, verifier, pm, architect, qa, critic) the /ship /rules /sec /harden skills, and the 8sync safety hooks (guard, verify, stop gate) when the 8sync binary is installed. Managed rules, mods and the full skill set come from `8sync ccc kit`.", "author": { "name": "8 Sync", "url": "https://8syncdev.com" }, "homepage": "https://get.8syncdev.com", diff --git a/crates/cli/src/verbs/ccc.rs b/crates/cli/src/verbs/ccc.rs index e1f11ff..38ba130 100644 --- a/crates/cli/src/verbs/ccc.rs +++ b/crates/cli/src/verbs/ccc.rs @@ -1461,9 +1461,11 @@ fn apply_lsp_plugins(v: &mut Value, on_path: impl Fn(&str) -> bool) { /// ECC's unpinned main on every tool call. Owner 2026-10-27: "sài mạnh cho claude code all máy tôi". const ECC_MARKETPLACE: &str = "ecc"; const ECC_REPO: &str = "affaan-m/ECC"; +/// Name Claude Code gives ECC's chrome-devtools server (`plugin::`). +const ECC_BROWSER_MCP: &str = "plugin:ecc:chrome-devtools"; -/// Insert-only, like the LSP plugins: `"ecc@ecc": false`, `autoUpdate: false` or -/// `ECC_HOOKS_ENABLED=true` set by the user is kept. +/// Insert-only, like the LSP plugins: `"ecc@ecc": false`, `autoUpdate: false`, +/// `ECC_HOOKS_ENABLED=true` or other `deniedMcpServers` entries set by the user are kept. fn apply_ecc_plugin(v: &mut Value) { let Some(obj) = v.as_object_mut() else { return }; if let Some(m) = obj.entry("extraKnownMarketplaces").or_insert_with(|| json!({})).as_object_mut() { @@ -1479,6 +1481,15 @@ fn apply_ecc_plugin(v: &mut Value) { if let Some(env) = obj.entry("env").or_insert_with(|| json!({})).as_object_mut() { env.entry("ECC_HOOKS_ENABLED").or_insert(json!("false")); } + // ECC's root `.mcp.json` starts chrome-devtools via `npx -y` (a download each session) while + // its plugin.json lists none; ego-browser covers browsing (owner 2026-10-27). The denylist is + // honoured in user settings and keeps the plugin's skills, agents and commands. + if let Some(d) = obj.entry("deniedMcpServers").or_insert_with(|| json!([])).as_array_mut() { + let deny = json!({ "serverName": ECC_BROWSER_MCP }); + if !d.contains(&deny) { + d.push(deny); + } + } } /// Merge the kit into a parsed `settings.json`, leaving everything else as is: @@ -2869,13 +2880,14 @@ mod tests { } #[test] - fn ecc_plugin_enabled_with_auto_update_and_hooks_off_and_user_values_kept() { + fn ecc_plugin_enabled_with_auto_update_hooks_off_browser_mcp_denied_and_user_values_kept() { let mut v = json!({}); apply_ecc_plugin(&mut v); assert_eq!(v["extraKnownMarketplaces"]["ecc"]["source"]["repo"], json!("affaan-m/ECC")); assert_eq!(v["extraKnownMarketplaces"]["ecc"]["autoUpdate"], json!(true)); assert_eq!(v["enabledPlugins"]["ecc@ecc"], json!(true)); assert_eq!(v["env"]["ECC_HOOKS_ENABLED"], json!("false")); + assert_eq!(v["deniedMcpServers"], json!([{ "serverName": "plugin:ecc:chrome-devtools" }])); let before = v.clone(); apply_ecc_plugin(&mut v); assert_eq!(v, before); @@ -2884,9 +2896,13 @@ mod tests { "env": { "ECC_HOOKS_ENABLED": "true" }, "extraKnownMarketplaces": { "ecc": { "source": { "source": "github", "repo": "affaan-m/ECC" }, "autoUpdate": false } } }); - let kept = user.clone(); + let mut kept = user.clone(); + kept["deniedMcpServers"] = json!([{ "serverName": "plugin:ecc:chrome-devtools" }]); apply_ecc_plugin(&mut user); assert_eq!(user, kept); + let mut own_deny = json!({ "deniedMcpServers": [{ "serverName": "x" }] }); + apply_ecc_plugin(&mut own_deny); + assert_eq!(own_deny["deniedMcpServers"], json!([{ "serverName": "x" }, { "serverName": "plugin:ecc:chrome-devtools" }])); let mut added_by_cli = json!({ "extraKnownMarketplaces": { "ecc": { "source": { "source": "github", "repo": "affaan-m/ECC" } } } }); apply_ecc_plugin(&mut added_by_cli); assert_eq!(added_by_cli["extraKnownMarketplaces"]["ecc"]["autoUpdate"], json!(true)); diff --git a/su-code/STATE.md b/su-code/STATE.md index e0d5322..64be508 100644 --- a/su-code/STATE.md +++ b/su-code/STATE.md @@ -19,6 +19,7 @@ CLI = on/off; everything else from HQ (local or internet link). Rooms never stay - [x] Release v0.101.1 (12 assets) → installed → HQ 8740 restarted on 0.101.1 → `auto up --roles full --clear-ss` (rd, ui restarted on the new kit; 6 busy rooms move at their next idle `--clear-ss`) → `--public` UAT: wrong key 401, right key 303 + `hq_pub` HttpOnly Secure cookie, app loads data at 430 px; HQ back to local-only. ## Current +v0.110.87: kit tắt MCP chrome-devtools của ECC (`deniedMcpServers` serverName `plugin:ecc:chrome-devtools`), giữ skill/agent `ecc:*`. v0.110.86: `8sync ccc kit` bật plugin ECC (affaan-m/ECC, MIT) trên mọi máy: 71 agent, 311 skill, 97 command `ecc:*`, marketplace `autoUpdate`, hook ECC tắt (`ECC_HOOKS_ENABLED=false`), giữ giá trị owner; policy org cho phép `affaan-m/ECC`. v0.110.85: R&D từ Feynman v0.5.58 (MIT): `deep-research` v3 (plan 6 mục, scale 0–6 researcher, claim `(D)` cần 2 nguồn, verifier trước `research-reviewer`, provenance PASS/BLOCKED), `/autoresearch` chỉ owner khởi động (Start card, worktree, keep rule theo nhiễu, held-out), test frontmatter YAML chặt; `8sync harness browser ego install|status` cài ego lite chính thức (Windows: chữ ký CITRO LABS). v0.110.84: hq-ui `pnpm dev`/`pnpm start` work on Windows (`scripts/next.mjs`, no POSIX `${PORT:-…}`); HQ on Next 16.4.1 (GHSA-2464-fhr4-w9xw, GHSA-673q-mjm6-r5xr, GHSA-p3m5-59mp-jv5r).