diff --git a/solstone/observe/categories/calendar.md b/solstone/observe/categories/calendar.md new file mode 100644 index 000000000..35b6e1547 --- /dev/null +++ b/solstone/observe/categories/calendar.md @@ -0,0 +1,35 @@ +{ + + "description": "Calendar and scheduling interfaces: day/week/month views, agenda lists, event details, event creation forms, booking pages, availability grids, and RSVP/scheduling workflows", + "output": "markdown", + "extraction": "Extract when the visible date range, event detail, availability grid, booking page, or scheduling workflow changes", + "importance": "high" + +} + +# Calendar Text Extraction + +Extract text from this calendar or scheduling screenshot. + +## Header + +`# [Calendar/App - View or Date Range]` + +## Content Focus + +Extract the scheduling information that is visible: + +- **Calendar views**: Preserve date range, visible days, event titles, times, locations, calendars/colors if meaningful, and attendee/status hints. +- **Event detail/edit forms**: Include title, start/end time, date, location, conferencing link/platform, guests/attendees, description, recurrence, reminders, RSVP/status, and calendar name when visible. +- **Availability/booking pages**: Include host/service name, timezone, available slots, selected slot, duration, location/meeting method, form fields, and booking state. +- **Scheduling assistants**: Preserve participant names, availability blocks, conflicts, proposed times, and selected time. + +## Quality + +- Preserve chronological order. +- Keep timezones and recurrence details when visible. +- Mark unclear text with `[unclear]`. +- Mark cut-off text with `...`. +- Skip unrelated app chrome unless it identifies the calendar account, date range, or scheduling state. + +Return ONLY the formatted markdown. diff --git a/solstone/observe/categories/productivity.md b/solstone/observe/categories/productivity.md index 37c2ac314..69f8cf662 100644 --- a/solstone/observe/categories/productivity.md +++ b/solstone/observe/categories/productivity.md @@ -1,15 +1,15 @@ { - "description": "Spreadsheets, slides, document editors, calendars, task and issue tracking tools, other workplace desktop or web apps and professional tools", + "description": "Spreadsheets, slides, document editors, task and issue tracking tools, dashboards, other workplace desktop or web apps and professional tools that are not primarily calendar/scheduling views", "output": "markdown", - "extraction": "Extract when different application or service is shown (e.g. ChatGPT vs Calendar vs Docs)", + "extraction": "Extract when different application or service is shown (e.g. ChatGPT vs Docs vs issue tracker)", "importance": "high" } # Productivity App Text Extraction -Extract text from this productivity screenshot (spreadsheets, slides, calendars, task managers, issue trackers, project management tools). +Extract text from this productivity screenshot (spreadsheets, slides, document editors, task managers, issue trackers, dashboards, project management tools). ## Header @@ -20,9 +20,9 @@ Extract text from this productivity screenshot (spreadsheets, slides, calendars, Extract all visible data with appropriate structure: - **Tables/Spreadsheets**: Use markdown tables, include headers -- **Calendars**: Include event times and titles (`**9:00 AM** - Team Standup`) - **Tasks/Issues**: Include title, status, assignee, and due date if visible - **Slides**: Use `##` for slide titles, bullets for content +- **Dashboards/Apps**: Preserve labels, values, statuses, and visible hierarchy ## Quality diff --git a/solstone/observe/describe.md b/solstone/observe/describe.md index 78ab88f5c..933f69ddc 100644 --- a/solstone/observe/describe.md +++ b/solstone/observe/describe.md @@ -27,3 +27,6 @@ Tie-break rules: - If a photo, video, image gallery, or visual media fills most of the screen, choose media even when it is inside a browser. - If the dominant surface is a feed, thread, profile, posts, comments, or timeline, choose social rather than browsing. - Choose browsing for ordinary web pages, search, news, shopping, or documentation when no social feed or media viewer dominates. +- Choose calendar for calendar grids, agenda views, event detail/edit forms, availability pickers, booking pages, and scheduling assistants, even when they appear inside a browser or productivity suite. +- Choose meeting only for an active live call/conference UI; a calendar event for a meeting is calendar, not meeting. +- Choose messaging/email when the dominant surface is an email or chat conversation, even if it discusses scheduling; choose calendar when an invite/event editor, RSVP pane, availability grid, or booking flow is dominant. diff --git a/solstone/observe/describe.schema.json b/solstone/observe/describe.schema.json index 09407232e..0cf61d3a4 100644 --- a/solstone/observe/describe.schema.json +++ b/solstone/observe/describe.schema.json @@ -15,6 +15,7 @@ "type": "string", "enum": [ "browsing", + "calendar", "code", "gaming", "media", @@ -30,6 +31,7 @@ "type": "string", "enum": [ "browsing", + "calendar", "code", "gaming", "media", diff --git a/solstone/talent/screen.md b/solstone/talent/screen.md index 0fe578f8f..c0c526d81 100644 --- a/solstone/talent/screen.md +++ b/solstone/talent/screen.md @@ -31,7 +31,7 @@ Spoken content captured during the segment - use this to understand context for Frame-by-frame analyses with: - **Timestamp**: Wall-clock time (HH:MM:SS) - **Monitor**: Which display (when multiple monitors present) -- **Category**: Activity type (terminal, code, messaging, meeting, browsing, reading, media, gaming, productivity, social) +- **Category**: Activity type (terminal, code, messaging, meeting, browsing, calendar, reading, media, gaming, productivity, social) - **Visual description**: What was visible on screen - **Extracted text**: OCR content (commands, code, messages, documents) - **Meeting analysis**: Participants, topics, shared content when meetings detected diff --git a/tests/baselines/api/settings/vision.json b/tests/baselines/api/settings/vision.json index 4763bd5b8..1da39e51f 100644 --- a/tests/baselines/api/settings/vision.json +++ b/tests/baselines/api/settings/vision.json @@ -7,6 +7,12 @@ "importance": "normal", "label": "Browsing" }, + "calendar": { + "extraction": "Extract when the visible date range, event detail, availability grid, booking page, or scheduling workflow changes", + "group": "Screen Analysis", + "importance": "high", + "label": "Calendar" + }, "code": { "extraction": "Extract when viewing different repositories, files, or switching between editor and browser", "group": "Screen Analysis", @@ -38,7 +44,7 @@ "label": "Messaging" }, "productivity": { - "extraction": "Extract when different application or service is shown (e.g. ChatGPT vs Calendar vs Docs)", + "extraction": "Extract when different application or service is shown (e.g. ChatGPT vs Docs vs issue tracker)", "group": "Screen Analysis", "importance": "high", "label": "Productivity" diff --git a/tests/test_describe_config.py b/tests/test_describe_config.py index 4e66243fd..2f7647fc1 100644 --- a/tests/test_describe_config.py +++ b/tests/test_describe_config.py @@ -101,12 +101,13 @@ Rules: Categories (choose one): - browsing: General web browsing, news, shopping, or reference pages without a dominant social feed or media viewer +- calendar: Calendar and scheduling interfaces: day/week/month views, agenda lists, event details, event creation forms, booking pages, availability grids, and RSVP/scheduling workflows - code: Code editors and IDEs - gaming: Video games, puzzles, idle games - media: Photos, video players, image galleries, or visual media dominating the view, even when displayed inside a browser tab - meeting: Video calls/conferencing (Zoom, Meet, Teams, Webex, etc.) - messaging: Chat or email apps (Slack, Discord, Messages/iMessage, Gmail, etc.) -- productivity: Spreadsheets, slides, document editors, calendars, task and issue tracking tools, other workplace desktop or web apps and professional tools +- productivity: Spreadsheets, slides, document editors, task and issue tracking tools, dashboards, other workplace desktop or web apps and professional tools that are not primarily calendar/scheduling views - reading: Documents, articles, PDFs, documentation - social: Social platforms with feeds, threads, profiles, posts, comments, or timelines (X, Bluesky, Reddit, Instagram, TikTok, LinkedIn, Mastodon, HN) - terminal: Command line interfaces, logs, shell @@ -114,7 +115,10 @@ Categories (choose one): Tie-break rules: - If a photo, video, image gallery, or visual media fills most of the screen, choose media even when it is inside a browser. - If the dominant surface is a feed, thread, profile, posts, comments, or timeline, choose social rather than browsing. -- Choose browsing for ordinary web pages, search, news, shopping, or documentation when no social feed or media viewer dominates.""" +- Choose browsing for ordinary web pages, search, news, shopping, or documentation when no social feed or media viewer dominates. +- Choose calendar for calendar grids, agenda views, event detail/edit forms, availability pickers, booking pages, and scheduling assistants, even when they appear inside a browser or productivity suite. +- Choose meeting only for an active live call/conference UI; a calendar event for a meeting is calendar, not meeting. +- Choose messaging/email when the dominant surface is an email or chat conversation, even if it discusses scheduling; choose calendar when an invite/event editor, RSVP pane, availability grid, or booking flow is dominant.""" prompt = describe_module.CATEGORIZATION_PROMPT assert prompt == expected @@ -123,7 +127,9 @@ Tie-break rules: assert "�" not in prompt assert "Tie-break rules:" in prompt assert prompt.index("- terminal:") < prompt.index("Tie-break rules:") - assert prompt.rstrip().endswith("when no social feed or media viewer dominates.") + assert prompt.rstrip().endswith( + "choose calendar when an invite/event editor, RSVP pane, availability grid, or booking flow is dominant." + ) def test_redact_instruction_empty(): diff --git a/tests/test_screen_formatter.py b/tests/test_screen_formatter.py index dc0371ba2..3db8925d8 100644 --- a/tests/test_screen_formatter.py +++ b/tests/test_screen_formatter.py @@ -505,6 +505,7 @@ def test_categories_includes_all_expected(): """ expected = [ "terminal", + "calendar", "code", "messaging", "meeting", @@ -517,7 +518,7 @@ def test_categories_includes_all_expected(): ] for cat in expected: assert cat in CATEGORIES, f"Expected category {cat} not found" - assert len(CATEGORIES) == 10 + assert len(CATEGORIES) == 11 def test_tmux_formatter_output():