Skip to content

feat(clink): add Grok Build and OpenCode CLI clients - #464

Closed
skibitskiy wants to merge 2 commits into
BeehiveInnovations:mainfrom
skibitskiy:feat/clink-grok-opencode
Closed

feat(clink): add Grok Build and OpenCode CLI clients#464
skibitskiy wants to merge 2 commits into
BeehiveInnovations:mainfrom
skibitskiy:feat/clink-grok-opencode

Conversation

@skibitskiy

Copy link
Copy Markdown

Summary

  • Add clink support for Grok Build (grok) and OpenCode (opencode) so PAL can spawn them as external CLI agents
  • Ship parsers/agents, CLI presets, roles, and unit tests for both clients
  • Document Grok Build MCP setup (local checkout + uvx) and add examples/grok_config_example.toml

Clink clients

CLI Command shape Parser
grok grok --prompt-file <tmp> --output-format json --always-approve grok_json
opencode opencode run --format json --auto <message> opencode_jsonl

Grok headless does not read stdin (uses --prompt-file). OpenCode takes the message as a positional arg; large prompts are attached via --file.

Test plan

  • pytest tests/test_clink_parsers.py tests/test_clink_grok_agent.py tests/test_clink_opencode_agent.py tests/test_clink_tool.py -q
  • Existing clink agent tests still pass (claude/codex/gemini)
  • Install grok / opencode CLIs and run a live clink smoke call for each
  • Confirm role presets (default, planner, codereviewer) load from conf/cli_clients/

moskibitskiy added 2 commits July 9, 2026 23:29
Enable clink to spawn Grok Build and OpenCode headless agents with
JSON parsers, role presets, and tests for prompt delivery and recovery.
Document local and uvx registration for Grok Build, and ship a
config.toml example with recommended timeouts.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 34df1f73b4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread clink/agents/grok.py
command.extend(self.client.config_args)

if self._pending_prompt_file:
command.extend(["--prompt-file", self._pending_prompt_file])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use Grok's supported headless prompt flag

When cli_name='grok', every request is launched as grok ... --prompt-file <tmp> while stdin is empty, but xAI's Grok Build Headless & Scripting docs (https://docs.x.ai/build/cli/headless-scripting) document headless prompts via grok -p "Your prompt here" / -p, --single <PROMPT> and list no --prompt-file flag. In that environment the new Grok integration exits on an unknown flag instead of running the prompt, so clink's advertised Grok support is unusable until the prompt is supplied through the supported headless interface.

Useful? React with 👍 / 👎.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for two new AI CLI agents, Grok Build (grok) and OpenCode (opencode), by updating the documentation, registering the agents, defining their CLI configurations, and adding a JSON parser for Grok. However, several critical issues were identified: the implementation files clink/agents/grok.py and clink/parsers/opencode.py are missing from the PR, which will cause immediate import and test failures. Additionally, type annotations should be added for the client parameter in OpenCodeAgent, and request-specific state variables should be refactored to prevent concurrency issues during asynchronous execution.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread clink/agents/__init__.py
from .claude import ClaudeAgent
from .codex import CodexAgent
from .gemini import GeminiAgent
from .grok import GrokAgent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The file clink/agents/grok.py is missing from this pull request. Importing GrokAgent here will raise a ModuleNotFoundError / ImportError immediately, breaking the application. Please ensure clink/agents/grok.py is added to the repository.

from clink.parsers.base import ParserError
from clink.parsers.codex import CodexJSONLParser
from clink.parsers.grok import GrokJSONParser
from clink.parsers.opencode import OpenCodeJSONLParser

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The file clink/parsers/opencode.py is missing from this pull request. Importing OpenCodeJSONLParser here will raise a ModuleNotFoundError / ImportError when running the tests. Please ensure clink/parsers/opencode.py is added to the repository.

Comment thread clink/agents/opencode.py
from collections.abc import Sequence
from pathlib import Path

from clink.models import ResolvedCLIRole

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Import ResolvedCLIClient to allow proper type annotation for the client parameter in __init__.

Suggested change
from clink.models import ResolvedCLIRole
from clink.models import ResolvedCLIClient, ResolvedCLIRole

Comment thread clink/agents/opencode.py
Comment on lines +27 to +28
def __init__(self, client):
super().__init__(client)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add type annotation for the client parameter to improve type safety and maintainability.

Suggested change
def __init__(self, client):
super().__init__(client)
def __init__(self, client: ResolvedCLIClient):
super().__init__(client)

Comment thread clink/agents/opencode.py
Comment on lines +29 to +30
self._pending_message: str | None = None
self._pending_prompt_file: str | None = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Storing request-specific state (_pending_message and _pending_prompt_file) as instance variables makes the agent stateful and unsafe for concurrent execution. If multiple asynchronous tasks call run concurrently on the same agent instance, they will overwrite each other's state.

Consider using contextvars.ContextVar to store these values safely across asynchronous tasks, or refactoring the base class to allow passing the prompt directly to _build_command.

@skibitskiy skibitskiy closed this Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant