Expand description
High-level summary extracted from a parsed bash Program.
summarise_bash_shape is the single public entry point. It walks the AST
once and returns a BashShape that the desktop host attaches to each
Bash tool-call frame as args._shape. The TS side reads this for the
ActivityReport bucket bar — no second parse, no full AST on the wire.
@yah:ticket(R196-T13, “BashShape.primary_program: skip pure-assignment stmts, recurse into compound bodies, unwrap assign=$(cmd)”) @yah:at(2026-05-16T02:42:10Z) @yah:status(review) @yah:parent(R196) @yah:severity(P2) @yah:next(“Repro: noisetable session:a5025082 — 10-iter loop where ./tests/run_replay_tests.sh is buried in for/do/done > out=$(VAR=1 ./tests/run_replay_tests.sh 27 2>&1). Three statement shapes the current ‘strip leading cd && / VAR=val’ heuristic misses.”) @yah:next(“Peel 1: pure-assignment stmts (pass=0; fail=0) — skip them as primary, same way leading var=val inside a command is skipped.”) @yah:next(“Peel 2: compound stmts (for/while/if/{…}) — recurse into the body; the load-bearing program is inside do…done, not the loop keyword.”) @yah:next(“Peel 3: assign-from-cmdsub (out=$(VAR=1 cmd …)) — when the stmt is only an assignment whose RHS is one command substitution, unwrap and take the inner command as primary. Same idea as ‘cd X && cmd’.”) @yah:next(“Edit extract_primary / extract_primary_stmt at summary.rs:431. side_effect + kind keep deriving off the unwrapped primary; cwd_hint stays untouched. all_programs unchanged.”) @yah:verify(“cargo test -p bash-ast (add fixture mirroring the noisetable shape under tests/summary.rs — assert primary_program == "./tests/run_replay_tests.sh")”) @yah:verify(“cargo test -p agent-tools –lib approval:: still 96/96 (no schema change)”) @yah:verify(“bun run typecheck (no TS change expected — BashShape wire format unchanged)”) @arch:see(.yah/docs/working/W055-agent-approval-evolution.md) @yah:handoff(“extract_primary refactored into extract_from_stmt_list() helper (R196-T13). Three peels: (1) VariableAssignment/VariableAssignments skipped (pure assignments); (2) For/While/If/CompoundStatement recurse into body via extract_from_stmt_list; (3) VariableAssignment where RHS is a CommandSubstitution unwraps to the inner body. loop_body_stmts() helper flattens LoopBody. 7 new tests in tests/summary.rs: peel1_pure_assignment_stmts_skipped, peel2_for_loop_body_recursed, peel2_while_loop_body_recursed, peel2_compound_body_recursed, peel3_assign_from_cmdsub_unwrapped, noisetable_repro_for_loop_with_assign_cmdsub. Also fixed pre-existing AgentSubclass missing caches:true in form_tools.rs (3x) and arch_tools.rs (1x).”) @yah:verify(“cargo test -p bash-ast # 62/62 including 7 new peel tests”) @yah:verify(“cargo test -p agent-tools –lib approval:: # 156/156 (no schema change)”) @yah:verify(“cargo check –workspace # clean”)
Structs§
- Bash
Shape - Compact summary of a bash command string, attached to
args._shapeon each normalisedBashtool-call frame. All fields are optional/additive: readers must ignore unknown keys, and missing keys mean “not computed” (older sessions, parse failure). - Statement
Slice - Byte range + coarse kind of one top-level statement in the parsed program. Stable for cross-language consumers (the desktop ships this on the wire to the UI). Byte indices are into the original source string.
Enums§
- Program
Kind - Coarse category for a primary program. Stable identifier used downstream for icon selection, activity bucketing, and permission heuristics.
- Side
Effect - Rule-based side-effect classification. Intentionally narrow — expand only with evidence; the classifier never fires on read-only siblings.
- Statement
Kind - Coarse tag mirroring
crate::ast::Statementvariants. Lets downstream consumers gate on statement shape (e.g. “skip splitting if any slice is a Pipeline / List / If / For”) without re-walking the full AST.
Functions§
- kind_
for - Map a primary program name to its
ProgramKind, orNonefor unknown commands. - summarise_
bash_ shape - Walk
programonce and extract aBashShapesummary.