Skip to content

feat: Add autonomous grok-swarm-agent for iterative file modifications#16

Merged
KHAEntertainment merged 7 commits intomasterfrom
feature/grok-swarm-agent
Mar 21, 2026
Merged

feat: Add autonomous grok-swarm-agent for iterative file modifications#16
KHAEntertainment merged 7 commits intomasterfrom
feature/grok-swarm-agent

Conversation

@KHAEntertainment
Copy link
Copy Markdown
Owner

@KHAEntertainment KHAEntertainment commented Mar 21, 2026

Summary

Implements a new grok-swarm-agent mode that transforms grok-swarm from a one-shot API caller into an autonomous agent that can iteratively discover files, apply changes, and verify results.

Key Changes

  1. New src/agent/grok_agent.py - Autonomous agent loop with:

    • Automatic file discovery in target directories
    • Iterative Grok 4.20 calls (up to 5 iterations)
    • Multiple code block annotation formats supported
    • Dry-run preview mode (--apply to actually write)
    • Verification command support
  2. Fixed src/bridge/grok_bridge.py - Parser improvements:

    • Added pattern 1b for python:cli.py format (common Grok output)
    • Handle paths without trailing newlines
    • Better error messages for malformed annotations
  3. Claude Code Integration (platforms/claude/):

    • New skill grok-swarm-agent/SKILL.md
    • New command grok-swarm-agent.sh
    • Triggers: "grok agent", "autonomous grok", "agent mode"
  4. OpenClaw Integration (src/plugin/):

    • New grok_agent_plugin.ts tool registration
    • Updated openclaw.plugin.json config

How It Works

User: "grok agent refactor auth module" --target ./src --apply
         │
         ▼
┌─────────────────────────────────────────────────────┐
│  grok_agent.py                                     │
│  1. Discover files in ./src                       │
│  2. Call Grok 4.20 with context                  │
│  3. Parse code blocks (multiple formats)           │
│  4. Apply changes using Write/Edit tools          │
│  5. Verify (if --verify-cmd provided)             │
│  6. Iterate if needed (up to max-iterations)     │
└─────────────────────────────────────────────────────┘

Usage Examples

# Preview mode (default)
grok-swarm-agent "refactor auth module" --target ./src

# Actually apply changes
grok-swarm-agent "refactor auth module" --target ./src --apply

# With verification
grok-swarm-agent "add tests" --apply --verify-cmd "pytest"

Test Results

Successfully tested on .sandbox task manager:

  • Added --priority and --all flags to list command
  • Agent discovered files, applied changes, completed in 1 iteration
  • 3 files modified (cli.py, database.py, task_manager.py)

Related Issue

Fixes issue #14 - grok-swarm Write/Edit File Flow problems

Test Plan

  • Agent loop executes successfully with Grok 4.20
  • Files are discovered and context is passed correctly
  • Code blocks are parsed with python:filename format
  • Changes are applied when --apply flag is set
  • Preview mode shows what would be changed without writing
  • Works with both Claude Code and OpenClaw platforms

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added an autonomous Grok Swarm Agent for iterative multi-file modifications with preview and apply modes.
    • CLI supports task, --apply, --target, --max-iterations, and --verify-cmd.
    • Plugin exposes a grok_swarm_agent tool and lets you configure a custom agent script path.
  • Improvements

    • Better parsing of multiple code-block and file-annotation formats from AI responses.
    • Verification runs are timeout-bounded and return pass/fail output.
  • Documentation

    • Added skill documentation with usage examples and configuration notes.

Implements a new agent mode that goes beyond single API calls:

## New Features

### grok_agent.py - Autonomous Agent Loop
- Automatic file discovery in target directories
- Iterative Grok 4.20 calls with context aggregation
- Parses code blocks with multiple annotation formats:
  - lang:/path/to/file (e.g., python:/path/file.py)
  - // FILE: path/to/file (C-style markers)
  - # FILE: path/to/file (Python-style markers)
  - # filename.py (common Grok output format)
- Applies changes with dry-run preview mode
- Verification command support
- Max iteration limits

### Parser Fixes
- Fixed parse_and_write_files() to handle "python:cli.py" format
- Added pattern 1b for lang:path without trailing newline
- Added return statement that was missing
- Fixed grok_bridge.py with same improvements

### Claude Code Integration
- New SKILL.md for /grok-swarm-agent invocation
- New command script for Claude Code
- Triggers: "grok agent", "autonomous grok", "agent mode"

### OpenClaw Integration
- New grok_agent_plugin.ts tool registration
- Updated openclaw.plugin.json with agentScript config
- Works with existing grok-swarm plugin structure

## Usage

Preview mode:
```
grok-swarm-agent "refactor auth module" --target ./src
```

Apply changes:
```
grok-swarm-agent "refactor auth module" --target ./src --apply
```

With verification:
```
grok-swarm-agent "add tests" --apply --verify-cmd "pytest"
```

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 21, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 61137f9c-1d99-4553-aeb4-d24f1bfe53f7

📥 Commits

Reviewing files that changed from the base of the PR and between 35ca81b and 4d460a4.

📒 Files selected for processing (3)
  • src/agent/grok_agent.py
  • src/shared/__init__.py
  • src/shared/patterns.py

Walkthrough

Adds a new autonomous Grok multi-agent: a Bash launcher and Claude skill, a Python agent package/CLI implementing iterative discovery/edits/verification, a TypeScript plugin tool to invoke it, enhanced Grok response parsing, and shared parsing patterns.

Changes

Cohort / File(s) Summary
Claude Platform Integration
platforms/claude/commands/grok-swarm-agent.sh, platforms/claude/skills/grok-swarm-agent/SKILL.md
New Bash launcher that invokes the Python agent with argument parsing and usage; new Claude skill docs describing triggers and options (--apply, --target, --max-iterations, --verify-cmd).
Plugin Configuration & Tooling
skills/grok-refactor/openclaw.plugin.json, src/plugin/grok_agent_plugin.ts, src/plugin/index.ts
Added agentScript config property; new grok_swarm_agent tool that locates/validates agent script, spawns python3 with timeout/kill logic and returns structured JSON; adjusted SKILL_DIR resolution to use fileURLToPath.
Agent Core (Python)
src/agent/__init__.py, src/agent/grok_agent.py
New agent package and CLI: enums/dataclass for AgentState, file discovery, prompt building, Grok calls, multi-format code-block parsing, path sanitization, preview vs apply modes, optional verification command, iterative loop and exit-status summary.
Bridge Parsing & Writing
src/bridge/grok_bridge.py
Tightened fence-header regex, added filename-only # filename.ext extraction, broadened marker regex to accept // FILE: and # FILE: with optional whitespace, and ensured proper content extraction and control flow after matches.
Shared Patterns
src/shared/patterns.py, src/shared/__init__.py
New shared regex/constants module exposing filename-pattern string and supported extensions; package init added for imports.
New Public Executables / Docs
platforms/claude/commands/grok-swarm-agent.sh, platforms/claude/skills/grok-swarm-agent/SKILL.md
Introduced a new public executable script and corresponding skill documentation entry.

Sequence Diagram(s)

sequenceDiagram
    participant Claude as Claude Platform
    participant Shell as grok-swarm-agent.sh
    participant Agent as grok_agent.py
    participant FS as Target Filesystem
    participant Grok as Grok Bridge
    participant Verify as Verification Command

    Claude->>Shell: invoke with task & options
    Shell->>Agent: spawn python3 with args
    Agent->>FS: discover source files
    Agent->>Grok: call_grok(task, file context)
    Grok-->>Agent: return annotated response
    Agent->>Agent: parse_code_blocks / sanitize paths
    Agent->>FS: preview or write changes
    alt apply mode and verify_cmd provided
        Agent->>Verify: run verify-cmd (cwd=target)
        Verify-->>Agent: return verification output
    end
    Agent->>Agent: update state, check completion/iterations
    alt continue
        Agent->>Grok: next iteration
    else finish
        Agent-->>Shell: exit summary & status
        Shell-->>Claude: return result
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

"A tiny swarm of Grok takes flight,
Reading files by dim terminal light.
It plans, it edits, then runs the test,
Iterates onward — does its best.
Repo refreshed — the changes take flight." 🐝

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary addition: an autonomous grok-swarm-agent for iterative file modifications, which aligns with the main feature—a new autonomous loop that discovers files, calls Grok iteratively, applies edits, and verifies changes.
Docstring Coverage ✅ Passed Docstring coverage is 92.86% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/grok-swarm-agent

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (5)
src/agent/grok_agent.py (3)

354-362: Shell execution is intentional but worth documenting.

Using shell=True here allows compound commands like pytest tests/ -v && npm test, which is useful for verification. Since the user explicitly provides --verify-cmd when invoking the agent, the trust boundary is appropriate.

However, if this agent is ever invoked by an untrusted source (web hook, chat input), this becomes an injection vector. Consider adding a docstring note:

📝 Documentation suggestion
 def verify_changes(state: AgentState) -> tuple[bool, str]:
     """
     Run verification command.
+
+    WARNING: verify_cmd is executed via shell. Only invoke this agent
+    from trusted contexts where the user controls the command.

     Returns (success, output).
     """
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/agent/grok_agent.py` around lines 354 - 362, Add a short
docstring/comment near the subprocess.run call that explains why shell=True is
used and the associated trust assumptions: document that state.verify_cmd is
executed with shell=True to allow compound commands (e.g., "pytest ... && npm
test"), that this is only safe when the verify command is provided by a trusted
actor, and that invoking this agent from untrusted sources (webhooks, chat
input) can create command-injection risks; reference the subprocess.run
invocation and state.verify_cmd in the comment so future maintainers know why
shell=True was chosen and when to avoid it.

473-476: Completion detection heuristic may trigger false positives.

Checking for words like "done" or "complete" anywhere in the response is quite broad. Code or explanations might naturally contain these words (e.g., callback_done, "...once complete, call...") without meaning the agent's task is finished.

For an MVP this is acceptable, but consider adding more context (e.g., checking the last few lines, requiring a specific marker like [AGENT_DONE]).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/agent/grok_agent.py` around lines 473 - 476, The current heuristic in
grok_agent.py that lowercases response and checks any occurrence of tokens in
done_markers (response_lower, done_markers) is too broad and causes false
positives; change the check to only consider the last N lines or last M
characters of the response and require a stricter token (e.g., an exact
standalone word at end-of-line or a dedicated marker like "[AGENT_DONE]")
instead of substring matches—update the logic where response_lower is used (the
completion detection function) to first trim and split response into lines,
inspect only the tail (e.g., last 3 lines) for either an exact match of one of
the done_markers as a whole word or the explicit marker "[AGENT_DONE]", and only
then return True.

32-34: The sys.path manipulation works but is fragile.

Directly inserting into sys.path is like hotwiring a car — it works, but it's not how things are supposed to work. If the directory structure changes, this breaks silently.

For now, this is fine for an MVP script. If this grows, consider proper package installation or a setup.py/pyproject.toml that installs both modules.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/agent/grok_agent.py` around lines 32 - 34, The sys.path insertion that
adds Path(__file__).parent.parent / "bridge" is fragile; remove that
manipulation and instead import the bridge package properly by making bridge a
real package and installing it (e.g., add __init__.py and publish/install via
pyproject.toml or install in editable mode), then replace the dynamic import
with a normal import like from bridge.grok_bridge import call_grok, read_files
and delete the sys.path change; ensure the bridge package name matches when
updating imports so calls to call_grok and read_files continue to work.
src/plugin/grok_agent_plugin.ts (1)

49-55: Consider typing params with TypeBox's Static utility.

You've defined a nice schema with TypeBox, but params: any throws away that type safety. It's like building a fence but leaving the gate open.

✨ Type-safe params
+import { Type, Static } from "@sinclair/typebox";
+
+type GrokAgentParams = Static<typeof GrokAgentSchema>;

-      async execute(_toolCallId: string, params: any) {
+      async execute(_toolCallId: string, params: GrokAgentParams) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugin/grok_agent_plugin.ts` around lines 49 - 55, The execute method
currently accepts params: any which discards the TypeBox schema you defined;
change the signature to accept a typed params using TypeBox's Static utility
(import { Static } from '@sinclair/typebox') and use Static<typeof
YourParamsSchema> (replace YourParamsSchema with the actual schema identifier
you defined) so the method becomes async execute(_toolCallId: string, params:
Static<typeof YourParamsSchema>); update any internal uses that assume any to
match the stronger type and keep the existing json helper (function json)
unchanged.
platforms/claude/skills/grok-swarm-agent/SKILL.md (1)

14-18: Add language specifiers to fenced code blocks.

The markdownlint tool flags these blocks for missing language hints. Adding bash or shell helps syntax highlighters and screen readers.

📝 Quick fix
-```
+```bash
 use grok agent to refactor src/auth/
-```
+```bash
 # Preview mode - shows what would change

Also applies to: 38-50

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platforms/claude/skills/grok-swarm-agent/SKILL.md` around lines 14 - 18,
Update the fenced code blocks in SKILL.md so they include a language specifier
(e.g., add ```bash or ```shell after the opening backticks) for the blocks
containing shell/CLI commands (the examples starting with "use grok agent to
refactor src/auth/" and "# Preview mode - shows what would change"); apply the
same change to the other fenced blocks flagged (around the later examples in the
file) so all shell snippets have an explicit language hint for markdownlint and
syntax highlighting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@platforms/claude/commands/grok-swarm-agent.sh`:
- Around line 38-41: The catch-all case currently swallows unknown flags (the *)
branch that just does "shift"); update that branch to notify the user and fail
fast: detect the unknown option ($1), print a clear error to stderr (e.g.,
"Unknown option: $1") and suggest correct usage or show the script's usage/help,
then exit with a non-zero status instead of silently shifting; modify the *)
case in the argument-parsing switch so unknown flags are reported and the script
stops (or at minimum warns) rather than discarding them.
- Around line 61-65: The script builds CMD and calls eval which allows command
injection via TASK or VERIFY_CMD; replace the eval-based execution with a direct
exec/spawn call that passes arguments as an array (no shell interpolation) using
AGENT_SCRIPT as the program and the flags/values as separate args (e.g.
"--platform", "claude", "--target", "$TARGET", etc.), and change how VERIFY_CMD
is captured so it contains only the command value (not a precombined
"--verify-cmd value" string) before adding it to the args array; remove use of
CMD and eval entirely and invoke the Python process with the safe argument
array.

In `@src/agent/grok_agent.py`:
- Around line 217-231: The filename-detection uses filename_pattern.match(part)
which only checks the start of part and misses cases where a language tag
precedes the filename (e.g., "python\n# cli.py..."); update the logic in the
same block that sets language and part to first strip the language line into a
new variable (e.g., rest or after_language) and run filename_pattern.match (or
search) against that rest instead of part, then adjust how you compute
filename_line_end and slice content from rest so blocks.append still gets
language, path_hint, content.strip(), and inferred_path filled correctly
(references: variables part, language, filename_pattern, filename_match,
filename_line_end, blocks).
- Line 439: The print statements use f-strings but contain no placeholders;
remove the unnecessary f prefix so they are plain strings. Locate the print(...)
calls that look like print(f"...", file=sys.stderr) (the four occurrences noted
in the review) and change them to print("...", file=sys.stderr) so the f prefix
is not used when there are no {placeholders}.

In `@src/bridge/grok_bridge.py`:
- Around line 204-208: The filename_pattern in src/bridge/grok_bridge.py
diverges from the equivalent regex in src/agent/grok_agent.py (it includes
sh|bash and jsx|tsx), causing inconsistent parsing; update filename_pattern to
match the agent's pattern exactly or extract the extension list into a shared
constant/function (e.g., a shared EXTENSIONS list or get_filename_regex()) used
by both grok_bridge.py and grok_agent.py so both modules use the identical regex
(ensure updates to the symbol filename_pattern in grok_bridge.py and the
corresponding pattern in grok_agent.py reference the same centralized source).

In `@src/plugin/grok_agent_plugin.ts`:
- Around line 18-19: Replace usage of new URL(import.meta.url).pathname with
Node's fileURLToPath to avoid Windows leading-slash paths: import {
fileURLToPath } from "url" and compute PLUGIN_ROOT as
join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..") so DEFAULT_AGENT
stays correct; update the declarations referencing PLUGIN_ROOT and DEFAULT_AGENT
accordingly. Also make the same change for the other module that uses
import.meta.url (the plugin index module) by switching its import.meta.url
handling to fileURLToPath/import.meta.url and using
dirname(fileURLToPath(import.meta.url)) before joining paths.

---

Nitpick comments:
In `@platforms/claude/skills/grok-swarm-agent/SKILL.md`:
- Around line 14-18: Update the fenced code blocks in SKILL.md so they include a
language specifier (e.g., add ```bash or ```shell after the opening backticks)
for the blocks containing shell/CLI commands (the examples starting with "use
grok agent to refactor src/auth/" and "# Preview mode - shows what would
change"); apply the same change to the other fenced blocks flagged (around the
later examples in the file) so all shell snippets have an explicit language hint
for markdownlint and syntax highlighting.

In `@src/agent/grok_agent.py`:
- Around line 354-362: Add a short docstring/comment near the subprocess.run
call that explains why shell=True is used and the associated trust assumptions:
document that state.verify_cmd is executed with shell=True to allow compound
commands (e.g., "pytest ... && npm test"), that this is only safe when the
verify command is provided by a trusted actor, and that invoking this agent from
untrusted sources (webhooks, chat input) can create command-injection risks;
reference the subprocess.run invocation and state.verify_cmd in the comment so
future maintainers know why shell=True was chosen and when to avoid it.
- Around line 473-476: The current heuristic in grok_agent.py that lowercases
response and checks any occurrence of tokens in done_markers (response_lower,
done_markers) is too broad and causes false positives; change the check to only
consider the last N lines or last M characters of the response and require a
stricter token (e.g., an exact standalone word at end-of-line or a dedicated
marker like "[AGENT_DONE]") instead of substring matches—update the logic where
response_lower is used (the completion detection function) to first trim and
split response into lines, inspect only the tail (e.g., last 3 lines) for either
an exact match of one of the done_markers as a whole word or the explicit marker
"[AGENT_DONE]", and only then return True.
- Around line 32-34: The sys.path insertion that adds
Path(__file__).parent.parent / "bridge" is fragile; remove that manipulation and
instead import the bridge package properly by making bridge a real package and
installing it (e.g., add __init__.py and publish/install via pyproject.toml or
install in editable mode), then replace the dynamic import with a normal import
like from bridge.grok_bridge import call_grok, read_files and delete the
sys.path change; ensure the bridge package name matches when updating imports so
calls to call_grok and read_files continue to work.

In `@src/plugin/grok_agent_plugin.ts`:
- Around line 49-55: The execute method currently accepts params: any which
discards the TypeBox schema you defined; change the signature to accept a typed
params using TypeBox's Static utility (import { Static } from
'@sinclair/typebox') and use Static<typeof YourParamsSchema> (replace
YourParamsSchema with the actual schema identifier you defined) so the method
becomes async execute(_toolCallId: string, params: Static<typeof
YourParamsSchema>); update any internal uses that assume any to match the
stronger type and keep the existing json helper (function json) unchanged.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4555c191-3851-4266-9126-4ddaf632174b

📥 Commits

Reviewing files that changed from the base of the PR and between 13de3a6 and 65c6b6b.

📒 Files selected for processing (7)
  • platforms/claude/commands/grok-swarm-agent.sh
  • platforms/claude/skills/grok-swarm-agent/SKILL.md
  • skills/grok-refactor/openclaw.plugin.json
  • src/agent/__init__.py
  • src/agent/grok_agent.py
  • src/bridge/grok_bridge.py
  • src/plugin/grok_agent_plugin.ts

Comment thread platforms/claude/commands/grok-swarm-agent.sh
Comment thread platforms/claude/commands/grok-swarm-agent.sh Outdated
Comment thread src/agent/grok_agent.py
Comment thread src/agent/grok_agent.py Outdated
Comment thread src/bridge/grok_bridge.py
Comment thread src/plugin/grok_agent_plugin.ts Outdated
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 21, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 5 file(s) based on 6 unresolved review comments.

Files modified:

  • platforms/claude/commands/grok-swarm-agent.sh
  • src/agent/grok_agent.py
  • src/bridge/grok_bridge.py
  • src/plugin/grok_agent_plugin.ts
  • src/plugin/index.ts

Commit: 35550a9527cb10e9f057b9ebd51efe1e23a7c11b

The changes have been pushed to the feature/grok-swarm-agent branch.

Time taken: 4m 13s

Fixed 5 file(s) based on 6 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/plugin/index.ts (1)

144-148: Consider clearing the SIGKILL fallback timeout.

If the process exits gracefully after receiving SIGTERM (but before the 5-second SIGKILL fires), the inner timeout still lingers. While calling kill("SIGKILL") on an already-dead process is harmless (it just returns false), storing and clearing this timeout would be tidier—like turning off the stove even after you've already removed the pot.

🧹 Optional: Track and clear the SIGKILL timeout
             const timer = setTimeout(() => {
               timedOut = true;
               child.kill("SIGTERM");
-              setTimeout(() => child.kill("SIGKILL"), 5000);
+              killTimer = setTimeout(() => child.kill("SIGKILL"), 5000);
             }, timeout * 1000);
+
+            let killTimer: ReturnType<typeof setTimeout> | undefined;

Then in the close handler:

             child.on("close", (code: number | null) => {
               clearTimeout(timer);
+              if (killTimer) clearTimeout(killTimer);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugin/index.ts` around lines 144 - 148, The SIGKILL fallback timeout
created inside the setTimeout should be stored in a variable (e.g.,
sigkillTimer) so it can be cleared if the child process exits after SIGTERM;
update the block where you call child.kill("SIGTERM") to assign the inner
setTimeout to sigkillTimer, and in the child's 'close' (or exit) handler clear
both timer and sigkillTimer (and also clear timer if the process exits before
the initial timeout) to avoid dangling timers; reference symbols: timer,
sigkillTimer (new), timedOut, child.kill("SIGTERM"), child.kill("SIGKILL"), and
the child 'close'/'exit' handler when making changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/agent/grok_agent.py`:
- Around line 470-488: The loop currently lets response prose (done_markers)
override a failed verification recorded in state.errors; change the control flow
so the result of verify_changes is honored: when state.verify_cmd and
state.apply run verify_changes (the call in verify_changes), capture the boolean
success and if it is False (or state.errors non-empty) prevent returning True
based on response_lower/done_markers — i.e., only evaluate done_markers when
verification either wasn't requested or succeeded; use the existing symbols
(state.verify_cmd, state.apply, verify_changes, state.errors, response_lower,
done_markers, parse_code_blocks, state.iteration) to gate the early return so a
failed verification blocks the success path.
- Around line 16-19: The CLI examples use a named flag (--task) but the
ArgumentParser defines task as a positional argument; make them consistent by
changing the argparse add_argument for task to a named option (e.g.,
parser.add_argument('--task', '-t', required=True, dest='task', help=...)) or
alternately update all examples/wrappers to pass the task positionally; also
update any other argparse references in parse_args/main that assume a positional
task (and the help text) so the code and docs match.
- Around line 205-223: The file_marker_pattern and filename_pattern are
currently searched across the entire code block (variable part / rest), causing
interior comments to be mis-parsed as path annotations; restrict both checks to
only the first non-language line immediately after the fence. Concretely:
compute the first_non_lang_line from rest (e.g., split rest into lines and take
the first non-empty line), run file_marker_pattern.search and
filename_pattern.search against that single line instead of part/rest, and if a
marker is found remove only that first line from the content (update content =
rest after the first line) before appending to blocks; update references to
marker_match, filename_match, content, part, and rest accordingly.
- Around line 89-90: apply_changes_from_response() currently constructs
target_path by naive joining (Path(state.target) / path_hint) which allows
absolute paths, ../ traversal and file-as-directory corruption; fix by routing
every write through a single sanitized destination resolver (e.g., new function
sanitize_target_path(path_hint, state.target, output_dir)) and use it everywhere
(apply_changes_from_response, parse_and_write_files, verify_changes,
discover_files call sites). The sanitizer must: 1) treat path_hint as a relative
path only (reject or strip leading "/" and "~"), 2) resolve and reject any path
that escapes the canonicalized target/output_dir root (use Path.resolve() then
ensure .is_relative_to(root) or equivalent), 3) if state.target is a file, treat
its parent as the root or refuse writes into it, and 4) honor the --output-dir
flag as the final write root when provided; replace direct
Path(state.target)/path_hint joins with calls to this sanitizer and return a
safe Path or raise/skip invalid hints.

---

Nitpick comments:
In `@src/plugin/index.ts`:
- Around line 144-148: The SIGKILL fallback timeout created inside the
setTimeout should be stored in a variable (e.g., sigkillTimer) so it can be
cleared if the child process exits after SIGTERM; update the block where you
call child.kill("SIGTERM") to assign the inner setTimeout to sigkillTimer, and
in the child's 'close' (or exit) handler clear both timer and sigkillTimer (and
also clear timer if the process exits before the initial timeout) to avoid
dangling timers; reference symbols: timer, sigkillTimer (new), timedOut,
child.kill("SIGTERM"), child.kill("SIGKILL"), and the child 'close'/'exit'
handler when making changes.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 69a7ab61-9967-4ead-a4f3-a2c7ac82817f

📥 Commits

Reviewing files that changed from the base of the PR and between 65c6b6b and 35550a9.

📒 Files selected for processing (5)
  • platforms/claude/commands/grok-swarm-agent.sh
  • src/agent/grok_agent.py
  • src/bridge/grok_bridge.py
  • src/plugin/grok_agent_plugin.ts
  • src/plugin/index.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • platforms/claude/commands/grok-swarm-agent.sh
  • src/plugin/grok_agent_plugin.ts
  • src/bridge/grok_bridge.py

Comment thread src/agent/grok_agent.py
Comment thread src/agent/grok_agent.py
Comment thread src/agent/grok_agent.py Outdated
Comment thread src/agent/grok_agent.py
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 21, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 4 unresolved review comments.

Files modified:

  • src/agent/grok_agent.py

Commit: 35ca81be34f1e0ab57c004769ed92fa2820f58aa

The changes have been pushed to the feature/grok-swarm-agent branch.

Time taken: 5m 55s

Fixed 1 file(s) based on 4 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
src/agent/grok_agent.py (1)

387-389: ⚠️ Potential issue | 🟠 Major

Verify the same tree you just wrote.

apply_changes_from_response() writes under output_dir when it is set and already treats a file target as “use the parent directory”. verify_changes() ignores both and always uses cwd=state.target, so --target path/to/file.py can fail with NotADirectoryError, and --output-dir verifies the stale tree instead of the generated one.

Suggested fix
+def get_work_root(state: AgentState) -> Path:
+    root = Path(state.output_dir) if state.output_dir else Path(state.target)
+    return root.parent if root.is_file() else root
+
 ...
-            base_root = state.output_dir if state.output_dir else state.target
-            target_path = sanitize_target_path(path_hint, base_root)
+            target_path = sanitize_target_path(path_hint, str(get_work_root(state)))
 ...
-            cwd=state.target,
+            cwd=get_work_root(state),

Also applies to: 419-425

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/agent/grok_agent.py` around lines 387 - 389, verify_changes() is using
cwd=state.target unconditionally which causes NotADirectoryError and verifies
the wrong tree when state.output_dir is set; change verify_changes() to compute
base_root the same way apply_changes_from_response() does (base_root =
state.output_dir if state.output_dir else state.target) and call
sanitize_target_path(path_hint, base_root) to get target_path/parent dir, then
use cwd=target_path (or its parent for file targets) so verification runs
against the actual generated output; apply the same fix to the duplicate block
around the 419-425 logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/agent/grok_agent.py`:
- Around line 474-481: The prompt returned by the function currently only
includes task, state.iteration/state.max_iterations and state.last_response;
update it to also include the verifier output (e.g., the variable capturing
verification failure such as verifier_output or verification_result) so the next
iteration sees why the previous attempt failed; modify the formatted string that
returns "Continue working on: {task}..." to append a labeled "Verifier output /
failure:" section containing the verifier text (or a truncated subset) and make
the same change wherever the previous-response-only prompt is produced (the
other occurrence around the verifier capture).
- Around line 387-389: The code currently applies state.output_dir to every
write by setting base_root = state.output_dir if state.output_dir else
state.target; change this so state.output_dir is used only for new files:
compute base_root = state.output_dir if (state.output_dir and the target is a
new file) else state.target. Determine "new file" by checking whether path_hint
refers to a non-existent file on disk (or an existing/new-file flag on state if
available) before calling sanitize_target_path(path_hint, base_root); also
update the CLI help text (lines referenced in the review) to match this
behavior. Ensure you touch the logic that builds target_path and any helper that
calls sanitize_target_path so existing-file edits continue to use state.target
while only newly created files are redirected to state.output_dir.
- Around line 505-514: call_grok() currently calls sys.exit() on failures which
raises SystemExit and bypasses the except Exception handler in this refactor
block; change the error handling so SystemExit is handled gracefully: either
(preferred) update call_grok to raise a regular exception (or a custom
exception) instead of calling sys.exit(), or (quicker) add an except SystemExit
as se: block around the call to call_grok (the call inside the try in
grok_agent.py) that converts the SystemExit into a handled error (append to
state.errors, print to stderr, and return False) so
state.last_response/state.errors are updated and the agent loop can continue;
reference call_grok, SystemExit, state.errors, and the try/except block
surrounding the Grok call when making the change.

---

Duplicate comments:
In `@src/agent/grok_agent.py`:
- Around line 387-389: verify_changes() is using cwd=state.target
unconditionally which causes NotADirectoryError and verifies the wrong tree when
state.output_dir is set; change verify_changes() to compute base_root the same
way apply_changes_from_response() does (base_root = state.output_dir if
state.output_dir else state.target) and call sanitize_target_path(path_hint,
base_root) to get target_path/parent dir, then use cwd=target_path (or its
parent for file targets) so verification runs against the actual generated
output; apply the same fix to the duplicate block around the 419-425 logic.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8b166b72-4d31-47a0-88aa-c5008ae66613

📥 Commits

Reviewing files that changed from the base of the PR and between 35550a9 and 35ca81b.

📒 Files selected for processing (1)
  • src/agent/grok_agent.py

Comment thread src/agent/grok_agent.py Outdated
Comment thread src/agent/grok_agent.py Outdated
Comment thread src/agent/grok_agent.py
KHAEntertainment pushed a commit that referenced this pull request Mar 21, 2026
Brings in the grok-swarm-agent feature from the open PR on
feature/grok-swarm-agent, fixing three regressions before landing:

Bug fixes vs. the open PR:
- Created src/shared/patterns.py (get_filename_pattern_string()) which
  was imported but never committed, causing ImportError at startup
- Fixed lang_path_pattern in grok_agent.py to match relative paths
  (python:cli.py) in addition to absolute paths — the PR's narrowed
  pattern ^(\w+):(/...) silently dropped relative-path annotations
- src/bridge/grok_bridge.py now imports shared patterns gracefully
  (try/except) so the bridge still works without the shared module

New files:
- src/shared/__init__.py + patterns.py — shared regex utilities
- src/agent/__init__.py + grok_agent.py — autonomous iterative agent loop
  (file discovery → Grok call → parse/apply → verify → iterate up to 5x)
- src/plugin/grok_agent_plugin.ts — OpenClaw/Claude Code tool registration
- platforms/claude/skills/grok-swarm-agent/SKILL.md — skill documentation
- platforms/claude/commands/grok-swarm-agent.sh — slash command

Updated:
- src/plugin/index.ts — imports and registers the agent tool

Closes #16

https://claude.ai/code/session_01No9S6TZbfTgocHwHYWwxRN
KHAEntertainment pushed a commit that referenced this pull request Mar 21, 2026
Applies all issue fixes (#14, #12, #11, #16) to the duplicate
skills/grok-refactor/bridge/ files so both installation paths stay
in parity:

- grok_bridge.py: absolute path rebasing, fallback response save,
  grounding prompt, usage tracking, shared patterns Pattern 3
- usage_tracker.py: new (copied from src/bridge/)
- shared/patterns.py: new (provides get_filename_pattern_string())
- SKILL.md: documents grounding prompt config and stats subcommand

https://claude.ai/code/session_01No9S6TZbfTgocHwHYWwxRN
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 21, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 3 unresolved review comments.

Files modified:

  • src/agent/grok_agent.py

Commit: ca49d2328666b1a29df3ccb9a0e1f5ef9c44236c

The changes have been pushed to the feature/grok-swarm-agent branch.

Time taken: 2m 43s

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 21, 2026

@KHAEntertainment I've opened a new pull request, #19, to work on those changes. Once the pull request is ready, I'll request review from you.

coderabbitai bot and others added 3 commits March 21, 2026 05:19
Fixed 1 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
…tern_string()

Co-authored-by: KHAEntertainment <43256680+KHAEntertainment@users.noreply.github.com>
Agent-Logs-Url: https://github.com/KHAEntertainment/grok-multiagent-plugin/sessions/c147bc88-9dac-4881-9e47-f0f87afc51d0
fix: Centralize filename regex into shared patterns module
@KHAEntertainment KHAEntertainment merged commit f93b9b8 into master Mar 21, 2026
1 check was pending
KHAEntertainment pushed a commit that referenced this pull request Mar 21, 2026
Resolve conflicts by keeping master (PR #16) canonical versions
for all overlapping files, preserving the PR branch's non-conflicting
ESM fix in src/plugin/index.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
KHAEntertainment added a commit that referenced this pull request Mar 21, 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.

2 participants