Activity command #277
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A new command type,
activity. It shows on which days shards matching one or more queries (series) were written: as a GitHub-style year grid, a month calendar or a single day, with day statistics. Typical uses: on which days did I run, climb, or both? How many days was I in the home office, and how many only in the office (hence "exclude mixed days")?The full spec from the design session (concepts, configuration, computation, app screens) is in the first comment. It is
plan/README.md, and the screenshots of the prototype are attached to the stories that use them. Split into #278–#286.Decisions (made after the spec, binding for all stories)
streamd <key> [RANGE]): an adaptive chart. One day prints its shards, 2–42 days a month calendar, longer ranges one 53-week strip per year. The totals and the Days table follow.streamd <key> shards [RANGE]lists shards asfile:line. The default range is this month, and--exclude-mixed/--include-mixedoverride the config. → #280streamd <key> -i): a dashboard with drill-down in boxed tiles like the app, with one page scrolling vertically. Ranges above 42 days are drawn as one strip per year, stacked. The day view is the shard list only (no axis in the terminal).topens an overlay with a text field and quick picks. → #281, #282mixed = "split": the app draws wedges. The terminal shows◩in the first two colours.ifreminder names its shards (R29). So nopropagate = falserule is needed. A shard matching two series counts for both and is reported as a warning at run time, not by validation.offset/limit).#D97A2B,#2F5BEAand has at least four more. The colour belongs to the series' position in the config.Dependencies
A solid arrow means "must be merged first". A dotted arrow is a link that works as a placeholder until the other story is merged.
Stories
Status (20 Oct 2026): done
All nine stories are merged into
main, and CI onmain(f9f1b12) is green. The terminal track (#280 → #281 → #282) and the app track (#283 → #284 → #285/#286) are complete. R36, the README and AGENTS.md describe the feature; #313 updates the last stale line about Edit command, which now opens the activity command's own form.Left over, outside this epic:
activitycommand type in .streamd.toml #278streamd <key> [RANGE]prints the chart and the Days table #280streamd <key> -i) #281The spec from the design session (
plan/README.md), verbatim. Where it conflicts with the Decisions in the issue body, the decisions win. The screenshots are attached to #282, #284, #285 and #286.streamd: Activity command — handover
Feature spec for a new command type,
activity, in streamd and its planned Android app. It shows on which days shards matching one or more queries were written, as a GitHub-style activity grid, a month calendar or a single-day timeline, with day statistics.Everything here comes from a design session. The screens in
screenshots/are rendered from the interactive prototype. Theactivitytype does not exist in streamd yet. All config keys below are a proposal agreed in that session.Typical uses:
1. Context (assumptions from earlier in the session)
kfickel/streamd) over time-stamped Markdown files (YYYYMMDD-HHMMSS [markers].md). Configuration lives in.streamd.toml: dimensions, tags, file types and typed commands (state,timesheet,file,reminder,alias).activitybecomes one more command type there.2. Concepts
query.timezonedecides which calendar day it belongs to.start(or the first matching shard) up to today. Future days and days beforestartare not counted.intensity = "count".3. Configuration (
.streamd.toml)Only the general form is in scope. A "short form" (
dimension+values) was discussed and dropped.Queries should support the same syntax as for example the day commands, multiple fields should be possible to be checked.
Home-office example:
Keys
type"activity".descriptionintensity"count"|"fixed""count"count: brightness steps at 1, 2, 3, 4+ shards per day.fixed: every matching day gets full colour.mixed"split"|"first"|"most""split"split: diagonal halves, series 1 upper-left, series 2 lower-right.first: colour of the first matching series in list order.most: the series with the most shards that day wins; a tie goes to the first in list order.exclude_mixedfalsestartseriessplitandfirst, and formostties.series.nameseries.colorseries.querydimension = valuepairs (all must match), same syntax asexpectin reminder rules. A list means OR. The key is deliberately namedquery, notexpect.Decisions:
levelskey. Brightness steps are fixed at 1, 2, 3 and 4+.Validation (proposed)
querymust exist.propagate = false), like the rule for state commands. Otherwise sub-headings would count as extra events.colormust be#RRGGBB. Default colours in the prototype are#D97A2B(orange) and#2F5BEA(blue); this pair passes colour-blindness separation checks.4. Computation (Rust core)
For a range
[from, to], clamped to[start, today]:count[series]and classify it as single, mixed or none.shards= total matching shards;shards_per_series.tracked_days,active_days= days with at least one match.shards / (tracked_days / 7), shown with one decimal.exclude_mixed = false):series_days[i]= days where series i matched, mixed days included;mixed_days;none_days.exclude_mixed = true):series_only_days[i]= days where only series i matched;mixed_days;none_days.tracked_days. Inclusive percentages may sum to more than 100 %.mixedandintensity(§3).Suggested core API (UniFFI):
activity(command, from, to, exclude_mixed) -> ActivityResult { days: [DayCell], stats, shards_page }, with paging for the shard list.5. App screens
The screenshots show the flow from coarse to fine. Sample data is generated: Run and Climbing, Jan 2025 – Oct 2026, with "today" = Sat 17 Oct 2026.
5.1 Header
streamd <key> · <view>.‹ label ›.All time,2026,Oct 2026,16 Oct 2026,3–17 Oct.5.2 View by range length
03-day-timeline.png02-month-calendar.png01-all-time-year-grid.png5.3 Year grid
#ECEDE8.5.4 Drill-down and back
5.5 Month calendar
5.6 Day timeline (events, not durations)
06:45) as a label. In the same lane, labels of dots within 150 minutes of each other alternate above and below the line.5.7 Totals tiles (all views)
5.8 Lists and the Days table
06-all-shards.png):02-…pnginclusive,05-…pngexclusive):<Series>"incl. N mixed" ·Mixed"also counted above" ·None"no series matched".<Series> only"no other series that day" ·Mixed"several series that day" ·None.5.9 ⋮ menu (
05-options-menu-exclude-mixed.png)exclude_mixedfor the session.5.10 Time range sheet (
04-time-range-sheet.png)A bottom sheet, simplified from a reference design.
2026-10-03..2026-10-17. Below it: the resolved dates2026-10-03 → 2026-10-17and "15 days · to today".5.11 Edit command, activity type (
07-edit-command-activity.png)query, "a shard matches if any line fits". Each condition is a chip (sport = climbing, removable); chips are joined by "or", with a "+ or" button.exclude_mixed).start)..streamd.toml; the change goes through the app's Git "Changes" flow.5.12 Integration
activity; tapping a row opens §5.11.6. Range text syntax (shared by the app input and the CLI)
CLI proposal:
7. Open questions
mixed = "split". The prototype only handles two halves. Options: thirds or wedges, or fall back tomost.8. Screenshots
01-all-time-year-grid.png02-month-calendar.png03-day-timeline.png04-time-range-sheet.png05-options-menu-exclude-mixed.png06-all-shards.png07-edit-command-activity.pngactivitycommand. → #286Screenshots are 2× (780 px wide) and rendered with fallback fonts. The prototype uses Instrument Sans for UI text and JetBrains Mono for timestamps, keys and numbers.