End-of-day — draft and post daily comments for tracked tickets missing a comment
76%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/work-end-day/SKILL.mdReview today's tracked work items, draft Linear comments for tickets that haven't been commented on today, present for approval, and post. In-progress tickets with no meaningful logged activity today are returned to Todo with a comment stating so. Takes no arguments.
today_date=$(date +%Y-%m-%d)
today_day=$(date +%A)
today_year=$(date +%Y)
note_path="$HOME/2ndBrain/daily-notes/${today_year}/${today_date} ${today_day}.md"Read the full note content.
Parse the # Work Items section for all H2 item sections. For each item, extract:
DXO-71)ticket:: field — the Linear URL (items without a ticket:: field are PR-only; skip them)commented:: field — if true, skip this itemstatus:: field — include in the comment for context- \HH:MM` ...`)Collect all items where commented:: false and a ticket:: field exists.
If no items need comments, report "All tracked tickets already have today's comment." and exit.
Classify each collected item (has ticket::, commented:: false) into exactly one bucket:
status:: is in-progress AND you judge the day's timestamped bullets contain no meaningful progress — an empty log or only trivial entries like a lone "Picked up ticket" count as idle; substantive work notes do not. When unsure, the item is NOT idle.Draft a Linear comment from the activity log. Format:
**Daily update — YYYY-MM-DD**
Status: <status>
- <activity bullet 1, without timestamp>
- <activity bullet 2, without timestamp>
- ...Strip the backtick-wrapped timestamps from the bullets — they're note-internal, not useful in Linear.
If the activity log is empty (item was tracked but no notes added), draft a minimal comment:
**Daily update — YYYY-MM-DD**
Status: <status>
Tracked today, no specific updates logged.Verify the real Linear state before final classification:
linear issue view <TICKET-ID> -j --no-comments --no-pagerThe JSON contains state.name / state.type (started issues show "name": "In Progress", "type": "started").
If state.type is started → confirmed revert. Draft this comment instead of a daily update:
**Daily update — YYYY-MM-DD**
No meaningful activity logged today — returning this ticket to Todo.If the ticket is no longer started (user already moved it) → treat as regular: draft a normal/minimal daily comment using the verified Linear state, no state change, and update the note's status:: field to match the verified state.
Show ALL drafts together in two labeled groups — Daily updates (existing per-ticket format) and Return to Todo (each entry shows ticket ID, title, the state change In Progress → Todo, and the comment body):
## Draft Linear Comments
### Daily updates
#### DXO-71 — fix(sdk-release): replace unreliable !failure()
> **Daily update — 2026-05-29**
>
> Status: in-progress
>
> - Picked up ticket, reviewing PR feedback
> - Kicked off test release
> - Test release passed, moving to review
#### DEVX-943 — Decommission 6 older macOS CI runners
> **Daily update — 2026-05-29**
>
> Status: in-progress
>
> - Removed atl-mac03 from runner group
> - PR approved, merged
### Return to Todo
#### DXO-88 — Title here
State change: In Progress → Todo
> **Daily update — 2026-05-29**
>
> No meaningful activity logged today — returning this ticket to Todo.Then ask the user using AskUserQuestion:
For each daily-update draft, ask:
commented:: false)For each return-to-Todo item, ask:
commented:: stays false, status:: untouched)First invoke the linear-cli:linear-cli skill to load the correct CLI syntax.
On macOS, run every linear ... command outside the sandbox on the first
attempt so the CLI can access credentials stored in the system keychain. Use
scoped escalation with prefix_rule: ["linear"]. If a sandboxed command
reports No keyring entry or No API key configured, retry outside the
sandbox before asking the user to authenticate. Never print, log, or expose
linear auth token or an API key.
For each approved comment, write the body to a temp file then post using the CLI:
# Write comment body to a temp file (required for markdown content)
cat > /tmp/linear-comment-<TICKET-ID>.md << 'EOF'
<comment body>
EOF
# Post the comment
linear issue comment add <TICKET-ID> --body-file /tmp/linear-comment-<TICKET-ID>.mdAfter successful post, update the daily note:
Edit: commented:: false → commented:: trueScope the edit to the specific item's section to avoid updating other items.
For each approved return item, post the comment first, then change the state:
cat > /tmp/linear-comment-<TICKET-ID>.md << 'EOF'
<comment body from Step 3>
EOF
linear issue comment add <TICKET-ID> --body-file /tmp/linear-comment-<TICKET-ID>.md
linear issue update <TICKET-ID> --state unstarted--state unstarted uses the state type (-s, --state accepts the workflow state by name or type), so it works regardless of the team's unstarted state names.
Daily-note updates per returned item, scoped to that item's section:
commented:: false → commented:: true.status:: in-progress → status:: todo.commented:: true, do NOT edit status:: (the note must keep matching real Linear state).## End of Day Complete
Posted: 2
✓ DXO-71 — fix(sdk-release): replace unreliable !failure()
✓ DEVX-943 — Decommission 6 older macOS CI runners
Returned to Todo: 1
↩ DXO-88 — Title here (no meaningful activity today)
Skipped: 0
All tracked tickets have today's comment.Omit the "Returned to Todo" section when nothing was returned.
If any were skipped:
Skipped: 1
✗ DXO-88 — Title here (user chose to skip)
⚠ 1 in-progress ticket still needs a comment today.| Scenario | Handling |
|---|---|
| Today's note doesn't exist | Error: "No daily note found for today" |
No items with commented:: false | Report "All done" and exit |
PR-only items (no ticket:: field) | Skip — can't post to Linear without a ticket |
| Linear API error on post | Report error for that ticket; continue with others |
Empty activity log + status:: in-progress | Idle candidate (Step 3) — verify Linear state before classifying |
| Empty activity log + any other status | Post minimal "Tracked today, no specific updates" comment |
| Note says in-progress but Linear state is no longer started | Normal/minimal comment, no state change |
linear issue view fails during idle verification | Report error, do not revert the item; treat as regular, continue |
linear issue update fails | Report error for that ticket, set commented:: true, leave status:: unchanged; continue with others |
Item status is done | Still post the comment (important to close the loop) |
| User edits a draft | Use the edited text verbatim |
| Run twice same day | Second run finds all commented:: true; reports "All done" |
phatblat/dotfiles
4d65cab
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.