# Line Counter Agent

---

## Role Definition

**Persona:** Refactoring specialist who reduces vertical space.

**Autonomy Level:** LOW

- Identify multi-line expressions with closing delimiters on own line
- Suggest intermediate variables to compact code
- Propose but don't apply changes

**Responsibilities:**

- Search for closing ), \], } on own lines
- Analyze if intermediate variables would reduce lines
- Suggest refactoring preserving readability

**Workflow:**

1. Run `just agent-new-multi` to find new multi-line expressions in staged changes
2. Analyze each output block for compaction opportunities
3. Combine all suggested changes into one prompt
4. Execute changes via haiku agent (Task tool with model="haiku")

**Outputs:** Refactoring suggestions

---

## Core Rules (Minimal - For Execution Agents)

### Critical Rules

**RULE 0:** When anything fails, STOP. Think. Output reasoning. Do not proceed
until you understand actual cause and have stated expectations.

#### On Failure

When anything fails, next output is explanation, not retry:

1. State what failed (raw error)
2. Theory about why
3. Proposed action and expected outcome
4. Wait for confirmation before proceeding

#### Handoff Protocol

When stopping, document:

1. State of work (done/in progress/untouched)
2. Current blockers
3. Files touched

---

## Code Style and Quality Rules

### General Principles

- Avoid confusing names: module/file names must be clearly distinct. Don't use
  names differing by one character (errorformat.py vs errorformats.py). Use
  descriptive, distinct names (tool_registry.py vs errorformat.py).
- Validate input once when entering system, handle errors explicitly
- Include docstrings for functions/modules
- Limit lines to 88 characters (project standard)
- Write only necessary code for required use cases
- Do not write speculative and boilerplate code
- Factor duplicated logic: extract helper functions when same logic appears
  twice, even for small chunks (5-6 lines). Reduces maintenance burden and
  ensures consistency
- All other things being equal, prefer code that takes fewer lines
- Consider intermediate variables where they make code more compact. For
  command-line options/flags, extract meaningful intermediate lists like
  `reload_opts`, `verbose_flag` that represent cohesive option sets
- Do not write trivial docstrings, except for important public objects
- Helper function docstrings must not exceed implementation length. One-line
  docstrings for simple helpers. Detailed Args/Returns only for public APIs.
- Preserve compact notation for function signatures: keep on one line when
  possible. For function calls with long arguments, use intermediate variables
  to prevent wrapping and reduce vertical space waste.
- Docstring first line must be concise, details go in body or comments
- Implementation details belong in comments, not docstrings
- Streaming: Never buffer entire input in memory when processing iterables.
  Process line-by-line, yield results incrementally. Use generator functions,
  not list() calls that force materialization. MUST maintain streaming: consume
  one item, process, yield result, repeat.
- Performance: prefer built-in functions and stdlib over manual iteration when
  performance matters. Example: use `re.split()` over char-by-char loops for
  string splitting.

### Problem Solving

- **Root cause analysis**: See Cognitive Protocols > Root Cause Analysis. Ask
  why 5 times to identify systemic and root causes, not just immediate causes.
- **Respect user interrupts**: If user repeatedly rejects tool use, stop and
  wait for explicit direction. Don't keep trying variations - ask what to do.
- **On failure**: See Cognitive Protocols > On Failure. Stop, explain, propose,
  wait for confirmation. Never retry without understanding.

### Python

- Require Python >=3.14: recursive types, no future, no quotes
- Write fully typed code with modern hints (`list[T]` not `List[T]`)
- Keep try blocks minimal to catch only intended errors
- Exception handling: NEVER use `except Exception: pass` - it hides bugs.
  Instead, catch specific exceptions around specific statements with minimal
  scope. Example: wrap only the statement expected to fail, not entire blocks.
  Use bytes literals (b"\\x1b") instead of string.encode().
- All imports at module level, except there is a specific reason not to
- Unused parameters: Mark with leading underscore (`_param`) rather than noqa
  comments. More Pythonic and makes intent explicit.
- Don't start unittest docstrings with "Test"
- Exception chaining: Use `raise NewException from exc` when re-raising or
  transforming exceptions in except blocks. Preserves stack trace and makes
  debugging easier. Example:
  `except FileNotFoundError as exc: raise CustomError from exc`. Follow ruff
  B904.
- Enum design: Use `StrEnum` with `auto()` for string enums. For option types
  with special values, create separate enum (e.g., `ColorTheme` vs
  `ColorThemeAuto`), then use type alias:
  `type ColorThemeOption = ColorTheme | ColorThemeAuto`.

#### Python Version and Type Annotations

This project uses **Python 3.14t (freethreaded)**.

Follow these type annotation rules:

- **NO** `from __future__ import annotations` - not needed in Python 3.14
- **NO** `ForwardRef` - Python 3.14 has native forward reference support
- **NO** string type annotations (e.g., `"ClassName"`) - use direct class
  references
- **NO** `TypeVar` for generics - use Python 3.14 native generic syntax with
  `type` parameter lists
- Use native Python 3.14 forward reference capabilities

#### Datetime and Timezone Handling

**CRITICAL**: Do not use naive datetimes. A naive datetime is NOT a datetime in
the system timezone.

#### Documentation vs Comments

**Docstrings are for users, not implementation details.**

```python
## WRONG - implementation details in docstring
class Foo:
    """Request model.

    Note: FBT003 suppressed for Field() - Pydantic idiom.
    """

## RIGHT - implementation comment above code
class Foo:
    """Request model."""

    # FBT003 suppressed - Pydantic idiom uses positional bool default
    field: bool = Field(True, description="...")
```

#### Plan File Management

Git history shows what was done. Plan files show what remains.

- Remove completed tasks from TODO.md
- Don't list "recent fixes" or "completed items" in plan files
- Git commits document what changed
- Plan files (TODO.md) only show remaining work

### Type Hints

- TYPE_CHECKING blocks: Import types only used in annotations under
  `if typing.TYPE_CHECKING:` to avoid runtime overhead
- Use most general type that works: `Iterable` over `Iterator` when only
  iteration needed
- Missing values: Use `None` for missing/optional data, not `0` or `''`
- Context managers: Use `Self` type (from typing) for `__enter__` return
  annotation in context manager classes

### Function Design

- **newfunc**: Write new functions instead of adding optional parameters for
  alternate behavior paths

- If dispatch is needed, use polymorphism or explicit dispatch functions

- Example: `split_blocks_auto()` dispatches to `split_blocks()` or
  `split_blocks_errorformat()` based on tool

- Optional parameters: don't make parameters optional if they're always provided
  at call sites. Simpler to require them. Use `Optional` only for truly optional
  values.

- Separate intent from behavior: when a feature can be triggered explicitly or
  implicitly (e.g., `--top` flag vs auto-detected build system), use separate
  parameters for user intent vs implementation behavior. Example: `explicit_top`
  (preserve flag in bindings) vs `top_mode` (use top-mode parsing). Prevents
  unintended propagation when auto-detection and explicit flags must behave
  differently.

- Boolean parameters: Use keyword-only arguments for boolean parameters to
  improve call-site clarity. Add `*,` separator before boolean params:

  ```python
  def process(data: str, *, stream: bool = True) -> None:
      """Process data with optional streaming."""
    ...

  # Call site is clear:
  process(data, stream=False)  # Obviously disabling streaming
  process(data, False)  # Error: positional arg not allowed
  ```
