v0.13.2Control flow and dataflow are rebuilt on explicit semantics, Z3 translation matches executable C# numeric rules, and the build chain is hermetic and supply-chain verified with hash- and size-pinned Z3 binaries.See what's new

calor hook

Host-specific hook commands for Calor-first enforcement

Internal hook commands used by Claude Code, Gemini CLI, and Codex project integrations. They are normally invoked by generated configuration rather than typed by a user.

Bash
calor hook <subcommand> [args]

Overview

calor init --ai <agent> writes the host-specific hook configuration.

SubcommandPurpose
validate-write <tool-input>Validate a Claude-style Write request
validate-edit <tool-input>Validate a Claude-style Edit request
validate-calr-content <tool-input>Check Calor content for its semantics declaration
post-write-lint <tool-input>Lint a .calr file after a write
validate-ids <tool-input>Validate declaration IDs in Calor content
codex-writeConsume Codex's hook JSON from stdin and validate all destinations

Subcommands

validate-write

Validates Write tool calls to enforce Calor-first development.

Bash
calor hook validate-write <tool-input-json>

Behavior:

File TypeAction
.calr filesAllowed (exit 0)
.g.cs generated filesAllowed (exit 0)
Files in obj/ directoryAllowed (exit 0)
Other .cs filesBlocked (exit 1)

Example:

Bash
# This will be blocked (exit 1)
calor hook validate-write '{"file_path": "MyClass.cs"}'

# Output:
# BLOCKED: Cannot create C# file 'MyClass.cs'
#
# This is an Calor-first project. Create an .calr file instead:
#   MyClass.calr
#
# Use /calor skill for Calor syntax help.

# This will be allowed (exit 0)
calor hook validate-write '{"file_path": "MyClass.calr"}'

How Hooks Work

When you initialize a project with calor init --ai claude, it creates .claude/settings.json with hook configuration:

JSON
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "calor hook validate-write $TOOL_INPUT"
          }
        ]
      }
    ]
  }
}

This hook runs before every Write tool call. If the hook returns exit code 1, Claude Code blocks the operation and shows the error message to Claude, who will then retry with an .calr file.


User Experience

When Claude tries to create a .cs file in an Calor-initialized project:

  1. Claude calls the Write tool with a .cs file path
  2. The hook intercepts the call and validates the path
  3. Hook returns exit 1 with guidance message
  4. Claude Code blocks the write operation
  5. Claude sees the error and creates an .calr file instead

This enforcement happens automatically - no user intervention required.

For Codex, the input schema and trust model differ. codex-write reads the Codex hook envelope from stdin; it does not use Claude's $TOOL_INPUT environment variable. Review and trust .codex/hooks.json with /hooks, run the generated smoke test, and retain CI checks because specialized tool and shell paths can fall outside lifecycle-hook coverage.


Troubleshooting

Hook Not Blocking .cs Files

  1. Verify hooks are configured:

    Bash
    cat .claude/settings.json

    Should contain PreToolUse hook for Write

  2. Verify calor is in PATH:

    Bash
    which calor
    calor hook validate-write '{"file_path": "test.cs"}'
    echo $?  # Should be 1
  3. Restart Claude Code - hooks are loaded at session start

Re-enable Hooks After Manual Removal

Bash
calor init --ai claude --force

See Also