Skip to content

feat: enable Codex CLI as a first-class agent alongside Claude Code#153

Merged
maxritter merged 9 commits into
mainfrom
dev
May 28, 2026
Merged

feat: enable Codex CLI as a first-class agent alongside Claude Code#153
maxritter merged 9 commits into
mainfrom
dev

Conversation

@maxritter

@maxritter maxritter commented May 27, 2026

Copy link
Copy Markdown
Owner

Full dual-agent support so Codex CLI users get the same Pilot Shell experience as Claude Code users across all Console features.

What changed

Sessions: CodexSessionReader parses ~/.codex/sessions/ JSONL files, merged with Claude sessions in Dashboard and Sessions views with agent badge and All/Claude/Codex filter toggle.

Usage: Codex cost tracking via codex-parser with model-specific pricing, aggregated into daily/monthly charts with agent filtering.

Memories: Hook pipeline fixed for Codex (hookSpecificOutput passthrough instead of systemMessage, context handler enabled, no ugly display), all memory lifecycle hooks added (session-init, observation, summarize, session-end), agent column migration on sdk_sessions, observations API agent filter, Memories UI toggle.

Extensions: Codex extensions discovery and display alongside Claude extensions in the Extensions view.

Quality hooks: file_checker (with apply_patch format support), tool_token_saver, context_monitor (transcript estimation fallback), spec_stop_guard — all ported to codex_hooks.json.

Installer: codex_files step installs hooks, skills, MCP config, and AGENTS.md for Codex CLI. Agent runtime detection for both CLIs.

Docs: Codex CLI getting-started guide, updated hooks/extensions/MCP docs for dual-agent coverage.

Stats

  • 179 files changed, 4729 insertions, 694 deletions
  • Tests: 1578 bun + 1234 pytest = 2812 total, 0 failures

Summary by cubic

Enable Codex CLI as a first-class agent alongside Claude Code. Running claude or codex now launches the same Pilot Shell with shared sessions, memories, MCP servers, extensions, and usage tracking.

  • New Features

    • Sessions/Usage: Merge Codex ~/.codex/sessions/*.jsonl with agent badges and All/Claude/Codex filters; Codex cost parser with model pricing and correct aggregation.
    • Memories/MCP: Full memory lifecycle on Codex; parity across all 7 MCP servers including mem-search.
    • Skills/Rules: All skills run on Codex; dual-agent CC-ONLY/CODEX blocks; orchestrator-level AskUserQuestion handling in fix, prd, benchmark, and setup-rules.
    • Installer/Runtime/UI: Split installer into PilotFiles/ClaudeFiles/CodexFiles; detect agents instead of installing; hard gate when neither is present; shared .pilot/hooks and Codex skills under ~/.agents/skills; Console gets AgentBadge + filters and a new Documentation view; status line simplified.
  • Bug Fixes

    • Usage: Codex parser reads turn_context.payload.model so charts show correct costs.
    • Data/Filters: Use COALESCE(..., 'claude') to keep orphan observations; safe JSON parsing for memory facts/concepts.
    • Hooks/Tools: file_checker trims CR/LF in apply_patch paths; restore suppressOutput: true; correct CodeGraph tool names; fix MCP tool naming in docs.
    • Shell/Installer: Fix fish PID expansion; stricter TOML and absolute CODEX_HOME validation; unified agent detection; uninstall cleans Codex artifacts; Python tools upgraded via uv.
    • Codex init: Return { continue: true } and emit a compact “[pilot] Memory loaded …” to stderr to avoid invalid JSON at startup.
    • Codex hooks polish and review feedback fixes.

Written for commit 492c6fa. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Codex CLI support and direct startup via claude/codex; Pilot Shell auto-loads. Hooks pipeline expanded (license checks, CodeGraph init, spec handoff/resume).
  • Documentation

    • Extensive docs and site updates covering Codex support, CLI workflows/examples, installation/prereqs, feature matrix, FAQs, console behavior, and marketing copy.
  • Chores

    • Installer and installer-step workflows extended for Codex, hooks relocated, shell wrappers added, dependency install behavior and upstream pins updated; minor .gitignore updates.
  • Tests

    • New/updated unit tests for installer, Codex generation, hook migration, dependencies, and shell config.

Review Change Stack

Full dual-agent support so Codex CLI users get the same Pilot Shell
experience as Claude Code users across all Console features.

Sessions: CodexSessionReader parses ~/.codex/sessions/ JSONL files,
  merged with Claude sessions in Dashboard and Sessions views with
  agent badge and All/Claude/Codex filter toggle.

Usage: Codex cost tracking via codex-parser with model-specific
  pricing, aggregated into daily/monthly charts with agent filtering.

Memories: Hook pipeline fixed for Codex (hookSpecificOutput passthrough
  instead of systemMessage, context handler enabled, no ugly display),
  all memory lifecycle hooks added (session-init, observation, summarize,
  session-end), agent column migration on sdk_sessions, observations API
  agent filter, Memories UI toggle.

Extensions: Codex extensions discovery and display alongside Claude
  extensions in the Extensions view.

Quality hooks: file_checker (with apply_patch format support),
  tool_token_saver, context_monitor (transcript estimation fallback),
  spec_stop_guard — all ported to codex_hooks.json.

Installer: codex_files step installs hooks, skills, MCP config, and
  AGENTS.md for Codex CLI. Agent runtime detection for both CLIs.

Docs: Codex CLI getting-started guide, updated hooks/extensions/MCP
  docs for dual-agent coverage.
@vercel

vercel Bot commented May 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
pilot-shell Ignored Ignored Preview May 28, 2026 1:29pm

Request Review

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

<review_stack_artifact_start -->
<stack_title>Codex CLI integration + hook migration</stack_title>
<stack_summary>Adds Codex CLI installer step and adapters, migrates Pilot-managed hooks to ~/.pilot/hooks, updates installer dependency behavior and shell wrappers, expands tests, refreshes upstream pins, and rebrands docs/site to “Claude Code and Codex”.</stack_summary>

All substantive, reviewable changes for Codex CLI support, hook migration, installer behavior, tests, and documentation/branding updates. Refresh upstream pins and audit dates, bump bootstrap Python dependency, and update manifest/site config entries used by installer bootstrap and site generation. range_d6274257c725 range_d8a58011a13c range_2e3689f103fb range_6e2f186112e5 range_005240e8da28 range_d8abb0ae01d5 range_3dd3133ffcf4 range_dbb938ac96da range_0d6030f25b15 range_5c429298f996 range_098a53f38185 range_00e45b3ae2de range_173eea2e334b range_6d17864fc82e range_98768c4418ca range_ced3a742d830 range_3dd58209180b range_8c35c8e0fee5 range_c6b65184af20 range_8b6ab17321e8 range_d259319059c7 range_005240e8da28 New CodexFilesStep: detection, hooks.json merging, MCP JSON→TOML conversion, AGENTS.md rule adaptation/insertion, SKILL.md generation, full-access TOML enforcement, TOML validation, and atomic writes. range_774ec1670ee6 range_ae6ce841b941 range_452ea682a3e9 range_e42efba63f1d range_e1f459791ef2 range_ffb461933da7 range_6e1009703da3 range_72e31cabc039 range_3b41a0a45d3f range_fa7e823eb3ec range_887693922971 range_a36e5624e888 range_17e1fb2407c4 range_ae18528ff5de range_4d8e80fda451 range_38542f8f12a3 range_9bc9ab832bda range_672 (placeholder) Move hook management from ~/.claude/hooks to ~/.pilot/hooks, add adapt_claude_rule_content(), update manifest bookkeeping, pre-install cleanup, destination mapping, and hook-merge logic to read ~/.pilot/hooks/hooks.json. range_2bccae2d5fab range_7df45ec3a898 range_7bb2efa295ba range_f5abd77af0bf range_f0d92c406c49 range_725acf03fd87 range_bdc2d93cb923 range_24ff88753d85 range_0751922ec87a range_5e73bb4ec091 range_5e73bb4ec091 Change installers to always run upgrade/install flows, add RTK init (including Codex init), update TypeScript/Prettier/golangci-lint flows, and rewrite pbt tools behavior. range_eb77b67e6aca range_d2b9f4d46c17 range_3f2392b9e401 range_e904830d53ac range_90c4d5dd1416 range_af67d39a3a06 range_27d55a6acb03 range_27d55a6acb03 range_27d55a6acb03 Register CodexFilesStep into get_all_steps(), update finalize next-steps, add claude/codex shell wrapper functions that set per-invocation session IDs and task list IDs, and expand alias removal to clean old codex wrappers. range_cfd03bd0fe09 range_cfd03bd0fe09 range_39c07422f96f range_4355eaeb5ed7 range_19facf3ba7aa range_15815edefa5e range_59a9f3f920fb range_5d84a00d1d27 range_b99f4ef74c9d range_6b9df235c605 New comprehensive tests for CodexFilesStep plus updates to tests for hook migration, dependency upgrades, shell wrapper session IDs, and finalize UI labels. range_ac791923ac9e range_6fa23d374f4d range_a7076c953595 range_90444d2ca928 range_f828b08679b3 range_403007aa7cdb range_fbd2440bec00 range_f4d3b3c31347 range_5fc6b8e7323e range_83872499de70 range_1f0dafc9def8 range_c2262dd678c7 range_da271edc13a7 range_3f49de99a06a range_a33074561e9f range_2767b047fc5d range_b9305acd21a1 range_d56aa5686688 range_b58399320f6f range_b297723f6f1e range_9d8ebde99a7c range_8e8a3f090a6f range_13673feae1a7 range_889f52b904b9 range_441daacf9fae range_11aae0f34205 range_bf8384828ba3 range_07a625e5e1c4 range_6486b0471eec range_e69060870be4 range_d259319059c7 README and many docs updated for Claude Code + Codex unified workflow, add getting-started/codex-cli, update features/CLI/extensions/hooks/mcp/prereqs/installation and site components (hero, footer, pricing, FAQ, manifest, SEO). range_7162bfe30995 range_45b3cd315f9a range_c699e7b2a9a3 range_700b81eb2c4d range_25b40f7439b5 range_2782a60c575d range_955ffe3e5973 range_499ce5f5aeb1 range_bdedcd055e3e range_38791b59d0ce range_be5e795c292c range_76bc611e6587 range_870580c5776a range_2ab561be765f range_cf48483f4d5a range_ca4c0bea0394 range_a07ff0efb3f3 range_d16d25858a01 range_1245e62f0c53 range_fa5dfa191789 range_15ba699e0d83 range_8d61fa9d9b73 range_4049fa245fc8 range_804b81d93f38 range_74f1957326c2 range_a9ad99e1e1cd range_ff120971ba4b range_72d5bd67cd6e range_7316c476ceb5 range_1f6e68745cc6 range_fc05d959fa91 range_7ca5a6fada24 range_f597477832eb range_e98710485ed8 range_1445b49aa1c1 range_4b3f9ff0da40 range_f4fbfd0c9142 range_6b9df235c605 range_c102ff18399b range_9735cfe2f529 range_e99c432bbb7c range_161731e8f2a4 range_24526138de55 range_3dd58209180b range_3dd3133ffcf4 range_3dd58209180b range_3dd3133ffcf4 range_3dd58209180b range_3dd3133ffcf4 range_3dd58209180b range_3dd3133ffcf4 Minor updates: add .gitignore entries, bump rich pin in install.sh, update logo alt text and demo video aria-label, pricing UI copy tweaks. range_d87115882c07 range_5f8413ec39f7 range_3dd3133ffcf4 range_3dd58209180b range_d3a1700c8c97 range_5a4d19a2fe0f range_cf7fd6ff2fa0 range_145fbc6b44ae range_7fdcbbd9853b range_1367dc44ecd0 range_500797478a2f range_833133ca7fa6 range_447e3619354b range_eb98fa226c59 range_13673feae1a7 range_8e8a3f090a6f range_889f52b904b9 range_441daacf9fae range_11aae0f34205 range_bf8384828ba3 range_07a625e5e1c4 range_6486b0471eec range_e69060870be4 range_d259319059c7
✨ 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 dev

@claude

claude Bot commented May 27, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 2m 53s —— View job


Code Review: feat: enable Codex CLI as a first-class agent alongside Claude Code

Tasks:

  • Gather context and read CLAUDE.md
  • Review installer changes (codex_files.py, claude_files.py, dependencies.py, etc.)
  • Review documentation changes
  • Review installer tests
  • Review shell config and finalize steps
  • Post comprehensive review feedback

Summary

This is a solid, well-architected PR. The Codex integration is implemented symmetrically to Claude Code across all major surfaces: hooks, config, skills, rules, MCP servers, and shell wrappers. Test coverage is extensive (788 new test lines for codex_files alone). The documentation is comprehensive and honest about limitations.

A few issues worth addressing before merge:


Bugs

1. TOML key detection may skip required top-level keys when a same-named key exists inside a section

installer/steps/codex_files.py:280

if not re.search(rf"(?m)^{re.escape(key)}\s*=", existing):

The (?m)^ pattern matches the start of any line, including lines inside TOML sections. If a user's config.toml has, for example:

[some_section]
approval_policy = "auto"

The installer would conclude approval_policy already exists and skip writing the required top-level value. The fix is to only search within the top-level scope (before the first [section] header):

m = re.search(r"(?m)^\[", existing)
top_level_scope = existing[:m.start()] if m else existing
if not re.search(rf"(?m)^{re.escape(key)}\s*=", top_level_scope):
    ...

Fix this →


2. _TomlStructureError propagates uncaught and can crash the installer

installer/steps/codex_files.py:186 and installer/steps/codex_files.py:324

_validate_toml_structure raises _TomlStructureError if generated TOML is malformed, but CodexFilesStep.run() calls _install_codex_mcp and _install_codex_config without catching it. The outer run_installation loop only catches FatalInstallError and KeyboardInterrupt, so a _TomlStructureError would terminate the entire installer process with a traceback. The TOML validator is a defense-in-depth check against generator bugs — it should either be caught and converted to a FatalInstallError, or the run() method should wrap Codex-config calls in a try/except that logs a warning rather than crashing:

try:
    self._install_codex_config(ctx)
    self._install_codex_mcp(ctx)
except _TomlStructureError as e:
    if ctx.ui:
        ctx.ui.warning(f"Skipping Codex TOML config due to structure error: {e}")

Fix this →


Dead Code

3. _AGENT_SUBAGENT_RE and _TASK_SUBAGENT_RE are defined but never used

installer/steps/codex_files.py:557-565

_TASK_SUBAGENT_RE = re.compile(
    r"Task\(\s*\n?\s*subagent_type=['\"]([^'\"]+)['\"].*?\)",
    re.DOTALL,
)

_AGENT_SUBAGENT_RE = re.compile(
    r"Agent\(\s*\n?\s*(?:subagent_type=['\"]([^'\"]+)['\"].*?|.*?subagent_type=['\"]([^'\"]+)['\"].*?)\)",
    re.DOTALL,
)

Neither is referenced in _adapt_invocation_syntax or anywhere else in the module. If these were intended to transform Task()/Agent() calls in skill content, the transformation logic is missing. If they were removed from an earlier design iteration, they should be deleted.


Minor Issues

4. Redundant import re inside _insert_top_level_key

installer/steps/codex_files.py:413

def _insert_top_level_key(content: str, key: str, value: str) -> str:
    import re   # ← already imported at module top level (line 11)

Remove the local import.


5. f"" in _mcp_json_to_toml adds an empty string redundantly

installer/steps/codex_files.py:456

lines.append(f"")

This is equivalent to lines.append(""). Use the plain string literal.


Design Observations

_is_pilot_managed_entry identification is brittle

installer/steps/codex_files.py:618-624

def _is_pilot_managed_entry(entry: dict[str, Any]) -> bool:
    for hook in entry.get("hooks", []):
        cmd = hook.get("command", "")
        if "/.pilot/" in cmd:
            return True
    return False

The identification of "Pilot-managed" hooks relies on the path substring /.pilot/ in command strings. If Pilot hooks use environment variables (e.g. $PILOT_HOME/hooks/...) or if a user coincidentally has /.pilot/ in a path, this could misidentify entries. The Claude Code side uses a dedicated baseline file (HOOKS_BASELINE_FILE) for the same purpose. Consider using an analogous approach (a managed-entry marker in the hook itself, or a separate Codex hooks baseline) for more robust idempotency in future iterations. For now, the current approach works given Codex hooks are generated with absolute ~/.pilot/ paths.


Codex config installs model_reasoning_effort = "xhigh" unconditionally

installer/steps/codex_files.py:273

This hardcodes GPT-5.5-style reasoning config keys. If OpenAI changes how these keys work across model versions (or if a user is running a different model via model = "o3-mini" in their config), these values might be ignored or cause unexpected behavior. The documentation notes "users can override via codex --model <name>", which is the right escape hatch. No action needed — just noting it for future consideration.


Test Coverage

The test suite (test_codex_files.py) is thorough — it covers:

  • TOML generation for stdio, HTTP, and env-var MCP servers
  • Hooks merge that preserves user entries
  • Rules adaptation (verifying ~20 forbidden strings don't appear in Codex output)
  • Skill syntax adaptation (CC-ONLY stripping, CODEX-START unwrapping)
  • Config merge idempotency

One gap: there's no test for the section-scoped key false-positive bug noted in issue #1 above.


Documentation

docs/docusaurus/docs/getting-started/codex-cli.md is excellent — the limitations table, feature matrix, and config reference are all clear. The "What requires Claude Code" section correctly sets expectations.

One clarification worth adding: the doc says approval_policy = "never" is "Equivalent to Claude Code's bypass permissions mode" — but bypass mode in Claude Code has been superseded by individual permission grants in recent versions. A brief note that this skips interactive permission prompts (equivalent to running claude --dangerously-skip-permissions) would be more precise.


@coderabbitai coderabbitai 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.

Actionable comments posted: 5

Caution

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

⚠️ Outside diff range comments (2)
docs/docusaurus/docs/getting-started/installation.md (1)

21-31: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Installer step list likely stale after CodexFilesStep addition.

The section still says “7 steps” and the table omits a Codex files step, which appears inconsistent with this PR’s documented installer changes. Please update the count and step table so it matches the actual installer flow users will see.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/docusaurus/docs/getting-started/installation.md` around lines 21 - 31,
Update the installer overview to reflect the new CodexFilesStep: change "7
steps" to "8 steps" and insert a new table row for the "Codex files" step
between the existing "Claude files" and "Config files" rows (or wherever the
installer flow places CodexFilesStep); include a brief title "Codex files" and a
short description like "Sets up `~/.codex/` assets — models, snippets, and
runtime metadata" so the markdown table in installation.md matches the actual
installer flow and step naming used in the PR.
installer/tests/unit/steps/test_dependencies.py (1)

63-117: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Newly patched install paths aren’t validated in the core orchestration test.

This test now mocks additional dependency steps but only asserts a subset, so orchestration regressions can pass silently. Please assert the newly introduced calls (and gated non-calls) explicitly.

Suggested assertion additions
             mock_claude_code.assert_called_once()
             mock_nodejs.assert_called_once()
             mock_uv.assert_called_once()
             mock_python_tools.assert_called_once()
             mock_plugin_deps.assert_called_once()
             _mock_semble.assert_called_once()
             _mock_rtk.assert_called_once()
+            _mock_codegraph.assert_called_once()
+            _mock_better_sqlite3.assert_called_once()
+            _mock_codex_plugin.assert_called_once()
+            _mock_lsp_plugins.assert_called_once()
+            _mock_playwright.assert_called_once()
+            _mock_codegraph_needs_work.assert_called_once()
+            _mock_init_codegraph.assert_not_called()

As per coding guidelines **/tests/**: Review test code briefly. Focus on: Test coverage for the feature being tested.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@installer/tests/unit/steps/test_dependencies.py` around lines 63 - 117, The
test test_dependencies_run_installs_core is missing assertions for several newly
mocked dependency calls causing orchestration regressions to be invisible;
update the test to assert that each new mock (e.g., _mock_codegraph,
_mock_better_sqlite3, _mock_codex_plugin, _mock_lsp_plugins, _mock_playwright,
_mock_codegraph_needs_work, _mock_init_codegraph, _mock_prettier,
_mock_golangci_lint, _mock_pbt_tools, _mock_agent_browser, _mock_semble,
_mock_rtk) is called or explicitly not called as appropriate after step.run(ctx)
when running DependenciesStep, and also add negative assertions for steps that
should not run in this scenario (use assert_called_once() or assert_not_called()
on the mock objects to make the orchestration expectations explicit).
🧹 Nitpick comments (5)
installer/steps/codex_files.py (3)

38-43: 💤 Low value

Consider validating CODEX_HOME is an absolute path.

get_claude_config_dir() in claude_files.py raises ValueError if CLAUDE_CONFIG_DIR is relative, but _get_codex_config_dir() accepts any path. This inconsistency could cause unexpected behavior if a user sets CODEX_HOME to a relative path.

Proposed fix
 def _get_codex_config_dir() -> Path:
     """Resolve the Codex config directory, respecting CODEX_HOME env var."""
     env_dir = os.environ.get("CODEX_HOME")
     if env_dir:
-        return Path(env_dir)
+        p = Path(env_dir)
+        if not p.is_absolute():
+            raise ValueError(f"CODEX_HOME must be an absolute path, got: {env_dir}")
+        return p
     return Path.home() / ".codex"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@installer/steps/codex_files.py` around lines 38 - 43, _in
_get_codex_config_dir(), validate that the CODEX_HOME env var is an absolute
path like get_claude_config_dir() does: if os.environ.get("CODEX_HOME") is set,
convert it to a Path and call is_absolute(); if it is not absolute, raise a
ValueError with a clear message referencing CODEX_HOME; otherwise return the
Path(env_dir) as before, and keep the fallback to Path.home() / ".codex" when
the env var is absent.

413-413: ⚡ Quick win

Remove redundant import re statement.

re is already imported at module level (line 11).

Proposed fix
 def _insert_top_level_key(content: str, key: str, value: str) -> str:
     """Insert a key=value pair into the top-level scope of a TOML string.
 
     Inserts before the first ``[section]`` header so the key doesn't
     accidentally land inside an unrelated table.
     """
-    import re
-
     line = f"{key} = {value}\n"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@installer/steps/codex_files.py` at line 413, Remove the redundant local
"import re" statement (the duplicate import re near the bottom of
installer/steps/codex_files.py) since re is already imported at module level;
locate the duplicate "import re" and delete that line so only the single
top-level import remains.

456-456: ⚡ Quick win

Remove unnecessary f-string prefix.

f"" has no placeholders; use "" instead.

Proposed fix
-            lines.append(f"")
+            lines.append("")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@installer/steps/codex_files.py` at line 456, Replace the unnecessary f-string
usage in the call to lines.append by removing the f prefix so it uses a plain
empty string; update the lines.append(f"") expression to lines.append("") where
it appears (e.g., in the code that builds the lines list).
installer/steps/dependencies.py (2)

1083-1107: 💤 Low value

Unreachable UNCHANGED outcome in success path.

When ok is True, both the hypothesis and fast-check installs succeeded, meaning any_changed is always True. The _OUTCOME_UNCHANGED branch on line 1106 is dead code within the success path.

If the intent is to track whether tools were already present (vs freshly installed/upgraded), the function would need to check command_exists before the install attempts, similar to other install functions.

Simplify by removing unreachable branch
     if ok:
-        _record_outcome(_OUTCOME_UPDATED if any_changed else _OUTCOME_UNCHANGED)
+        _record_outcome(_OUTCOME_UPDATED)
     return ok
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@installer/steps/dependencies.py` around lines 1083 - 1107, The success path
in install_pbt_tools sets any_changed to True whenever _run_bash_with_retry for
hypothesis and fast-check succeeds, making the _OUTCOME_UNCHANGED branch
unreachable; either remove the unreachable _OUTCOME_UNCHANGED usage or implement
pre-checks to detect already-present tools. Fix by adding command-existence
checks (e.g., use an existing command_exists helper) before calling
_run_bash_with_retry for hypothesis and fast-check (manifest_get), set
any_changed only when an install/upgrade is actually performed, and then call
_record_outcome(_OUTCOME_UPDATED if any_changed else _OUTCOME_UNCHANGED);
alternatively, simply always record _OUTCOME_UPDATED on ok and drop the
_OUTCOME_UNCHANGED branch. Ensure you update logic around install_pbt_tools,
any_changed, _run_bash_with_retry, manifest_get, _record_outcome,
_OUTCOME_UPDATED and _OUTCOME_UNCHANGED accordingly.

208-215: 💤 Low value

Outcome recording inconsistent with other install functions.

Unlike install_semble, install_typescript_lsp, install_prettier, etc., this function always records _OUTCOME_UPDATED without checking if the tools were previously present. This results in "Python tools updated" even on fresh installs.

Suggested fix for consistency
 def install_python_tools() -> bool:
     """Install or upgrade Python development tools."""
     tools = ["ruff", "basedpyright"]
+    any_was_present = any(command_exists(t) for t in tools)
     for tool in tools:
         if not _run_bash_with_retry(f"uv tool install --upgrade {tool}"):
             return False
-    _record_outcome(_OUTCOME_UPDATED)
+    _record_outcome(_OUTCOME_UPDATED if any_was_present else _OUTCOME_INSTALLED)
     return True
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@installer/steps/dependencies.py` around lines 208 - 215, The
install_python_tools function always records _OUTCOME_UPDATED; change it to
mirror the other installers by detecting whether each tool already exists before
installing and record _OUTCOME_INSTALLED if none were present or
_OUTCOME_UPDATED if at least one was previously installed. Concretely, in
install_python_tools use a pre-check (e.g., call _run_bash_with_retry("uv tool
show {tool}") or equivalent) to set a flag like had_any_installed = True if any
tool exists, then perform the installs with _run_bash_with_retry as now, and
after successful installs call _record_outcome(_OUTCOME_UPDATED) if
had_any_installed else _record_outcome(_OUTCOME_INSTALLED); keep function name
install_python_tools and the existing
_run_bash_with_retry/_record_outcome/_OUTCOME_UPDATED symbols so the change is
consistent with install_semble, install_typescript_lsp, and install_prettier.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/docusaurus/docs/features/extensions.md`:
- Around line 214-223: The two fenced code blocks showing the directory trees
(the block that starts with "~/.agents/" and the block that starts with
"<project>/") are missing a language tag and trigger MD040; update each opening
triple-backtick to include a language (e.g., add "text" so they read ```text) so
markdownlint is satisfied, ensuring both code blocks (the one containing
"~/.agents/ ... ~/.codex/ ..." and the one containing "<project>/ ... .codex/")
are updated consistently.

In `@docs/docusaurus/docs/getting-started/codex-cli.md`:
- Around line 90-96: Update the outdated Hook support section in the docs to
reflect that Codex now ships quality hooks beyond SessionStart and PreCompact:
remove the claim that "most Claude Code hooks ... are not available in Codex"
and instead list the actual registered hooks in ~/.codex/hooks.json (include
SessionStart, PreCompact plus the quality hooks now supported such as
file-checker, context-monitor, spec-stop-guard, spec-mode-guard,
token-saver/tool-redirect equivalents). Ensure the text describes any
Codex-specific fields or differences (e.g., how
hookSpecificOutput/suppressOutput are handled if applicable) and matches the
PR’s hook rollout so readers see the correct coverage and behavior for functions
like file checker, context monitor, spec stop guard, and token saver.

In `@installer/steps/codex_files.py`:
- Around line 352-360: The loop over decomposed skill dirs currently swallows
all exceptions silently which hides failures; update the try/except around
build_codex_skill_md(skill_dir) to catch specific exceptions (or catch Exception
but log it) and emit a warning including the skill_dir name and the exception
details before continuing, so callers can see which skill failed; reference the
build_codex_skill_md call and the _atomic_write/dest_dir logic and use the
existing logger (or add one) to log an informative message (e.g., "Failed to
build SKILL.md for {skill_dir}: {err}") before continue.

In `@installer/steps/shell_config.py`:
- Around line 32-39: The fish wrapper uses the literal token "%self-(random)" so
session IDs become "%self-<random>" instead of PID-based values; update the
claude and codex function definitions in installer/steps/shell_config.py to
build the session id from $fish_pid (e.g. use "$fish_pid-(random)" when
assigning to local _sid and when setting PILOT_SESSION_ID) and keep the existing
exported vars (PILOT_SESSION_ID and CLAUDE_CODE_TASK_LIST_ID) and command
invocation intact so the functions claude, codex, _sid, PILOT_SESSION_ID and
CLAUDE_CODE_TASK_LIST_ID produce correct PID-RANDOM values.

In `@installer/tests/unit/steps/test_dependencies.py`:
- Around line 1430-1441: The test
test_install_golangci_lint_upgrades_when_already_installed must assert the
installer helper was invoked; after calling install_golangci_lint() add an
assertion that the patched helper was called (use the existing patch parameter
_mock_curl or mock_subproc depending on which helper you want to verify) e.g.
assert _mock_curl.assert_called_once() or assert
mock_subproc.assert_called_with(...) to prove the upgrade path executed the
installer helper; keep the rest of the test and mocks intact.

---

Outside diff comments:
In `@docs/docusaurus/docs/getting-started/installation.md`:
- Around line 21-31: Update the installer overview to reflect the new
CodexFilesStep: change "7 steps" to "8 steps" and insert a new table row for the
"Codex files" step between the existing "Claude files" and "Config files" rows
(or wherever the installer flow places CodexFilesStep); include a brief title
"Codex files" and a short description like "Sets up `~/.codex/` assets — models,
snippets, and runtime metadata" so the markdown table in installation.md matches
the actual installer flow and step naming used in the PR.

In `@installer/tests/unit/steps/test_dependencies.py`:
- Around line 63-117: The test test_dependencies_run_installs_core is missing
assertions for several newly mocked dependency calls causing orchestration
regressions to be invisible; update the test to assert that each new mock (e.g.,
_mock_codegraph, _mock_better_sqlite3, _mock_codex_plugin, _mock_lsp_plugins,
_mock_playwright, _mock_codegraph_needs_work, _mock_init_codegraph,
_mock_prettier, _mock_golangci_lint, _mock_pbt_tools, _mock_agent_browser,
_mock_semble, _mock_rtk) is called or explicitly not called as appropriate after
step.run(ctx) when running DependenciesStep, and also add negative assertions
for steps that should not run in this scenario (use assert_called_once() or
assert_not_called() on the mock objects to make the orchestration expectations
explicit).

---

Nitpick comments:
In `@installer/steps/codex_files.py`:
- Around line 38-43: _in _get_codex_config_dir(), validate that the CODEX_HOME
env var is an absolute path like get_claude_config_dir() does: if
os.environ.get("CODEX_HOME") is set, convert it to a Path and call
is_absolute(); if it is not absolute, raise a ValueError with a clear message
referencing CODEX_HOME; otherwise return the Path(env_dir) as before, and keep
the fallback to Path.home() / ".codex" when the env var is absent.
- Line 413: Remove the redundant local "import re" statement (the duplicate
import re near the bottom of installer/steps/codex_files.py) since re is already
imported at module level; locate the duplicate "import re" and delete that line
so only the single top-level import remains.
- Line 456: Replace the unnecessary f-string usage in the call to lines.append
by removing the f prefix so it uses a plain empty string; update the
lines.append(f"") expression to lines.append("") where it appears (e.g., in the
code that builds the lines list).

In `@installer/steps/dependencies.py`:
- Around line 1083-1107: The success path in install_pbt_tools sets any_changed
to True whenever _run_bash_with_retry for hypothesis and fast-check succeeds,
making the _OUTCOME_UNCHANGED branch unreachable; either remove the unreachable
_OUTCOME_UNCHANGED usage or implement pre-checks to detect already-present
tools. Fix by adding command-existence checks (e.g., use an existing
command_exists helper) before calling _run_bash_with_retry for hypothesis and
fast-check (manifest_get), set any_changed only when an install/upgrade is
actually performed, and then call _record_outcome(_OUTCOME_UPDATED if
any_changed else _OUTCOME_UNCHANGED); alternatively, simply always record
_OUTCOME_UPDATED on ok and drop the _OUTCOME_UNCHANGED branch. Ensure you update
logic around install_pbt_tools, any_changed, _run_bash_with_retry, manifest_get,
_record_outcome, _OUTCOME_UPDATED and _OUTCOME_UNCHANGED accordingly.
- Around line 208-215: The install_python_tools function always records
_OUTCOME_UPDATED; change it to mirror the other installers by detecting whether
each tool already exists before installing and record _OUTCOME_INSTALLED if none
were present or _OUTCOME_UPDATED if at least one was previously installed.
Concretely, in install_python_tools use a pre-check (e.g., call
_run_bash_with_retry("uv tool show {tool}") or equivalent) to set a flag like
had_any_installed = True if any tool exists, then perform the installs with
_run_bash_with_retry as now, and after successful installs call
_record_outcome(_OUTCOME_UPDATED) if had_any_installed else
_record_outcome(_OUTCOME_INSTALLED); keep function name install_python_tools and
the existing _run_bash_with_retry/_record_outcome/_OUTCOME_UPDATED symbols so
the change is consistent with install_semble, install_typescript_lsp, and
install_prettier.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6e502fa8-7aa7-46b5-97b8-9e5a9dda6fed

📥 Commits

Reviewing files that changed from the base of the PR and between ac59664 and 2c733fe.

⛔ Files ignored due to path filters (136)
  • console/src/cli/adapters/codex.ts is excluded by !console/**
  • console/src/cli/adapters/index.ts is excluded by !console/**
  • console/src/cli/handlers/session-init.ts is excluded by !console/**
  • console/src/cli/hook-command.ts is excluded by !console/**
  • console/src/services/sqlite/SessionStore.ts is excluded by !console/**
  • console/src/services/sqlite/migrations/runner.ts is excluded by !console/**
  • console/src/services/sqlite/sessions/create.ts is excluded by !console/**
  • console/src/services/worker/CodexSessionReader.ts is excluded by !console/**
  • console/src/services/worker/PaginationHelper.ts is excluded by !console/**
  • console/src/services/worker/http/routes/DataRoutes.ts is excluded by !console/**
  • console/src/services/worker/http/routes/ExtensionRoutes.ts is excluded by !console/**
  • console/src/services/worker/http/routes/ExtensionTypes.ts is excluded by !console/**
  • console/src/services/worker/http/routes/SessionRoutes.ts is excluded by !console/**
  • console/src/services/worker/http/routes/SettingsRoutes.ts is excluded by !console/**
  • console/src/services/worker/http/routes/UsageRoutes.ts is excluded by !console/**
  • console/src/services/worker/http/routes/utils/planFileReader.ts is excluded by !console/**
  • console/src/services/worker/usage/aggregator.ts is excluded by !console/**
  • console/src/services/worker/usage/codex-parser.ts is excluded by !console/**
  • console/src/services/worker/usage/pricing.ts is excluded by !console/**
  • console/src/services/worker/usage/yield.ts is excluded by !console/**
  • console/src/shared/hook-constants.ts is excluded by !console/**
  • console/src/ui/viewer/components/ui/AgentBadge.tsx is excluded by !console/**
  • console/src/ui/viewer/components/ui/index.ts is excluded by !console/**
  • console/src/ui/viewer/hooks/useExtensions.ts is excluded by !console/**
  • console/src/ui/viewer/hooks/useUsage.ts is excluded by !console/**
  • console/src/ui/viewer/views/Changes/index.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Dashboard/RecentSessions.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Extensions/ExtensionDetail.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Extensions/ExtensionsGrid.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Extensions/ExtensionsView.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Memories/index.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Requirements/index.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Sessions/SessionCard.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Sessions/SessionDetail.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Sessions/SessionTimeline.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Sessions/index.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Settings/sections/SpecWorkflowSection.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Settings/sections/_shared.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Spec/SpecHeaderCard.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Spec/index.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Usage/ModelCostBreakdown.tsx is excluded by !console/**
  • console/src/ui/viewer/views/Usage/index.tsx is excluded by !console/**
  • console/src/utils/logger.ts is excluded by !console/**
  • console/tests/cli/codex-adapter.test.ts is excluded by !console/**
  • console/tests/cli/codex-agent-filter.test.ts is excluded by !console/**
  • console/tests/cli/context-handler-plan.test.ts is excluded by !console/**
  • console/tests/ui/ExtensionsGrid.test.ts is excluded by !console/**
  • console/tests/ui/spec-delete-selection.test.ts is excluded by !console/**
  • console/tests/unit/services/worker/usage/codex-parser.test.ts is excluded by !console/**
  • console/tests/worker/extension-routes.test.ts is excluded by !console/**
  • launcher/agent_runtime.py is excluded by !launcher/**
  • launcher/banner.py is excluded by !launcher/**
  • launcher/build.py is excluded by !launcher/**
  • launcher/cli.py is excluded by !launcher/**
  • launcher/codegraph.py is excluded by !launcher/**
  • launcher/config.py is excluded by !launcher/**
  • launcher/model_config.py is excluded by !launcher/**
  • launcher/session.py is excluded by !launcher/**
  • launcher/statusline/formatter.py is excluded by !launcher/**
  • launcher/statusline/widgets.py is excluded by !launcher/**
  • launcher/tests/unit/test_agent_runtime.py is excluded by !launcher/**
  • launcher/tests/unit/test_cli.py is excluded by !launcher/**
  • launcher/tests/unit/test_codegraph.py is excluded by !launcher/**
  • launcher/tests/unit/test_session.py is excluded by !launcher/**
  • launcher/tests/unit/test_updater.py is excluded by !launcher/**
  • launcher/updater.py is excluded by !launcher/**
  • launcher/wrapper.py is excluded by !launcher/**
  • pilot/.mcp.json is excluded by !pilot/**
  • pilot/hooks/codegraph_init.py is excluded by !pilot/**
  • pilot/hooks/codex_hooks.json is excluded by !pilot/**
  • pilot/hooks/codex_skill_sync.py is excluded by !pilot/**
  • pilot/hooks/context_monitor.py is excluded by !pilot/**
  • pilot/hooks/file_checker.py is excluded by !pilot/**
  • pilot/hooks/hooks.json is excluded by !pilot/**
  • pilot/hooks/license_check.py is excluded by !pilot/**
  • pilot/hooks/session_end.py is excluded by !pilot/**
  • pilot/hooks/tests/test_codegraph_init.py is excluded by !pilot/**
  • pilot/hooks/tests/test_codex_skill_sync.py is excluded by !pilot/**
  • pilot/hooks/tests/test_context_monitor.py is excluded by !pilot/**
  • pilot/hooks/tests/test_file_checker.py is excluded by !pilot/**
  • pilot/rules/cli-tools.md is excluded by !pilot/**
  • pilot/rules/development-practices.md is excluded by !pilot/**
  • pilot/rules/mcp-servers.md is excluded by !pilot/**
  • pilot/rules/task-and-workflow.md is excluded by !pilot/**
  • pilot/scripts/context-generator.cjs is excluded by !pilot/**
  • pilot/scripts/mcp-server.cjs is excluded by !pilot/**
  • pilot/scripts/worker-service.cjs is excluded by !pilot/**
  • pilot/settings.json is excluded by !pilot/**
  • pilot/skills/benchmark/orchestrator.md is excluded by !pilot/**
  • pilot/skills/benchmark/scripts/runner.py is excluded by !pilot/**
  • pilot/skills/benchmark/steps/03-author-evals.md is excluded by !pilot/**
  • pilot/skills/benchmark/steps/04-execute.md is excluded by !pilot/**
  • pilot/skills/benchmark/tests/test_runner.py is excluded by !pilot/**
  • pilot/skills/create-skill/steps/04-create.md is excluded by !pilot/**
  • pilot/skills/create-skill/steps/06-test.md is excluded by !pilot/**
  • pilot/skills/fix/steps/01-investigate.md is excluded by !pilot/**
  • pilot/skills/fix/steps/06-finalise.md is excluded by !pilot/**
  • pilot/skills/prd/orchestrator.md is excluded by !pilot/**
  • pilot/skills/prd/steps/01-understand.md is excluded by !pilot/**
  • pilot/skills/prd/steps/02-research.md is excluded by !pilot/**
  • pilot/skills/prd/steps/07-write-prd.md is excluded by !pilot/**
  • pilot/skills/prd/steps/08-handoff.md is excluded by !pilot/**
  • pilot/skills/setup-rules/steps/08-sync-mcp.md is excluded by !pilot/**
  • pilot/skills/spec-bugfix-plan/orchestrator.md is excluded by !pilot/**
  • pilot/skills/spec-bugfix-plan/steps/01-create-header.md is excluded by !pilot/**
  • pilot/skills/spec-bugfix-plan/steps/02-investigation.md is excluded by !pilot/**
  • pilot/skills/spec-bugfix-plan/steps/04-write-plan.md is excluded by !pilot/**
  • pilot/skills/spec-bugfix-plan/steps/06-approval.md is excluded by !pilot/**
  • pilot/skills/spec-bugfix-verify/steps/03-verification-scenario.md is excluded by !pilot/**
  • pilot/skills/spec-bugfix-verify/steps/06-code-review-gate.md is excluded by !pilot/**
  • pilot/skills/spec-implement/orchestrator.md is excluded by !pilot/**
  • pilot/skills/spec-implement/steps/01-setup.md is excluded by !pilot/**
  • pilot/skills/spec-implement/steps/02-tdd-loop.md is excluded by !pilot/**
  • pilot/skills/spec-implement/steps/03-completion.md is excluded by !pilot/**
  • pilot/skills/spec-plan/orchestrator.md is excluded by !pilot/**
  • pilot/skills/spec-plan/steps/02-create-header.md is excluded by !pilot/**
  • pilot/skills/spec-plan/steps/03-workspace-scan.md is excluded by !pilot/**
  • pilot/skills/spec-plan/steps/05-exploration.md is excluded by !pilot/**
  • pilot/skills/spec-plan/steps/09-write-plan.md is excluded by !pilot/**
  • pilot/skills/spec-plan/steps/10-plan-verification.md is excluded by !pilot/**
  • pilot/skills/spec-plan/steps/12-approval.md is excluded by !pilot/**
  • pilot/skills/spec-verify/orchestrator.md is excluded by !pilot/**
  • pilot/skills/spec-verify/steps/01-launch-review.md is excluded by !pilot/**
  • pilot/skills/spec-verify/steps/03-collect-results.md is excluded by !pilot/**
  • pilot/skills/spec-verify/steps/07-e2e-and-final-regression.md is excluded by !pilot/**
  • pilot/skills/spec-verify/steps/10-review-gate.md is excluded by !pilot/**
  • pilot/skills/spec/orchestrator.md is excluded by !pilot/**
  • pilot/skills/spec/steps/00-permission-mode.md is excluded by !pilot/**
  • pilot/skills/spec/steps/01-parse-route.md is excluded by !pilot/**
  • pilot/ui/ExtensionsView.js is excluded by !pilot/**
  • pilot/ui/index.js is excluded by !pilot/**
  • pilot/ui/index2.js is excluded by !pilot/**
  • pilot/ui/index3.js is excluded by !pilot/**
  • pilot/ui/index4.js is excluded by !pilot/**
  • pilot/ui/viewer-bundle.js is excluded by !pilot/**
  • pilot/ui/viewer.css is excluded by !pilot/**
📒 Files selected for processing (43)
  • .gitignore
  • README.md
  • docs/docusaurus/docs/features/cli.md
  • docs/docusaurus/docs/features/extensions.md
  • docs/docusaurus/docs/features/hooks.md
  • docs/docusaurus/docs/features/mcp-servers.md
  • docs/docusaurus/docs/features/open-source-tools.md
  • docs/docusaurus/docs/features/remote-control.md
  • docs/docusaurus/docs/getting-started/codex-cli.md
  • docs/docusaurus/docs/getting-started/installation.md
  • docs/docusaurus/docs/getting-started/prerequisites.md
  • docs/docusaurus/docs/intro.md
  • docs/docusaurus/docs/workflows/prd.md
  • docs/docusaurus/docs/workflows/quick-mode.md
  • docs/docusaurus/docusaurus.config.ts
  • docs/docusaurus/sidebars.ts
  • docs/site/index.html
  • docs/site/public/manifest.json
  • docs/site/src/components/DeploymentFlow.tsx
  • docs/site/src/components/FAQSection.tsx
  • docs/site/src/components/Footer.tsx
  • docs/site/src/components/HeroSection.tsx
  • docs/site/src/components/InstallSection.tsx
  • docs/site/src/components/Logo.tsx
  • docs/site/src/components/PricingSection.tsx
  • docs/site/src/components/SEO.tsx
  • docs/site/src/components/WhatsInside.tsx
  • docs/site/src/pages/Index.tsx
  • docs/site/src/pages/Shared.tsx
  • install.sh
  • installer/cli.py
  • installer/steps/claude_files.py
  • installer/steps/codex_files.py
  • installer/steps/dependencies.py
  • installer/steps/finalize.py
  • installer/steps/shell_config.py
  • installer/tests/unit/steps/test_claude_files.py
  • installer/tests/unit/steps/test_codex_files.py
  • installer/tests/unit/steps/test_dependencies.py
  • installer/tests/unit/steps/test_finalize.py
  • installer/tests/unit/steps/test_shell_config.py
  • installer/ui.py
  • installer/upstreams.yaml

Comment thread docs/docusaurus/docs/features/extensions.md Outdated
Comment thread docs/docusaurus/docs/getting-started/codex-cli.md Outdated
Comment thread installer/steps/codex_files.py
Comment thread installer/steps/shell_config.py
Comment thread installer/tests/unit/steps/test_dependencies.py

@cubic-dev-ai cubic-dev-ai 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.

9 issues found across 179 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="pilot/skills/prd/steps/02-research.md">

<violation number="1" location="pilot/skills/prd/steps/02-research.md:26">
P2: Inconsistent MCP tool naming: uses underscores (`mcp__web_search__search`) here but hyphens (`mcp__web-search__search`) in the Deep Tier CODEX block below. Since `.mcp.json` defines the server as `web-search` (with hyphen), the hyphenated form is correct. The agent may fail to find the tool with the underscore variant.</violation>
</file>

<file name="docs/docusaurus/docs/features/remote-control.md">

<violation number="1" location="docs/docusaurus/docs/features/remote-control.md:62">
P2: Inconsistency: this step now says `claude` but the rest of the page (Setup section, Channels section) still uses `pilot`. If `pilot` is the command that loads hooks/rules/MCP servers, users following the SSH path would bypass that environment setup. Should this remain `pilot` for consistency, or should the other sections be updated as well?</violation>
</file>

<file name="installer/steps/shell_config.py">

<violation number="1" location="installer/steps/shell_config.py:33">
P1: `%self` does not expand when concatenated with other text in fish shell — `%self-(random)` will produce the literal string `%self-<number>` instead of `<PID>-<number>`. Use `$fish_pid` (available since fish 3.0) which works correctly in concatenation and is the recommended replacement for the deprecated `%self`.</violation>
</file>

<file name="pilot/hooks/codex_hooks.json">

<violation number="1" location="pilot/hooks/codex_hooks.json:14">
P1: `codegraph_init.py` (120s timeout) runs synchronously without `"async": true`, potentially blocking session start for up to 2 minutes. In `hooks.json` this is explicitly async to avoid blocking. If Codex supports the `async` property, consider adding it here to match the non-blocking behavior.</violation>
</file>

<file name="docs/docusaurus/docs/getting-started/codex-cli.md">

<violation number="1" location="docs/docusaurus/docs/getting-started/codex-cli.md:95">
P3: This statement is outdated: Codex hooks in this PR already register `file_checker`, `context_monitor`, `spec_stop_guard`, and `tool_token_saver`. Update the matrix text so setup expectations match the shipped Codex hook coverage.</violation>
</file>

<file name="pilot/hooks/license_check.py">

<violation number="1" location="pilot/hooks/license_check.py:48">
P2: The `else: _allow()` branch is unreachable dead code. By the time execution reaches line 43, `data.get("valid", False)` is guaranteed to be falsy (line 38 would have returned otherwise), so the `elif not data.get("valid", False)` on line 46 is always `True`. This makes the logic confusing and could mask a missed intent (e.g., did you mean to check a different condition in the elif?).

Consider simplifying to remove the redundant check and dead branch:</violation>
</file>

<file name="installer/steps/codex_files.py">

<violation number="1" location="installer/steps/codex_files.py:355">
P2: Avoid swallowing all exceptions while building Codex skills. Silent `except Exception: continue` can skip skill installation with no user-visible signal, leaving Codex workflows partially installed.</violation>
</file>

<file name="docs/docusaurus/docs/features/hooks.md">

<violation number="1" location="docs/docusaurus/docs/features/hooks.md:9">
P2: Hook count is incorrect: tables list 18 hooks total but the text claims 19. If the 2 command-scoped Stop hooks mentioned in prose are included, the count should be 20.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic
Partial review: This PR has more than 50 files, so cubic reviewed the highest-priority files first. During the trial, paid plans get a higher file limit.
You can try an ultrareview to bypass the file limit, comment @cubic-dev-ai ultrareview. Learn more.

Re-trigger cubic

Comment thread installer/steps/shell_config.py Outdated
},
{
"type": "command",
"command": "uv run --no-project python \"$HOME/.pilot/hooks/codegraph_init.py\"",

@cubic-dev-ai cubic-dev-ai Bot May 27, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: codegraph_init.py (120s timeout) runs synchronously without "async": true, potentially blocking session start for up to 2 minutes. In hooks.json this is explicitly async to avoid blocking. If Codex supports the async property, consider adding it here to match the non-blocking behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At pilot/hooks/codex_hooks.json, line 14:

<comment>`codegraph_init.py` (120s timeout) runs synchronously without `"async": true`, potentially blocking session start for up to 2 minutes. In `hooks.json` this is explicitly async to avoid blocking. If Codex supports the `async` property, consider adding it here to match the non-blocking behavior.</comment>

<file context>
@@ -0,0 +1,143 @@
+          },
+          {
+            "type": "command",
+            "command": "uv run --no-project python \"$HOME/.pilot/hooks/codegraph_init.py\"",
+            "timeout": 120
+          },
</file context>
Fix with Cubic

Comment thread installer/steps/codex_files.py Outdated
Comment thread docs/site/src/components/HeroSection.tsx Outdated
Comment thread pilot/hooks/license_check.py
Comment thread docs/docusaurus/docs/features/hooks.md Outdated
Comment thread pilot/skills/prd/steps/02-research.md
Comment thread docs/docusaurus/docs/features/remote-control.md
Comment thread docs/docusaurus/docs/getting-started/codex-cli.md Outdated
- PaginationHelper: use COALESCE(s.agent, 'claude') so orphan observations
  aren't dropped when agent filter is applied (LEFT JOIN → INNER JOIN bug)
- file_checker: strip trailing whitespace/CR from regex-captured paths
  to handle Windows line endings in apply_patch content
- Memories UI: wrap JSON.parse of facts/concepts in safe helper to prevent
  render crash on malformed data
- hook-command: restore suppressOutput:true in error handler else branch
- codex_hooks.json: remove no-op context hook (handler early-returns for codex)
- installer codex_files: restrict TOML key detection to top-level scope,
  catch _TomlStructureError, remove dead regexes, cleanup
@claude

claude Bot commented May 27, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 3m 26s —— View job


Incremental Code Review: Push to feat/Codex CLI PR

Tasks:

  • Gather context and read repo guidelines
  • Review changed non-encrypted files in this push
  • Check which prior issues are resolved
  • Post incremental review findings

✅ Resolved from Prior Review

1. TOML key detection bug (section-scoped false positive)installer/steps/codex_files.py:294-300
top_level_scope is now computed and used for key-existence checks, so a [section]-scoped key no longer suppresses insertion of the required top-level key.

2. _TomlStructureError propagating uncaughtinstaller/steps/codex_files.py:62-66
_install_codex_config and _install_codex_mcp are now wrapped in try/except _TomlStructureError with a UI warning fallback in run().

3. Dead code: _TASK_SUBAGENT_RE / _AGENT_SUBAGENT_RE — removed entirely.

4. Redundant local import re — removed; only the module-level import remains.

5. f"" empty string — replaced with "".

6. HeroSection.tsx mobile text clippingwhitespace-nowrap now scoped to sm:whitespace-nowrap.

7. codex-cli.md hook section outdated — Updated with the full set of registered hooks (SessionStart, UserPromptSubmit, PostToolUse, Stop, PreCompact), accurate Codex-specific caveats, and correct feature availability.


New Issues in This Push

1. Stale _is_throttled docstringpilot/hooks/context_monitor.py:129-132

The docstring still says:

Orchestrator-aware: when a /spec orchestrator with a smaller window than main
is active, the percentage is computed against the orchestrator's window so the
throttle releases earlier…

But this push removed the _to_effective() function and all orchestrator-window scaling. The implementation now simply uses _get_max_context_tokens() (main window only). The docstring is misleading and should be trimmed to the actual behavior.

Fix this →


Still Open (No Change in This Push)

  • Silent skill install failureinstaller/steps/codex_files.py:374except Exception: continue still swallows errors with no user-visible signal. Use except (OSError, json.JSONDecodeError) as e: and log a warning.

  • Fish shell %self-(random)installer/steps/shell_config.py:33, 37%self only expands when it is the entire word; in %self-(random) it is treated literally. Yields %self-<number> instead of <PID>-<number>. Replace with $fish_pid-(random).

  • codegraph_init.py blocking SessionStartpilot/hooks/codex_hooks.json:14codegraph_init.py (120s timeout) runs synchronously without "async": true. In hooks.json (Claude Code) this hook is explicitly async. If Codex supports the property, add "async": true to avoid a potential 2-minute block on session start.


Code Quality Notes (New in Push)

context_monitor.py — 65% warning removed

The prior two-level alert system (65% inform, 75% autocompact) has been replaced with a single alert at 90%. The shown_80_warn flag and get_session_flags() are still written to cache but are no longer read or acted on in run_context_monitor. The code is consistent with the new design, just noting this is a deliberate behavioral change.

tool_token_saver.py — returncode guard removed (intentional)

if result.returncode != 0: return None was removed. The new test test_accepts_rewrite_when_rtk_exits_nonzero_with_output explicitly validates this: a non-zero exit from rtk rewrite is treated as "still potentially usable if stdout is non-empty and different." This is an intentional policy change and is correctly tested.

file_checker.pyapply_patch path extraction looks correct

The _extract_file_paths() helper handles both file_path (CC) and *** Update File: / *** Add File: markers in command (Codex). The regex and loop are clean. No issues found.


@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 20 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/docusaurus/docs/features/remote-control.md">

<violation number="1" location="docs/docusaurus/docs/features/remote-control.md:62">
P2: Inconsistency: this step now says `claude` but the rest of the page (Setup section, Channels section) still uses `pilot`. If `pilot` is the command that loads hooks/rules/MCP servers, users following the SSH path would bypass that environment setup. Should this remain `pilot` for consistency, or should the other sections be updated as well?</violation>
</file>

<file name="pilot/hooks/codex_hooks.json">

<violation number="1" location="pilot/hooks/codex_hooks.json:14">
P1: `codegraph_init.py` (120s timeout) runs synchronously without `"async": true`, potentially blocking session start for up to 2 minutes. In `hooks.json` this is explicitly async to avoid blocking. If Codex supports the `async` property, consider adding it here to match the non-blocking behavior.</violation>
</file>

<file name="pilot/hooks/context_monitor.py">

<violation number="1" location="pilot/hooks/context_monitor.py:290">
P2: Unreachable dead code: the two preceding conditions (`< THRESHOLD_AUTOCOMPACT` and `>= THRESHOLD_AUTOCOMPACT`) are exhaustive, so this `save_cache` call and `return 0` can never execute. Remove these lines or restructure the logic if a third branch was intended.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread pilot/hooks/context_monitor.py Outdated
- Fix CI: add command_exists early-exit to install_pbt_tools
- Fix fish shell %self not expanding in concatenation (use $fish_pid)
- Fix silent exception swallowing in codex_files skill builder
- Add CODEX_HOME absolute path validation
- Remove unreachable else branch in license_check.py
- Fix HeroSection whitespace-nowrap clipping on mobile
- Fix MCP tool naming (underscores → hyphens) in PRD skill
- Fix test_codex_rules local_mode mock (was truthy, skipping Path.home path)
- Add missing test assertions for dependency orchestration
- Update installation.md step count (7 → 8) with Codex files row
- Update codex-cli.md hooks section to match actual coverage
- Fix hooks.md count (19 → 18) to match table rows
- Add language tags to fenced code blocks in extensions.md
@claude

claude Bot commented May 27, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 4m 4s —— View job


Incremental Code Review: Push to feat/Codex CLI PR

Tasks:

  • Gather context and read repo guidelines
  • Review changed files in this push
  • Identify newly fixed issues from prior review
  • Check for new issues introduced in this push
  • Post incremental review findings

✅ Resolved from Prior Reviews

The following issues from prior Claude, CodeRabbit, and Cubic reviews are now addressed:

Issue File Status
Fish shell %self-(random) not expanding shell_config.py:33,37 ✅ Fixed — now $fish_pid-(random); test added
Silent skill install failure codex_files.py:386-388 ✅ Fixed — ctx.ui.warning(...) with details
Dead code in license_check.py license_check.py:43-47 ✅ Fixed — simplified to if/else
MCP tool naming (underscore vs hyphen) 02-research.md:26,28,69,71 ✅ Fixed — hyphens used throughout
codex-cli.md hooks section outdated codex-cli.md:90-99 ✅ Fixed — all 6 hook events documented
hooks.md count incorrect hooks.md:4,9 ✅ Fixed — both frontmatter and body show 18
installation.md step count stale installation.md:21-32 ✅ Fixed — 8 steps with Codex files row
extensions.md fenced blocks missing language extensions.md:214,227 ✅ Fixed — text language tag added
test_golangci_lint_upgrades missing assertion test_dependencies.py:1448 ✅ Fixed — mock_curl.assert_called_once() added
test_dependencies_run_installs_core incomplete test_dependencies.py:110-122 ✅ Fixed — all newly-mocked deps asserted
CODEX_HOME relative path accepted codex_files.py:43-44 ✅ Fixed — ValueError raised if not absolute
Redundant local import re codex_files.py ✅ Fixed — removed
f"" empty f-string codex_files.py ✅ Fixed — ""

New Issue

command_exists("fast-check") is always False — short-circuit guard unreachableinstaller/steps/dependencies.py:1095

if command_exists("hypothesis") and command_exists("fast-check"):
    _record_outcome(_OUTCOME_UNCHANGED)
    return True

fast-check is an npm library, not a CLI tool. It installs no binary, so shutil.which("fast-check") is always None and command_exists("fast-check") is always False. The _OUTCOME_UNCHANGED path is unreachable — every installation run will attempt to upgrade fast-check even when it is already at the pinned version.

The prior implementation correctly used npm list -g fast-check --depth=0 to check for npm package presence. Restoring that check or using a separate _is_npm_package_installed helper would fix this:

def _is_npm_package_installed(package: str) -> bool:
    try:
        result = subprocess.run(
            ["npm", "list", "-g", package, "--depth=0"],
            capture_output=True, text=True, timeout=15,
        )
        return result.returncode == 0 and package in result.stdout
    except Exception:
        return False

if command_exists("hypothesis") and _is_npm_package_installed("fast-check"):
    _record_outcome(_OUTCOME_UNCHANGED)
    return True

Fix this →


Still Open (not in this push)

  • _is_throttled stale docstringpilot/hooks/context_monitor.py:129-132 — "Orchestrator-aware" paragraph still present after _to_effective() was removed
  • Unreachable dead codepilot/hooks/context_monitor.py:290-291save_cache(total_tokens, session_id) / return 0 can never execute because the preceding < THRESHOLD_AUTOCOMPACT and >= THRESHOLD_AUTOCOMPACT branches are exhaustive
  • codegraph_init.py blocking SessionStartpilot/hooks/codex_hooks.json:14 — 120s timeout hook runs synchronously; hooks.json (Claude Code) marks this hook "async": true, Codex should match
  • remote-control.md:62 — step says claude while the rest of the page uses pilot; users following the SSH path would bypass the hook/rules/MCP environment loaded by pilot

@cubic-dev-ai cubic-dev-ai 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.

3 issues found across 12 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/docusaurus/docs/features/remote-control.md">

<violation number="1" location="docs/docusaurus/docs/features/remote-control.md:62">
P2: Inconsistency: this step now says `claude` but the rest of the page (Setup section, Channels section) still uses `pilot`. If `pilot` is the command that loads hooks/rules/MCP servers, users following the SSH path would bypass that environment setup. Should this remain `pilot` for consistency, or should the other sections be updated as well?</violation>
</file>

<file name="pilot/hooks/codex_hooks.json">

<violation number="1" location="pilot/hooks/codex_hooks.json:14">
P1: `codegraph_init.py` (120s timeout) runs synchronously without `"async": true`, potentially blocking session start for up to 2 minutes. In `hooks.json` this is explicitly async to avoid blocking. If Codex supports the `async` property, consider adding it here to match the non-blocking behavior.</violation>
</file>

<file name="pilot/hooks/context_monitor.py">

<violation number="1" location="pilot/hooks/context_monitor.py:290">
P2: Unreachable dead code: the two preceding conditions (`< THRESHOLD_AUTOCOMPACT` and `>= THRESHOLD_AUTOCOMPACT`) are exhaustive, so this `save_cache` call and `return 0` can never execute. Remove these lines or restructure the logic if a third branch was intended.</violation>
</file>

<file name="installer/steps/codex_files.py">

<violation number="1" location="installer/steps/codex_files.py:44">
P2: Unhandled `ValueError` will crash the installer if `CODEX_HOME` is set to a relative path. Neither the `run()` method nor the step orchestrator catch this exception — only `_TomlStructureError` and `KeyboardInterrupt` are handled. Wrap the early `_get_codex_config_dir()` call in `run()` with a `try/except ValueError` that reports via `ctx.ui.warning()` and returns gracefully.</violation>
</file>

<file name="installer/steps/dependencies.py">

<violation number="1" location="installer/steps/dependencies.py:1095">
P2: `command_exists("fast-check")` will always be False because `fast-check` is an npm library without a CLI binary — this guard never triggers. If the intent is to skip reinstallation when already present, `fast-check` needs a different existence check (e.g., checking the npm global `node_modules` directory). Also, skipping the `--upgrade` flag when the tools are already present breaks the installer's idempotent upgrade contract.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread docs/docusaurus/docs/getting-started/codex-cli.md Outdated
Comment thread installer/steps/codex_files.py
Comment thread installer/steps/dependencies.py Outdated
…ction

- Installer post-steps: show all 6 Codex skills (was 3), remove Claude Code Only section
- Enable mem-search MCP for Codex: remove _CODEX_SKIP_MCP entirely
- Enable memory context injection for Codex: remove early-return in context handler,
  restore context hook in codex_hooks.json
- codex-cli.md: remove Console Views table (all ✅), update MCP list (all 7 servers),
  remove memory/context from Claude Code-only table, update hooks section
- README: update Codex skill list (all 6), remove persistent memory from limitations
- prerequisites.md: update Codex description
- FAQSection.tsx: remove persistent memory from limitations
- Test updates: add benchmark/setup-rules/create-skill to Codex skill safety tests,
  update invocation regex, fix context handler test to expect injection
- create-skill: simplify allowed-tools examples to pass Codex safety checks
- Codex rules audit: all rules properly adapted via CC-ONLY/CODEX blocks
@claude

claude Bot commented May 27, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 3m 48s —— View job


Incremental Code Review: Push to feat/Codex CLI PR

Tasks:

  • Gather context and identify changed files
  • Review installer/steps/codex_files.py changes
  • Review installer/steps/finalize.py changes
  • Review installer tests changes
  • Review docs changes (codex-cli.md, prerequisites.md, FAQSection.tsx)
  • Check which prior issues are resolved
  • Post incremental review findings

✅ Resolved from Prior Reviews

Issue File Status
_CODEX_SKIP_MCP blocking mem-search codex_files.py:463 ✅ Fixed — frozenset removed, mem-search now included in Codex TOML config
codex-cli.md token optimization listed as CC-only codex-cli.md:139 ✅ Fixed — RTK/context monitoring removed from CC-only table
codex-cli.md Console Views table with ❌ Memories row codex-cli.md:39 ✅ Fixed — simplified to "All Console views work with Codex sessions"
Finalize "Claude Code Only" section missing shared skills finalize.py:113 ✅ Fixed — /setup-rules, /create-skill, /benchmark promoted to "Workflows (Claude Code + Codex)"
Memory context injection incorrectly disabled on Codex codex_hooks.json / context.ts ✅ Fixed — context handler enabled; test inverted to assert injection IS present
codex-cli.md hooks section listed as CC-only codex-cli.md:81-89 ✅ Fixed — CC-only table updated; hook events listed accurately for Codex

New Issue in This Push

codex-cli.md:139 — Memory row in "Differences" table contradicts the "What works on Codex" section

The doc now says in two places:

  1. Under "What works on Codex" (top of file): "Persistent memory is shared between both agents via the mem-search MCP server."

  2. In the "Differences from Claude Code" table at line 139:

    | Memory | Pilot Console (mem-search MCP) | Codex built-in memories (features.memories) |

The table row still shows Codex using "Codex built-in memories (features.memories)" rather than the mem-search MCP, directly contradicting the paragraph above. A reader following the table would not realize Codex now has access to Pilot Console's cross-session memory via mem-search.

Fix: update the Codex column of the Memory row to reflect both:

| Memory | Pilot Console (mem-search MCP) | Pilot Console (mem-search MCP) + Codex built-in memories (`features.memories`) |

or, if Pilot Console memory fully supersedes the Codex built-in for Pilot users:

| Memory | Pilot Console (mem-search MCP) | Pilot Console (mem-search MCP) |

Fix this →


Still Open (not in this push)

  • _is_throttled stale docstringpilot/hooks/context_monitor.py:129-132 — "Orchestrator-aware" paragraph still present after _to_effective() was removed
  • Unreachable dead codepilot/hooks/context_monitor.py:290-291save_cache(total_tokens, session_id) / return 0 can never execute (exhaustive if/elif above)
  • codegraph_init.py blocking SessionStartpilot/hooks/codex_hooks.json:14 — 120s timeout hook runs synchronously; hooks.json (Claude Code) marks it "async": true
  • remote-control.md:62 — step says claude while Setup/Channels sections use pilot; users following SSH path bypass hook/rules/MCP environment
  • command_exists("fast-check") always Falseinstaller/steps/dependencies.py:1095fast-check is an npm library with no CLI binary; early-return guard is unreachable
  • Unhandled ValueError in run()installer/steps/codex_files.py:57_get_codex_config_dir() raises ValueError for relative CODEX_HOME; none of the _install_codex_* callers in run() catch it

…ificOutput

Codex CLI doesn't support Claude Code's additionalContext protocol — returning
hookSpecificOutput causes 'invalid session start JSON output' error. Instead:
- Return { continue: true } (valid Codex JSON)
- Write compact one-liner to stderr: '[pilot] Memory loaded for [project]'
- mem-search MCP still available for on-demand memory lookups
@claude

claude Bot commented May 27, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 3m 36s —— View job


Incremental Code Review: Push to feat/Codex CLI PR

Tasks:

  • Gather context and read CLAUDE.md
  • Review changed non-encrypted files in this push (codex-cli.md, worker-service.cjs)
  • Check which prior issues are resolved
  • Post incremental review findings

✅ Resolved in This Push

Issue Location Status
Codex context handler returning hookSpecificOutput (wrong format for Codex) pilot/scripts/worker-service.cjs (kP context handler) ✅ Fixed — now writes compact stderr summary and returns {continue: true} for Codex
codex-cli.md SessionStart hook description inaccurate codex-cli.md:76 ✅ Fixed — now accurately states CC injects full index as hidden context; Codex shows compact summary and uses mem-search MCP

New Issue in This Push

worker-service.cjsCLAUDE_PILOT_NO_CONTEXT early-return uses CC-only format for Codex

pilot/scripts/worker-service.cjs (context handler kP)

The new context handler correctly differentiates platforms in the main path:

// ✅ Correct: platform-aware in main path
let l=(await o.text()).trim();
if(t.platform==="codex"){
  // ...
  return {continue: true}
}
return {hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:l}}

But the early-return when CLAUDE_PILOT_NO_CONTEXT=1 is set still returns the Claude Code-only format unconditionally:

// ❌ Missing platform check
if(process.env.CLAUDE_PILOT_NO_CONTEXT==="1"||...)
  return {hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:""}}

For a Codex user with CLAUDE_PILOT_NO_CONTEXT=1, this returns hookSpecificOutput — a Claude Code-specific response field that Codex doesn't use for context injection. Practically harmless since additionalContext is empty, but inconsistent with the platform-aware logic directly below it. The fix mirrors the main path:

if(process.env.CLAUDE_PILOT_NO_CONTEXT==="1"||...) {
  if(t.platform==="codex") return {continue: true};
  return {hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:""}}
}

Fix this →


Still Open (no change in this push)

  • codex-cli.md:139 — "Differences" table Memory row still says Codex built-in memories (features.memories) but the hooks section now says mem-search MCP handles on-demand lookups — the contradiction identified in the prior review is now more visible
  • _is_throttled stale docstringpilot/hooks/context_monitor.py:129-132 — "Orchestrator-aware" paragraph present after _to_effective() was removed
  • Unreachable dead codepilot/hooks/context_monitor.py:290-291save_cache / return 0 after exhaustive if/elif
  • codegraph_init.py blocking SessionStartpilot/hooks/codex_hooks.json:14 — 120s timeout, no "async": true; CC's hooks.json marks it async
  • remote-control.md:62 — step says claude; Setup and Channels sections use pilot
  • command_exists("fast-check") always Falseinstaller/steps/dependencies.py:1095fast-check has no CLI binary; guard is unreachable
  • Unhandled ValueErrorinstaller/steps/codex_files.py:57 — relative CODEX_HOME raises ValueError uncaught in run()

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="pilot/scripts/worker-service.cjs">

<violation number="1">
P2: The condition `p>0` is always true because `split("\n")` returns at least one element even on an empty string. When the context API returns empty content, users will still see "Memory loaded... — 1 lines" which is misleading. The check should guard against empty content (e.g. `l.length > 0`) rather than line count.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

- Add CC-ONLY/CODEX blocks to 5 Skill() calls in spec-verify and
  spec-bugfix-verify that would break the verify→implement loop in Codex
- Add orchestrator-level Codex AskUserQuestion handling to fix, prd,
  benchmark, and setup-rules skills
- Add CODEX blocks to mcp-servers.md (ToolSearch → tool_search) and
  browser-automation.md (Chrome tool detection)
- Fix wrong CodeGraph tool names in spec-implement (trace_call_path →
  codegraph_callers/callees, search_graph → codegraph_search)
- Add CODEX blocks to spec-plan step 00 and setup-rules step 01 for
  AskUserQuestion consistency
@claude

claude Bot commented May 27, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 5m 12s —— View job


Incremental Code Review: Latest Push to PR #153

Tasks:

  • Gather context and read CLAUDE.md
  • Review changed installer files (codex_files.py, test_codex_files.py)
  • Review changed pilot/rules files
  • Review changed pilot/skills files
  • Check which prior issues are resolved
  • Post incremental review findings

Summary of This Push

This push wires up full Codex compatibility across the benchmark runner, create-skill, setup-rules, fix, prd, spec-verify, spec-bugfix-verify, and spec-implement skills. The main patterns used are correct: CC-ONLY/CODEX-START conditional blocks for platform-divergent instructions, AskUserQuestion → plain-text numbered options for Codex, and Skill()/Agent() call → $skill-name handoff references. The benchmark runner changes (_prepare_codex_config_dir, CODEX_DEFAULT_MODEL sentinel, isolation module) are solid. One correctness bug and one style issue in the new additions.


Bug

1. Grader model sentinel CODEX_DEFAULT_MODEL can leak into the Claude CLI command

pilot/skills/benchmark/scripts/runner.py:1002-1004

grader_model: str = args.grader_model or (
    CODEX_DEFAULT_MODEL if grader_agent == "codex" and agent != "codex" else executor_model
)

When --agent codex (no --modelexecutor_model = CODEX_DEFAULT_MODEL) and --grader-agent claude (explicit cross-agent grading, with no --grader-model):

  • grader_agent == "codex" is False → falls through to executor_model
  • grader_model = "codex-default"

Then _run_grader(..., model="codex-default", agent="claude") runs:

claude -p --output-format text --model codex-default

codex-default is not a valid Claude model name. The sentinel value bleeds into the Claude code path which has no guard against it (CODEX_DEFAULT_MODEL is only checked in the if agent == "codex": branch at line 633).

Fix in main():

grader_model: str = args.grader_model or (
    CODEX_DEFAULT_MODEL if grader_agent == "codex"
    else executor_model if executor_model != CODEX_DEFAULT_MODEL
    else resolve_executor_model(target)
)

This covers the cross-agent case: Codex executor + Claude grader falls back to the skill's declared model (same fallback Claude uses when run alone).

Fix this →


Minor Issue

2. CC-ONLY/CODEX-START markers placed inside fenced code blocks

pilot/skills/create-skill/steps/03-check.md:3-20
pilot/skills/benchmark/steps/02-target-discovery.md:26-35

In both files, the conditional markers appear as content inside a ```bash fence:

```bash

ls .claude/skills/ 2>/dev/null
...



HTML comments inside fenced code blocks are **not** treated as invisible markup — they render as literal text. For the Codex installer path (`_adapt_invocation_syntax` with `re.DOTALL`), this is handled correctly. But for Claude Code agents reading the raw source, the `` and `CODEX-START/CODEX-END` markers appear as part of the bash snippet, making the code block visually cluttered and potentially confusing if an agent tries to copy-paste the commands.

The correct structure puts the code fences inside the conditional blocks:

```markdown

```bash
ls .claude/skills/ 2>/dev/null

This is non-blocking since the regex still works correctly for Codex adaptation and Claude Code agents understand the intent, but it makes the Claude Code-facing markdown cleaner.

---

### Design Note (No Action Needed)

**`CODEX_DEFAULT_MODEL` sentinel approach is correct**

The sentinel `"codex-default"` for "let Codex use its active model" is the right pattern here — Codex CLI has no `--model` flag equivalent of Claude's fallback, so omitting the flag is the correct default. The `if model and model != CODEX_DEFAULT_MODEL:` guard in `_execute_run_codex` and `_run_grader` is consistent and well-tested by the new `test_codex_agent_omits_model_flag_for_codex_default` / `test_codex_grader_omits_model_flag_for_codex_default` tests. The only gap is the cross-agent leak described in issue #1.

---

### Still Open (no change in this push)

- **`codex-cli.md:139`** — Memory row still says "Codex built-in memories (`features.memories`)" but line 40 says "Persistent memory is shared between both agents via the mem-search MCP server" — contradiction
- **`_is_throttled` stale docstring** — `pilot/hooks/context_monitor.py:129-132` — "Orchestrator-aware" paragraph present after `_to_effective()` was removed
- **Unreachable dead code** — `pilot/hooks/context_monitor.py:290-291` — `save_cache` / `return 0` after exhaustive if/elif
- **`codegraph_init.py` blocking SessionStart** — `pilot/hooks/codex_hooks.json:14` — 120s timeout hook has no `"async": true`; Claude Code's `hooks.json` marks it async
- **`remote-control.md:62`** — step says `claude`; Setup and Channels sections use `pilot`
- **`command_exists("fast-check")` always False** — `installer/steps/dependencies.py:1095` — `fast-check` has no CLI binary; early-return guard is unreachable
- **Unhandled `ValueError` in `run()`** — `installer/steps/codex_files.py:57` — `_get_codex_config_dir()` raises `ValueError` for relative `CODEX_HOME`; `_install_codex_hooks`, `_install_codex_skills`, `_install_codex_rules` call it outside the `try/except _TomlStructureError` block

---

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 30 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="pilot/hooks/codex_hooks.json">

<violation number="1" location="pilot/hooks/codex_hooks.json:14">
P1: `codegraph_init.py` (120s timeout) runs synchronously without `"async": true`, potentially blocking session start for up to 2 minutes. In `hooks.json` this is explicitly async to avoid blocking. If Codex supports the `async` property, consider adding it here to match the non-blocking behavior.</violation>
</file>

<file name="installer/steps/codex_files.py">

<violation number="1" location="installer/steps/codex_files.py:44">
P2: Unhandled `ValueError` will crash the installer if `CODEX_HOME` is set to a relative path. Neither the `run()` method nor the step orchestrator catch this exception — only `_TomlStructureError` and `KeyboardInterrupt` are handled. Wrap the early `_get_codex_config_dir()` call in `run()` with a `try/except ValueError` that reports via `ctx.ui.warning()` and returns gracefully.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread pilot/skills/benchmark/scripts/runner.py Outdated
- README + Docusaurus restructured: prerequisites, examples, and feature
  pages treat Claude Code and Codex as equals (drop Claude-only framing).
- Console: dashboard / sessions / memories / requirements show consistent
  agent badges; settings page agent styling matches across the app.
- Console Help page renamed to Documentation and moved below Settings;
  vim-style G-sequence shortcuts removed; sidebar ordering: Usage →
  Settings → Documentation.
- Console screenshot assets renamed help.webp → documentation.webp
  (full, _sm, thumbs) and surfaced in marketing site.
- Codex usage cost calculation fixed — parser now reads model from
  JSONL turn_context.payload.model instead of relying on the brittle
  ~/.codex/state_5.sqlite lookup. Previously all Codex sessions resolved
  to model='unknown' and total cost = $0.
- Codex skill migration: skills, hooks, and installer support both
  agents via shared .pilot/hooks layout and Codex agent skills under
  ~/.agents/skills/. uninstall.sh cleans Codex artifacts too.
- Statusline simplified to surface only Pilot Shell updates (Claude/Codex
  CLI updates removed — agents manage their own update prompts).
- Website SEO updated: index.html keywords, HowTo schema, FAQ schema,
  noscript fallback, SEO component defaults, and Docusaurus config
  (blog/RSS descriptions, metadata keywords) all include Codex/GPT-5.
- pilot/scripts and pilot/ui bundles rebuilt against the new console
  source.
@claude

claude Bot commented May 28, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 3m 35s —— View job


Incremental Code Review: Latest Push to PR #153

Tasks:

  • Gather context and read CLAUDE.md
  • Diff non-encrypted changed files (.gitignore, README.md)
  • Check which prior issues are resolved in this push
  • Post incremental review findings

✅ Resolved by This Push

Issue Location Status
codex-cli.md:139 — "Differences" table Memory row contradicting the hooks section docs/docusaurus/docs/getting-started/codex-cli.md ✅ Fixed — page completely rewritten; the table with conflicting rows is gone. New page correctly lists "Console — all 10 views, persistent memory, sessions, and memories shared between agents" under "Works on Both"
Unhandled ValueError in run() when CODEX_HOME is relative installer/steps/codex_files.py:57 ✅ Fixed — run() now wraps _install_codex_hooks/skills/agents in try/except ValueError (line 70) and _install_codex_config/mcp in a separate try/except (ValueError, _TomlStructureError) block (line 80). A relative CODEX_HOME caught in the first group exits early, preventing _install_codex_rules at line 84 from being reached
Unreachable save_cache / return 0 dead code pilot/hooks/context_monitor.py:290-291 ✅ Fixed — function now ends cleanly after the if percentage >= THRESHOLD_AUTOCOMPACT: block (line 288); no dead code remains

New Issue in This Push

README.md — prose typo "through with" in the /prd bullet

README.md (in the "Why Pilot Shell" bullet list, added in this push)

- **`/prd`** — brainstorm ideas into clear requirements through with optional deep research

"through with" is ungrammatical. Based on the fuller /prd description below it, the intended wording is either:

- **`/prd`** — brainstorm ideas into clear requirements with optional deep research

or

- **`/prd`** — brainstorm ideas into clear requirements through optional deep research

Fix this →


Still Open (no change in this push)

  • _is_throttled stale docstringpilot/hooks/context_monitor.py:129-132 — "Orchestrator-aware" paragraph remains after _to_effective() was removed; function now uses only _get_max_context_tokens()
  • codegraph_init.py blocking SessionStartpilot/hooks/codex_hooks.json:14 — 120s-timeout hook has no "async": true; Claude Code's hooks.json marks the same hook async

@cubic-dev-ai cubic-dev-ai 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.

4 issues found across 186 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="README.md">

<violation number="1" location="README.md:46">
P3: Fix the wording typo here (`through with`) to keep the `/prd` description clear and grammatically correct.</violation>
</file>

<file name="docs/docusaurus/docs/features/remote-control.md">

<violation number="1" location="docs/docusaurus/docs/features/remote-control.md:66">
P2: Contradicts the warning at the top of the page. The SSH section is about starting sessions visible via Remote Control, but the warning states Remote Control is not available with Codex CLI. Suggesting `codex` here will confuse users.</violation>
</file>

<file name="pilot/skills/prd/steps/04-clarify.md">

<violation number="1" location="pilot/skills/prd/steps/04-clarify.md:9">
P2: The Codex-specific block contradicts the unconditional instruction above it ("⛔ ALWAYS use the `AskUserQuestion` tool — never list numbered questions in plain text"). When CC-ONLY blocks are stripped for Codex, the agent sees both "never use plain text" and "ask one bundled plain-text prompt." Either wrap the unconditional line in `` with a Codex alternative, or rephrase the Codex block to avoid contradicting the shared rule.</violation>
</file>

<file name="docs/docusaurus/docs/workflows/create-skill.md">

<violation number="1" location="docs/docusaurus/docs/workflows/create-skill.md:36">
P2: Inconsistency: Phase 3 only mentions `~/.agents/skills/` (global) for Codex, but the info box at the bottom lists both `.agents/skills/` (project) and `~/.agents/skills/` (global). The Phase 3 description should include both paths for Codex to match.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.
Partial review: This PR has more than 50 files, so cubic reviewed the highest-priority files first. During the trial, paid plans get a higher file limit.
You can try an ultrareview to bypass the file limit, comment @cubic-dev-ai ultrareview. Learn more.

Fix all with cubic | Re-trigger cubic

Comment thread docs/docusaurus/docs/features/remote-control.md Outdated
Comment thread pilot/skills/prd/steps/04-clarify.md Outdated
Comment thread docs/docusaurus/docs/workflows/create-skill.md Outdated
Comment thread README.md Outdated
…them

- Add cmd_install agent prerequisite gate (EXIT 1 with README links when
  neither Claude Code nor Codex CLI detected)
- Remove install_claude_code + upstreams.yaml entry: installer no longer
  installs either agent (README contract)
- Three sibling file steps with clear separation:
  * PilotFilesStep — always; ~/.pilot/* runtime + canonical skill source +
    ~/.pilot/rules/ raw sources read by Codex adapter
  * ClaudeFilesStep — gated on is_claude_installed(); ~/.claude/{rules,
    agents,settings.json} + Claude post-install merges
  * CodexFilesStep — gated on is_codex_installed(); ~/.agents/skills/ +
    ~/.codex/*, per-category output mirroring Claude
- Fix is_claude_installed paths to launcher canonical set
  (~/.claude/local/bin/claude + Claude.app bundle)
- Unify agent detection: dependencies._init_rtk and codex_files now use
  platform_utils.is_*_installed
- PilotFilesStep switches inheritance → composition over ClaudeFilesStep
  to avoid LSP violation
- CodexFilesStep output via _CodexReport accumulator + label formatters
- Promote cache keys to named constants; remove dead
  _post_install_processing and dead _get_cached_pilot_files fallback
- Update README, Docusaurus installation guide, installer patterns rule
@claude

claude Bot commented May 28, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 4m 21s —— View job


Claude finished @maxritter's task in 4m 11s —— View job


Incremental Code Review: Latest Push to PR #153

Tasks:

  • Gather context and read repo guidelines
  • Review non-encrypted changed files in this push (installer/, pilot/, docs/)
  • Check which prior issues are resolved
  • Post incremental review findings

Summary of This Push

Major installer refactor: the monolithic ClaudeFilesStep is split into three steps — new PilotFilesStep (always runs, agent-neutral runtime + skills), ClaudeFilesStep (now gated on is_claude_installed()), and the existing CodexFilesStep (gated on is_codex_installed()). The installer now also aborts early when neither agent is detected. install_claude_code() is removed from DependenciesStep since users must install their own agents. _init_rtk() now uses the canonical platform_utils helpers for per-agent gating. Supporting _CodexReport helper cleans up the verbose UI-gate pattern in CodexFilesStep.run().

The new tests are thorough: TestInitRtk covers agent-presence gating for RTK init, TestPilotFilesStepScope covers the category-scope contract, TestClaudeFilesStepGated covers the skip path, and TestAgentPrerequisiteGate in test_cli.py covers the new abort-on-no-agent gate.


✅ Resolved from Prior Reviews

Issue Location Status
README.md "through with" prose typo README.md:46 ✅ Fixed — "with"
command_exists("fast-check") always False — unreachable guard installer/steps/dependencies.py:1095 ✅ Resolved — early-return guard removed; install_pbt_tools() now always runs upgrade
install_claude_code() installer installs Claude Code (users should do this) installer/steps/dependencies.py ✅ Removed — regression-guarded by test_install_claude_code_no_longer_exists
Finalize "pilot update" message mentions updating Claude Code installer/steps/finalize.py ✅ Fixed — message now says "update Pilot Shell" only; asserted in test
docs/docusaurus/docs/features/remote-control.md:62 says claude remote-control.md:66 ✅ Fixed — now says "Run claude or codex in any project directory"
docs/docusaurus/docs/workflows/create-skill.md:36 missing Codex project path create-skill.md:36 ✅ Fixed — now includes .agents/skills/ (project) alongside ~/.agents/skills/ (global)

New Issue

_check_license() changed fail-open → fail-closed; may remove skills on transient pilot verify timeout

pilot/hooks/codex_skill_sync.py:108

-        return True   # fail-open: exception → allow skill sync
+        return False  # fail-closed: exception → remove all Codex skills

When pilot verify --json times out (10 s timeout), crashes, or returns unparseable JSON, _check_license() now returns False. The caller at line 462 then runs _remove_codex_skills() + _remove_codex_review_agents() — removing every adapted SKILL.md from ~/.agents/skills/. Skills are rebuilt on the next SessionStart, but for the current session the Codex agent starts without any $spec, $prd, $fix, etc. skills available.

This affects licensed users with transient pilot process failures (network blip during --json call, slow startup on cold host, process contention). The previous fail-open behavior allowed skill sync to proceed when the check itself was uncertain. If the intent is to harden against license bypass, the safer approach is to skip the sync (return existing skills unchanged) rather than remove them:

except (OSError, subprocess.TimeoutExpired, json.JSONDecodeError, ValueError):
    return None  # sentinel: "unknown" → preserve existing skills, don't sync or remove

Then in the caller:

valid = _check_license()
if valid is None:
    print(json.dumps({"continue": True}))  # unknown: leave skills as-is
    return

Fix this →


Design Note (No Action Required)

PilotFilesStep._stage_raw_rules_for_codex passes FileInfo objects directly to download_files_parallel

installer/steps/pilot_files.py:122-125

This works in normal mode because download_files_parallel reads the download config to resolve GitHub URLs. In --local mode, the CodexFilesStep._install_codex_rules first fallback (local_repo_dir/pilot/rules) correctly bypasses the staged ~/.pilot/rules/ entirely, so any failure in _stage_raw_rules_for_codex during local installs is harmless. No action needed, but worth keeping in mind if local-mode behavior of download_files_parallel ever changes.


Still Open (no change in this push)

  • _is_throttled stale docstringpilot/hooks/context_monitor.py:129-132 — "Orchestrator-aware" paragraph still present after _to_effective() was removed; function now uses only _get_max_context_tokens()
  • codegraph_init.py blocking SessionStartpilot/hooks/codex_hooks.json:14 — 120s timeout hook still has no "async": true; Claude Code's hooks.json marks the same hook async

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 74 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="pilot/hooks/codex_hooks.json">

<violation number="1" location="pilot/hooks/codex_hooks.json:14">
P1: `codegraph_init.py` (120s timeout) runs synchronously without `"async": true`, potentially blocking session start for up to 2 minutes. In `hooks.json` this is explicitly async to avoid blocking. If Codex supports the `async` property, consider adding it here to match the non-blocking behavior.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.
Partial review: This PR has more than 50 files, so cubic reviewed the highest-priority files first. During the trial, paid plans get a higher file limit.
You can try an ultrareview to bypass the file limit, comment @cubic-dev-ai ultrareview. Learn more.

Fix all with cubic | Re-trigger cubic

Comment thread docs/docusaurus/docs/getting-started/installation.md Outdated
Comment thread installer/ui.py Outdated
@claude

claude Bot commented May 28, 2026

Copy link
Copy Markdown

Claude finished @maxritter's task in 3m 29s —— View job


Claude finished @maxritter's task in 4m 30s ——


Incremental Code Review: Latest Push to PR #153

Tasks:

  • Gather context and read repo guidelines
  • Review changed non-encrypted files in this push
  • Check which prior issues are resolved
  • Post incremental review findings

✅ Resolved from Prior Reviews

Issue Location Status
README.md "through with" prose typo README.md:46 ✅ Fixed
remote-control.md suggests codex for SSH/Remote Control remote-control.md:66 ✅ Fixed — reverted to claude only
installation.md broken #prerequisites internal anchor installation.md:21 ✅ Fixed — now ./prerequisites
create-skill.md Phase 3 missing Codex project path create-skill.md:36 ✅ Fixed — both .agents/skills/ (project) and ~/.agents/skills/ (global) listed
prd/04-clarify.md CC-ONLY conflict with Codex block pilot/skills/prd/steps/04-clarify.md:3 ✅ Fixed — both "ALWAYS use AskUserQuestion" paragraphs wrapped in ``
installer/ui.py Rich Text object in f-string loses styling installer/ui.py:309 ✅ Fixed — " ", sub_text, sep="" passes object directly; test added
Unhandled ValueError in run() for _install_codex_rules installer/steps/codex_files.py:125-129 ✅ Fixed — now wrapped in its own try/except ValueError

New Issue in This Push

Test name is misleading and the new rules-path ValueError handler is not actually tested

installer/tests/unit/steps/test_codex_files.py:61

The new test test_run_warns_and_returns_when_codex_home_is_relative_during_rules_install uses side_effect=[codex_dir, codex_dir, ValueError(...)] — three calls, third raises ValueError. But run() calls _get_codex_config_dir() inside _install_codex_hooks (1st), _install_codex_skills (2nd), and _install_codex_agents (3rd). The 3rd call raises ValueError inside the first try block, which catches it and returns early — before reaching _install_codex_rules. The new try/except ValueError block around _install_codex_rules is not exercised by this test at all.

The test name says "during_rules_install" but is actually testing "during_agents_install." The rules-specific handler (the newly added except ValueError in the third try block) needs a separate test that raises ValueError specifically from the 6th or later call (whichever call _install_codex_rules makes to _get_codex_config_dir).

Fix this →


Still Open (no change in this push)

  • _is_throttled stale docstringpilot/hooks/context_monitor.py:129-132 — "Orchestrator-aware" paragraph still present after _to_effective() removal
  • codegraph_init.py blocking SessionStartpilot/hooks/codex_hooks.json:14 — 120s-timeout hook still has no "async": true; Claude Code's hooks.json marks it async
  • _check_license() fail-closedpilot/hooks/codex_skill_sync.py:108 — returns False on timeout/crash, triggering _remove_codex_skills() for licensed users with transient failures
  • CLAUDE_PILOT_NO_CONTEXT early-return missing platform checkpilot/scripts/worker-service.cjs — returns {hookSpecificOutput: ...} unconditionally instead of {continue: true} for Codex platform

@maxritter maxritter merged commit fdbe276 into main May 28, 2026
22 checks passed
github-actions Bot pushed a commit that referenced this pull request May 28, 2026
# [9.1.0](v9.0.6...v9.1.0) (2026-05-28)

### Features

* enable Codex CLI as a first-class agent alongside Claude Code ([#153](#153)) ([fdbe276](fdbe276))
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 9.1.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@maxritter maxritter deleted the dev branch May 28, 2026 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant