diff options
Diffstat (limited to 'assets/2026-07-31-agenda-json-api-contract.txt')
| -rw-r--r-- | assets/2026-07-31-agenda-json-api-contract.txt | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/assets/2026-07-31-agenda-json-api-contract.txt b/assets/2026-07-31-agenda-json-api-contract.txt new file mode 100644 index 0000000..e4253e1 --- /dev/null +++ b/assets/2026-07-31-agenda-json-api-contract.txt @@ -0,0 +1,79 @@ +It's built and pushed. Function, call example, then three things you need to know before you wire it. + +* The call + + (cj/agenda-window-json START-EPOCH END-EPOCH &optional OUT-PATH) + +From a shell: + + emacsclient --eval '(cj/agenda-window-json 1785474000 1785560399 "/tmp/agenda.json")' + +Both bounds are epoch seconds, inclusive. It returns the JSON string and, with +OUT-PATH, also writes it there through a temp file and a rename. The file lands +0644 so a reader running as anyone can open it. + +Per row: title, start, end, all-day, type, file, keyword, done, repeater, +location, organizer. Absent values are null rather than omitted, so the shape is +stable. Verified against my real agenda: 13 rows today, sorted by start, both +calendars and both todo files, no Emacs buffer left modified. + +* The repeater premise was wrong, and the real gap is bigger + +You cited "Sched. 19x:" as evidence of repeating entries. That is +org-agenda-scheduled-leaders, and the number counts days an unfinished +scheduled item has been carried forward. It is not a repeater. My agenda files +contain zero repeating timestamps right now. + +Your instinct was right anyway, and it points at something worse than the case +you asked about. I have 18 undone scheduled items dated before today. Org shows +every one of them on today's agenda, because that is what carrying forward +means. A query that selects on timestamps inside the window cannot see them. So +today my agenda has about 31 items and this query returns 13. + +Deadlines do the same thing in the other direction: org surfaces a deadline up +to 14 days before its date, and the query only returns it on the day itself. + +I have not guessed at what you want here, because it is a real design question +for your surface rather than a bug. A 24-hour axis has nowhere obvious to draw +"overdue since the 12th." Three options, roughly: leave it (a timed-events +surface, which is defensible), add an overdue flag and let you decide where they +go, or pin them to the window start. Tell me which and I will build it. + +* The .+ field is not there, and I think it should not be + +You asked for the fallback mark as a testable field. I did not add it, because +the state it marks cannot occur, and I would rather tell you than ship a field +that is permanently false. + +Org's own org-closest-date matches the repeater with a regexp that ignores the +prefix entirely, so .+ and ++ expand from the base exactly like +. The restart +semantics happen at completion time: org rewrites the base timestamp in the file +when you close the task. So for an open task the base already is the last +repeat, and there is nothing unresolved to mark. + +You said to tell you rather than guess, so this is me telling you. If you still +want the field for defensive reasons, say so and it is a one-line addition. + +* Smaller things worth knowing + +Repeats resolve at day granularity, matching org's agenda, so an hourly repeater +gives one row per day rather than one per hour. + +Archived and commented subtrees are skipped, because org's agenda skips them. + +Titles render org links as their description text. One of my live entries is a +captured web item, and it would otherwise arrive as [[https://...][Tracking your +habits]] on your wallpaper. + +The window is capped at 366 days, and each bound must fall between 1900 and +2200. Both checks exist for one reason: Date.now() returns milliseconds. Passing +it for both bounds looks like a plausible 41-day window and answers with dates in +the year 58549, so magnitude is checked as well as width. + +* On the tests + +58 of them, across three files. The SCHEDULED one you asked for is there, and +its fixture carries no body timestamp on purpose, so an implementation that +drops planning timestamps fails it rather than passing on the body stamp. + +The trap earned its comment in the source, as you suggested. |
