Skip to content

Commit 8bb0742

Browse files
committed
Codex Plugin
1 parent 3dd367d commit 8bb0742

11 files changed

Lines changed: 585 additions & 15 deletions

File tree

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ Then start a new session and define your first job:
2828

2929
> **Note:** DeepWork stores job definitions in `.deepwork/jobs/` and creates work branches in Git. Your project folder should be a Git repository. If it isn't, run `git init` first, or ask Claude to do so.
3030
31+
### Codex
32+
33+
When you run the DeepWork MCP server with `--platform codex`, DeepWork bootstraps
34+
repo-local Codex hooks for you by ensuring:
35+
36+
- `.codex/config.toml` enables `codex_hooks`
37+
- `.codex/hooks.json` contains the DeepWork `SessionStart` and `PostToolUse` handlers
38+
39+
This keeps the Codex hook setup checked into the project instead of relying on a
40+
manual one-time local setup step.
41+
3142
---
3243

3344
## The Problem

doc/architecture.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ The serve command:
133133
- Creates `.deepwork/tmp/` lazily for session state
134134
- Launches the FastMCP server (stdio or SSE transport)
135135
- No config file required — works out of the box
136+
- When started with `--platform codex`, also ensures repo-local Codex hook files
137+
exist under `.codex/` so SessionStart and PostToolUse DeepWork hooks are enabled
136138

137139
### 2. Hook Command (`hook.py`)
138140

@@ -180,6 +182,10 @@ Platform-specific delivery is now handled by plugins in `plugins/`:
180182
- **Claude Code**: `plugins/claude/` — installed as a Claude Code plugin via marketplace
181183
- **Gemini CLI**: `plugins/gemini/` — skill files copied to `.gemini/skills/`
182184

185+
Codex hook integration is repo-local rather than plugin-local today. When the MCP
186+
server starts with `--platform codex`, DeepWork ensures `.codex/config.toml`
187+
enables `codex_hooks` and `.codex/hooks.json` contains the DeepWork hook entries.
188+
183189
Each plugin contains static files (skill, hooks, MCP config) rather than generated content. The shared skill body lives in `platform/skill-body.md` as the single source of truth.
184190

185191
---
@@ -1108,4 +1114,3 @@ deepwork serve --transport sse --port 8000
11081114
- [JSON Schema](https://json-schema.org/)
11091115
- [Model Context Protocol](https://modelcontextprotocol.io/)
11101116
- [FastMCP Documentation](https://github.com/jlowin/fastmcp)
1111-

src/deepwork/cli/codex_hook.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""Internal Codex hook entrypoints for DeepWork."""
2+
3+
from __future__ import annotations
4+
5+
import sys
6+
7+
import click
8+
9+
from deepwork.codex_hooks import CodexHookSetupError, run_codex_hook
10+
11+
12+
@click.command(name="codex-hook", hidden=True)
13+
@click.argument("hook_name", type=click.Choice(["session_start", "post_tool_use"]))
14+
def codex_hook(hook_name: str) -> None:
15+
"""Run a DeepWork Codex hook and emit the JSON response expected by Codex."""
16+
raw_input = sys.stdin.read() if not sys.stdin.isatty() else ""
17+
try:
18+
click.echo(run_codex_hook(hook_name, raw_input))
19+
except CodexHookSetupError as e:
20+
click.echo(f"Error: {e}", err=True)
21+
sys.exit(1)

src/deepwork/cli/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ def cli() -> None:
1111

1212

1313
# Import commands
14+
from deepwork.cli.codex_hook import codex_hook # noqa: E402
1415
from deepwork.cli.hook import hook # noqa: E402
1516
from deepwork.cli.install import install, sync # noqa: E402
1617
from deepwork.cli.jobs import jobs # noqa: E402
1718
from deepwork.cli.review import review # noqa: E402
1819
from deepwork.cli.serve import serve # noqa: E402
1920

21+
cli.add_command(codex_hook)
2022
cli.add_command(hook)
2123
cli.add_command(jobs)
2224
cli.add_command(review)

src/deepwork/cli/review.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
@click.option(
1616
"--instructions-for",
1717
"instructions_for",
18-
type=click.Choice(["claude"]),
18+
type=click.Choice(["claude", "codex"]),
1919
required=True,
2020
help="Target platform for review instructions.",
2121
)
@@ -54,15 +54,15 @@ def review(
5454
5555
\b
5656
# Pipe from git
57-
git diff --name-only HEAD~3 | deepwork review --instructions-for claude
57+
git diff --name-only HEAD~3 | deepwork review --instructions-for codex
5858
5959
\b
6060
# Glob (shell expands the pattern)
61-
printf '%s\n' src/**/*.py | deepwork review --instructions-for claude
61+
printf '%s\n' src/**/*.py | deepwork review --instructions-for codex
6262
6363
\b
6464
# find
65-
find src -name '*.py' | deepwork review --instructions-for claude
65+
find src -name '*.py' | deepwork review --instructions-for codex
6666
"""
6767
project_root = Path(path).resolve()
6868

@@ -101,7 +101,7 @@ def review(
101101
sys.exit(1)
102102

103103
# Step 5: Format and output
104-
if instructions_for == "claude":
104+
if instructions_for in {"claude", "codex"}:
105105
output = format_for_claude(task_files, project_root)
106106
click.echo(output)
107107

0 commit comments

Comments
 (0)