Releases: LovelaceLoom/grok-plugin-cc
Release list
v1.2.2 — Repository and CI hardening
v1.1.0 — Codex CLI support
The plugin now installs in both Claude Code and OpenAI's Codex CLI from a single repo.
No companion.mjs changes were needed: Codex sets CLAUDE_PLUGIN_ROOT for back-compat with CC's plugin contract, so the existing commands/agents/hooks layout already runs inside Codex. v1.1.0 ships the manifest and skill metadata that make the plugin discoverable by Codex's marketplace + skill router.
Install in Codex CLI
codex plugin marketplace add taibaran/grok-plugin-ccAfter install, the model auto-routes to the matching skill on intent:
- "Ask grok…" →
grok-ask(live web search) - "Research…" →
grok-research(effort=max +--checkself-verification) - "Generate an image of…" →
grok-imagine - "Delegate this to grok…" →
grok-rescue(read-only;GROK_PLUGIN_ALLOW_WRITE=1for edits)
Install in Claude Code (unchanged)
/plugin marketplace add https://github.com/taibaran/grok-plugin-cc
/plugin install grok@grok-plugin-cc
/grok:setup
Full slash-command surface (/grok:ask, /grok:research, /grok:imagine, /grok:rescue, /grok:review, /grok:best-of, /grok:aggregate-review, /grok:sessions, /grok:memory, /grok:mcp, /grok:status, /grok:result, /grok:cancel, /grok:purge, etc.) all unchanged.
What's new
.agents/plugins/marketplace.json— Codex marketplace manifest at repo root.plugins/grok/.codex-plugin/plugin.json— Codex-native plugin manifest withinterfaceblock (displayName, category, capabilities, defaultPrompt) so the Codex TUI surfaces the plugin properly.- 4 user-facing skills (
grok-ask,grok-research,grok-imagine,grok-rescue) that Codex's (and CC's) skill router auto-invokes by intent. All four shell out to the samescripts/companion.mjs. - README documents the Codex install command and a comparison table of CC slash commands vs Codex skills.
- 9 new structural tests pinning manifest schemas, version lockstep across all four manifest files, and skill metadata.
Numbers
- 405 tests → 400 pass + 5 skipped (integration tests requiring real Grok auth).
- No behavior change to
companion.mjs, hooks, or existing slash commands. - v1.0.6 fixes carry forward (runJob silent-on-exit-0 + cross-plugin state-dir collision).
Compatibility
- CC users keep the full slash-command surface unchanged.
- Codex users get equivalent functionality via auto-invoked skills.
- The 3 internal skills (
grok-cli-runtime,grok-prompting,grok-result-handling) remainuser-invocable: falseand are inert in Codex (they were only ever called from CC'sgrok-rescuesubagent).
v1.0.6 — fix runJob silent-on-exit-0 + cross-plugin state-dir (issue #10)
Two-part patch for #10: `companion.mjs task` reported "completed exit 0" with empty stdout/stderr logs, breaking `grok-rescue`. Triaged with codex + gemini in parallel.
Fixed
runJob diagnostic-gate bug
v1.0.1/v1.0.5's empty-output diagnostic in `runJob` was nested inside `(code !== 0 || grokInternalError)`. Exit-0 with empty output AND no JSON error envelope fell into the `else` (status=completed) branch and the diagnostic was silently skipped. Reporter saw "Job xxx completed (exit 0)" with 0-byte logs and no signal.
Fix: `runJob` now sets `meta.no_output = true` whenever both buffers are whitespace-only. New `else if (meta.no_output && status !== "cancelled")` branch fires the diagnostic on exit 0 too. `cmdResult` also surfaces the warning when `meta.no_output` is true so users discovering the empty output later get the same recovery hints.
Cross-plugin state-dir collision
Reporter's grok job state landed at `~/.claude/plugins/data/codex-openai-codex/state/...`. `CLAUDE_PLUGIN_DATA` inherits to child processes, so when grok is invoked from a parent codex/gemini subagent, our state went into their namespace.
Fix: `stateDir` now prefixes the env-backed base with `grok-plugin-cc/`, matching the `/tmp/grok-plugin-cc/` namespace already in `FALLBACK_STATE_ROOT`. Paths become `$CLAUDE_PLUGIN_DATA/grok-plugin-cc/state/-/` regardless of which plugin owns the env-set base.
Back-compat: pre-v1.0.6 jobs at `$CLAUDE_PLUGIN_DATA/state/...` become inaccessible after upgrade. Job logs are ephemeral (`MAX_JOBS=50`), configs recreated by `/grok:setup` — acceptable for a patch.
Investigated, not changed
Codex hypothesized that `--permission-mode plan` suppresses tool execution in headless `-p` mode. A/B test refuted this (both plan and default modes produced legit weather data via web_search). `cmdTask`'s default permission-mode stays `plan`. The reporter's specific case is likely the same upstream silent-abort pattern as issue #9.
Tests
10 new behavioral tests in `tests/v1-0-6-issue-10.test.mjs`. 396 tests total (391 passing + 5 integration skipped).
Update
`/plugin` → `Manage installed plugins` → `grok@grok-plugin-cc` → `Update` → `/reload-plugins`.
v1.0.5 — tighten silent-empty detector (issue #9)
Diagnostic-tightening patch driven by #9, filed by @eyalRonen1 while real-world-testing the v1.0.4 bash workaround from #8.
The bug
Reporter followed the recommended workaround: 2 parallel grok runs (8KB + 9KB output ✓), then a synthesis call with ~18KB combined prompt. The synthesis returned 1 byte (just a newline), exit 0, empty stderr. The plugin's v1.0.1 `diagnoseEmptySpawnFailure` missed this because the check was `if (!r.stdout && !r.stderr)` and `"\n"` is truthy in JS.
Root cause (per Gemini's triage)
The bash workaround inadvertently performs prompt injection by tool-error patterns: the sample outputs contained `browser_tab failed` text (Grok recovering from tool errors via web_search), which looks like grok's own internal tool-call meta-syntax. When concatenated into the synthesis prompt, the model parser likely treats them as live tool calls and triggers an early stop. A synthetic 28KB English test WITHOUT those patterns produced 815 bytes of legitimate output — length isn't the trigger.
Fixed
- New `isWhitespaceOnly()` helper in `companion.mjs`.
- All 3 `diagnoseEmptySpawnFailure` call sites (`runHeadlessGrok`, `cmdImagine`, `runJob` close handler) now use it instead of `!r.stdout && !r.stderr`.
- Banner text expanded to mention the issue-#9 upstream silent-abort path + point at the eventual `/grok:aggregate-of-n` v1.1.0 fix.
Upstream
Submitted to xAI via grok's built-in `/feedback` channel. Submission id: `94e62200-3fa5-495c-bf4a-e18b107a0b34`. The model-layer fix has to come from xAI.
Tests
6 new behavioral tests covering 1-byte newline triggering across all 3 call sites at both exit codes. 386 tests total (381 passing + 5 integration skipped).
Update
`/plugin` → `Manage installed plugins` → `grok@grok-plugin-cc` → `Update` → `/reload-plugins`.
v1.0.4 — security patch (Codex P0 review of v1.0.3)
Security + correctness patch driven by a deep-research review of v1.0.3. All three reviewer agents (codex + gemini + grok) participated in the v1.0.3 audit; Codex caught two real P0 regressions plus one P1 inconsistency. Same-day patch.
Fixed
P0-A — `--effort` gate bypass in `cmdReview` + `cmdImagine`
v1.0.3's per-model gate (`modelSupportsReasoningEffort`) was only enforced inside `grokBaseArgs`. Two call sites appended `--effort` outside that helper — re-introducing the 4× 400 cascade on `grok-build` for:
- `/grok:review --effort high`
- `/grok:adversarial-review --effort high`
- `/grok:imagine --effort high`
- `/grok:imagine-video --effort high`
Fix: new `effortFlagForModel({effort, model, cwd, kind})` helper in `lib/grok.mjs` is the single source of truth. `grokBaseArgs` delegates to it. `cmdReview` now passes `effort` through (was missing). `cmdImagine` calls the helper directly.
P0-B — `--save-to` source-path exfiltration vector
`isSafeMediaPath` only validated characters (it approved any `/A-Za-z0-9._/-%@+` path including `/etc/passwd`). A prompt-injected grok could return `` and the plugin would copy `/etc/passwd` to the user's `--save-to` destination — local-file exfiltration. Only triggerable with `--save-to` (v1.0.2+).
Fix: new `isUnderGrokSessionsDir(p)` helper uses `path.resolve` (collapses `..` segments) to require the resolved path equals or descends from `${GROK_HOME}/sessions/`. `copyMediaToSaveTo` guards before any `copyFileSync`.
P1 (bundled) — `GROK_HOME` consistency
`cleanGrokEnv` allows `GROK_HOME` through but `readGrokModelsCache` hardcoded `~/.grok/`. Enterprise users with re-homed grok hit null cache → conservative-forward → 400 cascade.
Fix: exported `grokHomeDir()` resolves `GROK_HOME || ~/.grok`. Used by both `readGrokModelsCache` and `isUnderGrokSessionsDir`.
Tests
13 new behavioral tests in `tests/v1-0-4-issue-fixes.test.mjs` covering all three fixes. 380 tests total (375 passing + 5 integration skipped).
Update
`/plugin` → `Manage installed plugins` → `grok@grok-plugin-cc` → `Update` → `/reload-plugins`.
v1.0.3 — fix --effort 400 cascade on grok-build (#7) + best-of-n docs/banner (#8)
Bug + docs release driven by #7 and #8. Triaged with codex + gemini + grok agents in parallel.
Fixed
- #7 —
--efforttriggers cryptic 400 cascade on grok-build: today's only public model declares `supports_reasoning_effort: false` in `~/.grok/models_cache.json` but the plugin's `/grok:research` always emits `--effort max` by default. New `modelSupportsReasoningEffort()` gate reads the cache and strips `--effort` / `--reasoning-effort` with a clear stderr warning when the resolved model declares no support. Cache-miss is conservative (forward — never silently strip on missing data).
Docs + UX
- #8 — `--best-of-n` is implicitly code-task-only: `commands/best-of.md` rewritten to lead with "CODE / FILE-CHANGE tasks only" and direct text/research users to `/grok:research` or `/grok:ask`. New one-line stderr banner on every `/grok:best-of` invocation. Suppressed in `--json` mode and via `GROK_PLUGIN_QUIET_BANNERS=1`.
Deferred
- #8 `--aggregate-of-n` (run N + synthesize): medium-to-large new feature (synthesis prompt + parallel orchestrator + aggregator). Added to v1.1.0 roadmap. Issue stays open as tracker.
Internal
- `GROK_PLUGIN_DISABLE_EFFORT_GATE=1`: bypass the per-model gate. Primary use is test isolation. End-users can use it to roll back the gate if needed.
- `GROK_PLUGIN_QUIET_BANNERS=1`: opt out of informational stderr banners.
Tests
11 new behavioral tests via fake cache fixtures + fake-grok stubs. 367 tests total (362 passing + 5 integration skipped).
v1.0.2 — --save-to flag on imagine + imagine-video (issue #5)
Feature release driven by #5. Triaged with the codex + gemini + grok multi-agent pipeline; 3/3 reviewers converged on ship #5 / defer #6.
Added
- #5:
--save-to <path>on `/grok:imagine` and `/grok:imagine-video`. Plugin copies the generated media from grok's internal session dir to the user's path. Creates parent dirs (mkdirp). POSIX cp semantics: a destination ending with `/` or naming an existing directory triggers basename-append. The internal session copy is preserved for `grok -r ` resume. Copy failures surface on stderr; generation still succeeds.- `--json` exposes `sessionPath` (always internal), `savedTo` (when --save-to succeeds), `saveError` (when it fails). `.path` becomes "where the file IS NOW" — preserves backward compat.
Deferred (with reason)
- #6 (`--shot-list` YAML batch mode): once `--save-to` ships, `for n in beat1 beat2 ...; do --save-to ... & done; wait` covers the parallelism need. All 3 reviewers agreed the YAML+semaphore+summary-table scope isn't justified vs. the bash workaround. Will revisit if user feedback shows the bash pattern isn't enough.
Tests
9 new behavioral tests via fake-grok stub with a real on-disk source file (true end-to-end copy verification). 356 tests total (351 passing + 5 integration skipped).
v1.0.1 — fix silent failure on broken auto-update (issues #1, #2)
Bug-fix release driven by #1 and #2. Both triaged with the codex + gemini + grok multi-agent pipeline.
Fixed
- #1:
grok0.1.211 auto-update silently breaks all plugin calls.grokVersion()now distinguishes "exit 0 with empty output" from "couldn't run";cmdSetupsurfaces a 3-step recovery path (grok update→ roll back via~/.grok/downloads/→ reinstall). - #2:
companion.mjsswallowed underlying grok errors. NewdiagnoseEmptySpawnFailure()helper prints the exit code + shell-quoted argv + recovery hints whenever the spawned grok exits with both stdout AND stderr empty. Called from all 3 subprocess paths (runHeadlessGrok,cmdImagine,runJob).
Deferred (with reason)
- #3 (
--init-image) and #4 (--aspect-ratio): verified locally thatgrok -p "/imagine-video --help"is consumed as a literal video prompt by the builtin slash command — the CLI's slash-command parser doesn't see flags. Will revisit whengithub.com/xai-orgadds CLI-level support. See issue comments for details.
Tests
8 new behavioral tests via fake-grok stubs. 347 tests total (342 passing + 5 integration skipped).
v1.0.0 — first stable release
First stable release of grok-plugin-cc.
No code changes from v0.9.13. The plugin has been hardened through 13 rounds of multi-LLM /grok:aggregate-review against the v0.9.x line.
What's included
20 slash commands wrapping the official xAI Grok CLI:
/grok:ask,/grok:research,/grok:rescue/grok:review,/grok:adversarial-review,/grok:aggregate-review/grok:imagine,/grok:imagine-video/grok:best-of,/grok:models/grok:worktree,/grok:sessions,/grok:memory,/grok:mcp/grok:inspect,/grok:status,/grok:result,/grok:cancel,/grok:purge/grok:setup
Security baseline
- Env scrubbing allowlist for the spawned
grokchild - ANSI escape sanitization (4 KiB pending-escape cap)
- TOCTOU/symlink defenses on job state reads (O_NOFOLLOW, fstat, 0700 chmod chain, realpath-on-fd, root-only safe-boundary check)
- POSIX
--terminator for literal positionals - Refusal of unknown flag-like positionals by default
- Capability-probe gating for worktree/continue/resume/memory flags so older grok CLIs degrade cleanly
- Prompt-injection defenses for reviewer-style commands
Stability promise
v1.x will not break any of the 20 command surfaces. Internal helpers may continue to evolve.
Tests
339 tests (334 passing + 5 real-grok integration smoke tests skipped by default; opt-in via GROK_INTEGRATION_TEST=1).
See CHANGELOG.md for the full v0.9.x → v1.0.0 history.