Add selectable CASAN IDE integrations

This commit is contained in:
thanhnv
2026-07-23 23:04:54 +07:00
parent ff4e9d5a53
commit ce708fafe5
28 changed files with 1658 additions and 407 deletions
@@ -1,9 +1,9 @@
# CASAN Codex adoption template (Plan-20)
Drop `hooks.json` → `.codex/hooks.json` and merge `config.toml` into
`.codex/config.toml` in the target repo (the installer does this). It wires the
Codex lifecycle hooks to the CASAN agentic bridge via the thin renderer
`packages/casan-harness/adapters/codex/codex_hook.py`.
`casan init --client codex` merges `hooks.json` into `.codex/hooks.json`. Each
handler calls `.casan/casan-hook.py`, which resolves and verifies the pinned
global harness before dispatching the Codex adapter. No custom `[casan]` TOML
keys are required.
Important Codex-specific facts (Spike-20 §4.2):
@@ -21,6 +21,6 @@ Important Codex-specific facts (Spike-20 §4.2):
disable them and set `CASAN_AGENTIC_INTEGRATION_MODE=managed_hook` through the
managed environment (not the committed config).
The command contract is stable (stdin JSON → exit 0 allow / exit 2 block); the
exact Codex payload key names are pinned during the Wave-3 payload spike, which
is why `codex_hook.py` reads several field aliases defensively.
The command shape follows current Codex hooks: nested command handlers,
`timeout` in seconds, `continue`/`stopReason` for turn events, and exit 2 for a
denied `PreToolUse`. The adapter reads documented fields plus defensive aliases.
@@ -1,18 +1,11 @@
# CASAN Plan-20 Codex config fragment (.codex/config.toml).
# Merge these keys into the target repo's .codex/config.toml. This enables the
# project hooks in hooks.template.json after Codex trust review.
# Optional CASAN Plan-20 Codex config fragment (.codex/config.toml).
# Hooks are enabled by default in current Codex; this explicit feature flag is
# useful only when an organization wants the project intent visible in TOML.
#
# For ENTERPRISE enforcement, the managed policy path pins hooks so a member
# cannot disable them (Spike-20 §4.2, Plan-20 Wave 3.3). In that deployment set
# CASAN_AGENTIC_INTEGRATION_MODE=managed_hook via managed environment/MDM, not
# in this committed file.
[hooks]
enabled = true
# project-local hooks load only after the user accepts the trust prompt.
project_hooks = true
[casan]
# Bridge feature flags — safe defaults (observe first, then enforce per Plan-20 §9).
enforcement_mode = "observe" # observe | enforce
integration_mode = "project_hook"
[features]
hooks = true
@@ -1,18 +1,59 @@
{
"//": "CASAN Plan-20 Codex project hooks. Commit as .codex/hooks.json in the target repo. Codex loads project-local hooks ONLY after a trust review — run `casan doctor --client codex` to confirm the trust/onboarding state (Spike-20 §4.2). The exact key names are pinned during the Wave-3 Codex payload spike; the command contract (stdin JSON -> exit 0 allow / exit 2 block) is stable. No secrets or absolute paths here.",
"version": 1,
"description": "CASAN Plan-20 lifecycle hooks. Review with /hooks; the project bootstrap resolves and verifies the pinned global harness.",
"hooks": {
"UserPromptSubmit": [
{ "command": ["python3", "packages/casan-harness/adapters/codex/codex_hook.py", "--event", "UserPromptSubmit"], "timeout_ms": 15000 }
{
"hooks": [
{
"type": "command",
"command": "python3 \"$(git rev-parse --show-toplevel)/.casan/casan-hook.py\" --client codex --event UserPromptSubmit",
"commandWindows": "py -3 \"$(git rev-parse --show-toplevel)/.casan/casan-hook.py\" --client codex --event UserPromptSubmit",
"timeout": 15,
"statusMessage": "CASAN admission"
}
]
}
],
"PreToolUse": [
{ "matcher": "*", "command": ["python3", "packages/casan-harness/adapters/codex/codex_hook.py", "--event", "PreToolUse"], "timeout_ms": 15000 }
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "python3 \"$(git rev-parse --show-toplevel)/.casan/casan-hook.py\" --client codex --event PreToolUse",
"commandWindows": "py -3 \"$(git rev-parse --show-toplevel)/.casan/casan-hook.py\" --client codex --event PreToolUse",
"timeout": 15,
"statusMessage": "CASAN policy gate"
}
]
}
],
"PostToolUse": [
{ "matcher": "*", "command": ["python3", "packages/casan-harness/adapters/codex/codex_hook.py", "--event", "PostToolUse"], "timeout_ms": 15000 }
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "python3 \"$(git rev-parse --show-toplevel)/.casan/casan-hook.py\" --client codex --event PostToolUse",
"commandWindows": "py -3 \"$(git rev-parse --show-toplevel)/.casan/casan-hook.py\" --client codex --event PostToolUse",
"timeout": 15,
"statusMessage": "CASAN evidence"
}
]
}
],
"Stop": [
{ "command": ["python3", "packages/casan-harness/adapters/codex/codex_hook.py", "--event", "Stop"], "timeout_ms": 15000 }
{
"hooks": [
{
"type": "command",
"command": "python3 \"$(git rev-parse --show-toplevel)/.casan/casan-hook.py\" --client codex --event Stop",
"commandWindows": "py -3 \"$(git rev-parse --show-toplevel)/.casan/casan-hook.py\" --client codex --event Stop",
"timeout": 15,
"statusMessage": "CASAN finalize"
}
]
}
]
}
}