diff --git a/apps/todos/muse/todo.md b/apps/todos/muse/todo.md index 2d5fc0066..9771a1013 100644 --- a/apps/todos/muse/todo.md +++ b/apps/todos/muse/todo.md @@ -38,13 +38,11 @@ Use the Activity Context and Activity State Per Segment sections above to unders - `sol call todos upcoming` – view upcoming todos to avoid duplicates ### Transcript Commands -- `sol call transcripts read --segment SEGMENT_KEY --transcripts` – read audio transcript for a segment -- `sol call transcripts read --segment SEGMENT_KEY --agents` – read agent outputs (screen summaries) for a segment -- `sol call transcripts read --segment SEGMENT_KEY --full` – read everything for a segment +- `sol call transcripts read --segments $activity_segments --transcripts` – read audio transcripts for this activity +- `sol call transcripts read --segments $activity_segments --agents` – read agent outputs (screen summaries) for this activity +- `sol call transcripts read --segment SEGMENT_KEY --full` – read everything for a single segment - `sol call journal search QUERY` – cross-reference journal content -Activity segments: $activity_segments - **Query syntax**: Terms are AND'd by default; use `OR` for alternatives, quote phrases for exact matches, append `*` for prefix matching. ## Process @@ -53,10 +51,8 @@ Activity segments: $activity_segments Read the activity's transcript and current todo state before making any changes. -1. For each segment in this activity ($activity_segments), load the transcript: - `sol call transcripts read --segment SEGMENT_KEY --transcripts` - Also load screen agent output for context: - `sol call transcripts read --segment SEGMENT_KEY --agents` +1. Load the activity's transcript and screen agent context: + `sol call transcripts read --segments $activity_segments --transcripts --agents --max 0` 2. Call `sol call todos list` to see the current checklist 3. Call `sol call todos upcoming -l 50` to check what's already scheduled diff --git a/apps/transcripts/call.py b/apps/transcripts/call.py index 3f9ae26d5..6e6dd2e66 100644 --- a/apps/transcripts/call.py +++ b/apps/transcripts/call.py @@ -17,6 +17,7 @@ from think.cluster import ( cluster_range, cluster_scan, cluster_segments, + cluster_span, ) from think.utils import ( day_dirs, @@ -85,6 +86,9 @@ def read( segment: str | None = typer.Option( None, "--segment", help="Segment key (HHMMSS_LEN, default: SOL_SEGMENT env)." ), + segments: str | None = typer.Option( + None, "--segments", help="Comma-separated segment keys for a span." + ), stream: str | None = typer.Option( None, "--stream", help="Stream name (default: SOL_STREAM env)." ), @@ -140,8 +144,17 @@ def read( else: sources = {"transcripts": True, "percepts": False, "agents": True} - if segment and (start or length is not None): - typer.echo("Error: Cannot mix --segment with --start/--length.", err=True) + # Validate mutually exclusive selection modes + mode_count = sum([ + segment is not None, + segments is not None, + start is not None or length is not None, + ]) + if mode_count > 1: + typer.echo( + "Error: Cannot mix --segment, --segments, and --start/--length.", + err=True, + ) raise typer.Exit(1) if (start is not None) != (length is not None): @@ -154,6 +167,9 @@ def read( start_dt = datetime.strptime(start, "%H%M%S") end_dt = start_dt + timedelta(minutes=length) markdown = cluster_range(day, start, end_dt.strftime("%H%M%S"), sources) + elif segments is not None: + span = [s.strip() for s in segments.split(",") if s.strip()] + markdown, _counts = cluster_span(day, span, sources, stream=stream) elif segment is not None: markdown, _counts = cluster_period(day, segment, sources, stream=stream) else: diff --git a/apps/transcripts/muse/transcripts/SKILL.md b/apps/transcripts/muse/transcripts/SKILL.md index 4a9cd14e2..e865e5e22 100644 --- a/apps/transcripts/muse/transcripts/SKILL.md +++ b/apps/transcripts/muse/transcripts/SKILL.md @@ -68,18 +68,19 @@ sol call transcripts segments 20260115 ## read ```bash -sol call transcripts read [DAY] [--start HHMMSS --length MINUTES] [--segment KEY] [--stream NAME] [--full] [--raw] [--audio] [--screen] [--agents] +sol call transcripts read [DAY] [--start HHMMSS --length MINUTES] [--segment KEY] [--segments KEYS] [--stream NAME] [--full] [--raw] [--audio] [--screen] [--agents] ``` -Read transcript content for a day, time range, or segment. +Read transcript content for a day, time range, segment, or span. - `DAY`: day in `YYYYMMDD` (default: `SOL_DAY` env). Read modes (mutually exclusive): 1. `--start HHMMSS --length MINUTES`: range mode. Both flags are required together; end time is auto-computed. -2. `--segment KEY`: segment mode using key from `segments`. -3. No time flags: whole-day mode. +2. `--segment KEY`: single segment mode using key from `segments`. +3. `--segments KEY1,KEY2,...`: span mode — comma-separated segment keys, merged in time order. +4. No time flags: whole-day mode. Source flags: @@ -92,7 +93,7 @@ Source flags: Rules: -- Do not combine `--segment` with `--start/--length`. +- Do not combine `--segment`, `--segments`, or `--start/--length` with each other. - Do not combine `--full` or `--raw` with individual source flags. Source type meanings: @@ -107,6 +108,7 @@ Examples: sol call transcripts read 20260115 sol call transcripts read 20260115 --start 090000 --length 30 --raw sol call transcripts read 20260115 --segment 091500_300 --full +sol call transcripts read 20260115 --segments 091500_300,092000_300,092500_300 --transcripts --agents sol call transcripts read 20260115 --audio ```