diff --git a/apps/emdash-desktop/src/main/core/pty/pty-env.test.ts b/apps/emdash-desktop/src/main/core/pty/pty-env.test.ts index 2f91378c33..7fa0686df4 100644 --- a/apps/emdash-desktop/src/main/core/pty/pty-env.test.ts +++ b/apps/emdash-desktop/src/main/core/pty/pty-env.test.ts @@ -127,6 +127,7 @@ describe('buildAgentEnv provider env forwarding', () => { GOOGLE_GENAI_API_VERSION: 'v1beta', GROK_CODE_XAI_API_KEY: 'xai-key', GROK_HOME: '/tmp/grok-home', + GROK_POOL_IDLE_TIMEOUT_SECS: '120', BAILIAN_CODING_PLAN_API_KEY: 'bailian-key', GOOSE_PROVIDER: 'openai', GOOSE_MODEL: 'gpt-5.1', diff --git a/apps/emdash-desktop/src/main/core/pty/pty-env.ts b/apps/emdash-desktop/src/main/core/pty/pty-env.ts index a121425063..24278a3665 100644 --- a/apps/emdash-desktop/src/main/core/pty/pty-env.ts +++ b/apps/emdash-desktop/src/main/core/pty/pty-env.ts @@ -64,6 +64,7 @@ export const AGENT_ENV_VARS = [ 'GROK_CODE_XAI_API_KEY', 'GROK_DEPLOYMENT_KEY', 'GROK_HOME', + 'GROK_POOL_IDLE_TIMEOUT_SECS', 'GROK_PROXY_URL', 'GROK_SANDBOX', 'HTTP_PROXY', diff --git a/apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.test.ts b/apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.test.ts index a972f47600..4ca151b9f4 100644 --- a/apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.test.ts +++ b/apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.test.ts @@ -18,4 +18,13 @@ describe('AGENT_PROVIDERS', () => { sessionIdOnResumeOnly: true, }); }); + + it('uses the current Grok docs URL while keeping the official installer as default', () => { + const grok = AGENT_PROVIDERS.find((provider) => provider.id === 'grok'); + + expect(grok).toMatchObject({ + docUrl: 'https://docs.x.ai/build/overview', + installCommand: 'curl -fsSL https://x.ai/cli/install.sh | bash', + }); + }); }); diff --git a/apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.ts b/apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.ts index 4cb88b8c9b..1eae0ba194 100644 --- a/apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.ts +++ b/apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.ts @@ -152,7 +152,7 @@ export const AGENT_PROVIDERS: AgentProviderDefinition[] = [ name: 'Grok', description: "xAI's Grok CLI for terminal-first coding sessions with plans, subagents, and parallel work.", - docUrl: 'https://x.ai/cli', + docUrl: 'https://docs.x.ai/build/overview', installCommand: 'curl -fsSL https://x.ai/cli/install.sh | bash', commands: ['grok'], versionArgs: ['--version'], diff --git a/packages/plugins/src/agents/impl/grok/index.ts b/packages/plugins/src/agents/impl/grok/index.ts index 30960085e5..5180e5ab25 100644 --- a/packages/plugins/src/agents/impl/grok/index.ts +++ b/packages/plugins/src/agents/impl/grok/index.ts @@ -9,7 +9,7 @@ export const plugin = definePlugin( name: 'Grok', description: "xAI's Grok CLI for terminal-first coding sessions with plans, subagents, and parallel work.", - websiteUrl: 'https://x.ai/cli', + websiteUrl: 'https://docs.x.ai/build/overview', }, { autoApprove: { @@ -28,19 +28,52 @@ export const plugin = definePlugin( { method: 'curl', command: 'curl -fsSL https://x.ai/cli/install.sh | bash', + updateCommand: 'grok update', + recommended: true, + }, + { + method: 'npm', + command: 'npm install -g @xai-official/grok@latest', + updateCommand: 'npm install -g @xai-official/grok@latest', + uninstallCommand: 'npm uninstall -g @xai-official/grok', }, ], linux: [ { method: 'curl', command: 'curl -fsSL https://x.ai/cli/install.sh | bash', + updateCommand: 'grok update', + recommended: true, + }, + { + method: 'npm', + command: 'npm install -g @xai-official/grok@latest', + updateCommand: 'npm install -g @xai-official/grok@latest', + uninstallCommand: 'npm uninstall -g @xai-official/grok', + }, + ], + windows: [ + { + method: 'powershell', + command: + 'powershell -ExecutionPolicy ByPass -c "irm https://x.ai/cli/install.ps1 | iex"', + updateCommand: 'grok update', + recommended: true, + }, + { + method: 'npm', + command: 'npm install -g @xai-official/grok@latest', + updateCommand: 'npm install -g @xai-official/grok@latest', + uninstallCommand: 'npm uninstall -g @xai-official/grok', }, ], }, + installDocs: 'https://docs.x.ai/build/overview', updates: { kind: 'supported', releaseSource: { - kind: 'none', + kind: 'npm', + package: '@xai-official/grok', }, update: { kind: 'package-manager', @@ -68,6 +101,7 @@ export const provider = registerPluginBehavior(plugin, { sessionIdFlag: '-r', sessionIdOnResumeOnly: true, resumeWithoutSessionFlag: '-r', + modelFlag: '-m', }), }, hooks: buildGrokHookConfig(), diff --git a/packages/plugins/src/agents/impl/index.test.ts b/packages/plugins/src/agents/impl/index.test.ts index 39edd5d787..350ecefb6c 100644 --- a/packages/plugins/src/agents/impl/index.test.ts +++ b/packages/plugins/src/agents/impl/index.test.ts @@ -144,6 +144,38 @@ describe('pluginRegistry', () => { }); }); + it('uses current Grok docs, npm release source, Windows install, and model flag', () => { + const grok = pluginRegistry.get('grok')!; + + expect(grok.metadata.websiteUrl).toBe('https://docs.x.ai/build/overview'); + expect(grok.capabilities.hostDependency.installDocs).toBe('https://docs.x.ai/build/overview'); + expect( + grok.capabilities.hostDependency.installCommands.macos?.map((opt) => opt.method) + ).toEqual(['curl', 'npm']); + expect(grok.capabilities.hostDependency.installCommands.macos?.[1]?.command).toBe( + 'npm install -g @xai-official/grok@latest' + ); + expect( + grok.capabilities.hostDependency.installCommands.windows?.map((opt) => opt.method) + ).toEqual(['powershell', 'npm']); + expect(grok.capabilities.hostDependency.updates).toMatchObject({ + kind: 'supported', + releaseSource: { kind: 'npm', package: '@xai-official/grok' }, + update: { kind: 'package-manager' }, + }); + + const result = grok.behavior.prompt!.buildCommand({ + cli: 'grok', + autoApprove: true, + initialPrompt: 'Fix the bug', + sessionId: 'conv-1', + isResuming: false, + model: 'my-model', + }); + + expect(result.args).toEqual(['--always-approve', '-m', 'my-model', 'Fix the bug']); + }); + it('uses the current Amp npm package for install and updates', () => { const amp = pluginRegistry.get('amp')!;