From 370527c0e70f9757f484cb1a46646f96c567ced5 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Fri, 30 Oct 2026 13:25:39 -0700 Subject: [PATCH 1/4] fix(byo): say what to do when npm -g hits EACCES (TASK-645 item 2) On a stock Mac Node install, `npm i -g @commonlyai/cli` fails with EACCES and the listener page gave no hint. The page now says what to do under the command, and says not to use sudo. The fix is a copy line, not a new install path. Test: the hint renders after the command in the listener box. Co-Authored-By: Claude Haiku 5.5 Co-authored-by: rivet Agent-Model: claude/claude-haiku-5-5/default --- frontend/src/i18n/locales/en.json | 1 + frontend/src/i18n/locales/zh-CN.json | 1 + .../src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx | 9 +++++++++ frontend/src/v2/components/V2AgentBYO.tsx | 5 +++++ 4 files changed, 16 insertions(+) diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index ecc980e131..bcdf9a61e6 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -1711,6 +1711,7 @@ "waiting": "Waiting for {{name}} to check in… this turns green the moment the command connects.", "verified": "{{name}} is listening — mentions will wake it.", "stillWaiting": "Still no check-in from {{name}}. Run the command above in Terminal on your computer, and this page will confirm it.", + "npmPermission": "If npm stops with EACCES (permission denied), don’t add sudo. Install Node from nodejs.org or with Homebrew, then run the four lines again. Or point npm at a folder you own with npm config set prefix ~/.npm-global.", "ctaWarning": "{{name}} isn’t listening yet: it won’t answer mentions until the command above is running.", "needs": "Needs Node 20+ with npm and {{tool}} signed in. Run all four lines in one window: the exports last only there.", "osLabel": "Setting up on:", diff --git a/frontend/src/i18n/locales/zh-CN.json b/frontend/src/i18n/locales/zh-CN.json index ec401c9906..09209e09f0 100644 --- a/frontend/src/i18n/locales/zh-CN.json +++ b/frontend/src/i18n/locales/zh-CN.json @@ -1771,6 +1771,7 @@ "waiting": "正在等待 {{name}} 接入…命令一接通,这里就会变绿。", "verified": "{{name}} 已在监听 —— @提及 会唤醒它。", "stillWaiting": "{{name}} 还没接入。请在你电脑的终端里运行上面的命令,这里会自动确认。", + "npmPermission": "如果 npm 报 EACCES(权限被拒绝),不要加 sudo。请从 nodejs.org 或用 Homebrew 安装 Node,然后重新运行这四行。或者用 npm config set prefix ~/.npm-global 把 npm 指向你有权限的文件夹。", "ctaWarning": "{{name}} 尚未监听:上面的命令运行起来之前,它不会回复 @提及。", "needs": "需要 Node 20+(含 npm)和已登录的 {{tool}}。四行都要在同一个窗口里运行,换了窗口 export 就失效。", "osLabel": "你的系统:", diff --git a/frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx b/frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx index dd3b1e5481..324c02a02f 100644 --- a/frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx +++ b/frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx @@ -159,6 +159,15 @@ describe('BYO listener snippet', () => { expect(zhNeeds).toMatch(new RegExp(`需要 Node ${CLI_NODE_FLOOR}\\+`)); }); + test('an npm EACCES names the fix and says not to use sudo, right after the command', async () => { + await issueToken(); + const hint = screen.getByTestId('byo-listen-npm-hint'); + expect(hint).toHaveTextContent(/npm stops with EACCES/); + expect(hint).toHaveTextContent(/don’t add sudo/); + // eslint-disable-next-line no-bitwise + expect(listenCommand().compareDocumentPosition(hint) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy(); + }); + test('"I use Codex instead" gives a Codex command and says Codex is what it needs', async () => { await issueToken(); fireEvent.click(screen.getByTestId('byo-listen-adapter-switch')); diff --git a/frontend/src/v2/components/V2AgentBYO.tsx b/frontend/src/v2/components/V2AgentBYO.tsx index d7571f97ab..072eeff44f 100644 --- a/frontend/src/v2/components/V2AgentBYO.tsx +++ b/frontend/src/v2/components/V2AgentBYO.tsx @@ -1563,6 +1563,11 @@ const V2AgentBYO: React.FC = () => { )} + {listenerAvailable && ( +

+ {t('agentByo.listen.npmPermission')} +

+ )} {!listenerAvailable ? null : listenState === 'listening' ? (

{t('agentByo.listen.verified', { name: issued.agentName })} From b98cab11c2a59f57cf2f5be8e70029f6787296a0 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Fri, 30 Oct 2026 14:36:01 -0700 Subject: [PATCH 2/4] fix(byo): EACCES hint points to a version manager, not prefix or nodejs.org (TASK-645 item 2) Lane HOLD on #3016: nodejs.org reinstall is the cause of EACCES on macOS (root-owned /usr/local), and the npm prefix route leaves ~/.npm-global/bin off PATH so commonly is not found. Reword en and zh-CN to a version manager (nvm) or Homebrew on a Mac. Co-Authored-By: Claude Haiku 5.5 Co-authored-by: rivet Agent-Model: claude/claude-haiku-5-5/default --- frontend/src/i18n/locales/en.json | 2 +- frontend/src/i18n/locales/zh-CN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index bcdf9a61e6..f728e1f5fc 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -1711,7 +1711,7 @@ "waiting": "Waiting for {{name}} to check in… this turns green the moment the command connects.", "verified": "{{name}} is listening — mentions will wake it.", "stillWaiting": "Still no check-in from {{name}}. Run the command above in Terminal on your computer, and this page will confirm it.", - "npmPermission": "If npm stops with EACCES (permission denied), don’t add sudo. Install Node from nodejs.org or with Homebrew, then run the four lines again. Or point npm at a folder you own with npm config set prefix ~/.npm-global.", + "npmPermission": "If npm stops with EACCES (permission denied), don’t add sudo. Reinstall Node with a version manager such as nvm (or with Homebrew on a Mac), then run the four lines again.", "ctaWarning": "{{name}} isn’t listening yet: it won’t answer mentions until the command above is running.", "needs": "Needs Node 20+ with npm and {{tool}} signed in. Run all four lines in one window: the exports last only there.", "osLabel": "Setting up on:", diff --git a/frontend/src/i18n/locales/zh-CN.json b/frontend/src/i18n/locales/zh-CN.json index 09209e09f0..fc1f7c8ea2 100644 --- a/frontend/src/i18n/locales/zh-CN.json +++ b/frontend/src/i18n/locales/zh-CN.json @@ -1771,7 +1771,7 @@ "waiting": "正在等待 {{name}} 接入…命令一接通,这里就会变绿。", "verified": "{{name}} 已在监听 —— @提及 会唤醒它。", "stillWaiting": "{{name}} 还没接入。请在你电脑的终端里运行上面的命令,这里会自动确认。", - "npmPermission": "如果 npm 报 EACCES(权限被拒绝),不要加 sudo。请从 nodejs.org 或用 Homebrew 安装 Node,然后重新运行这四行。或者用 npm config set prefix ~/.npm-global 把 npm 指向你有权限的文件夹。", + "npmPermission": "如果 npm 报 EACCES(权限被拒绝),不要加 sudo。请用版本管理工具(如 nvm)重新安装 Node,在 Mac 上也可以用 Homebrew。然后重新运行这四行。", "ctaWarning": "{{name}} 尚未监听:上面的命令运行起来之前,它不会回复 @提及。", "needs": "需要 Node 20+(含 npm)和已登录的 {{tool}}。四行都要在同一个窗口里运行,换了窗口 export 就失效。", "osLabel": "你的系统:", From 3a2327fb80f35fd6afd367249ae3b6aa9d845b09 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Fri, 30 Oct 2026 15:24:35 -0700 Subject: [PATCH 3/4] test(byo): the EACCES hint is absent where no listener runs; Homebrew advice is Apple silicon only (TASK-645 item 2) Vera HOLD on #3016: the hint sits behind listenerAvailable but no test pinned it, so Windows and Linux would show four lines to run that do not exist. Assert the hint is absent in those tests; the ungated mutant fails three of them. Homebrew's installer refuses Intel Macs, so the parenthetical now says Apple silicon in en and zh-CN. Co-Authored-By: Claude Haiku 5.5 Co-authored-by: rivet Agent-Model: claude/claude-haiku-5-5/default --- frontend/src/i18n/locales/en.json | 2 +- frontend/src/i18n/locales/zh-CN.json | 2 +- frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index f728e1f5fc..d177a41d24 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -1711,7 +1711,7 @@ "waiting": "Waiting for {{name}} to check in… this turns green the moment the command connects.", "verified": "{{name}} is listening — mentions will wake it.", "stillWaiting": "Still no check-in from {{name}}. Run the command above in Terminal on your computer, and this page will confirm it.", - "npmPermission": "If npm stops with EACCES (permission denied), don’t add sudo. Reinstall Node with a version manager such as nvm (or with Homebrew on a Mac), then run the four lines again.", + "npmPermission": "If npm stops with EACCES (permission denied), don’t add sudo. Reinstall Node with a version manager such as nvm (or with Homebrew on an Apple silicon Mac), then run the four lines again.", "ctaWarning": "{{name}} isn’t listening yet: it won’t answer mentions until the command above is running.", "needs": "Needs Node 20+ with npm and {{tool}} signed in. Run all four lines in one window: the exports last only there.", "osLabel": "Setting up on:", diff --git a/frontend/src/i18n/locales/zh-CN.json b/frontend/src/i18n/locales/zh-CN.json index fc1f7c8ea2..721695a325 100644 --- a/frontend/src/i18n/locales/zh-CN.json +++ b/frontend/src/i18n/locales/zh-CN.json @@ -1771,7 +1771,7 @@ "waiting": "正在等待 {{name}} 接入…命令一接通,这里就会变绿。", "verified": "{{name}} 已在监听 —— @提及 会唤醒它。", "stillWaiting": "{{name}} 还没接入。请在你电脑的终端里运行上面的命令,这里会自动确认。", - "npmPermission": "如果 npm 报 EACCES(权限被拒绝),不要加 sudo。请用版本管理工具(如 nvm)重新安装 Node,在 Mac 上也可以用 Homebrew。然后重新运行这四行。", + "npmPermission": "如果 npm 报 EACCES(权限被拒绝),不要加 sudo。请用版本管理工具(如 nvm)重新安装 Node,在 Apple 芯片的 Mac 上也可以用 Homebrew。然后重新运行这四行。", "ctaWarning": "{{name}} 尚未监听:上面的命令运行起来之前,它不会回复 @提及。", "needs": "需要 Node 20+(含 npm)和已登录的 {{tool}}。四行都要在同一个窗口里运行,换了窗口 export 就失效。", "osLabel": "你的系统:", diff --git a/frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx b/frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx index 324c02a02f..f3d4a89f00 100644 --- a/frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx +++ b/frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx @@ -263,6 +263,7 @@ describe('BYO listener snippet', () => { expect(notice).toHaveTextContent(/Claude Code can’t answer @mentions from Windows yet/); expect(notice).toHaveTextContent(/with the command below, or choose “Run it here”/); expect(notice).not.toHaveTextContent(/WSL/); + expect(screen.queryByTestId('byo-listen-npm-hint')).toBeNull(); expect(mcpBox().split('\n')).toEqual([ 'npm i -g @commonlyai/mcp', expect.stringMatching(/^claude mcp add commonly -e COMMONLY_API_URL=\S+ -e COMMONLY_AGENT_TOKEN=cm_agent_test_token -- cmd \/c commonly-mcp$/), @@ -280,11 +281,13 @@ describe('BYO listener snippet', () => { expect(listener()).toBeUndefined(); expect(screen.queryByTestId('byo-listen-reach')).toBeNull(); expect(screen.getByTestId('byo-listen-unavailable')).toHaveTextContent(/from Linux yet/); + expect(screen.queryByTestId('byo-listen-npm-hint')).toBeNull(); expect(mcpBox()).toMatch(/-- npx -y @commonlyai\/mcp$/); expect(screen.getByTestId('byo-mcp-claude')).not.toHaveTextContent(/command above|Optional/); fireEvent.click(screen.getByTestId('byo-listen-adapter-switch')); expect(listener()).toBeUndefined(); expect(screen.getByTestId('byo-listen-unavailable')).toHaveTextContent(/The Codex CLI can’t answer @mentions from Linux yet\. .*Linux is not tested yet\./); + expect(screen.queryByTestId('byo-listen-npm-hint')).toBeNull(); }); test('Codex on Windows says so, and offers hosted or another machine', async () => { @@ -294,6 +297,7 @@ describe('BYO listener snippet', () => { expect(listener()).toBeUndefined(); expect(screen.getByTestId('byo-listen-unavailable')) .toHaveTextContent(/The Codex CLI can’t answer @mentions from Windows yet\. Choose “Run it here”/); + expect(screen.queryByTestId('byo-listen-npm-hint')).toBeNull(); expect(screen.queryByTestId('byo-mcp-claude')).toBeNull(); }); From 7aa5bb64af84266e8766252dce1c3f81f5e8f251 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Fri, 30 Oct 2026 15:25:46 -0700 Subject: [PATCH 4/4] fix(byo): drop the Homebrew parenthetical from the EACCES hint (TASK-645 item 2) Lily's ruling on Vera's HOLD: nvm works on Intel and Apple silicon, so the Homebrew clause goes from en and zh-CN. The hint now names nvm only. Co-Authored-By: Claude Haiku 5.5 Co-authored-by: rivet Agent-Model: claude/claude-haiku-5-5/default --- frontend/src/i18n/locales/en.json | 2 +- frontend/src/i18n/locales/zh-CN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index d177a41d24..0de3fb82e6 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -1711,7 +1711,7 @@ "waiting": "Waiting for {{name}} to check in… this turns green the moment the command connects.", "verified": "{{name}} is listening — mentions will wake it.", "stillWaiting": "Still no check-in from {{name}}. Run the command above in Terminal on your computer, and this page will confirm it.", - "npmPermission": "If npm stops with EACCES (permission denied), don’t add sudo. Reinstall Node with a version manager such as nvm (or with Homebrew on an Apple silicon Mac), then run the four lines again.", + "npmPermission": "If npm stops with EACCES (permission denied), don’t add sudo. Reinstall Node with a version manager such as nvm, then run the four lines again.", "ctaWarning": "{{name}} isn’t listening yet: it won’t answer mentions until the command above is running.", "needs": "Needs Node 20+ with npm and {{tool}} signed in. Run all four lines in one window: the exports last only there.", "osLabel": "Setting up on:", diff --git a/frontend/src/i18n/locales/zh-CN.json b/frontend/src/i18n/locales/zh-CN.json index 721695a325..8de5961df7 100644 --- a/frontend/src/i18n/locales/zh-CN.json +++ b/frontend/src/i18n/locales/zh-CN.json @@ -1771,7 +1771,7 @@ "waiting": "正在等待 {{name}} 接入…命令一接通,这里就会变绿。", "verified": "{{name}} 已在监听 —— @提及 会唤醒它。", "stillWaiting": "{{name}} 还没接入。请在你电脑的终端里运行上面的命令,这里会自动确认。", - "npmPermission": "如果 npm 报 EACCES(权限被拒绝),不要加 sudo。请用版本管理工具(如 nvm)重新安装 Node,在 Apple 芯片的 Mac 上也可以用 Homebrew。然后重新运行这四行。", + "npmPermission": "如果 npm 报 EACCES(权限被拒绝),不要加 sudo。请用版本管理工具(如 nvm)重新安装 Node,然后重新运行这四行。", "ctaWarning": "{{name}} 尚未监听:上面的命令运行起来之前,它不会回复 @提及。", "needs": "需要 Node 20+(含 npm)和已登录的 {{tool}}。四行都要在同一个窗口里运行,换了窗口 export 就失效。", "osLabel": "你的系统:",