Skip to content

wrap truncates at 20k lines silently — and keeps the oldest lines, dropping the incident tail #7

Description

@NGHINAI

All three input paths cap collection at 20,000 lines: wrapMaxLines (cmd/wrap.go:20), mcpMaxLines (internal/mcp/dispatch.go:16), and maxInputLines for stdin (cmd/io.go:26). When the cap is hit, the child is killed (internal/exec/stream.go:124-128) and the kill is mapped to success (stream.go:173-176), so the first 20k lines are compacted as if they were the whole input.

Two problems compound here:

1. The truncation is invisible. Neither the CLI summary line nor the MCP tool text mentions that input was cut. The user (or agent) sees a confident "N→M tok (X% reduction)" summary computed over the kept slice only. An agent debugging an incident has no signal that it analyzed a fraction of the logs.

2. The wrong fraction is kept. Because collection stops at the cap, codag keeps the oldest 20k lines and drops the newest. For the core use case — incident debugging — the recent lines are usually where the incident is. codag wrap -- cat /var/log/app.log on a large log file analyzes the oldest slice and can miss today's incident entirely, while reporting a clean compaction summary. Same applies to the MCP wrap/tail_* tools when an agent doesn't pre-bound the window.

Suggested fixes (independent):

  • Minimal: when hitLimit fires, append a marker to the compact output and stderr summary, e.g. [codag] input truncated at 20,000 lines (oldest kept) — bound the window with --since/--tail for full coverage. The MCP tools should include it in the returned text so agents can react.
  • Better: ring-buffer the most recent maxLines instead of killing at the cap (trade-off: the child then runs to completion or the 90s timeout, so latency changes; could apply keep-last only to file readers like cat/zcat where "newest = end of file" is unambiguous, or expose --keep first|last).

Happy to PR the minimal marker version if you're open to it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions