Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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. 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:",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,7 @@
"waiting": "正在等待 {{name}} 接入…命令一接通,这里就会变绿。",
"verified": "{{name}} 已在监听 —— @提及 会唤醒它。",
"stillWaiting": "{{name}} 还没接入。请在你电脑的终端里运行上面的命令,这里会自动确认。",
"npmPermission": "如果 npm 报 EACCES(权限被拒绝),不要加 sudo。请用版本管理工具(如 nvm)重新安装 Node,然后重新运行这四行。",
"ctaWarning": "{{name}} 尚未监听:上面的命令运行起来之前,它不会回复 @提及。",
"needs": "需要 Node 20+(含 npm)和已登录的 {{tool}}。四行都要在同一个窗口里运行,换了窗口 export 就失效。",
"osLabel": "你的系统:",
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/v2/__tests__/V2AgentBYOListenSnippet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
Expand Down Expand Up @@ -254,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$/),
Expand All @@ -271,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 () => {
Expand All @@ -285,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();
});

Expand Down
5 changes: 5 additions & 0 deletions frontend/src/v2/components/V2AgentBYO.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,11 @@ const V2AgentBYO: React.FC = () => {
</button>
</div>
)}
{listenerAvailable && (
<p className="v2-byo__listen-note" data-testid="byo-listen-npm-hint">
{t('agentByo.listen.npmPermission')}
</p>
)}
{!listenerAvailable ? null : listenState === 'listening' ? (
<p className="v2-byo__live" data-testid="byo-listen-ok">
{t('agentByo.listen.verified', { name: issued.agentName })}
Expand Down
Loading