Skip to content

feat(session-kickoff): start one Claude Code session per handoff note in today's focus list - #15

Open
lhoupert wants to merge 5 commits into
feat/session-handoffsfrom
feat/session-kickoff
Open

lhoupert wants to merge 5 commits into
feat/session-handoffsfrom
feat/session-kickoff

Conversation

@lhoupert

@lhoupert lhoupert commented Oct 2, 2026 •

Copy link
Copy Markdown

Adds session-kickoff, the morning half of session-handoffs (#13). For each open item in today's focus list that links a handoff note, it starts a background Claude Code session in that note's project and asks it to read the note and say what to do next; --digest then lists their answers in one table. It skips notes a session already works from, so a re-run starts only what's missing. I've run it every morning since 30 Sep from my own skills repo: the first commit imports it unchanged, the second packages it as a plugin, the third drops the Terminal tab and window modes, which had never run live, and the fourth fixes the two review findings (paths with spaces, stopped sessions). Tested with python3 -m unittest discover -s skills/session-kickoff/scripts (41 tests, Python 3.9 and 3.13), claude plugin validate, and a --dry-run on a real daily note.

For reviewers: stacked on #13, so it targets feat/session-handoffs; I'll retarget it to main once #13 merges. Like #13 it reads Claude Code's transcripts and claude agents --json, which are not documented interfaces, and stops with an error inside the sandbox rather than open duplicates.

Author attestation

  • I am a human, these are my changes, and I have reviewed and understood every change and can explain why each is correct.

AI-assisted: Claude Code wrote the skill, script and tests. It went through a /code-review max (15 findings, 14 fixed, one disproved by a live probe) and two later /code-review passes, and every script rule has a test. A ponytail pass led to dropping the --open tabs|windows Terminal modes (−118 lines).

🤖 Generated with Claude Code

lhoupert and others added 2 commits October 2, 2026 10:11
The morning half of session-handoffs: for each open item of today's
focus list that links a handoff note, start a Claude Code session in
that note's project, asking it to read the note and say what to do
next. Copied unchanged from a personal skills repo, where it has run
daily since 30 Sep; the next commit packages it as a plugin.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add plugin.json, the marketplace entry and a README line next to
session-handoffs. ruff format the scripts as the repo's others are.
SKILL.md asks for the daily note when no line names it, and shows a
focus-list item; the example folders lose personal names.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Claude finished @lhoupert's task in 16s —— View job


✅ No blocking issues — safe to merge.

I read kickoff.py in full. I did not run the tests.

  • dannybauman's two findings are already fixed in the current head:
    • Backticked paths with spaces are matched by the first alternative of PATH (kickoff.py:65).
    • stopped now counts like failed, through GONE (kickoff.py:81, kickoff.py:290).
  • I found no correctness or security problems. Arguments go to subprocess as a list, so there is no shell injection. The note path only reaches the prompt text, and the code stops with an error inside the sandbox instead of opening duplicates.

Minor, non-blocking:

  • kickoff.py:479: daily.read_text() has no encoding=, unlike unusable(), which reads with utf-8-sig. A non-UTF-8 locale or a BOM in the daily note could break parsing. Use daily.read_text(encoding="utf-8-sig").

Simplify (ponytail)

  • kickoff.py:362-401 (worked_from/claims): subagent transcript scanning, snapshot-writer exclusion and the self-session special case make up about 60 lines. Only the "first prompt names the note" rule is cheap. Consider dropping the edit and subagent detection until a re-run actually starts a duplicate session.
  • kickoff.py:209-218 (carried/day_of/CARRIED): the "carried Nd" flag is a feature nobody asked for. Cut it, or reduce it to calendar days, (day - since).days, instead of counting working days.
  • kickoff.py:73-78 (BANNER): this regex with an optional date prefix handles several banner forms. "superseded" in head.lower() over the first few lines would do, and the false positives are harmless because the row only reads "superseded".
  • kickoff.py:227-235 (slug): the 41-character word-cut logic can become base[:40].strip("-"). Names are cosmetic.

💰 Estimated review cost: $0.14 · 0m16s · 4 turns

… sessions only

The Terminal modes never ran live, tabs needed Accessibility
permission to press ⌘T, and `claude agents` already lists every
session and opens any of them. A failure no longer stops the run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dannybauman

Copy link
Copy Markdown
Member

cool idea!

one issue I found: if the notes folder from #13 is somewhere with a whitespace in the path, it stops reading the path at the space, so the item comes back no note

another small thing: the agent view docs list stopped as a background state too (https://code.claude.com/docs/en/agent-view), and only failed is filtered out, so a session I ran claude stop on would still hold its note. should stopped count the same as failed?

lhoupert and others added 2 commits October 5, 2026 10:10
… sessions

Two findings from review on #15:

- A note under a folder with a space (an iCloud vault) came back
  `no note`: the path pattern stopped at whitespace. A path in
  backticks, as /session-handoffs writes it, may now hold spaces, and
  the question to the new session quotes the path in backticks.
- A `claude stop`-ed session kept holding its note. `stopped` now
  counts like `failed`, as the agent-view docs group them.

SKILL.md: the example item uses /session-handoffs' backticked format,
and the "paths with spaces aren't recognised" limit is gone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The backtick alternative added in 606af28 read a code span holding two
paths ("`~/old/handoff.md → ~/new/handoff_2.md`") as one path with a
space in it, so the item came back `missing` instead of opening the
first note. A backticked path may still hold spaces, but not a second
" ~/" or " /".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0153mtqWdmWUTRhahqHipCka
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants