---
description: Draft a daily standup from work done since the last push, surface in-progress local work and follow-ups, show the draft, and post to LaunchSecure Comm Hub as a daily_update after explicit confirmation.
---

# Standup

Generates a daily-update comment for the LaunchSecure Comm Hub. Pulls commits since the last push (with fallbacks), surfaces what's still in-flight locally (uncommitted work, explicit follow-ups, in-progress work items), drafts a summary in the project's house style, shows it to the user, and posts only after the user confirms. Never posts without explicit "yes".

## Preflight

1. Verify `.launch-secure.cred.config` exists at the repo root. If missing, abort and tell the user to run `npx @launchsecure/launch-kit init` first — without the cred file the `launch-secure` MCP cannot authenticate, so we cannot read prior standups or post the new one.
2. Verify we are inside a git repo (`git rev-parse --git-dir`). If not, abort with a clear message.
3. Record the current branch (`git rev-parse --abbrev-ref HEAD`) and current git email (`git config user.email`).

## Gather

Pull data from layered sources, in this order. Default to git + commit messages — they already carry the structure. Only reach for `launch-chart` in the explicit case described in step 3.

### 1. Determine the window

- **Primary**: `git log --reverse --pretty=format:'%h%x09%an%x09%ae%x09%s%n%b%n%x00' @{push}..HEAD`. The `@{push}` revspec resolves to where this branch was last pushed; the diff is commits ahead of upstream.
- **Fallback 1**: if the primary returns empty OR `@{push}` errors with `unknown revision`, query the `launch-secure` MCP via `communication_read({ tag: "daily_update", limit: 1 })`. Take the most recent comment's `createdAt`; gather commits since then via `git log --since="<that timestamp>"`.
- **Fallback 2**: if no prior `daily_update` exists either, use `git log --since="24 hours ago"`.

Tell the user which window was used in one short line ("Using commits since last push (12 commits)" or "No commits since last push — falling back to commits since 2026-05-20 14:01 (last standup)").

### 2. Collect change context

- `git diff --stat @{push}..HEAD` (or whichever window was chosen) — file paths + line counts. Drives theme grouping.
- `git log --pretty=format:'%h %s' <window>` — short subject lines for quick scan.
- `git log --pretty=format:'%h%n%B%n---' <window>` — full commit bodies. Needed for step 4 (follow-up detection).
- Branch names + PR references in commit messages (look for `#<digits>`, `LS-<id>`, branch slugs like `fix/foo-bar`). These are work-item handles.

### 3. Group into themes

**Default: group by commit-message scope.** Conventional-commit subjects like `feat(launch-kit): …`, `refactor(server): …`, `chore(lint): …` already declare the theme — use the scope as the theme name. Multiple commits with the same scope collapse into one `→ <Scope>` section.

**Only escalate to `launch-chart` when ALL of these are true:**
- Window has ≥20 changed files across ≥5 top-level directories, AND
- Commit scopes are missing, inconsistent, or too coarse to reveal structure (e.g. everything is `chore: …` or untagged).

In that case: call `mcp__launch-chart__detect_project_stack` to verify the chart is wired, then for each changed file call `mcp__launch-chart__read_graph({ search: "<basename>" })` and group by the resolved node's `module` field. Common LS modules: `auth`, `pda`, `pda-guides`, `pda-shell`, `radar`, `chart`, `orbit`, `recall`, `comms`, `board`, `webhooks`, `feedback`, `briefs`, `mcp`.

Files that don't resolve in the chart (new files, non-TS, config) bucket under "Misc" or by directory.

### 4. Collect in-progress signals (the "what's still in flight" data)

This is the data that makes the standup honest about what's still open, not just what shipped. Always run all three:

**4a. Uncommitted local work** — `git status --short`. Group by area (e.g. `scripts/`, `.claude/`, untracked dirs). Filter out build artifacts that don't represent intentional work (`.launchsecure/graphs/*.json`, `node_modules`, `dist`, `.next`). What remains is in-flight code or scaffolds — surface it under "Pending / in-progress".

**4b. Follow-up flags in commit bodies** — grep the full commit bodies pulled in step 2 for these patterns (case-insensitive): `follow-up`, `followup`, `TODO`, `flagged`, `deferred`, `not patched`, `rolled back`, `revert`, `queued`, `to be solved`, `next pass`. Each hit is a self-declared open item by the author — surface the sentence verbatim or paraphrased under "Pending / in-progress".

**4c. In-progress work items assigned to current user** — call `mcp__launch-secure__work_items_list({ assignee_email: "<git email from preflight>", status: "IN_PROGRESS" })`. For each returned item, capture title + id. Don't list more than 5; if more exist, list 5 + "(N more)".

If any of 4a/4b/4c return nothing, that section just doesn't appear in the draft. Don't fabricate filler.

### 5. Work-item closure linkage

For each work-item handle found in commit messages from step 2 (regex `#\d+|LS-\w+`), call `mcp__launch-secure__work_item_get({ id: "<id>" })` (or `work_items_list` with id filter). If any status changed to DONE/COMPLETED, call them out in the closing `----` block as a one-liner.

Skip this step if no handles were found in commit messages — don't pull the full work-items list to fish for closures.

### 6. Release detection

A commit qualifies the post for the `release` tag if ANY of the following are true. These signals are **stack-detected**, not hardcoded — match against whatever the project actually uses, and a signal that doesn't apply to this stack simply doesn't fire:
- The project's **version** changed — detect from the stack's version source: `package.json` `version` (Node), `pyproject.toml`/`setup.py`/`__version__` (Python), `Cargo.toml` `version` (Rust), `<Version>` in a `*.csproj` (.NET), a gemspec/`version.rb` (Ruby), `version` in `pubspec.yaml` (Dart), or a new `vX.Y.Z` git tag pushed in this window (language-agnostic). Diff the relevant file over `@{push}..HEAD`.
- A **migration** was added — any file under the project's migrations directory (detected as in `/kit:ship`: `prisma/migrations/`, `supabase/migrations/`, `db/migrate/`, `alembic/versions/`, `drizzle/`, `src/main/resources/db/migration/`, etc.), or the schema/DDL source changed. Skip this signal when the project has no migrations.
- A deploy/publish was mentioned in commit subjects (regex: `\b(publish|release|deploy|bump)\b`).
- A new **public entry point** was added — a bin/CLI command, package export, or exported library symbol (e.g. a new `bin`/`exports` entry in `package.json`, a new console-script in `pyproject.toml`, a new exported package in Go, etc.).

If any are true, set `addReleaseTag = true`. Otherwise `false`.

## Draft

Produce the standup in the **exact** house format. This is the format Prajyot uses for human-written daily updates (verified against the May 18, 19, 20, 21 posts in the Comm Hub):

```
Hey @everyone

Pushed <N> commits to <branch> today. Highlights:

→ <Theme 1>
- <outcome bullet, not a commit message>
- <outcome bullet>

→ <Theme 2>
- <outcome bullet>

→ <Theme N>
- <outcome bullet>

----

Pending / in-progress:

→ <Pending area 1>
- <one-line item — what's open, why, where>

→ <Pending area 2>
- <one-line item>

----

<one-line PSA or deploy-safety note, phrased for the project's stack. Examples: "Typecheck clean, no schema/migration changes, safe to deploy." or "Includes a <migration-tool> migration <name> — take a DB backup before deploy." or "Bumps to vX.Y.Z — publishes on merge.">

Thanks
```

**Strict format rules:**

- `Hey @everyone` — exactly this. Not "Hey team", not "Hi everyone". Single line, blank line after.
- `Pushed N commits to <branch> today. Highlights:` — replace `<branch>` with the actual branch from preflight. If the window was a fallback (not "since last push"), say "Drafted N commits' worth of work on <branch> today. Highlights:" instead — be honest about the window.
- `→ <Theme>` — right-arrow + space + theme name. Theme names come from commit-message scope (default) or chart module grouping (escalated case). Capitalize the first letter.
- `- <bullet>` — plain hyphen + space. Bullets are **outcomes**, not commit messages. Translate "feat(radar): add transcript view" into "Structured transcript view with overlay reply drawer". Drop scope prefixes and verb tense.
- Blank line between themes.
- `----` — four hyphens, on its own line, blank line above and below. Used twice: once to open the Pending block, once to close it.
- **Pending / in-progress block** — omit entirely if steps 4a/4b/4c all returned nothing. If present, populate from those three sources. Each `→` sub-heading names an area (e.g. `→ Feedback widget`, `→ Codex config writer`, `→ Beacon monitor UX`). Bullets are short, factual, name the file or symbol when relevant.
- Closing block: one short line is fine. Don't pad. Mention work-item closures + any deploy-affecting changes here.
- `Thanks` — exact word, no comma, no name signature (the post's author is attached automatically).

**Constraints:**

- Plain text only. No `**bold**`, no `*italic*`, no backticks, no `# headers`, no markdown link syntax. The Comm Hub renders as plain text.
- Aim for ≤ 400 words total (was 350; bumped to accommodate the Pending block). Standups are skim-able; trim aggressively.
- Top 3–6 themes is the sweet spot. If you have 20 commits in 12 different modules, collapse the small ones into a "→ Misc" theme.
- Bullets should be **outcome-shaped**: what landed in the product, not what the diff did. "Multi-select EventTypesPicker on subscription forms" beats "modified components/webhooks/EventTypesPicker.tsx".
- Pending items are honest snapshots, not commitments. "Drawer fix reverted — to be solved fresh" is fine; "will be fixed by EOD" is not.

## Confirm

Show the draft to the user verbatim in a code-fenced block (so they see plain-text formatting as-is), then ask **exactly**:

> "Post this as a daily_update to LS Comm Hub? Reply `yes` to post, `edit` to revise, or `cancel` to abort."

Responses:

- **`yes`, `y`, `ok`, `post it`** — proceed to duplicate check + post.
- **`edit`, `change <thing>`, free-form revisions** — apply the edits, regenerate the draft, re-show, re-ask.
- **`cancel`, `no`, `nope`** — abort. Don't post. Don't keep partial state.

Anything ambiguous → treat as "edit, what would you like changed?".

## Duplicate check

Before posting, call `mcp__launch-secure__communication_read({ tag: "daily_update", limit: 5 })`. If any returned comment has:
- `resourceType: "comment"` (not `"daily_update"` — that's bot-only, distinct stream)
- `author.email` matches the current user's email (from preflight)
- `createdAt` within the last 12 hours

…then a manual daily_update already exists from today. Offer:

> "A daily_update already exists from you today (posted at <time>, <preview-50-chars>). Choose: `replace` to update it (communication_update), `append` to post another, `cancel` to stop."

- **replace** → call `mcp__launch-secure__communication_update({ id: "<existing-id>", content: <new-draft> })`. Preserve tags.
- **append** → proceed to post.
- **cancel** → abort.

## Post

Call `mcp__launch-secure__communication_write`:

```
{
  resourceType: "comment",
  content: "<the final draft, plain text>",
  tags: addReleaseTag ? ["daily_update", "release"] : ["daily_update"]
}
```

`org_slug` and `project_slug` are auto-supplied from the cred config via the MCP's headersHelper — do NOT pass them yourself.

On success: report the comment ID and a friendly "posted to LS Comm Hub" line. If the response includes a URL field, surface it.

On failure: surface the error verbatim. Don't retry automatically — auth or schema errors deserve human attention. The draft is preserved in chat so the user can retry manually.

## Idempotency

Re-running `/kit:standup`:
- Always re-pulls the window fresh. No cached state.
- Duplicate check handles same-day reposts.
- The draft is never written to disk — only shown in chat. User can copy it manually if they cancel.

## Notes for the assistant

- **Default to git, not the chart.** Conventional-commit scopes already declare themes; only reach for `launch-chart` when scopes are missing or inconsistent across ≥20 files / ≥5 directories. This was the most common failure of the previous prompt — chart calls produced no different grouping than commit-scope grouping would have.
- **The Pending / in-progress block is the standup's main job, not the shipped-themes block.** Shipped work is visible in `git log`; what's still open isn't. Always run the three step-4 gathers.
- **Don't ask clarifying questions before drafting.** Produce a first cut from whatever data step 1–6 returned, then iterate. The draft is cheap; the conversation isn't.
- **Outcome bullet, not commit message** is the single most important transform. A standup full of "feat(x): add y" reads like a changelog, not a status.
- **Never assume `release` tag without evidence** (see step 6). False positives confuse downstream consumers.
- **If a step's tool fails**, note it inline and continue with the remaining sources — don't abort the whole standup over one failed call.
