vendor: import codex-plugins as packages/omo-codex/{plugin,scripts,marketplace.json,MARKETPLACE.md}
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.DS_Store
|
||||
.env
|
||||
.env.*
|
||||
@@ -0,0 +1,37 @@
|
||||
# Repository Conventions
|
||||
|
||||
Conventions for human contributors and AI agents working on this repository.
|
||||
|
||||
## Style
|
||||
|
||||
- Terse technical prose. No emojis in commits, issues, PR comments, or code.
|
||||
- Python: PEP 484 type hints. Hook script stays in standard-library only — no pip dependencies.
|
||||
- Tabs for indentation in JSON and Markdown tables. Spaces (4) for Python.
|
||||
- Double quotes for JSON strings.
|
||||
|
||||
## Layout
|
||||
|
||||
- `hooks/ultrawork-detector.py` — pure stdlib `UserPromptSubmit` hook. Reads JSON on stdin, writes the directive to stdout when the keyword matches, exits 0 otherwise.
|
||||
- `hooks/sync-agents.py` — pure stdlib `SessionStart` hook. Copies bundled `agents/*.toml` into `CODEX_HOME/agents`, exits 0.
|
||||
- `agents/*.toml` — bundled Codex agent role files.
|
||||
- `hooks/hooks.json` — registers hook scripts.
|
||||
- `.codex-plugin/plugin.json` — Codex plugin manifest. Marketplace metadata lives here, not in `package.json`.
|
||||
|
||||
## Constraints
|
||||
|
||||
- Never let the hook block a turn — exit code is always 0.
|
||||
- Never make a network call from the hook.
|
||||
- Keep the directive in `ULTRAWORK_DIRECTIVE` self-contained inside the Python file. The prompt hook is a single artifact a reviewer can read top-to-bottom.
|
||||
- Keep bundled agent role prompts concise and model-specific; measure prompt length when changing them.
|
||||
- When editing `ULTRAWORK_DIRECTIVE`, apply the `prompt-engineering` skill's entropy gate: every edit must reduce uncertainty per token. Re-measure character count before committing.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# smoke test the hook
|
||||
PAYLOAD='{"cwd":"/tmp","hook_event_name":"UserPromptSubmit","model":"gpt-5.5","permission_mode":"default","session_id":"x","transcript_path":"","turn_id":"y","prompt":"please ultrawork"}'
|
||||
echo "$PAYLOAD" | python3 hooks/ultrawork-detector.py | head -3
|
||||
|
||||
# pattern boundary check (must be empty)
|
||||
echo '{"hook_event_name":"UserPromptSubmit","prompt":"refactor ulw_helper.ts"}' | python3 hooks/ultrawork-detector.py | wc -c
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## 0.1.0 — 2026-05-23
|
||||
|
||||
Initial release.
|
||||
|
||||
- Codex `UserPromptSubmit` hook (`hooks/ultrawork-detector.py`) that detects `ultrawork` / `ulw` (word-bounded, case-insensitive) in the user prompt and injects the ultrawork orchestration directive.
|
||||
- Directive enforces: goal + binding success criteria with manual-QA scenarios + evidence, durable `/tmp` notepad lifecycle, obsessive atomic todos, scenario-driven execution loop, and a GPT-5.2 xhigh verification gate with no "false positive" escape hatch.
|
||||
- Directive size: 5,775 chars across 143 lines.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Yeongyu Kim
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,5 @@
|
||||
codex-ultrawork
|
||||
Copyright (c) 2026 Yeongyu Kim
|
||||
|
||||
This product includes software released under the MIT License.
|
||||
See LICENSE for the full text.
|
||||
@@ -0,0 +1,67 @@
|
||||
# codex-ultrawork
|
||||
|
||||
Codex plugin that injects a compact orchestration directive (the **ultrawork** prompt) when the user prompt contains `ultrawork` or `ulw` (word-bounded, case-insensitive). It also syncs the bundled `codex-ultrawork-reviewer` agent role into `CODEX_HOME/agents` on `SessionStart`.
|
||||
|
||||
## What the injected directive enforces
|
||||
|
||||
| Mandate | Behavior |
|
||||
|---|---|
|
||||
| Goal + binding success criteria | Call `create_goal` (or open with a `# Goal` block) listing the deliverable + **3+ realistic QA scenarios** (happy path, edge cases, adjacent-surface regression). Each scenario's PASS condition is **observable evidence from the real surface** (`tmux` transcript, `curl` status+body, browser screenshot, Playwright assertion, computer-use action log, CLI stdout, parsed config dump, DB state diff). "Tests pass" alone is not evidence. |
|
||||
| Durable /tmp notepad | `mktemp -t ulw-$(date +%Y%m%d-%H%M%S).XXXXXX.md` with sections `Plan`, `Success criteria + QA scenarios`, `Now`, `Todo`, `Findings`, `Learnings`. **Append**, never rewrite. |
|
||||
| Obsessive atomic todos | Every action — even one-line edits, `ls`, single test runs — becomes a todo. Format: `path: <action> for <criterion> — verify by <check>`. One in_progress at a time, mark completed immediately. |
|
||||
| GPT-5.2 xhigh verification gate | Triggered automatically on user-requested rigor, 3+ files, 20+ turns, 30+ minutes, or refactor/migration/perf/security work. Use the bundled `codex-ultrawork-reviewer` agent role when available. Reviewer verdict is **binding** — no "false positive", no minimising, no arguing. Loop until **unconditional** approval. "Looks good but…" = REJECTION. |
|
||||
|
||||
The directive is currently 5,821 chars (was 7,761) and follows the GPT-5.5 prompting structure (Role / Goal / Bootstrap / Execution loop / Verification gate / Commits / Constraints / Output / Stop rules).
|
||||
|
||||
## Install (via this marketplace)
|
||||
|
||||
```bash
|
||||
codex plugin marketplace add /path/to/codex-plugins
|
||||
node /path/to/codex-plugins/scripts/install-local.mjs /path/to/codex-plugins
|
||||
```
|
||||
|
||||
The installer copies the plugin into `~/.codex/plugins/cache/code-yeongyu-codex-plugins/omo/0.1.0`, enables it in `~/.codex/config.toml`, and registers the `UserPromptSubmit` and `SessionStart` hooks.
|
||||
|
||||
## How it works
|
||||
|
||||
`hooks/hooks.json` registers a `UserPromptSubmit` hook running:
|
||||
|
||||
```
|
||||
python3 ${PLUGIN_ROOT}/hooks/ultrawork-detector.py
|
||||
```
|
||||
|
||||
Codex passes the prompt payload on stdin. When the pattern `\b(?:ultrawork|ulw)\b` (case-insensitive) matches, the hook writes the directive to stdout — Codex injects non-JSON stdout as `additional_context` for the next turn. Otherwise the hook writes nothing and exits 0. Malformed input also exits 0 to never block the turn.
|
||||
|
||||
It also registers a `SessionStart` hook running:
|
||||
|
||||
```
|
||||
python3 ${PLUGIN_ROOT}/hooks/sync-agents.py
|
||||
```
|
||||
|
||||
That hook copies bundled `agents/*.toml` files into `CODEX_HOME/agents`. It writes nothing on success and exits 0 even on malformed input.
|
||||
|
||||
## Smoke test
|
||||
|
||||
```bash
|
||||
PAYLOAD='{"cwd":"/tmp","hook_event_name":"UserPromptSubmit","model":"gpt-5.5","permission_mode":"default","session_id":"x","transcript_path":"","turn_id":"y","prompt":"please ultrawork"}'
|
||||
echo "$PAYLOAD" | python3 hooks/ultrawork-detector.py | head -3
|
||||
```
|
||||
|
||||
Expect `<ultrawork-mode>` ... directive body.
|
||||
|
||||
## Agent role smoke test
|
||||
|
||||
```bash
|
||||
CODEX_HOME="$(mktemp -d)"
|
||||
echo '{"hook_event_name":"SessionStart"}' | CODEX_HOME="$CODEX_HOME" python3 hooks/sync-agents.py
|
||||
```
|
||||
|
||||
Expect `CODEX_HOME/agents/codex-ultrawork-reviewer.toml` to exist.
|
||||
|
||||
## License
|
||||
|
||||
MIT. See `LICENSE`.
|
||||
|
||||
## Privacy
|
||||
|
||||
This plugin only reads local hook payloads, emits the bundled directive text on keyword match, and syncs bundled agent TOML files locally. It does not perform network requests or telemetry.
|
||||
@@ -0,0 +1,17 @@
|
||||
name = "codex-ultrawork-reviewer"
|
||||
description = "Strict ultrawork verification reviewer. Use after full QA evidence to audit the diff, goal, and scenario evidence before declaring done."
|
||||
nickname_candidates = ["Verifier"]
|
||||
model = "gpt-5.2"
|
||||
model_reasoning_effort = "xhigh"
|
||||
developer_instructions = """You are the ultrawork verification reviewer.
|
||||
|
||||
Review only. Do not implement.
|
||||
|
||||
Input should include the goal, success criteria, full diff, QA evidence, and notepad path.
|
||||
|
||||
Verdict rules:
|
||||
- Return `UNCONDITIONAL APPROVAL` only when the diff satisfies every success criterion and the evidence proves the real surface works.
|
||||
- Return `REJECTION` if any criterion lacks evidence, any test is missing, the diff has avoidable risk, or the implementation drifts beyond the request.
|
||||
- Treat "looks good but..." as rejection. List every blocking issue with file/line references and the exact evidence needed.
|
||||
|
||||
Be concise, specific, and strict."""
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"${PLUGIN_ROOT}/hooks/sync-agents.py\"",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"UserPromptSubmit": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"${PLUGIN_ROOT}/hooks/ultrawork-detector.py\"",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Final, cast
|
||||
|
||||
|
||||
AGENTS_DIR: Final = "agents"
|
||||
SESSION_START_EVENT: Final = "SessionStart"
|
||||
|
||||
|
||||
def _load_payload() -> dict[str, object] | None:
|
||||
try:
|
||||
raw = sys.stdin.read()
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
if not raw.strip():
|
||||
return None
|
||||
try:
|
||||
parsed = cast(object, json.loads(raw))
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
if not isinstance(parsed, dict):
|
||||
return None
|
||||
values = cast(dict[object, object], parsed)
|
||||
return {str(k): v for k, v in values.items()}
|
||||
|
||||
|
||||
def _should_sync(payload: dict[str, object]) -> bool:
|
||||
return payload.get("hook_event_name") == SESSION_START_EVENT
|
||||
|
||||
|
||||
def _plugin_root() -> Path:
|
||||
env_root = os.environ.get("PLUGIN_ROOT")
|
||||
if env_root:
|
||||
root = Path(env_root).expanduser().resolve()
|
||||
if root.joinpath(AGENTS_DIR).is_dir():
|
||||
return root
|
||||
return Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def _codex_home() -> Path:
|
||||
env_home = os.environ.get("CODEX_HOME")
|
||||
if env_home:
|
||||
return Path(env_home).expanduser().resolve()
|
||||
return Path.home().joinpath(".codex")
|
||||
|
||||
|
||||
def _copy_agent_file(source: Path, target: Path) -> None:
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
if target.is_symlink() or target.is_file():
|
||||
target.unlink()
|
||||
elif target.exists():
|
||||
raise IsADirectoryError(target)
|
||||
_ = target.write_bytes(source.read_bytes())
|
||||
|
||||
|
||||
def _sync_agents(plugin_root: Path, codex_home: Path) -> None:
|
||||
source_dir = plugin_root / AGENTS_DIR
|
||||
if not source_dir.is_dir():
|
||||
return
|
||||
|
||||
target_dir = codex_home / AGENTS_DIR
|
||||
for source in sorted(source_dir.rglob("*.toml")):
|
||||
if not source.is_file():
|
||||
continue
|
||||
target = target_dir / source.relative_to(source_dir)
|
||||
_copy_agent_file(source, target)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
try:
|
||||
payload = _load_payload()
|
||||
if payload is not None and _should_sync(payload):
|
||||
_sync_agents(_plugin_root(), _codex_home())
|
||||
except Exception as err: # noqa: BLE001 - hook boundary must never block turns.
|
||||
_ = sys.stderr.write(f"codex-ultrawork agent sync failed: {err}\n")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Codex UserPromptSubmit hook: inject ultrawork directive on `ulw`/`ultrawork`.
|
||||
|
||||
Contract (required for codex hooks runtime):
|
||||
stdin: JSON {cwd, hook_event_name="UserPromptSubmit", model,
|
||||
permission_mode, prompt, session_id, transcript_path, turn_id}
|
||||
stdout: when the user prompt matches the ultrawork keyword, the directive
|
||||
text below; otherwise empty. Non-JSON stdout is treated by codex as
|
||||
`additional_context` and injected into the model's turn context.
|
||||
exit: 0 always (this hook never blocks the turn).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from typing import cast
|
||||
|
||||
|
||||
# `\b(?:ultrawork|ulw)\b` — word-bounded match excludes paths and identifiers.
|
||||
ULTRAWORK_PATTERN = re.compile(r"\b(?:ultrawork|ulw)\b", re.IGNORECASE)
|
||||
|
||||
|
||||
ULTRAWORK_DIRECTIVE = """<ultrawork-mode>
|
||||
|
||||
**MANDATORY**: First user-visible line this turn MUST be exactly:
|
||||
`ULTRAWORK MODE ENABLED!`
|
||||
|
||||
[CODE RED] Maximum precision. Outcome-first. Evidence-driven.
|
||||
|
||||
# Role
|
||||
Expert coding agent. Plan obsessively. Ship verified work. No process
|
||||
narration.
|
||||
|
||||
# Goal
|
||||
Deliver EXACTLY what the user asked, end-to-end working, proven by
|
||||
(a) a test written test-first that went RED→GREEN and (b) manual QA
|
||||
from the real surface with captured observable evidence. BOTH gates,
|
||||
every change, no exceptions.
|
||||
|
||||
# Bootstrap (DO ALL THREE BEFORE ANY OTHER WORK — NO SKIPPING)
|
||||
|
||||
## 1. Create the goal with binding success criteria
|
||||
Call `create_goal` (or open your reply with a `# Goal` block treated as
|
||||
binding) using exactly `objective` and `status` fields. Goals are
|
||||
unlimited; never invent a numeric budget or limit.
|
||||
The criteria MUST list, upfront:
|
||||
- The user-visible deliverable in one line.
|
||||
- 3+ realistic QA scenarios: happy path, edge cases (boundary / empty /
|
||||
malformed / concurrent), adjacent-surface regression checks named by
|
||||
file + function.
|
||||
- Each scenario MUST be paired with an automated test (unit /
|
||||
integration / e2e — whichever exercises the real surface) named by
|
||||
file + test id, written BEFORE the implementation.
|
||||
- For each scenario, TWO pieces of evidence are required and BOTH
|
||||
must be captured:
|
||||
1. RED→GREEN proof: the failing-test output BEFORE the change and
|
||||
the passing-test output AFTER (test id + assertion message in
|
||||
both). Tests added AFTER the green code do NOT satisfy this.
|
||||
2. Real-surface artifact — `tmux` session transcript, `curl` status
|
||||
+ body, browser screenshot / Playwright assertion, computer-use
|
||||
action log, CLI stdout, parsed config dump, DB state diff.
|
||||
Tests are the FLOOR (required, never sufficient); the surface
|
||||
artifact is the CEILING (also required). "tests pass" alone is NOT
|
||||
done.
|
||||
|
||||
These scenarios are the contract. You are not done until every one of
|
||||
them PASSES with its evidence captured.
|
||||
|
||||
## 2. Open the durable notepad
|
||||
Run: `NOTE=$(mktemp -t ulw-$(date +%Y%m%d-%H%M%S).XXXXXX.md)`. Echo the
|
||||
path. Initialise it with these sections and APPEND (never rewrite) as
|
||||
you work:
|
||||
|
||||
```
|
||||
# Ultrawork Notepad — <one-line goal>
|
||||
Started: <ISO timestamp>
|
||||
|
||||
## Plan (exhaustively detailed)
|
||||
<every step you will take, in order, broken to atomic actions>
|
||||
|
||||
## Success criteria + QA scenarios
|
||||
<copied from the goal>
|
||||
|
||||
## Now
|
||||
<the single step in progress>
|
||||
|
||||
## Todo
|
||||
<every remaining step, ordered>
|
||||
|
||||
## Findings
|
||||
<every non-obvious fact discovered, with file:line refs>
|
||||
|
||||
## Learnings
|
||||
<patterns / pitfalls / principles to remember next turn>
|
||||
```
|
||||
|
||||
Update `## Now` and `## Todo` on every status change. Append findings
|
||||
and learnings the moment they surface. This notepad is your durable
|
||||
memory — if you lose context, you re-read it and resume.
|
||||
|
||||
## 3. Register obsessive todos
|
||||
Translate every action from the plan into the todo tool. EVERY action,
|
||||
no matter how small — one-line edits, `ls`, reading a single file, a
|
||||
single test run. If you will do it, it is a todo. Format:
|
||||
`path: <action> for <criterion> — verify by <check>` encoding WHERE /
|
||||
WHY (which criterion it advances) / HOW / VERIFY. Exactly ONE in_progress
|
||||
at a time. Mark completed IMMEDIATELY — never batch.
|
||||
|
||||
GOOD pair (test-first, ordered):
|
||||
`foo.test.ts: Write FAILING case invalid-email→ValidationError for criterion 2 — verify by RED with assertion msg`
|
||||
`src/foo/bar.ts: Implement validateEmail() RFC-5322-lite for criterion 2 — verify by foo.test.ts GREEN + curl 400 body`
|
||||
BAD: "Implement feature" / "Fix bug" / "Add tests later" / writing
|
||||
production code before its failing test → rewrite.
|
||||
|
||||
# Execution loop (strict TDD — RED → GREEN → SURFACE)
|
||||
Until every success-criteria scenario PASSES with BOTH evidence pieces:
|
||||
1. Pick next criterion → mark in_progress → update notepad `## Now`.
|
||||
2. RED: write the failing test FIRST. Run it. Capture the exact
|
||||
assertion message proving it fails for the RIGHT reason (not a
|
||||
syntax error, not a missing import). Paste RED output into the
|
||||
notepad. No production code yet.
|
||||
3. GREEN: write the SMALLEST production change that flips RED→GREEN.
|
||||
Re-run the test. Capture GREEN output. If GREEN required more than
|
||||
~20 lines, your test was too coarse — split it.
|
||||
4. SURFACE: exercise the real user-facing surface named by the
|
||||
criterion (tmux / curl / browser / computer-use / CLI / DB).
|
||||
Capture the artifact path into the notepad.
|
||||
5. Verify: LSP diagnostics clean on changed files + full test suite
|
||||
green (no skipped, no xfail added this turn).
|
||||
6. Mark completed. Append non-obvious findings / learnings.
|
||||
7. After each increment, re-run the FULL scenario list. Record
|
||||
PASS/FAIL inline with BOTH evidence paths. Loop until all PASS.
|
||||
|
||||
Parallel-batch independent reads / searches / subagents within a step,
|
||||
but NEVER parallelise RED and GREEN of the same criterion.
|
||||
|
||||
# Verification gate (TRIGGERED, NOT OPTIONAL)
|
||||
|
||||
Trigger when ANY apply:
|
||||
- User said "엄밀", "strictly", "rigorously", "properly review", or
|
||||
explicitly demanded review.
|
||||
- Task touches 3+ files OR ran 20+ turns OR 30+ minutes wall-clock.
|
||||
- Refactor, migration, performance change, security-sensitive work, or
|
||||
anything the user called "깊게" / "deeply".
|
||||
|
||||
Procedure (NON-NEGOTIABLE):
|
||||
1. Spawn agent_type `codex-ultrawork-reviewer` (or any `gpt-5.2`
|
||||
xhigh reviewer if unavailable). Pass: goal, success-criteria,
|
||||
scenario evidence, full diff, notepad path.
|
||||
2. Treat the reviewer's verdict as binding. There is NO "false
|
||||
positive". Every concern is real. Do not argue. Do not minimise. Do
|
||||
not explain it away.
|
||||
3. Fix every issue. Re-run the FULL scenario QA. Capture fresh
|
||||
evidence. Update notepad.
|
||||
4. Re-submit to the SAME reviewer. Loop until you receive an
|
||||
UNCONDITIONAL approval ("looks good but..." = REJECTION).
|
||||
5. Only on unconditional approval may you declare done. Stopping early
|
||||
IS failure.
|
||||
|
||||
# Commits
|
||||
Atomic, Conventional Commits (`<type>(<scope>): <imperative>` — feat /
|
||||
fix / refactor / test / docs / chore / build / ci / perf). One logical
|
||||
change per commit; each commit builds + tests green on its own. No WIP
|
||||
on the final branch. If a plan file exists, final commit footer:
|
||||
`Plan: plans/<slug>.md`. Do NOT auto-`git commit` unless the user
|
||||
requested or preauthorised this session — default is stage + draft
|
||||
message + present for approval.
|
||||
|
||||
# Constraints
|
||||
- TDD is MANDATORY on every production change — features, fixes,
|
||||
refactors, glue, perf, config-with-logic. No "too small", "too
|
||||
obvious", or "just a one-liner" exemptions. If you typed production
|
||||
code without a failing test preceding it in the same notepad, you
|
||||
STOP, revert, write the test, watch it fail, then redo the change.
|
||||
- Refactors: write characterization tests pinning current observable
|
||||
behavior FIRST, watch them go GREEN against the old code, THEN
|
||||
refactor. They must remain green throughout.
|
||||
- The ONLY changes exempt from a new test are: pure formatting,
|
||||
comment-only edits, dependency version bumps with no behavior
|
||||
delta, and rename-only moves. Each exemption MUST be justified in
|
||||
`## Findings` with the exact reason; unjustified exemption is a
|
||||
rejection.
|
||||
- Smallest correct change. No drive-by refactors.
|
||||
- Never suppress lints / errors / test failures. Never delete, skip,
|
||||
`.only`, `.skip`, `xfail`, or comment out tests to green the suite.
|
||||
- Never claim done from inference — only from RED→GREEN + surface.
|
||||
- Parallel tool calls for any independent work.
|
||||
|
||||
# Output discipline
|
||||
- First line literally: `ULTRAWORK MODE ENABLED!`
|
||||
- After bootstrap: 1-2 paragraph plan summary + notepad path.
|
||||
- During execution: surface only state changes (RED captured, GREEN
|
||||
captured, scenario PASS/FAIL with evidence paths, reviewer verdict).
|
||||
- Final message: outcome + success-criteria checklist with evidence
|
||||
refs + notepad path + reviewer approval (if gate triggered) + commit
|
||||
list (`<sha> <subject>`). No file-by-file changelog unless asked.
|
||||
|
||||
# Stop rules
|
||||
- Stop ONLY when every scenario PASSES with captured evidence, notepad
|
||||
is current, and (if gate triggered) reviewer approved unconditionally.
|
||||
- After 2 identical failed attempts at one step, surface what was tried
|
||||
and ask the user before another retry.
|
||||
- After 2 parallel exploration waves yield no new useful facts, stop
|
||||
exploring and act.
|
||||
|
||||
</ultrawork-mode>"""
|
||||
|
||||
|
||||
def _load_payload() -> dict[str, object] | None:
|
||||
try:
|
||||
raw = sys.stdin.read()
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
if not raw.strip():
|
||||
return None
|
||||
try:
|
||||
parsed = cast(object, json.loads(raw))
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
if not isinstance(parsed, dict):
|
||||
return None
|
||||
values = cast(dict[object, object], parsed)
|
||||
return {str(k): v for k, v in values.items()}
|
||||
|
||||
|
||||
def _should_inject(payload: dict[str, object]) -> bool:
|
||||
if payload.get("hook_event_name") != "UserPromptSubmit":
|
||||
return False
|
||||
prompt = payload.get("prompt")
|
||||
if not isinstance(prompt, str) or not prompt:
|
||||
return False
|
||||
return ULTRAWORK_PATTERN.search(prompt) is not None
|
||||
|
||||
|
||||
def main() -> None:
|
||||
payload = _load_payload()
|
||||
if payload is not None and _should_inject(payload):
|
||||
_ = sys.stdout.write(ULTRAWORK_DIRECTIVE)
|
||||
_ = sys.stdout.flush()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,158 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { spawn } from "node:child_process";
|
||||
import { lstat, mkdtemp, readFile, rm, stat } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import test from "node:test";
|
||||
|
||||
const hookDir = dirname(fileURLToPath(import.meta.url));
|
||||
const pluginRoot = dirname(hookDir);
|
||||
const detectorPath = join(hookDir, "ultrawork-detector.py");
|
||||
const syncAgentsPath = join(hookDir, "sync-agents.py");
|
||||
|
||||
async function makeTempDir() {
|
||||
return mkdtemp(join(tmpdir(), "codex-ultrawork-"));
|
||||
}
|
||||
|
||||
async function runPython(scriptPath, input, env = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn("python3", [scriptPath], {
|
||||
env: {
|
||||
...process.env,
|
||||
...env,
|
||||
},
|
||||
});
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
child.stdout.setEncoding("utf8");
|
||||
child.stderr.setEncoding("utf8");
|
||||
child.stdout.on("data", (chunk) => {
|
||||
stdout += chunk;
|
||||
});
|
||||
child.stderr.on("data", (chunk) => {
|
||||
stderr += chunk;
|
||||
});
|
||||
child.once("error", reject);
|
||||
child.once("close", (code, signal) => {
|
||||
resolve({ code, signal, stdout, stderr });
|
||||
});
|
||||
child.stdin.end(input);
|
||||
});
|
||||
}
|
||||
|
||||
test("#given session start #when sync hook runs #then installs bundled reviewer agent", async () => {
|
||||
const codexHome = await makeTempDir();
|
||||
try {
|
||||
const result = await runPython(
|
||||
syncAgentsPath,
|
||||
'{"hook_event_name":"SessionStart"}',
|
||||
{ CODEX_HOME: codexHome },
|
||||
);
|
||||
|
||||
assert.equal(result.code, 0);
|
||||
assert.equal(result.signal, null);
|
||||
assert.equal(result.stdout, "");
|
||||
assert.equal(result.stderr, "");
|
||||
|
||||
const targetPath = join(codexHome, "agents", "codex-ultrawork-reviewer.toml");
|
||||
const targetStat = await lstat(targetPath);
|
||||
assert.equal(targetStat.isFile(), true);
|
||||
assert.equal(targetStat.isSymbolicLink(), false);
|
||||
const syncedAgent = await readFile(targetPath, "utf8");
|
||||
assert.match(syncedAgent, /^name = "codex-ultrawork-reviewer"$/m);
|
||||
assert.match(syncedAgent, /^model = "gpt-5.2"$/m);
|
||||
assert.match(syncedAgent, /^model_reasoning_effort = "xhigh"$/m);
|
||||
assert.match(syncedAgent, /^developer_instructions = """/m);
|
||||
} finally {
|
||||
await rm(codexHome, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("#given malformed session payload #when sync hook runs #then exits zero without output", async () => {
|
||||
const codexHome = await makeTempDir();
|
||||
try {
|
||||
const result = await runPython(syncAgentsPath, "{", { CODEX_HOME: codexHome });
|
||||
|
||||
assert.equal(result.code, 0);
|
||||
assert.equal(result.signal, null);
|
||||
assert.equal(result.stdout, "");
|
||||
assert.equal(result.stderr, "");
|
||||
await assert.rejects(
|
||||
stat(join(codexHome, "agents", "codex-ultrawork-reviewer.toml")),
|
||||
/code: 'ENOENT'|ENOENT/,
|
||||
);
|
||||
} finally {
|
||||
await rm(codexHome, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("#given ultrawork prompt #when detector runs #then emits directive", async () => {
|
||||
const payload = JSON.stringify({
|
||||
hook_event_name: "UserPromptSubmit",
|
||||
prompt: "please ulw this change",
|
||||
});
|
||||
|
||||
const result = await runPython(detectorPath, payload);
|
||||
|
||||
assert.equal(result.code, 0);
|
||||
assert.equal(result.signal, null);
|
||||
assert.equal(result.stderr, "");
|
||||
assert.match(result.stdout, /^<ultrawork-mode>/);
|
||||
assert.match(result.stdout, /First user-visible line this turn MUST be exactly:/);
|
||||
});
|
||||
|
||||
test("#given ultrawork prompt #when detector runs #then directive keeps goal budget unlimited", async () => {
|
||||
const payload = JSON.stringify({
|
||||
hook_event_name: "UserPromptSubmit",
|
||||
prompt: "please ultrawork this change",
|
||||
});
|
||||
|
||||
const result = await runPython(detectorPath, payload);
|
||||
|
||||
assert.equal(result.code, 0);
|
||||
assert.equal(result.signal, null);
|
||||
assert.equal(result.stderr, "");
|
||||
assert.match(result.stdout, /Goals are\s+unlimited/);
|
||||
assert.match(result.stdout, /exactly `objective` and `status` fields/);
|
||||
assert.doesNotMatch(result.stdout, /token[_-]?budget/i);
|
||||
assert.doesNotMatch(result.stdout, /200000/i);
|
||||
});
|
||||
|
||||
test("#given identifier-like ulw #when detector runs #then does not emit directive", async () => {
|
||||
const payload = JSON.stringify({
|
||||
hook_event_name: "UserPromptSubmit",
|
||||
prompt: "refactor ulw_helper.ts",
|
||||
});
|
||||
|
||||
const result = await runPython(detectorPath, payload);
|
||||
|
||||
assert.equal(result.code, 0);
|
||||
assert.equal(result.signal, null);
|
||||
assert.equal(result.stdout, "");
|
||||
assert.equal(result.stderr, "");
|
||||
});
|
||||
|
||||
test("#given hook manifest #when read #then registers prompt and session hooks", async () => {
|
||||
const manifest = JSON.parse(await readFile(join(hookDir, "hooks.json"), "utf8"));
|
||||
|
||||
assert.match(
|
||||
manifest.hooks.UserPromptSubmit[0].hooks[0].command,
|
||||
/ultrawork-detector\.py/,
|
||||
);
|
||||
assert.match(
|
||||
manifest.hooks.SessionStart[0].hooks[0].command,
|
||||
/sync-agents\.py/,
|
||||
);
|
||||
assert.equal(pluginRoot.endsWith("components/ultrawork"), true);
|
||||
});
|
||||
|
||||
test("#given component package #when inspected #then plugin identity is owned by aggregate root", async () => {
|
||||
const pkg = JSON.parse(await readFile(join(pluginRoot, "package.json"), "utf8"));
|
||||
|
||||
assert.equal(pkg.files.includes(".codex-plugin"), false);
|
||||
await assert.rejects(
|
||||
readFile(join(pluginRoot, ".codex-plugin", "plugin.json"), "utf8"),
|
||||
/code: 'ENOENT'|ENOENT/,
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@code-yeongyu/codex-ultrawork",
|
||||
"version": "0.1.0",
|
||||
"description": "Codex plugin that injects the ultrawork orchestration directive and syncs the ultrawork reviewer agent role.",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/code-yeongyu/codex-ultrawork",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/code-yeongyu/codex-ultrawork.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/code-yeongyu/codex-ultrawork/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"codex",
|
||||
"codex-plugin",
|
||||
"ultrawork",
|
||||
"agents",
|
||||
"hooks",
|
||||
"orchestration"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "node --test hooks/*.test.mjs"
|
||||
},
|
||||
"files": [
|
||||
"agents",
|
||||
"hooks/hooks.json",
|
||||
"hooks/sync-agents.py",
|
||||
"hooks/ultrawork-detector.py",
|
||||
"README.md",
|
||||
"LICENSE",
|
||||
"NOTICE"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user