magi-code 0.97.2

Repository-aware CLI coding agent for terminal work
Documentation
# Shared tool-card projection

## Ownership and inputs

`src/output/tool_card.rs` owns display-only tool meaning for Mission Control and future local-agent cards. `project_tool_card` accepts normalized `ToolActivityDetail`, an observed lifecycle status, explicit interrupted-history evidence, Bash command, selected child facts and bounded source text. It never looks up a transcript row, terminal width or `MissionControlState`.

Use `output::tool_display::{tool_activity_detail_pending,tool_activity_detail}` for normalization. Generic redaction does not authorize exporting parameter or metadata maps. The projection returns selected strings and typed blocks, not those maps. `project_task` and `project_task_activity` accept delegated-task facts and explicitly permitted activity summaries. Unknown identity/model/usage stay absent. Raw live reasoning is not a permitted input.

Mission Control's `projection/tool_adapters.rs` gathers facts and maps shared block meaning to terminal rendering roles. Bash highlighting, wrapping, transcript indices, navigation and selected-task state stay in TUI. Service workers can call the same pure projection without constructing terminal state.

## Outcomes and effects

`ToolOutcome` distinguishes success, failure, cancellation, interruption and unknown. Running observations have no terminal outcome. Only observed tool terminal status establishes success/failure; assistant text, run completion and requesting cancellation do not. Interrupted evidence applies when no tool terminal observation exists.

`ChangeState` is independent of outcome:

- Read/search/Web/View Image/Magi Control: not applicable to filesystem changes.
- Hash Edit: committed operation rows establish applied changes; no-op rows, stale-tag rejection, denied prose or an explicit zero changed count establish none. Partial commit evidence remains partial, including cancellation after changes.
- Write: returned byte metadata establishes application, including committed-but-undurable results. A denied write establishes none. Failure without mutation evidence stays unknown.
- Code Mode: positive host-owned tracked-change evidence establishes applied or partial tracked changes. Zero tracked paths does not establish absence of shell/MCP effects.
- Bash, custom/MCP and delegation without effect evidence: unknown. Cancellation never implies rollback.

Displayed counts come from source metadata or an explicitly complete child inventory. Retained UI children are not a complete inventory. Missing call counts, elapsed time, exit code, resource results and usage stay unavailable. Script completion and inner-tool failures remain separate facts.

## Selected sources

| Adapter | Selected display facts |
| --- | --- |
| Bash | Explicit command/intent, exit code, independent timeout/truncation/cleanup notices, retained sanitized stream line count and bounded failure explanation; public protection and inferred file-count summaries. |
| Read | Requested resources, observed per-resource success/error, known line counts; no file contents in compact cards. |
| Grep / AST Grep | Explicit search/outline/rewrite-preview operation, patterns/symbol filters, scope/language, returned/seen/exact counts with output-line versus outline-entry units, scan-limit facts and bounded literal previews. |
| Find / List Files | Scope/query/kind, known counts, selected paths and fixed traversal/output limits. |
| Write / Hash Edit | Resource/operation, known bytes/change counts, rejected input preview, stale-tag details, partial commit rows, selected applied diff. Rejected input is not an applied diff. |
| Web / View Image | Selected query/URL/path, operation/provider/model, known result/image counts and bounded response/error text. |
| Magi Control | Allowlisted operation, recorded numeric usage and compaction request status; no private context or raw output. |
| Custom / MCP | Sanitized tool name and observed status; arbitrary arguments, metadata and raw results are unavailable. |
| Code Mode | Intent, host-owned execution counts, response token estimate, selected action names, built-in child failures/warnings, tracked paths, attributed child rows and no-rollback explanation. Script exception text is unavailable: scripts can repeat private custom-tool results. |
| Subagents | Intent, selected identity/agent/provider/model/effort, optional normalized usage and attributed permitted activity summaries. Caller owns relationship lookup and task selection. |

Resource adapters share [fixed labels, nullable count meanings and bounded display-only persistence](resource-operation-card-facts.md). Missing legacy aggregate-retention facts cannot establish supplied Read line counts. Local-agent and Mission Control restore the same selected report; no current-file lookup or provider-visible result change.

Web, View Image and Control share [fixed public facts](web-image-control-card-facts.md). Control normalization removes private input before expanded activity display as well as card projection. Saved history uses the same selection without parsing output text.

Public protection uses fixed decision labels. Scores, probabilities, confidence, assessments, evidence, prompts and arbitrary decision strings never enter shared cards. The typed public decision survives summary truncation. File tracking is inference, not proof a mutation occurred. Custom-tool metadata cannot impersonate backend protection facts.

Bash public notices share one selector across terminal metadata and rich live/saved `results` rows: `Humanize protection`, `Bash protection`, `File tracking`, `Inferred file activity`. Missing values stay unavailable; terminal text says `not reported`. Aggregate inference selects first 32 entries, deduplicates valid paths internally and reports supported R/W/E counts, selection limits and unsupported entries without exporting paths. Limited/unsupported selection says full totals unknown; inference never establishes applied effects. [Exact wire semantics](local-agent-tool-cards.md#public-bash-notices).

Bash terminal results also select separate typed `Results` rows for command timeout, each stream's truncation, cleanup warning, bounded failure explanation and retained sanitized output lines. Shared Mission Control/wire labels, null semantics, ordering and count provenance: [Bash execution notices](local-agent-tool-cards.md#bash-execution-notices). No numeric count claims complete raw process output; available empty streams report zero and absent streams remain unavailable. Independent notices survive timeout and exit-0 failed results; omitted explanation never suppresses safety facts.

## Selection bounds and wire handoff

Preview rows retain four lines for ordinary tools, ten for Grep, and ten changed lines for applied diffs. Text lines use a 240-Unicode-scalar source cap, preserving graphemes, without terminal-column calculations. Shared output caps titles at 256 UTF-8 bytes, metadata rows at 512 bytes/eight rows, public protection summaries at 256 bytes, copy bodies and commands at 4096 bytes, semantic lines at 1024 bytes, resource rows at 32 and blocks at 16. Task fields use bounded single-line text; activity tails select at most 32 attributed lines. Tool-card omission subjects/reasons describe unavailable or excluded detail; overlapping losses use an unknown count rather than double counting. Preselected task activity has no omitted-source count.

These are internal selection bounds, not proof an escaped JSON card fits. The [negotiated contract](local-agent-tool-cards.md) still requires its fixed metadata object, typed resource/result/diff rows, mapped identities, hierarchy depth, origin/revision/detail fields and actual serialized-byte accounting. Local-agent must convert selected semantic facts into that allowlisted schema, preserve missing diff line numbers, and enforce card/core/frame/page/run budgets on its existing workers. Never serialize the internal Rust model or raw detail wholesale.

Local-agent wire selection, bounded live hierarchy/revisions and immutable saved cards share this projection. Prospective applied previews persist separately from raw `ToolResult.display` and hydrate both saved local-agent cards and Mission Control. Shared projection adds no provider-facing output or raw-detail endpoint. See [delivery status and source boundaries](local-agent-tool-cards-handoff.md#implementation).

## Verification scope

Source comparison against backend `e006ba70` covers every adapter listed above. [Recorded Mission Control observations](../archive/tool-card-projection-863-observations.md) compare that baseline with `fd48176c` using isolated synthetic histories and one bounded direct Bash command. Captured terminal text covers timeout, stale tags, partial commits, denied attempted previews, search limits, unknown children, missing counts and public protection. Observation found two terminal integration regressions; both were repaired and after frames recaptured.

Intentional presentation changes are recorded in `CHANGELOG.md`: private assessments are excluded, custom/MCP detail and unstructured Code Mode exceptions are unavailable, Bash-mode/compaction display text is bounded, absent resource/call counts are not replaced with failure or zero, and scalar limits replace column-based source truncation. Provider output and stored compaction handoffs are unchanged.

Required static checks: `cargo fmt --check`, `cargo check --locked`, `cargo clippy --locked --all-targets --all-features -- -D warnings`, `git diff --check`. Check results and executable provenance belong in the implementing PR. No new correctness tests or replacement scripts.

[Bounded local-agent observations](../archive/local-agent-tool-cards-864-observations.md) cover actual synthetic tool dispatch, live/saved applied diffs, partial commits, cancellation, timeout, child failures, legacy output and output pressure. They do not establish native frontend layout/input/accessibility, live remote-provider behavior, exhaustive boundary/race coverage or cross-repository parity. Missing legacy/partial applied previews remain explicitly unavailable; current filesystem is never historical diff evidence.