Skip to content

Preflight

preflight

Preflight hook action.

Runs git status --porcelain and git diff -U2 to report working-tree state before a protocol phase.

PreflightHook dataclass

Report working-tree status and diff as a pre-hook.

Designed for injection into protocol briefings via inject_result + inline: true.

params: path — project root (default "."). diff_lines — max diff lines (default 200, 0 to disable).

Source code in packages/axm-git/src/axm_git/hooks/preflight.py
Python
@dataclass
class PreflightHook:
    """Report working-tree status and diff as a pre-hook.

    Designed for injection into protocol briefings via
    ``inject_result`` + ``inline: true``.

    *params*:
        ``path`` — project root (default ``"."``).
        ``diff_lines`` — max diff lines (default 200, 0 to disable).
    """

    def execute(self, context: dict[str, object], **params: object) -> HookResult:
        """Execute the hook action.

        Args:
            context: Session context dictionary.
            **params: Optional ``path`` and ``diff_lines``.

        Returns:
            HookResult with a compact ``text`` render (via ``render_text``)
            and metadata containing ``files``, ``diff``, ``file_count``,
            and ``clean``.
        """
        if not params.get("enabled", True):
            return HookResult.ok(skipped=True, reason="git disabled")

        working_dir = resolve_working_dir(params, context, param_key="path").resolve()
        max_diff_lines = int(cast("int | str", params.get("diff_lines", 200)))

        git_root = find_git_root(working_dir)
        if git_root is None:
            return HookResult.ok(skipped=True, reason="not a git repo")

        pathspec = _compute_pathspec(working_dir, git_root)

        status = run_git(["status", "--porcelain", *pathspec], git_root)
        if status.returncode != 0:
            return HookResult.fail(f"git status failed: {status.stderr}")

        files = _collect_status_files(status.stdout)
        diff_stat_out = _collect_diff_stat(git_root, pathspec)
        diff_content, diff_truncated = _collect_diff(git_root, pathspec, max_diff_lines)

        rendered = render_text(
            files=files,
            diff_stat=diff_stat_out,
            diff=diff_content,
            diff_truncated=diff_truncated,
            max_diff_lines=max_diff_lines,
        )

        return HookResult(
            success=True,
            text=rendered,
            metadata={
                "files": files,
                "diff": diff_content,
                "file_count": len(files),
                "clean": len(files) == 0,
            },
        )
execute(context, **params)

Execute the hook action.

Parameters:

Name Type Description Default
context dict[str, object]

Session context dictionary.

required
**params object

Optional path and diff_lines.

{}

Returns:

Type Description
HookResult

HookResult with a compact text render (via render_text)

HookResult

and metadata containing files, diff, file_count,

HookResult

and clean.

Source code in packages/axm-git/src/axm_git/hooks/preflight.py
Python
def execute(self, context: dict[str, object], **params: object) -> HookResult:
    """Execute the hook action.

    Args:
        context: Session context dictionary.
        **params: Optional ``path`` and ``diff_lines``.

    Returns:
        HookResult with a compact ``text`` render (via ``render_text``)
        and metadata containing ``files``, ``diff``, ``file_count``,
        and ``clean``.
    """
    if not params.get("enabled", True):
        return HookResult.ok(skipped=True, reason="git disabled")

    working_dir = resolve_working_dir(params, context, param_key="path").resolve()
    max_diff_lines = int(cast("int | str", params.get("diff_lines", 200)))

    git_root = find_git_root(working_dir)
    if git_root is None:
        return HookResult.ok(skipped=True, reason="not a git repo")

    pathspec = _compute_pathspec(working_dir, git_root)

    status = run_git(["status", "--porcelain", *pathspec], git_root)
    if status.returncode != 0:
        return HookResult.fail(f"git status failed: {status.stderr}")

    files = _collect_status_files(status.stdout)
    diff_stat_out = _collect_diff_stat(git_root, pathspec)
    diff_content, diff_truncated = _collect_diff(git_root, pathspec, max_diff_lines)

    rendered = render_text(
        files=files,
        diff_stat=diff_stat_out,
        diff=diff_content,
        diff_truncated=diff_truncated,
        max_diff_lines=max_diff_lines,
    )

    return HookResult(
        success=True,
        text=rendered,
        metadata={
            "files": files,
            "diff": diff_content,
            "file_count": len(files),
            "clean": len(files) == 0,
        },
    )

truncate_diff(stdout, max_lines)

Truncate diff output to max_lines.

Returns the first max_lines lines joined by newlines, or the stripped original when it fits. Returns an empty string when max_lines is 0.

Source code in packages/axm-git/src/axm_git/hooks/preflight.py
Python
def truncate_diff(stdout: str, max_lines: int) -> str:
    """Truncate diff output to *max_lines*.

    Returns the first *max_lines* lines joined by newlines,
    or the stripped original when it fits.  Returns an empty
    string when *max_lines* is ``0``.
    """
    if max_lines <= 0:
        return ""
    lines = stdout.splitlines()
    if len(lines) > max_lines:
        return "\n".join(lines[:max_lines])
    return stdout.strip()