submit-use-case

$npx mdskill add sonichi/sutando/submit-use-case

Submit a Sutando use case to the community via GitHub issue and PR

  • Shares external Sutando use cases with the public community
  • Uses GitHub API and CLA validation for PR submission
  • Checks titles for outcome-framed language consistency
  • Creates labeled issues and markdown files for community use cases
SKILL.md
.github/skills/submit-use-caseView on GitHub ↗
---
name: submit-use-case
description: "OSS-facing channel to share a Sutando use case with the community. Opens a labeled GitHub issue on sonichi/sutando and (CLA-gated) a PR adding community-use-cases/<slug>.md. Validates outcome-framed titles with the same checker as add-use-case. Default: both; flags --issue-only / --pr-only opt out."
user-invocable: true
---

# submit-use-case

OSS counterpart to `add-use-case`. `add-use-case` targets the private
`AG2Platform/agent-universe` repo (rendered on sutando.ai) and is for the
internal fleet. `submit-use-case` targets the public `sonichi/sutando` repo
so external contributors can share a use case without needing access to the
private rendering repo.

## Usage

```bash
python3 "$SKILL_DIR/scripts/submit_use_case.py" \
    --title "Your AI plays piano while you sleep" \
    --summary "Outcome-first summary that appears on tile + detail page." \
    --bullets "bullet1" --bullets "bullet2" \
    [--video /abs/path/to/clip.mp4] \
    [--media-url https://example.com/clip.jpg] \
    [--youtube-id ABCDEFG1234] \
    [--x-url https://x.com/...] \
    [--linkedin-url https://www.linkedin.com/...] \
    [--contact "you@example.com or @yourhandle"] \
    [--issue-only | --pr-only] \
    [--dry-run]
```

`--dry-run` runs the framing check and prints both the rendered issue body
and the rendered `community-use-cases/<slug>.md` file to stdout. No clone, no
gh calls.

## What the skill does

1. **Validate title is outcome-framed.** Reuses `REJECT_PATTERNS` + `validate_title` +
   `suggest_reframes` from `add-use-case` verbatim. Capability-listy titles
   ("Ask your AI to ...", "Sutando can ...", "Send a ...") are rejected with
   deterministic reframe suggestions. Same rules, same voice.
2. **Derive slug.** `slugify(title)` — lowercased, non-alphanum→`-`, trimmed to 60 chars.
3. **Idempotency checks** (skipped in `--dry-run`):
   - Does a branch `community-use-case/<slug>` already exist on `sonichi/sutando`?
     If yes, abort with a pointer to the existing PR.
   - Is there an open issue on `sonichi/sutando` with the same `title`? If yes,
     abort with the existing issue URL.
4. **Open an issue** (unless `--pr-only`). `gh issue create --repo sonichi/sutando`
   with label `use-case-submission`. Body has structured sections: Title,
   Summary, Bullets, Links (video / youtube / x / linkedin), Contact, and a
   forward-ref to the PR if one is opened in the same invocation.
5. **Open a PR** (unless `--issue-only`).
   - Fresh clone: `gh repo clone sonichi/sutando /tmp/sutando-submit-use-case-{ts}/`
   - Branch: `community-use-case/<slug>` from `main`
   - File: `community-use-cases/<slug>.md` — YAML frontmatter mirroring the
     agent-universe `UseCase` shape so the sync script can later promote it.
   - Identity: **only** set repo-local `user.email` / `user.name` to
     `4250911+sonichi@users.noreply.github.com` / `Chi Wang` when the runner
     is on Chi's fleet (detected via `/Users/wangchi/.sutando/workspace/`
     existing OR env `SUTANDO_FLEET_OWNER=chi`). For OSS submitters the
     script leaves git config alone so their own identity flows through —
     that's the whole point of CLA-Assistant signing.
   - Commit, push, `gh pr create`. PR body cross-links the issue if one was opened.
6. **Return** both URLs to stdout (issue URL, then PR URL, last two lines).

## File schema (`community-use-cases/<slug>.md`)

```yaml
---
slug: <derived>
title: <user title>
summary: <user summary>
videoUrl: <if --video>            # absolute or hosted; raw path uploaded to issue, not PR
youtubeId: <if --youtube-id>
xUrl: <if --x-url>
linkedinUrl: <if --linkedin-url>
thumbnail: /use-cases/<slug>.jpg
contact: <if --contact>
submitted_at: <ISO UTC timestamp>
---

<longDescription stitched from --bullets, or summary if no bullets>
```

The frontmatter intentionally mirrors `AG2Platform/agent-universe`'s
`lib/use-cases.ts` `UseCase` TypeScript type so a later sync script can read
this YAML and emit the literal entry the rendering repo expects. The
submitter is **not** asked to upload the thumbnail in the PR — it stays as a
pending path that the maintainer fills in when promoting.

## Issue label

`use-case-submission` (the maintainer monitors this label to triage incoming
community submissions).

## Idempotency

- Branch name `community-use-case/<slug>` is checked on `origin` before pushing.
- Existing issue with the same `title` (case-insensitive, open state) aborts.
- `--dry-run` skips all remote checks and only prints rendered output.

## Why we don't auto-set git identity for OSS submitters

CLA-Assistant signs the contributor under the email of the commit author.
For OSS contributors that MUST be their own email — that's the whole point
of the CLA channel. If we overwrote it with Chi's `noreply` address, every
external PR would be wrongly attributed and the CLA would be signed under
the wrong identity. The Chi-fleet override exists only so the same script
works for internal demo submissions without an extra step.

## Dependencies

- `git`, `gh` (authenticated to GitHub as the submitter)
- Python ≥ 3.9 (stdlib only — no third-party libs)
More from sonichi/sutando