diff --git a/.claude/skills/_shared/status-workflow/OVERVIEW.template.md b/.claude/skills/_shared/status-workflow/OVERVIEW.template.md new file mode 100644 index 0000000000..dcc9303c1d --- /dev/null +++ b/.claude/skills/_shared/status-workflow/OVERVIEW.template.md @@ -0,0 +1,52 @@ +# Projects overview + +_Last updated: YYYY-MM-DD_ + +Actionable status hub across your active docs projects. Each entry shows status, blockers, and where to pick up. Full task detail lives in each project's [plans/](plans/) file. + +## At a glance + +| Project | Progress | Immediate next / blocker | +|---|---|---| +| ๐Ÿ”ด **** (#1 priority) | `~40%` | | +| ๐ŸŸก **** | `~10%` | | +| ๐ŸŸข **** | `DONE` | โ€” | +| ๐Ÿ”ต **** | parked | | + + + +--- + +# ๐Ÿ”€ GitHub โ€” my open PRs & issues (redis/docs) + +_Snapshot YYYY-MM-DD (refreshed via full `/checkpoint`) ยท live via `/standup`_ + +**Open PRs (0):** +- _<#PR "title" โ€” review state, one-line status, (which project)>_ + +**Open issues assigned (0):** +- _<#issue "title">_ + +--- + +# ๐Ÿ”ด Active priorities + +## โ€” +`โ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ ~40%` ยท **** ยท PR # + +- **Status:** +- **Next:** + 1. + 2. +- **Blockers:** +- **Plan:** [plans/project-a.md](plans/project-a.md) + +--- + +## โ€” +`โ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ ~10%` + +- **Status:** +- **Next:** +- **Blockers:** +- **Plan:** [plans/project-b.md](plans/project-b.md) diff --git a/.claude/skills/_shared/status-workflow/README.md b/.claude/skills/_shared/status-workflow/README.md new file mode 100644 index 0000000000..652dbdfea7 --- /dev/null +++ b/.claude/skills/_shared/status-workflow/README.md @@ -0,0 +1,59 @@ +# Status-tracking workflow (standup / startwork / checkpoint) + +A lightweight system for staying on top of many parallel docs projects: a private local **hub** of markdown + a few **slash-command skills** that form a daily loop. The skills are checked into this repo, so once you pull the branch they're available in any Claude Code session started here. You just add your own hub. + +## The daily loop + +| Skill | When | What it does | Writes? | +|---|---|---|---| +| **`/standup`** | Start of day / back at desk | Reads the hub + pulls **live signals** (Jira, GitHub, Calendar, Gmail, Slack) โ†’ ranked "do this next" list, each with a reason | Read-only | +| **`/startwork `** | Diving into one task | Reads that project's plan โ†’ checks out the right branch โ†’ loads product context (`/rs`, `/k8s`, `/ff`) โ†’ briefs where to start | Read-only on hub (git checkout only) | +| **`/checkpoint`** | Switching tasks / end of a block | Detects the project from the git branch โ†’ updates its plan + OVERVIEW row (done / next / blockers / resume) โ†’ reconciles its Jira tickets against live status | Writes hub | + +They compose: **standup** tells you what to do โ†’ **startwork** loads it โ†’ work โ†’ **checkpoint** saves state. + +> **Why `/startwork` and not `/pickup`?** This repo already has an unrelated `/pickup` skill (thawing a *parked PR*, pairs with `/park`). The standup companion is named `/startwork` here to avoid the collision. Natural-language triggers like "pick up featureform", "work on X", or "resume X" still invoke it. + +## Setup (one time, ~5 minutes) + +1. **Pull this branch** (or merge it) so the skills land in `.claude/skills/`. They auto-register โ€” no config. + +2. **Create your private hub** at `~/claude-overview/` and seed it from these templates: + ``` + mkdir -p ~/claude-overview/plans + cp .claude/skills/_shared/status-workflow/OVERVIEW.template.md ~/claude-overview/OVERVIEW.md + cp .claude/skills/_shared/status-workflow/plans/example-project.md ~/claude-overview/plans/.md + ``` + Fill in `OVERVIEW.md` (the at-a-glance table + a detail section per project) and one plan file. Start with a single project and grow from there. + +3. **Keep the hub private.** It's your personal working state โ€” don't commit it. Add `claude-overview/` to your global gitignore, or just keep it outside any repo (the default `~/claude-overview/` already is). + +4. **Connect the live integrations** (optional but that's the point of `/standup`): + - **Jira** via the Atlassian MCP connector. + - **GitHub** via the `gh` CLI (`gh auth login`). + - **Calendar / Gmail / Slack** via their MCP connectors. + Every signal is best-effort โ€” if one isn't connected, the skills skip it and say so. `/standup --fast` and `/checkpoint --fast` skip all live fetches for a quick hub-only pass. + +## How it works / design principles + +- **Split read from write.** `standup`/`startwork` never edit the hub; `checkpoint` is the only writer โ€” so you can run standup any number of times a day with zero risk. +- **Never fabricate status.** Every "PR approved / ticket closed / newly unblocked" claim comes from a **live fetch this run**, not memory. If a source is down, the skill says so. +- **The plan carries nuance; live tools catch drift.** Reconciling tickets flags *changes* (closed, reassigned, advanced); the hand-written plan stays the source for the "why." +- **Resume pointers.** Every plan records the branch + Claude session to jump back into. +- **Respect real priorities.** Hard deadlines and explicit priority order beat raw recency in the ranked output. + +## The hub layout + +``` +~/claude-overview/ +โ”œโ”€โ”€ OVERVIEW.md # at-a-glance table + per-project detail + GitHub snapshot +โ””โ”€โ”€ plans/ + โ”œโ”€โ”€ .md # Next / Blocked / Resume / Done per project + โ””โ”€โ”€ .md +``` + +The plans are the source of truth; the skills read and maintain them. Templates for both files live next to this README. + +## Adapting it + +These skills are wired for the Redis docs team: they default to the `redis/docs` repo at `~/repos/docs`, load the `/rs` `/k8s` `/ff` product contexts, and reconcile `DOC-`/`RED-` Jira keys. If you work in a different repo or tracker, edit those references in the three `SKILL.md` files โ€” the structure carries over unchanged. diff --git a/.claude/skills/_shared/status-workflow/plans/example-project.md b/.claude/skills/_shared/status-workflow/plans/example-project.md new file mode 100644 index 0000000000..d9eaedf60a --- /dev/null +++ b/.claude/skills/_shared/status-workflow/plans/example-project.md @@ -0,0 +1,21 @@ +# โ€” plan + +_Last updated: YYYY-MM-DD_ + +**Ticket:** ยท **PR:** # ยท **Product:** +**Status (YYYY-MM-DD):** + +**Resume:** branch `` โ†’ switch branch, then pick the latest session in the Claude panel history _(terminal alt: `claude --resume `)_ + +## Scope + + +## Next (pick up here) +- [ ] +- [ ] + +## Blocked / waiting on +- + +## Done +- [x] diff --git a/.claude/skills/checkpoint/SKILL.md b/.claude/skills/checkpoint/SKILL.md new file mode 100644 index 0000000000..5e67b4994a --- /dev/null +++ b/.claude/skills/checkpoint/SKILL.md @@ -0,0 +1,75 @@ +--- +name: checkpoint +description: Save a status checkpoint before switching tasks. Detects the project from the current git branch, then updates that project's plan file in ~/claude-overview/plans/ and its entry in ~/claude-overview/OVERVIEW.md โ€” recording what got done this session, what's next, blockers, %-complete (if known), and a resume pointer. Also reconciles the plan's referenced Jira tickets (DOC-/RED-) against their live status via the Atlassian MCP so stale tickets get flagged. Use when the user says "checkpoint", "save my progress", "update my overview/plan before I switch", "log where I'm at", "snapshot this", or is about to switch tasks. Accepts a `--fast` argument (aliases `--local`/`--quick`) for a quick thread-only update that skips the Jira/GitHub reconciles. +--- + +# Checkpoint + +Snapshot the current session's progress into the shared tracking files so you can switch tasks without losing state. This skill runs **from any session/repo** and writes to the `claude-overview` hub at `~/claude-overview/` (absolute path โ€” not the current working directory). + +> **First-time setup:** this skill expects a personal hub at `~/claude-overview/` (an `OVERVIEW.md` plus `plans/.md` files). If you don't have one yet, see `_shared/status-workflow/README.md` and copy the templates there into `~/claude-overview/`. + +> **Sandbox note:** when run from a repo other than `claude-overview` (e.g. `~/repos/docs`), writes to `~/claude-overview/โ€ฆ` fall outside the session's writable cwd and the sandbox will block them. That's expected โ€” retry those Edits/Writes with the sandbox override. (Alternatively you can add `~/claude-overview` to your global write allowlist once.) + +## Arguments + +- **`--fast`** (aliases: `--local`, `--quick`) โ€” **fast checkpoint from the current thread only.** Records the update using what's already known in this conversation, skipping every external/network reconcile. Use for small, frequent updates where a full reconcile is overkill. Specifically, in fast mode: + - **Skip step 4 entirely** (no Atlassian/Jira MCP fetch โ€” no drift reconcile). + - **Skip the GitHub snapshot refresh in step 6** (no `gh` calls; leave the `๐Ÿ”€ GitHub` block untouched). + - **Skip the `git log`/`git status` gathering in step 3** โ€” take "what changed" from the conversation instead. + - Still do the instant-local basics: project detection (step 1) and the resume pointer (step 2), plus the plan + OVERVIEW row/detail writes (steps 5โ€“6). + - In the step 7 report, **state that it was a `--fast` checkpoint** and that Jira/GitHub were **not** reconciled (so those may be stale โ€” run a full `/checkpoint` to refresh them). + +Default (no argument) runs all steps below, including the external reconciles. + +## Steps + +1. **Identify the current project.** + - Run `pwd` and `git -C "$PWD" branch --show-current` to get the working dir and branch. + - Match the branch (or its ticket key, e.g. `DOC-6645`) to a plan file: `grep -rli --exclude-dir=archive "" ~/claude-overview/plans/`. That plan file is the target. (Case-insensitive `-i` to match `/startwork`, so a lowercase branch name still matches `DOC-`/`RED-` keys. Exclude `archive/` โ€” standup skips it too, so an archived plan must not shadow the active one.) + - If exactly one plan matches, use it. If none or several match, **ask the user which project** this checkpoint is for (list the candidates). + +2. **Capture the resume pointer.** + - Branch = the current branch. + - Session id = the current session. Prefer the `$CLAUDE_CODE_SESSION_ID` env var โ€” it's the running session's exact id (matches `~/.claude/projects//.jsonl`). Only if it's unset, fall back to the most-recently-modified `.jsonl` in `~/.claude/projects//` (the slug is the cwd with `/` โ†’ `-`, e.g. `-Users-you-repos-docs`), using its filename minus `.jsonl` โ€” but note this fallback can pick another tab's session if two run in the same repo. + +3. **Gather what changed this session.** + - From the conversation: what got completed, what's now next, any new blockers or decisions. + - From git _(skip in `--fast` โ€” use the conversation only)_: `git -C "$PWD" log --oneline -10` (recent commits) and `git -C "$PWD" status --short` (uncommitted work). Mention committed drafts / staged work in the plan. + - Do **not** invent a %-complete. Update it only if you can ground it (OKR sheet, a real done/total count, or the user tells you). Otherwise leave the existing number. + +4. **Reconcile the plan's Jira tickets** (via the Atlassian MCP). _**Skip this entire step in `--fast`.**_ + - Extract the ticket keys referenced in the **target plan only**: `grep -oiE '(DOC|RED)-[0-9]+' ~/claude-overview/plans/.md | sort -u`. + - Fetch their live status in one batch โ€” `searchJiraIssuesUsingJql` with `key in (DOC-123, RED-456, โ€ฆ)`, requesting `status`, `assignee`, and `summary`. (Fall back to per-ticket `getJiraIssue` only if the JQL batch fails.) + - Reconcile against the plan and flag drift โ€” don't silently rewrite: + - Ticket is **Done/Closed/Resolved** in Jira but still under **Next** or **Blocked / waiting on** โ†’ move it to **Done** (note the Jira status) or flag it for the user. + - Ticket **assignee changed** (esp. assigned to you, or reassigned away) โ†’ note it on the relevant line. + - Ticket **status advanced** (e.g. To Do โ†’ In Progress) โ†’ update the plan's wording to match. + - Blocker whose ticket is now resolved โ†’ move out of **Blocked / waiting on**. + - **Trust the plan's nuance over Jira's terse fields.** The plan often carries richer context (who said what, sub-tasks, "shipped per release board") than the ticket. Use Jira to catch *drift* (closed/reassigned/advanced), not to overwrite hand-written notes. + - If the Atlassian MCP is unavailable or unauthenticated, **skip this step** and say so in the report โ€” never block the checkpoint on it, and never guess a ticket's status. + +5. **Update the plan file** (`~/claude-overview/plans/.md`): + - Bump `_Last updated:_` to today (`date +%Y-%m-%d` โ€” never guess). + - Move finished items into **Done** (check them off / add them). + - Update **Next (pick up here)** so the top item is the true next action. + - Update **Blockers / waiting on** (add new, remove cleared ones). + - Refresh the **Resume** line (panel-first format): `**Resume:** branch \`\` โ†’ switch branch, then pick the latest session in the Claude panel history _(terminal alt: \`claude --resume \`)_`. + +6. **Update `~/claude-overview/OVERVIEW.md`** for the same project: + - Bump `_Last updated:_` at the top to today. + - Update the project's **at-a-glance table row** (progress + immediate next/blocker). + - Update the project's detailed section (Status, Next, Blockers, progress bar) to match the plan. + - Keep every other project untouched. + - **Refresh the `๐Ÿ”€ GitHub โ€” my open PRs & issues` snapshot block** (the one cross-project section checkpoint may touch). _**Skip this bullet in `--fast`** โ€” leave the block as-is._ Re-run `gh pr list --repo redis/docs --author "@me" --state open --json number,title,reviewDecision,isDraft,updatedAt` and `gh issue list --repo redis/docs --assignee "@me" --state open --json number,title,updatedAt`, rewrite the block, and bump its `Snapshot ` line to today. If `gh` can't reach the API (keyring/TLS error in a restricted shell โ€” see the standup skill's operator note), leave the block as-is and say it's stale. + +7. **Report** a 3-5 line summary of exactly what you changed (which plan, which OVERVIEW row, new next-action, resume pointer) plus any Jira drift you found (tickets closed/reassigned/advanced since the plan was last touched) so the user can eyeball it before switching. _In `--fast`, there's no Jira/GitHub drift to report โ€” instead note that it was a fast checkpoint and that those reconciles were skipped (may be stale)._ + +## Rules + +- **Low friction:** apply the updates directly; only stop to ask if you can't identify the project. Report clearly afterward so the user can correct. +- **Scope to one project:** only touch the plan + OVERVIEW entry for the project detected from the branch. Never rewrite other projects' sections. +- **Never fabricate status or %-complete** โ€” ground it or leave it. This includes Jira: only report a ticket's status from a live MCP fetch, never from memory or inference. +- **Jira is for catching drift, not authority.** Reconcile only the target plan's tickets, prefer the plan's hand-written nuance over terse Jira fields, and never let an unreachable Atlassian MCP block the checkpoint. +- **Preserve structure and tone** of the existing files (compact headers, checkbox lists, progress bars). +- If the project has **no plan file yet**, offer to create one from the standard template used by the other files in `~/claude-overview/plans/` (see `_shared/status-workflow/plans/example-project.md`). diff --git a/.claude/skills/standup/SKILL.md b/.claude/skills/standup/SKILL.md new file mode 100644 index 0000000000..46ddf87495 --- /dev/null +++ b/.claude/skills/standup/SKILL.md @@ -0,0 +1,66 @@ +--- +name: standup +description: Start-of-day / back-at-desk briefing. Reads the claude-overview hub (~/claude-overview/OVERVIEW.md + plans/), pulls live signals from Jira, GitHub, Google Calendar, Gmail, and Slack, then recommends a ranked "do this next" list with the reason for each. Read-only โ€” it advises, it does not modify plans. Use when the user says "standup", "what should I work on", "what's next", "start my day", "catch me up", "back at my desk", "good morning", or asks where to pick up. Accepts a `--fast` argument (aliases `--local`/`--quick`) for a quick hub-only briefing that skips the live signal fetches. +--- + +# Standup + +The inverse of `/checkpoint`. Where checkpoint saves state on the way out, standup reads the hub and current signals and tells you **where to dive in right now**. This skill reads from the `claude-overview` hub at `~/claude-overview/` (absolute path โ€” not the current working directory) and is **read-only**: it never edits plans or `OVERVIEW.md`. If it finds drift worth persisting, it offers to run `/checkpoint` rather than writing itself. + +> **First-time setup:** expects a personal hub at `~/claude-overview/`. If you don't have one, see `_shared/status-workflow/README.md`. + +Run it from any repo โ€” it always reads the hub by absolute path. + +## Arguments + +- **`--fast`** (aliases: `--local`, `--quick`) โ€” **fast briefing from the hub only.** Reads `OVERVIEW.md` + the active plans and ranks from those alone, **skipping every live signal fetch** (the slow part). Use for a quick "where do I pick up" when you don't need overnight-change detection. Specifically, in fast mode: + - **Skip step 2 entirely** โ€” no Jira, GitHub (`gh`), Calendar, Gmail, or Slack fetches. + - **Rank (step 3) from the hub only** โ€” plans' **Next (pick up here)** + OVERVIEW priority order/deadlines. + - **Output (step 4):** keep **๐Ÿ“Œ Top of the day**, **โ–ถ๏ธ Do next (ranked)**, **โณ Still blocked**, and resume pointers. For **๐Ÿ”€ My open PRs & issues**, read the OVERVIEW **`๐Ÿ”€ GitHub`** snapshot block (the documented fallback) instead of live `gh`. **Omit ๐Ÿ†• Changed since last checkpoint and ๐Ÿ“Ž Flagged to revisit** โ€” both are signal-derived. + - **State up front that it's a `--fast` briefing** โ€” signals weren't pulled, so anything since the hub's last update won't show; run a full `/standup` for live change detection. + +Default (no argument) runs all steps below, including the live signals. + +## Steps + +1. **Read the hub.** + - `~/claude-overview/OVERVIEW.md` โ€” the at-a-glance table + active-priority sections. This is the source of priority order and deadlines. + - The active `~/claude-overview/plans/*.md` files (skip `archive/` and anything marked DONE/parked/not-started unless the user asks). Each plan's **Next (pick up here)**, **Blocked / waiting on**, and **Resume** lines are the raw material. + - Note the priority signals already encoded: ๐Ÿ”ด > ๐ŸŸก > ๐ŸŸข/๐Ÿ”ต, explicit "#1 priority", and hard deadlines (e.g. a GA date). Convert relative dates using `date +%Y-%m-%d` โ€” never guess today. + +2. **Pull live signals** _(**skip this entire step in `--fast`** โ€” brief from the hub only)_ (each is **best-effort โ€” skip gracefully and say so if unavailable**; never block the briefing on a signal, never guess a status from memory). Run the independent fetches in parallel: + + - **Jira** โ€” extract the ticket keys referenced across the active plans (`grep -rhoiE '(DOC|RED)-[0-9]+' ~/claude-overview/plans/*.md | sort -u`) and batch-fetch live status/assignee via `searchJiraIssuesUsingJql` (`key in (โ€ฆ)`). Flag: newly **assigned to you**, newly **closed/resolved** (โ†’ possibly unblocked or already-done), and status advances. (Same reconcile logic as `/checkpoint` step 4.) + - **GitHub** (docs repo `redis/docs`, local clone `~/repos/docs`). Fetch three things: + - *My open PRs:* `gh pr list --repo redis/docs --author "@me" --state open --json number,title,reviewDecision,isDraft,updatedAt`. Flag **ready to merge** (reviewDecision APPROVED + not draft), **approved but still draft** (un-draft + merge), and **stale** (no update in >2 weeks). + - *Issues assigned to me:* `gh issue list --repo redis/docs --assignee "@me" --state open --json number,title,updatedAt`. (Authored issues are usually empty โ€” assignee is the useful list.) + - *Plan-referenced PRs:* for PR numbers named in the plans (`grep -rhoE '#[0-9]{3,5}' ~/claude-overview/plans/*.md`), `gh pr view --repo redis/docs --json state,reviewDecision,statusCheckRollup,mergeable,title` to catch newly **approved / failing-CI / merged**. + - If `gh` errors, check `gh auth status`; a keyring "token invalid" or an `api.github.com` TLS/x509 error in a restricted shell is usually an environment restriction rather than real auth loss โ€” see the operator note at the bottom of this skill. Skip GitHub and say so only if it truly can't reach the API. + - **Calendar** โ€” today's events via the Google Calendar MCP (`list_events` for today). Use them to time-box recommendations ("do X before the 2pm SME meeting") and to flag prep needed for upcoming meetings. + - **Gmail** โ€” recent/unread mail (past ~1โ€“2 days) from people the plans say you're **blocked on or waiting for**. Surfaces "you've been unblocked" signals. Use `search_threads` scoped to those senders + recency. + - **Slack** โ€” two passes via the Slack MCP search: + - *Mentions/DMs* โ€” recent (past ~1 day, `to:me`) messages that might change priorities. These feed the ranked list and "Changed" section. + - *Saved items* (`is:saved`, recent-first) โ€” your flagged-to-revisit pile. **Note:** results sort by message post date, not save date, so this is a standing backlog spanning weeks/months, **not** an overnight-change signal โ€” keep it out of the ranked "Do next." Drop empty-body/bot entries, cap at ~8, and cross-reference against the active plans so items tied to current work (a PR on a live project, a bug from a stakeholder) are highlighted. + +3. **Synthesize a ranked recommendation.** Combine the plans' stated next-actions with what the live signals changed. Rank by: (a) hard deadline proximity, (b) explicit priority order from OVERVIEW, (c) **newly unblocked** work (do the thing that was waiting the moment it frees up), (d) quick wins that unblock others. Down-rank anything still blocked. + +4. **Output** โ€” keep it tight and skimmable: + - **๐Ÿ“Œ Top of the day** โ€” 1 line on the single highest-leverage thing and why. + - **โ–ถ๏ธ Do next (ranked)** โ€” 3โ€“5 concrete actions, each with a one-line *why* (deadline / newly unblocked / someone waiting) and its **resume pointer** (project, branch, `claude --resume ` from the plan's Resume line) so you can jump straight in. + - **๐Ÿ†• Changed since last checkpoint** โ€” newly unblocked, newly blocked, newly assigned, PRs now approved, meetings today that need prep. Only include real, signal-backed items. + - **๐Ÿ”€ My open PRs & issues** โ€” open PRs authored by you on `redis/docs` (each with merge-readiness: ready / approved-but-draft / stale) + issues assigned to you. Sort merge-ready first โ€” these are the fastest wins. + - **โณ Still blocked** โ€” one line each, who/what it's waiting on. + - **๐Ÿ“Ž Flagged to revisit** โ€” your Slack saved items (filtered/capped per step 2). List each with source + one-line gist; **flag the ones that map to an active plan** ("โ† ties to "). This is a don't-let-these-rot tail, deliberately *below* the deadline-driven sections and not ranked into "Do next." Omit the section entirely if there are no non-noise saved items. + - If Jira/GitHub reconciliation surfaced **drift** from the plans (ticket closed but still under Next, PR merged, etc.), note it and **offer to run `/checkpoint`** to persist the corrections. Do not write files from standup. + +## Rules + +- **Read-only.** Standup never edits `OVERVIEW.md` or plan files. It recommends; `/checkpoint` records. Safe to run any number of times a day. +- **Never fabricate status.** Every "newly closed / approved / assigned" claim must come from a live fetch this run, not memory or inference. If a signal source is down, say "couldn't check X" โ€” don't guess. +- **Best-effort signals.** Any of Jira / GitHub / Calendar / Gmail / Slack may be unauthenticated or unavailable (non-interactive sessions, expired tokens). Skip the missing ones, note them briefly, and brief on the rest. +- **Respect the hub's priorities.** Deadlines and the ๐Ÿ”ด/#1 ordering from OVERVIEW win over raw recency. A hard GA date outranks nice-to-haves. +- **Concrete over comprehensive.** The goal is "start here," not a full status dump โ€” that's what OVERVIEW.md is for. Cap the ranked list at ~5. + +## Operator note โ€” GitHub / `gh` + +`gh` needs both the OS keyring (for the token) and network access to `api.github.com`. In a restricted shell those can be unavailable, producing a keyring "token invalid" message or an `api.github.com` x509/TLS verification error โ€” neither means the token is actually bad (verify with `gh auth status` in a normal shell). For the GitHub signal to work reliably, `gh` should be run in an environment where the keyring and `api.github.com` are reachable. You can manage what the sandbox permits via the `/sandbox` command; a one-time allow for `gh` / `api.github.com` makes this seamless. Until then, the OVERVIEW `๐Ÿ”€ GitHub` snapshot block is the fallback source. diff --git a/.claude/skills/startwork/SKILL.md b/.claude/skills/startwork/SKILL.md new file mode 100644 index 0000000000..ba35017260 --- /dev/null +++ b/.claude/skills/startwork/SKILL.md @@ -0,0 +1,69 @@ +--- +name: startwork +description: Start focused work on one task โ€” the "dive in" companion to /standup and /checkpoint. Given a project/ticket/branch (or the top OVERVIEW priority if none named), reads the claude-overview hub for that project, checks out the appropriate branch in the docs repo, and loads the matching product context (/rs, /k8s, or /ff) so the thread is ready to work. Read-only on the hub; it prepares, it does not record. Use when the user says "start work on ", "pick up ", "start on ", "dive into", "work on", "get me set up on", "resume ", "load context for", or names a project/ticket to begin. +--- + +# Start work + +The "dive in" companion to `/standup` and `/checkpoint`. Where **standup** ranks *what* to do (read-only briefing) and **checkpoint** saves state on the way *out*, **startwork** gets a fresh thread fully loaded to *start* on **one** task: it reads the `claude-overview` hub for that project, **checks out the right branch** in the docs repo, and **loads the matching product context** (`/rs`, `/k8s`, `/ff`) โ€” then tells you exactly where to start. + +> **Naming note:** in this repo this skill is `startwork` because the repo already has a different `/pickup` skill (thawing a *parked PR*, pairs with `/park`). They're unrelated โ€” this one is the standup/checkpoint companion. + +Reads the hub at `~/claude-overview/` by **absolute path** (not the current working directory). **Read-only on the hub** โ€” it never edits `OVERVIEW.md` or plans (that's `/checkpoint`'s job). Its only side effects are git operations (`fetch` / `checkout`) and loading a product-context skill. + +> **First-time setup:** expects a personal hub at `~/claude-overview/`. If you don't have one, see `_shared/status-workflow/README.md`. + +Run it from any repo โ€” it resolves the hub and the docs repo by absolute path. + +## Steps + +1. **Identify the target project (resolve to exactly one).** + - If the user named a project / ticket key / branch in the invocation, match it to a plan file (`grep -rli "" ~/claude-overview/plans/*.md`) and/or against the OVERVIEW at-a-glance rows. + - If **no** argument, read `~/claude-overview/OVERVIEW.md` and **suggest the highest-leverage actionable project** โ€” nearest hard deadline, then ๐Ÿ”ด > ๐ŸŸก > ๐ŸŸข/๐Ÿ”ต priority, skipping anything `parked` / `not started` / fully `DONE` or currently blocked โ€” and **ask the user to confirm or pick another**. + - If the arg matches several plans, list the candidates and **ask which one**. Never guess when ambiguous. + +2. **Read the hub for that project (read-only).** + - The OVERVIEW row **and** the project's detailed section: status, priority, deadline, blockers, progress. + - The plan file `~/claude-overview/plans/.md`: **Next (pick up here)**, **Blocked / waiting on**, the **Resume** line (branch + session id), and the referenced Jira tickets + PR numbers. + - Convert any relative dates with `date +%Y-%m-%d` โ€” never guess today. + +3. **Check out the appropriate branch.** + - **Repo:** default to the docs clone at `~/repos/docs` (all plan branches/PRs live in `redis/docs`). If the plan's Resume/branch line points at a different repo (e.g. the Redis-Enterprise source repo at `~/repos/Redis-Enterprise`), use that. If genuinely ambiguous, ask. + - **Branch:** take it from the plan's **Resume** line / branch reference. If the plan records none, derive it from the ticket key (e.g. `DOC-6576`) and confirm, or ask. + - **Safety first โ€” never discard uncommitted work.** Run `git -C fetch` then `git -C status --short`. If the working tree is **dirty**, **stop and surface it** โ€” do not `stash`, `reset`, `checkout -f`, or discard anything. You may be mid-work on another task; offer to run `/checkpoint` on the current branch first, then let the user decide. + - **If clean:** `git -C checkout `. If the branch is remote-only, `git -C checkout -b --track origin/`. If the local branch is **behind** `origin`, say so and **offer** to `git -C pull` (never force, never auto-pull). + - Report the result: branch name, ahead/behind vs origin, and the last commit (`git -C log --oneline -1`). + +4. **Load the product context.** + - Map the project to its docs-context skill and **invoke it** so the source repo + conventions load: + - **Redis Software** (RS release notes, RS release-process runbook, custom modules, etc.) โ†’ **`/rs`** + - **Kubernetes / operator** (operator releases, K8s RBAC, K8s maintenance RN, etc.) โ†’ **`/k8s`** + - **Feature Form** (restructure, develop/deploy/UI docs) โ†’ **`/ff`** + - If the project maps to no known product context (e.g. professional-development, backlog-reduction), **skip and say so** โ€” there's nothing to load. + - If a project spans two products, load the one this task belongs to (ask if unclear). + +5. **Pull live task signals** (best-effort โ€” run in parallel, skip gracefully, never fabricate). + - The plan's **Jira tickets** โ€” live status/assignee via `searchJiraIssuesUsingJql` (`key in (โ€ฆ)`). + - The plan's **PRs** โ€” `gh pr view --repo redis/docs --json state,reviewDecision,mergeable,isDraft,statusCheckRollup` for review/merge/CI state. (`gh` is sandbox-excluded, so it works in-sandbox; if it errors, see `/standup`'s operator note.) + - Flag anything that **changed since the plan was last touched** โ€” newly unblocked, PR now approved, ticket advanced/closed โ€” so the thread starts from truth, not a stale plan. + +6. **Brief: "you're set up โ€” start here."** Keep it tight: + - **One line:** project ยท priority ยท deadline. + - **Branch:** `` checked out in `` (+ ahead/behind, + any dirty-tree warning that stopped the checkout). + - **Context:** which product skill loaded (or "none โ€” not a product-doc task"). + - **โ–ถ๏ธ Start here:** the top **Next** action from the plan, adjusted for any live-signal change. + - **โณ Blockers:** anything still waiting, one line each. + - Close by noting the user can run **`/checkpoint`** when they switch out. + +## Rules + +- **Read-only on the hub.** Startwork never edits `OVERVIEW.md` or any plan file โ€” it reads them, acts on git, and loads context. Recording state is `/checkpoint`'s job. +- **Never discard uncommitted work.** A dirty working tree halts the checkout. No `stash` / `reset` / `-f` / discard without the user's explicit OK. Offer `/checkpoint` on the current branch first. +- **One project per run.** Resolve to a single plan + branch. If the target is ambiguous or unnamed, ask (or suggest the top OVERVIEW priority and confirm) โ€” don't guess. +- **Best-effort signals; never fabricate status.** Jira / GitHub may be unavailable โ€” skip and say so. Every "changed / approved / unblocked" claim must come from a live fetch this run, not memory. +- **Absolute paths.** Hub = `~/claude-overview/`; default git repo = `~/repos/docs`. Resolve both regardless of the current working directory. +- **Respect the hub's priorities.** When suggesting a project (no arg), hard deadlines and ๐Ÿ”ด/#1 ordering win over recency. + +## Operator note โ€” git in the sandbox + +`git fetch` / `checkout` / `pull` in `~/repos/docs` and reading `~/claude-overview/` are normal reads/writes within the clone and hub. If a git network op (`fetch`/`pull`) hits a TLS/keyring error in a restricted shell, that's the same environment restriction described in `/standup`'s operator note โ€” retry outside the sandbox. `gh` is typically sandbox-excluded (`sandbox.excludedCommands: ["gh *"]` in `~/.claude/settings.json`), so PR lookups work in-sandbox.