vendor: import codex-plugins as packages/omo-codex/{plugin,scripts,marketplace.json,MARKETPLACE.md}

This commit is contained in:
YeonGyu-Kim
2026-05-25 22:24:37 +09:00
parent 06c86f526a
commit 2415f37bc0
260 changed files with 22715 additions and 0 deletions
@@ -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()
@@ -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"
]
}