Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ All notable changes to DeepWork will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.0] - 2026-01-16
## [0.3.0] - 2026-01-16

### Added
- Cross-platform hook wrapper system for writing hooks once and running on multiple platforms
- `wrapper.py`: Normalizes input/output between Claude Code and Gemini CLI
- `claude_hook.sh` and `gemini_hook.sh`: Platform-specific shell wrappers
- `policy_check.py`: Cross-platform policy evaluation hook
- Platform documentation in `doc/platform/` and `doc/platforms/` with hook references and learnings
- Claude Code platform documentation (`doc/platforms/claude/`)
- `update.job` for maintaining standard jobs (#41)
- `make_new_job.sh` script and templates directory for job scaffolding (#37)
- Default policy template file created during `deepwork install` (#42)
- Full e2e test suite: define → implement → execute workflow (#45)
- Automated tests for all shell scripts (#40)
- Automated tests for all shell scripts and hook wrappers (#40)

### Changed
- Standardized on "ask structured questions" phrasing across all jobs (#48)
Expand Down Expand Up @@ -58,6 +64,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

Initial version.

[0.2.0]: https://github.com/anthropics/deepwork/releases/tag/0.2.0
[0.3.0]: https://github.com/anthropics/deepwork/releases/tag/0.3.0
[0.1.1]: https://github.com/anthropics/deepwork/releases/tag/0.1.1
[0.1.0]: https://github.com/anthropics/deepwork/releases/tag/0.1.0
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,18 @@ deepwork/
│ │ ├── parser.py # Job definition parsing
│ │ ├── detector.py # Platform detection
│ │ └── generator.py # Skill file generation
│ ├── hooks/ # Cross-platform hook wrappers
│ │ ├── wrapper.py # Input/output normalization
│ │ ├── claude_hook.sh # Claude Code adapter
│ │ └── gemini_hook.sh # Gemini CLI adapter
│ ├── templates/ # Jinja2 templates
│ │ ├── claude/ # Claude Code templates
│ │ └── gemini/ # Gemini CLI templates
│ ├── schemas/ # JSON schemas
│ └── utils/ # Utilities (fs, yaml, git, validation)
├── tests/
│ ├── unit/ # Unit tests (147 tests)
│ ├── integration/ # Integration tests (19 tests)
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ └── fixtures/ # Test fixtures
└── doc/ # Documentation
```
Expand Down
58 changes: 56 additions & 2 deletions doc/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,13 @@ deepwork/ # DeepWork tool repository
│ │ ├── parser.py # Job definition parsing
│ │ ├── policy_parser.py # Policy definition parsing
│ │ └── hooks_syncer.py # Hook syncing to platforms
│ ├── hooks/ # Hook evaluation modules
│ ├── hooks/ # Hook system and cross-platform wrappers
│ │ ├── __init__.py
│ │ └── evaluate_policies.py # Policy evaluation CLI
│ │ ├── wrapper.py # Cross-platform input/output normalization
│ │ ├── claude_hook.sh # Shell wrapper for Claude Code
│ │ ├── gemini_hook.sh # Shell wrapper for Gemini CLI
│ │ ├── policy_check.py # Cross-platform policy evaluation hook
│ │ └── evaluate_policies.py # Legacy policy evaluation CLI
│ ├── templates/ # Command templates for each platform
│ │ ├── claude/
│ │ │ └── command-job-step.md.jinja
Expand Down Expand Up @@ -1064,6 +1068,56 @@ The hooks are installed to `.claude/settings.json` during `deepwork sync`:
}
```

### Cross-Platform Hook Wrapper System

The `hooks/` module provides a wrapper system that allows writing hooks once in Python and running them on multiple platforms. This normalizes the differences between Claude Code and Gemini CLI hook systems.

**Architecture:**
```
┌─────────────────┐ ┌─────────────────┐
│ Claude Code │ │ Gemini CLI │
│ (Stop event) │ │ (AfterAgent) │
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ claude_hook.sh │ │ gemini_hook.sh │
│ (shell wrapper) │ │ (shell wrapper) │
└────────┬────────┘ └────────┬────────┘
│ │
└───────────┬───────────┘
┌─────────────────┐
│ wrapper.py │
│ (normalization) │
└────────┬────────┘
┌─────────────────┐
│ Python Hook │
│ (common logic) │
└─────────────────┘
```

**Key normalizations:**
- Event names: `Stop` ↔ `AfterAgent`, `PreToolUse` ↔ `BeforeTool`, `UserPromptSubmit` ↔ `BeforeAgent`
- Tool names: `Write` ↔ `write_file`, `Bash` ↔ `shell`, `Read` ↔ `read_file`
- Decision values: `block` → `deny` for Gemini CLI
- Environment variables: `CLAUDE_PROJECT_DIR` ↔ `GEMINI_PROJECT_DIR`

**Usage:**
```python
from deepwork.hooks.wrapper import HookInput, HookOutput, run_hook, Platform

def my_hook(input: HookInput) -> HookOutput:
if input.event == NormalizedEvent.AFTER_AGENT:
return HookOutput(decision="block", reason="Complete X first")
return HookOutput()

# Called via: claude_hook.sh mymodule or gemini_hook.sh mymodule
```

See `doc/platform/` for detailed platform-specific hook documentation.

### Policy Schema

Policies are validated against a JSON Schema:
Expand Down
54 changes: 54 additions & 0 deletions doc/platform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Platform Documentation

This directory contains internal documentation about how different AI CLI platforms behave in ways that matter for DeepWork's hook system and adapter implementations.

## Purpose

These documents capture:

1. **Hook System Behavior** - Input/output formats, blocking mechanisms, event types
2. **Environment Variables** - What each platform provides to hook scripts
3. **Quirks and Edge Cases** - Platform-specific behaviors discovered during development
4. **Learnings** - Insights gained from implementing and testing adapters

## Adding Learnings

**IMPORTANT**: As you work on platform-specific code, document learnings here!

When you discover something about how a platform behaves that isn't obvious from official documentation, add it to the relevant platform's folder. Examples:

- "Gemini CLI's AfterAgent hook doesn't receive transcript_path when the session was resumed"
- "Claude Code's Stop hook JSON must have `decision: block` exactly, not `deny`"
- "Exit code 2 blocks in both platforms but stderr handling differs"

## Directory Structure

```
doc/platform/
├── README.md # This file
├── claude/
│ ├── hooks.md # Claude Code hooks system documentation
│ └── learnings.md # Discovered behaviors and quirks
└── gemini/
├── hooks.md # Gemini CLI hooks system documentation
└── learnings.md # Discovered behaviors and quirks
```

## Platform Comparison Summary

| Feature | Claude Code | Gemini CLI |
|---------|-------------|------------|
| Event: After agent | `Stop` | `AfterAgent` |
| Event: Before tool | `PreToolUse` | `BeforeTool` |
| Event: Before prompt | `UserPromptSubmit` | `BeforeAgent` |
| Project dir env var | `CLAUDE_PROJECT_DIR` | `GEMINI_PROJECT_DIR` |
| Block exit code | `2` | `2` |
| Block decision | `"block"` | `"deny"` or `"block"` |
| Input format | JSON via stdin | JSON via stdin |
| Output format | JSON via stdout | JSON via stdout |

## Related Files

- `src/deepwork/core/adapters.py` - Platform adapter implementations
- `src/deepwork/hooks/` - Hook wrapper scripts
- `doc/platforms/` - External platform documentation (configuration, commands)
Loading