Skip to content

fix: mode-aware response handling and PGP block stripping#27

Merged
KHAEntertainment merged 4 commits intomasterfrom
fix/26-pgp-text-response
Mar 31, 2026
Merged

fix: mode-aware response handling and PGP block stripping#27
KHAEntertainment merged 4 commits intomasterfrom
fix/26-pgp-text-response

Conversation

@KHAEntertainment
Copy link
Copy Markdown
Owner

@KHAEntertainment KHAEntertainment commented Mar 31, 2026

Summary

  • Add PGP block detection and stripping to filter xAI encrypted sub-agent state from responses before file parsing
  • Fix --write-files to handle text-only responses gracefully: text modes (analyze/reason/orchestrate) print to stdout instead of erroring, code modes save fallback with WARNING instead of ERROR + exit(1)
  • Add CLAUDE.md for AI assistant project guidance and .claude/skills/grok-multi-agent-api/ skill for xAI API reference

Details

The parse_and_write_files() function treated all non-code responses as fatal errors when --write-files was enabled — exiting with code 1 and printing "ERROR". This broke legitimate text responses from analyze, reason, and orchestrate modes.

Changes applied to both bridge files:

  • src/bridge/grok_bridge.py — primary fix target
  • skills/grok-refactor/bridge/grok_bridge.py — synced copy

Key changes:

  1. TEXT_MODES constant — identifies modes that normally return text, not code
  2. PGP_BLOCK_PATTERN regex — detects -----BEGIN PGP MESSAGE-----...-----END PGP MESSAGE----- blocks
  3. strip_pgp_blocks() — strips encrypted sub-agent state before parsing
  4. Mode-aware --write-files branch — text modes print to stdout (exit 0), code modes warn but don't fail (exit 0)

Closes #26

Test plan

  • Verify --mode analyze --write-files with text response prints to stdout and exits 0
  • Verify --mode refactor --write-files with annotated code blocks writes files and exits 0
  • Verify --mode refactor --write-files without annotations saves fallback with WARNING and exits 0
  • Verify PGP blocks in responses are stripped before parsing
  • npm run build && npm test pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Added Grok Multi-Agent API integration docs with endpoints, usage examples, and configuration notes.
    • Added Claude Code integration guide covering setup, architecture, and usage.
    • Simplified project tasks/status document with updated checklist and pending items.
  • Bug Fixes

    • Strips PGP-encrypted blocks from model outputs to prevent exposing armored content.
    • Improves output handling: cleaned responses are saved/printed reliably and no longer cause error exits when no annotated files are produced.

KHAEntertainment and others added 2 commits March 31, 2026 12:27
Add PGP block detection to strip encrypted sub-agent state from Grok
responses before parsing. Fix --write-files to handle text-only responses
gracefully: text modes (analyze/reason/orchestrate) print to stdout,
code modes save fallback with WARNING instead of ERROR + exit(1).

Also adds CLAUDE.md for AI assistant guidance, xAI multi-agent API
skill reference, and condenses TASKS.md to current actionable items.

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

coderabbitai bot commented Mar 31, 2026

Warning

Rate limit exceeded

@KHAEntertainment has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 23 minutes and 32 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 23 minutes and 32 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 689b443d-b7fe-483b-b6ad-dcf663a0acef

📥 Commits

Reviewing files that changed from the base of the PR and between b11d3c0 and cf8b9c8.

📒 Files selected for processing (2)
  • CLAUDE.md
  • tasks.md

Walkthrough

Added Grok Multi-Agent API and Claude Code integration docs; introduced PGP-armored block detection/stripping and changed bridge scripts to emit cleaned text responses (or save them with a warning) instead of treating missing annotated files as errors.

Changes

Cohort / File(s) Summary
Documentation & Tasks
.claude/skills/grok-multi-agent-api/SKILL.md, CLAUDE.md, TASKS.md
New Grok multi-agent skill doc and Claude integration guide; replaced verbose project-status doc with a concise task checklist and sync notes.
Bridge: PGP stripping & response handling
skills/grok-refactor/bridge/grok_bridge.py, src/bridge/grok_bridge.py
Added TEXT_MODES and PGP_BLOCK_PATTERN, implemented strip_pgp_blocks(text); normalize responses once, run parsing on cleaned text, print cleaned output for text modes, and save-and-warn (no non-zero exit) when no annotated files found.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

PGP fences swept away with care,
Clean text flows out into the air.
When code isn't found, a gentle note—
Saved and warned, not a failing vote.
A quieter bridge, a smoother share.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive Documentation files (CLAUDE.md, SKILL.md, TASKS.md) provide context but fall outside issue #26 scope; core bridge changes directly address the issue. Clarify whether documentation additions were necessary for the fix or if they should be separated into a follow-up PR for better change isolation.
✅ 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 directly and accurately summarizes the main changes: implementing mode-aware response handling and PGP block stripping from encrypted sub-agent state.
Linked Issues check ✅ Passed All objectives from issue #26 are met: PGP detection via regex is implemented, mode-aware processing differentiates text modes, and graceful fallback behavior replaces error exits.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/26-pgp-text-response

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: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/skills/grok-multi-agent-api/SKILL.md:
- Around line 107-113: Add an import for the os module at the top of the file
(so os.getenv(...) used in the OpenAI client instantiation works) and update the
streaming usage: replace any occurrences of the invalid pattern
client.chat.create(...).stream() (or client.chat.create(...).stream) with the
SDK's streaming parameter form, e.g., call the completions creation method
client.chat.completions.create(..., stream=True) so that streaming is enabled
via the stream=True argument; locate these changes around the OpenAI
instantiation and streaming examples referenced by the symbols OpenAI,
os.getenv, client.chat.create, and client.chat.completions.create.

In `@CLAUDE.md`:
- Line 97: The documentation currently shows literal version examples that are
out of sync; update CLAUDE.md (around the "Version is defined in multiple
places..." line) to remove hard-coded version literals and instead instruct
readers to use a single canonical source or a placeholder token (e.g.,
"<VERSION>") and list the files to update: package.json, VERSION,
pyproject.toml, CLAWHUB.md, .claude-plugin/marketplace.json, and
platforms/claude/.claude-plugin/plugin.json; ensure the text advises to keep
those files synchronized but does not include stale inline version numbers.

In `@skills/grok-refactor/bridge/grok_bridge.py`:
- Around line 530-531: The output is being written from the raw variable result
before PGP stripping, so files written via --output may contain armored blocks;
call strip_pgp_blocks(result) first and use the cleaned_result for all
subsequent write operations (both the direct --output write and
parse_and_write_files), i.e., replace usages of result when writing to
args.output_dir with cleaned_result and ensure
parse_and_write_files(cleaned_result, args.output_dir) continues to be used so
both paths receive the normalized content (functions: strip_pgp_blocks,
parse_and_write_files, variable: result/cleaned_result).

In `@src/bridge/grok_bridge.py`:
- Around line 484-485: The code currently writes the raw `result` to the
`--output` path before calling `strip_pgp_blocks`, causing `--output` to contain
unstripped PGP blocks while `parse_and_write_files` gets the cleaned payload;
fix by using a single cleaned payload source: call `strip_pgp_blocks(result)`
first, store it (e.g., `cleaned_result`), then use that same `cleaned_result`
for both writing the `--output` target and for
`parse_and_write_files(cleaned_result, args.output_dir)` so both outputs are
consistently sanitized; update any code that writes `result` directly to use
`cleaned_result` instead.

In `@TASKS.md`:
- Line 25: The "Status: Documentation Complete ✅" line is incorrect given the
unfinished docs noted earlier (line 18); update the status line (the "Status:
Documentation Complete ✅" text) to accurately reflect that docs are still
pending—for example change it to "Status: Documentation In Progress ⚠️" or
"Pending: Documentation Remaining" and ensure it matches the tracking item on
line 18 so the file shows consistent documentation status.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c910ac2b-6dec-4603-a939-1dbec5c3f350

📥 Commits

Reviewing files that changed from the base of the PR and between 2378f9b and 85d7561.

📒 Files selected for processing (5)
  • .claude/skills/grok-multi-agent-api/SKILL.md
  • CLAUDE.md
  • TASKS.md
  • skills/grok-refactor/bridge/grok_bridge.py
  • src/bridge/grok_bridge.py

Comment on lines +107 to +113
```python
from openai import OpenAI

client = OpenAI(
api_key=os.getenv("OPENROUTER_API_KEY"),
base_url="https://openrouter.ai/api/v1",
)
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 31, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

`For the current Python OpenAI SDK, what are the valid streaming call patterns for:

  1. chat completions
  2. responses API
    Is client.chat.create(...).stream() valid? Also confirm whether examples using os.getenv(...) require import os.`

💡 Result:

1) Chat Completions streaming (Python SDK)

Valid pattern (SSE token streaming):

stream = client.chat.completions.create(
    model="…",
    messages=[...],
    stream=True,
)

for chunk in stream:
    ...

This is driven by the stream request parameter on the Chat Completions create call. [1]

Notes:

  • The resource is client.chat.completions.create(...) (not client.chat.create(...)). [2]
  • The SDK also supports HTTP-body streaming (not “model delta events”) via:
    client.chat.completions.with_streaming_response.create(...) (context manager + iter_lines(), etc.). [3]

2) Responses API streaming (Python SDK)

Valid pattern (SSE events):

stream = client.responses.create(
    model="…",
    input="…",   # or input=[...]
    stream=True,
)

for event in stream:
    ...

(and async for with AsyncOpenAI). [3][4]

Is client.chat.create(...).stream() valid?

No.

  • client.chat.completions.create(..., stream=True) is the supported streaming shape for Chat Completions (and client.responses.create(..., stream=True) for Responses). [2][3]
  • .stream() is not the documented Python call pattern for those endpoints. [2][3]

Do examples using os.getenv(...) require import os?

Yes—os.getenv(...) requires import os (or import os as ...) in that module. The official Python examples that use env vars explicitly import os (often using os.environ.get(...), which likewise requires import os). [3]

Sources:
[1] https://platform.openai.com/docs/api-reference/chat/create/
[2] https://github.com/openai/openai-python/blob/main/api.md
[3] https://github.com/openai/openai-python
[4] https://platform.openai.com/docs/guides/streaming-responses


Fix missing import os and correct the streaming API pattern.

The code snippet uses os.getenv() on line 109 without importing os at the top of the file—this will fail at runtime with a NameError. Additionally, the streaming examples in this section (lines 107–113, also 141–151) likely use client.chat.create(...).stream(), which isn't a valid pattern in the Python OpenAI SDK. The correct approach is to pass stream=True to the create call itself: client.chat.completions.create(..., stream=True). Think of it like the difference between asking for a fire hose with .stream() at the end versus telling the vendor upfront you want the streaming version of the product.

Add import os at the top of the file and update the streaming calls to use the stream=True parameter instead of the .stream() method suffix.

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

In @.claude/skills/grok-multi-agent-api/SKILL.md around lines 107 - 113, Add an
import for the os module at the top of the file (so os.getenv(...) used in the
OpenAI client instantiation works) and update the streaming usage: replace any
occurrences of the invalid pattern client.chat.create(...).stream() (or
client.chat.create(...).stream) with the SDK's streaming parameter form, e.g.,
call the completions creation method client.chat.completions.create(...,
stream=True) so that streaming is enabled via the stream=True argument; locate
these changes around the OpenAI instantiation and streaming examples referenced
by the symbols OpenAI, os.getenv, client.chat.create, and
client.chat.completions.create.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@coderabbitai Not addressed (reviewer appears to be incorrect):

  1. ❌ SKILL.md (grok-multi-agent-api): Reviewer said to add import os at top of
    file - but this is a Markdown documentation file, not Python code. The import os is
    correctly placed inside a code example. Also, reviewer wants to change
    client.chat.create().stream() to client.chat.completions.create(..., stream=True) -
    but this file documents the xAI SDK which uses the chat.create().stream() pattern.
    The OpenAI SDK uses stream=True as a parameter.

The core PGP fix is correct and pushed. The SKILL.md comments seem to conflate xAI
SDK examples with OpenAI SDK patterns.

Ready to re-review PR #27 when you get a chance.

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.

🧩 Analysis chain

@KHAEntertainment, you are absolutely correct on both counts — I apologize for the inaccurate review comments.

  1. import os suggestion was wrong. SKILL.md is a Markdown documentation file. The os.getenv() usage lives inside Python code blocks that already have import os — there's no "top of the file" to add it to in a Markdown context.

  2. chat.stream() is the correct xAI SDK pattern. I conflated the xAI native SDK with the OpenAI SDK. The official xAI SDK docs confirm that streaming uses for response, chunk in chat.stream(): — that is, .stream() is called as a method on the chat object returned by client.chat.create(). The xAI SDK has a different streaming API compared to other providers: instead of passing stream=True as a parameter, xAI uses a .stream() method on the chat object that returns tuples of (response, chunk). The stream=True parameter style belongs to the OpenAI SDK, not the xAI native SDK.

The SKILL.md documentation is correct as-written. Sorry for the noise!


🌐 Web query:

xAI Python SDK client.chat.create stream method streaming pattern

💡 Result:

In the official xai-sdk Python SDK, you stream from the chat object returned by client.chat.create(...):

from xai_sdk import Client
from xai_sdk.chat import user

client = Client()
chat = client.chat.create(model="grok-3")

chat.append(user("Tell me a short story."))

final_response = None
for final_response, chunk in chat.stream():
    # chunk = the incremental delta
    if chunk.content:
        print(chunk.content, end="", flush=True)

print()  # newline

# final_response = the fully-accumulated response (auto-built while streaming)
chat.append(final_response)  # keep conversation history

chat.stream() yields (response, chunk) pairs where chunk.content is the text delta and response is the accumulating final message. [1][2]


🌐 Web query:

xAI SDK Python chat.create stream versus openai sdk stream=True

💡 Result:

xAI Python SDK (client.chat.create(...).stream())

  • You create a stateful chat helper (chat = client.chat.create(...)), chat.append(...), then stream via chat.stream().
  • Iteration yields a tuple: (response, chunk):
    • chunk contains text deltas (print chunk.content as they arrive)
    • response is auto-accumulated as streaming progresses (after the loop, response is the full message; you typically chat.append(response)). [1]

OpenAI Python SDK (stream=True)

You stream by passing stream=True on the request (no (response, chunk) tuple).

A) Responses API (recommended)

  • stream = client.responses.create(..., stream=True)
  • Iteration yields semantic SSE events; each has a type (e.g., response.output_text.delta, response.completed, error). You handle deltas by filtering events. [2]

B) Chat Completions API (legacy)

  • stream = client.chat.completions.create(..., stream=True)
  • Iteration yields chunks; incremental text is in chunk.choices[0].delta.content (you generally accumulate into a string yourself). [2]

In short: xAI streaming is a chat-session method that yields (final-so-far response, delta chunk), while OpenAI streaming is a request flag (stream=True) that yields events/chunks only (Responses: typed events by event.type; Chat Completions: choices[0].delta). [1][2]


@KHAEntertainment, you are absolutely correct on both counts — I apologize for the inaccurate review comments.

  1. import os suggestion was wrong. SKILL.md is a Markdown documentation file. The os.getenv() usage lives inside Python code example blocks that already include import os — there's no "top of the file" to add an import to in a Markdown context.

  2. chat.stream() is the correct xAI SDK pattern. In the official xai-sdk Python SDK, streaming is done from the chat object returned by client.chat.create(...) by calling chat.stream(). The xAI SDK uses a stateful chat helper (chat = client.chat.create(...)), then iterates via chat.stream(), which yields (response, chunk) tuples where chunk contains text deltas and response is auto-accumulated. In contrast, the OpenAI SDK streams by passing stream=True on the request itself. These are fundamentally different streaming patterns — I incorrectly conflated the two.

The SKILL.md documentation is correct as-written. Sorry for the noise!


✏️ Learnings added
Learnt from: KHAEntertainment
Repo: KHAEntertainment/grok-multiagent-plugin PR: 27
File: .claude/skills/grok-multi-agent-api/SKILL.md:107-113
Timestamp: 2026-03-31T20:54:43.884Z
Learning: In the xAI native Python SDK (`xai_sdk`), streaming is done by calling `.stream()` as a method on the chat object returned by `client.chat.create()`, e.g. `for response, chunk in chat.stream():`. This is different from the OpenAI SDK which uses `stream=True` as a parameter to `client.chat.completions.create()`. Do not flag `chat.stream()` as an incorrect pattern in xAI SDK code examples.

Learnt from: KHAEntertainment
Repo: KHAEntertainment/grok-multiagent-plugin PR: 27
File: .claude/skills/grok-multi-agent-api/SKILL.md:107-113
Timestamp: 2026-03-31T20:54:43.884Z
Learning: SKILL.md files (e.g. `.claude/skills/grok-multi-agent-api/SKILL.md`) in this repository are Markdown documentation files, not executable Python. Python `import` statements and code patterns within them exist inside fenced code blocks as examples. Do not suggest adding `import os` at the "top of the file" for a Markdown document — the imports belong inside the code example blocks, where they already are.

Learnt from: KHAEntertainment
Repo: KHAEntertainment/grok-multiagent-plugin PR: 27
File: .claude/skills/grok-multi-agent-api/SKILL.md:107-113
Timestamp: 2026-03-31T20:54:43.884Z
Learning: In the xAI native Python SDK (`xai_sdk`), streaming is done by calling `.stream()` as a method on the chat object returned by `client.chat.create()`, e.g., `for response, chunk in chat.stream():`. This yields (response, chunk) tuples. This is different from the OpenAI SDK which uses `stream=True` as a parameter to `client.chat.completions.create()`. Do not flag `chat.stream()` as an incorrect pattern in xAI SDK code examples.

Learnt from: KHAEntertainment
Repo: KHAEntertainment/grok-multiagent-plugin PR: 27
File: .claude/skills/grok-multi-agent-api/SKILL.md:107-113
Timestamp: 2026-03-31T20:54:43.884Z
Learning: SKILL.md files (e.g. `.claude/skills/grok-multi-agent-api/SKILL.md`) in this repository are Markdown documentation files, not executable Python. Python `import` statements and code patterns within them exist inside fenced code example blocks. Do not suggest adding `import os` at the "top of the file" for a Markdown document — the imports belong inside the code example blocks, where they already are.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment thread CLAUDE.md Outdated
Comment thread skills/grok-refactor/bridge/grok_bridge.py Outdated
Comment thread src/bridge/grok_bridge.py Outdated
Comment thread TASKS.md
KHAEntertainment and others added 2 commits March 31, 2026 13:41
…iles

The PGP stripping was happening AFTER the args.output write, causing
--output files to contain PGP blocks while parse_and_write_files got
cleaned content. Now strip once at the start of output section and
use cleaned_result for both write paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CLAUDE.md: Use placeholder instead of hardcoded version numbers
TASKS.md: Fix inconsistent status (docs still in progress per line 18)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/bridge/grok_bridge.py (1)

509-510: ⚠️ Potential issue | 🟠 Major

Use sanitized output on the default stdout path too.

When --write-files is not set and --output is not set, the code still prints raw result. That bypasses the new sanitizer and can reintroduce PGP blocks in normal CLI output.

🔧 Minimal fix
-    elif not args.output:
-        print(result)
+    elif not args.output:
+        print(cleaned_result)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/bridge/grok_bridge.py` around lines 509 - 510, The branch that handles
the default stdout path currently prints the raw result (elif not args.output:
print(result)) which bypasses the sanitizer; change this to pass result through
the same sanitizer used for file/explicit-output paths (e.g., call the existing
sanitizer function that other branches use — sanitize_result/sanitize_output or
equivalent) and then print the sanitized string, ensuring this covers the case
when args.write_files is False and args.output is not provided (reference:
args.output, args.write_files, result).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/bridge/grok_bridge.py`:
- Around line 509-510: The branch that handles the default stdout path currently
prints the raw result (elif not args.output: print(result)) which bypasses the
sanitizer; change this to pass result through the same sanitizer used for
file/explicit-output paths (e.g., call the existing sanitizer function that
other branches use — sanitize_result/sanitize_output or equivalent) and then
print the sanitized string, ensuring this covers the case when args.write_files
is False and args.output is not provided (reference: args.output,
args.write_files, result).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 74ec63e0-1a62-47ae-b9a2-8f3cb462b157

📥 Commits

Reviewing files that changed from the base of the PR and between 85d7561 and b11d3c0.

📒 Files selected for processing (2)
  • skills/grok-refactor/bridge/grok_bridge.py
  • src/bridge/grok_bridge.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • skills/grok-refactor/bridge/grok_bridge.py

@KHAEntertainment
Copy link
Copy Markdown
Owner Author

Review Comments Addressed

✅ Fixed:

  1. src/bridge/grok_bridge.py & skills/grok-refactor/bridge/grok_bridge.py: PGP stripping now happens BEFORE --output write, not just before parse_and_write_files. Both write paths now receive cleaned_result.

  2. CLAUDE.md: Removed hardcoded version numbers. Now uses <VERSION> placeholder.

  3. TASKS.md: Fixed inconsistent status line to reflect "Documentation In Progress ⚠️".

❌ Not Fixed - Explanation:

  1. SKILL.md (grok-multi-agent-api): The reviewer cited OpenAI SDK patterns, but this file documents the xAI SDK, not OpenAI SDK. The xAI SDK uses client.chat.create(...).stream() which is valid for the xAI SDK. The import os is correctly placed inside a code block (not at file level - this is Markdown). These are xAI API examples, not OpenAI SDK examples.

  2. SKILL.md streaming: Changing xAI SDK's chat.create().stream() to OpenAI's chat.completions.create(..., stream=True) would document the wrong SDK entirely.

Summary: The core PGP fix is correct. The SKILL.md comments appear to conflate xAI SDK (documented) with OpenAI SDK (not what this file is about).

@KHAEntertainment KHAEntertainment merged commit 01b825d into master Mar 31, 2026
1 check passed
KHAEntertainment added a commit that referenced this pull request Mar 31, 2026
Comprehensive test suite for validating grok-multiagent-plugin
in a Claude Code context. Tests verify PR #27 and PR #13 fixes.

Test coverage:
- preflight.sh: Environment validation and cleanup checks
- test_setup.py: OAuth flow, key detection, key validation
- test_modes.py: All 5 modes (analyze, refactor, code, reason, orchestrate)
- test_edge_cases.py: PGP stripping, mode-aware response handling
- test_tools.py: File writing, path safety, annotated block parsing
- mock_responses/: Sample Grok responses for unit testing
- REPORT.md: Template for capturing manual test results

All 50 tests pass on baseline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

Plugin Uses Size-Based Filtering Instead of PGP Detection, Causing Legitimate Responses to Fail

1 participant