# Data-driven goosedump cases. One case per line, fields joined by " | ".
#
# name= test label
# args= goosedump arguments (quote a token to keep embedded spaces)
# cwd run in the fixture root (needed for crush config discovery)
# status exit code: 0 (default), !0 (any failure), or an exact integer
# out= substring that must appear in stdout (repeatable)
# out!= substring that must not appear in stdout (repeatable)
#
# The fixture tree (tests/data.rs) stages one store per provider, so every
# case shares the same data. Blank lines and lines starting with # are ignored.
# opencode
name=opencode: list contexts | args=list * | out=opencode:sesh-alpha | out=opencode:sesh-bravo
name=opencode: display messages | args=show opencode:sesh-alpha | out="id":"entry-alpha" | out="role":"user" | out=STARTREK-DISCO | out="id":"entry-bravo" | out="role":"assistant"
name=opencode: native assistant parts | args=show opencode:sesh-alpha | out="type":"reasoning" | out=need to read a file | out="type":"text" | out=found STARTREK-DISCO in source | out="type":"tool" | out="tool":"read" | out="filePath":"src/main.rs"
name=opencode: grep literal match | args=grep opencode:sesh-alpha STARTREK-DISCO | out=STARTREK-DISCO
name=opencode: grep glob match | args=grep opencode:sesh-alpha START*DISCO | out=STARTREK-DISCO
name=opencode: grep no match | args=grep opencode:sesh-alpha NONEXISTENT-ZZ | out="messages":[] | out!=STARTREK-DISCO
name=opencode: ranked search | args=search opencode:sesh-alpha STARTREK-DISCO | out="id":"entry-alpha" | out=STARTREK-DISCO
name=opencode: ID filter | args=show opencode:sesh-alpha -m entry-alpha | out="id":"entry-alpha"
name=opencode: ID filter excludes other | args=show opencode:sesh-alpha -m entry-alpha | out!=entry-bravo
name=opencode: lineage scope | args=show opencode:sesh-alpha --scope lineage | out="id":"entry-alpha" | out="id":"entry-bravo"
name=opencode: grep preserves utf-8 | args=grep opencode:sesh-alpha café | out=café-日本語-🦀-résumé
# crush
name=crush: list contexts | cwd=yes | args=list * | out=crush:sesh-crush
name=crush: display messages | cwd=yes | args=show crush:sesh-crush | out=explain ZULU-NOVEMBER | out="role":"user" | out=ZULU-NOVEMBER is a code pattern | out="role":"assistant"
name=crush: native tool result | cwd=yes | args=show crush:sesh-crush | out="type":"tool_call" | out="name":"grep" | out=\"filePath\":\"lib.rs\" | out="type":"tool_result" | out="tool_call_id":"call-crush-0" | out="role":"tool" | out=lib.rs:9: ZULU-NOVEMBER
# pi
name=pi: list contexts | args=list * | out=pi:sesh-pi
name=pi: display messages | args=show pi:sesh-pi | out="id":"pi-entry-1" | out=TRIPLA-ESPRESSO | out="id":"pi-entry-2" | out="id":"pi-entry-3" | out=grep TRIPLA src/*.rs
name=pi: filtered grep no match | args=grep pi:sesh-pi found -m pi-entry-1 | out="type":"session" | out!=found TRIPLA-ESPRESSO
name=pi: unfiltered grep match | args=grep pi:sesh-pi found | out=found TRIPLA-ESPRESSO in file
name=pi: ranked search | args=search pi:sesh-pi TRIPLA-ESPRESSO | out="id":"pi-entry-1" | out=TRIPLA-ESPRESSO
name=pi: compact compaction context | args=compact pi:sesh-pi | out="type":"compaction" | out="version":3 | out="tokensBefore" | out=## Goal | out=find TRIPLA-ESPRESSO (#pi-entry-1) | out=[user] | out=[assistant] | out=* bash | out=$ grep TRIPLA src/*.rs
name=pi: compact from entry | args=compact pi:sesh-pi --from pi-entry-2 | out="type":"compaction" | out=Ongoing development work | out=[assistant]
name=pi: compact from excludes earlier entry | args=compact pi:sesh-pi --from pi-entry-2 | out!=find TRIPLA-ESPRESSO
name=pi: compact until excludes later entry | args=compact pi:sesh-pi --from pi-entry-2 --until pi-entry-3 | out!=Recent check passed
name=pi: compact invalid range | args=compact pi:sesh-pi --from pi-entry-4 --until pi-entry-2 | status=!0
name=pi: compact from with message-id | args=compact pi:sesh-pi --from pi-entry-2 -m pi-entry-2 | out=[assistant]
name=pi: compact surfaces todo state | args=compact pi:sesh-pi | out=[todo] Review compact parity (in_progress) | out!=Created #99
name=pi: compact filters todo tool call | args=compact pi:sesh-pi | out!=* todo
name=pi: compact skips resolved failure | args=compact pi:sesh-pi | out=[ ] [todo] Review compact parity (in_progress) (#pi-entry-4)
name=pi: compact merges prior durable section | args=compact pi:sesh-pi-merge | out=Always run clippy (#prior-pref)
name=pi: compact skips prior transcript | args=compact pi:sesh-pi-merge | out!=old transcript line
name=pi: compact plain prints pi screen style | args=compact pi:sesh-pi --format plain | out=[compaction] Compacted from | out=## Goal | out=find TRIPLA-ESPRESSO (#pi-entry-1)
name=pi: compact emits pi compaction entry | args=compact pi:sesh-pi --as-provider pi | out="type":"compaction" | out="firstKeptEntryId" | out="parentId":null | out=## Goal | out!=[Session Goal]
name=pi: compact converts summary to gemini | args=compact pi:sesh-pi --as-provider gemini | out="$set" | out=<state_snapshot> | out=<overall_goal> | out=Got it. Thanks for the additional context! | out="projectHash"
name=pi: compact plain gemini prints status line | args=compact pi:sesh-pi --format plain --as-provider gemini | out=Chat history compressed from | out= tokens.
name=pi: compact converts summary to opencode | args=compact pi:sesh-pi --as-provider opencode | out="summary":true | out="type":"compaction" | out="finish":"stop" | out=## Goal
name=pi: compact plain opencode prints rule | args=compact pi:sesh-pi --format plain --as-provider opencode | out= Compaction ─ | out=## Goal
name=pi: compact converts summary to codex | args=compact pi:sesh-pi --as-provider codex | out="type":"session_meta" | out="type":"compacted" | out="replacement_history" | out=Another language model started to solve this problem | out="input_text"
name=pi: compact plain codex prints info cell | args=compact pi:sesh-pi --format plain --as-provider codex | out=• Context compacted | out=Heads up: Long threads and multiple compactions
name=pi: compact converts summary to claude | args=compact pi:sesh-pi --as-provider claude | out="subtype":"compact_boundary" | out="parentUuid":null | out="isCompactSummary":true | out="isVisibleInTranscriptOnly":true | out=This session is being continued from a previous conversation
name=pi: compact plain claude prints transcript marker | args=compact pi:sesh-pi --format plain --as-provider claude | out=✻ Conversation compacted (ctrl+o for history) | out=Compact summary
name=pi: compact converts summary to goose | args=compact pi:sesh-pi --as-provider goose | out="userVisible":false | out="agentVisible":true | out=1. **User Intent** | out=Your context was compacted.
name=pi: compact plain goose prints notice | args=compact pi:sesh-pi --format plain --as-provider goose | out=Compaction complete
name=pi: compact converts summary to crush | args=compact pi:sesh-pi --as-provider crush | out="is_summary_message":1 | out="summary_message_id" | out="reason":"end_turn" | out=## Current State
name=pi: compact plain crush prints summary | args=compact pi:sesh-pi --format plain --as-provider crush | out=## Current State
name=pi: compact rejects unknown style | args=compact pi:sesh-pi --format fancy | status=!0
name=pi: compact rejects unknown format | args=compact pi:sesh-pi --as-provider bogus | status=!0
name=pi: show preserves image part | args=show pi:sesh-pi-image | out="mimeType":"image/png" | out="data":"aGVsbG8="
name=claude: show preserves image part | args=show claude:sesh-claude-image | out="media_type":"image/png" | out="data":"aGVsbG8="
name=pi: compact filters hashline noise | args=compact pi:sesh-pi | out!=1:928|//
name=pi: compact filters file-list noise | args=compact pi:sesh-pi | out!=.git/
name=pi: compact keeps brief opening and recent tail | args=compact pi:sesh-pi-long | out=OPENING-ASSISTANT-MARKER | out=earlier lines omitted | out=TAIL-RECENT-MARKER
name=pi: compact commit from porcelain | args=compact pi:sesh-pi-commit | out=a1b2c3d: Fix the parser
name=pi: compact ignores prose commit hash | args=compact pi:sesh-pi-commit | out!=abc9999
# codex
name=codex: list contexts | args=list * | out=codex:019eb466-8e72-7dd0-8a10-9c8963f7d86c
name=codex: display messages | args=show codex:019eb466-8e72-7dd0-8a10-9c8963f7d86c | out="type":"session_meta" | out=DEADBEEF | out="type":"function_call" | out="call_id":"call-codex-grep" | out=src/main.rs | out=consider DEADBEEF search plan | out=DEADBEEF custom | out=grep DEADBEEF src/main.rs | out="type":"function_call_output"
name=codex: grep match | args=grep codex:019eb466-8e72-7dd0-8a10-9c8963f7d86c DEADBEEF | out=DEADBEEF
name=codex: grep command match | args=grep codex:019eb466-8e72-7dd0-8a10-9c8963f7d86c "grep DEADBEEF src/main.rs" | out=grep DEADBEEF src/main.rs
# goose
name=goose: list contexts | args=list * | out=goose:sesh-goose
name=goose: display messages | args=show goose:sesh-goose | out="message_id":"goose-1" | out=YANKEE-ECHO | out="message_id":"goose-2" | out=let me search | out="message_id":"goose-3" | out="pattern":"YANKEE" | out="message_id":"goose-4" | out="toolResponse"
name=goose: native assistant and tool result | args=show goose:sesh-goose | out="type":"thinking" | out=searching for YANKEE-ECHO | out="toolRequest" | out="pattern":"YANKEE" | out=src/main.rs:42: YANKEE-ECHO
name=goose: grep match | args=grep goose:sesh-goose YANKEE-ECHO | out=YANKEE-ECHO
name=goose: lineage scope | args=show goose:sesh-goose --scope lineage | out="message_id":"goose-1" | out="message_id":"goose-4"
# claude
name=claude: list contexts | args=list * | out=claude:sesh-claude
name=claude: display messages | args=show claude:sesh-claude | out="uuid":"claude-user-1" | out=SLOP-STARS | out="uuid":"claude-asst-1" | out="uuid":"claude-tool-1" | out="tool_use_id":"toolu_grep" | out=src/main.rs:7: SLOP-STARS
name=claude: native assistant parts | args=show claude:sesh-claude | out="type":"thinking" | out=looking for SLOP-STARS | out=I found SLOP-STARS in source | out="type":"tool_use" | out="command":"grep SLOP src/*.rs"
name=claude: tool result error marker | args=show claude:sesh-claude | out="uuid":"claude-tool-2" | out="tool_use_id":"toolu_read" | out="is_error":true | out=file not found
name=claude: grep literal match | args=grep claude:sesh-claude SLOP-STARS | out=SLOP-STARS
name=claude: grep glob match | args=grep claude:sesh-claude SLOP*STARS | out=SLOP-STARS
name=claude: ranked search | args=search claude:sesh-claude SLOP-STARS | out="uuid" | out=SLOP-STARS
name=claude: shows sesh-claude session | args=show claude:sesh-claude | out="uuid":"claude-user-1"
name=claude: lineage scope | args=show claude:sesh-claude --scope lineage | out="uuid":"claude-user-1" | out="uuid":"claude-tool-2"
# gemini
name=gemini: list contexts | args=list * | out=gemini:session-gemini-1
name=gemini: display messages | args=show gemini:session-gemini-1 | out="id":"gem-user-1" | out=find SLOP-STARS | out="id":"gem-asst-1" | out="name":"grep_search" | out=src/main.rs:7: SLOP-STARS
name=gemini: native assistant parts | args=show gemini:session-gemini-1 | out="thoughts" | out=looking for SLOP-STARS | out=I found SLOP-STARS in source | out="toolCalls" | out="pattern":"SLOP"
name=gemini: tool result error marker | args=show gemini:session-gemini-1 | out="name":"read_file" | out="status":"error" | out=file not found
name=gemini: grep glob match | args=grep gemini:session-gemini-1 SLOP*STARS | out=SLOP-STARS
name=gemini: ranked search | args=search gemini:session-gemini-1 SLOP-STARS | out="id":"gem-user-1" | out=SLOP-STARS
name=gemini: shows session-gemini-1 session | args=show gemini:session-gemini-1 | out="id":"gem-user-1"
name=gemini: jsonl list | args=list * | out=gemini:session-gemini-jl
name=gemini: jsonl streaming upsert | args=show gemini:session-gemini-jl | out=I found MOON-BEAM in source | out="name":"grep_search" | out=src/lib.rs:3: MOON-BEAM | out!=still searching
# delete (dry-run is non-destructive; real deletes live in data.rs delete_cases)
name=delete: dry-run lists matches | args=delete goose:sesh-goose --dry-run | out=goose:sesh-goose
name=delete: dry-run keeps context | args=show goose:sesh-goose | out=YANKEE-ECHO
name=delete: no match errors | args=delete zzz-nomatch | status=!0
# import (mutating imports live in data.rs import_cases; these stay non-destructive)
name=import: dry-run lists cross-provider match | args=import goose pi:sesh-pi --dry-run | out=pi:sesh-pi
name=import: same-provider prints empty array | args=import goose goose:sesh-goose | status=0 | out=[] | out!=goose:
name=import: no match errors | args=import goose zzz-nomatch | status=!0
name=import: unknown provider errors | args=import bogus pi:sesh-pi | status=!0
# list aggregation and globbing
name=list: aggregates all providers with tags | args=list | out=opencode:sesh-alpha | out=goose:sesh-goose | out=pi:sesh-pi
name=list: ID glob scopes to one | args=list goose:sesh-goose | out=goose:sesh-goose
name=list: ID excludes other providers | args=list goose:sesh-goose | out!=opencode:sesh-alpha
name=list: path glob matches native id | args=list opencode:sesh-alpha | out=opencode:sesh-alpha
name=list: bare filter not matched | args=list goose | status=0
name=list: path glob matches a project dir | args=list --path /tmp/project | out=pi:sesh-pi
name=list: path glob is scoped | args=list --path /no/such/dir | out!=pi:sesh-pi
name=list: path wildcard matches a prefix | args=list --path '/tmp/proj*' | out=pi:sesh-pi
name=list: path wildcard rejects mismatches | args=list --path '/nope*' | out!=pi:sesh-pi
# cli errors
name=cli: unknown provider | args=show bogus:abc | status=!0
name=cli: target not found | args=show ffffffff | status=!0
name=cli: short target id rejected | args=show 1 | status=!0
name=cli: no arguments | args= | status=2 | out=Usage: goosedump <command> [<args>]
name=cli: grep without context-id | args=grep opencode:foo | status=!0
name=cli: missing subcommand | args=opencode sesh-alpha | status=!0
name=cli: --page with grep | args=grep opencode:sesh-alpha STARTREK --page 1 | status=!0
name=cli: invalid --scope | args=show opencode:sesh-alpha --scope bogus | status=!0
name=cli: --page zero | args=search opencode:sesh-alpha STARTREK --page 0 | status=!0
name=cli: invalid format | args=show claude:sesh-claude --as-provider bogus | status=2
# Omitting --as-provider renders in the source provider's native shape; --as-provider <provider> cross-converts
name=convert: claude to pi | args=show claude:sesh-claude --as-provider pi | out="type":"session" | out="version":3 | out="type":"toolCall" | out="role":"toolResult" | out="toolName":"Bash" | out=SLOP-STARS
name=convert: claude to codex | args=show claude:sesh-claude --as-provider codex | out="type":"session_meta" | out="type":"function_call" | out="call_id":"toolu_grep" | out="type":"function_call_output" | out=SLOP-STARS
name=convert: claude to goose | args=show claude:sesh-claude --as-provider goose | out="content_json" | out="toolRequest" | out="id":"toolu_grep" | out="toolResponse" | out=SLOP-STARS
name=convert: claude to crush | args=show claude:sesh-claude --as-provider crush | out="parts" | out="type":"tool_call" | out="type":"tool_result" | out="tool_call_id" | out=SLOP-STARS
name=convert: claude to opencode | args=show claude:sesh-claude --as-provider opencode | out="parts" | out="type":"tool" | out="type":"reasoning" | out=SLOP-STARS
name=convert: claude to gemini | args=show claude:sesh-claude --as-provider gemini | out="toolCalls" | out="thoughts" | out="result" | out=SLOP-STARS
name=convert: goose to crush | args=show goose:sesh-goose --as-provider crush | out="type":"tool_call" | out="type":"tool_result" | out="tool_call_id" | out=YANKEE-ECHO
name=convert: codex to claude | args=show codex:019eb466-8e72-7dd0-8a10-9c8963f7d86c --as-provider claude | out="type":"assistant" | out="type":"tool_use" | out="tool_use_id":"call-codex-grep" | out=DEADBEEF
name=convert: grep then render goose | args=grep claude:sesh-claude SLOP-STARS --as-provider goose | out="toolResponse" | out=SLOP-STARS
name=convert: search then render gemini | args=search claude:sesh-claude SLOP-STARS --as-provider gemini | out="toolCalls" | out=SLOP-STARS
name=native: claude source native | args=show claude:sesh-claude | out="type":"assistant" | out="type":"tool_use" | out=SLOP-STARS
name=native: pi source native | args=show pi:sesh-pi | out="type":"session" | out="type":"toolCall" | out=TRIPLA-ESPRESSO
name=native: codex source native | args=show codex:019eb466-8e72-7dd0-8a10-9c8963f7d86c | out="type":"session_meta" | out="type":"function_call" | out=DEADBEEF
name=native: goose source native | args=show goose:sesh-goose | out="content_json" | out="toolResponse" | out=YANKEE-ECHO
name=native: crush source native | cwd=yes | args=show crush:sesh-crush | out="parts" | out="type":"tool_call" | out=ZULU-NOVEMBER
name=native: opencode source native | args=show opencode:sesh-alpha | out="parts" | out="type":"tool" | out=STARTREK-DISCO
name=native: gemini source native | args=show gemini:session-gemini-1 | out="toolCalls" | out=SLOP-STARS
name=native: grep renders source native | args=grep claude:sesh-claude SLOP-STARS | out="type":"assistant" | out=SLOP-STARS
name=native: search renders source native | args=search claude:sesh-claude SLOP-STARS | out=SLOP-STARS
name=range: show --from drops earlier entries | args=show claude:sesh-claude --from claude-asst-2 | out!="find SLOP-STARS" | out=file not found
name=range: show --until keeps earlier entries | args=show claude:sesh-claude --until claude-tool-1 | out=find SLOP-STARS | out!="file not found"
name=range: show --from nonexistent errors | args=show claude:sesh-claude --from no-such-entry | status=!0
name=range: show --from precedes --until errors | args=show claude:sesh-claude --from claude-tool-2 --until claude-user-1 | status=!0
name=range: grep --from bounds search | args=grep claude:sesh-claude SLOP-STARS --from claude-asst-2 | out!=find SLOP-STARS