diff --git a/.claude/skills/dispatch-oneshot/SKILL.md b/.claude/skills/dispatch-oneshot/SKILL.md index 3961d64..2109820 100644 --- a/.claude/skills/dispatch-oneshot/SKILL.md +++ b/.claude/skills/dispatch-oneshot/SKILL.md @@ -36,6 +36,26 @@ Specify the work before feeding it. Two ways in: do not feed an underspecified task into the pipeline; it is L3-class automation and will not reliably succeed. +### Input shapes — a task need not be in the issue format + +The feeder builds the seed controller's raw intake (the front door) from each +task; inputs do **not** have to be pre-split into the issue format. The seed +content-classifies: + +- **A real GitHub issue** (`"issue": ` with a `repo`) → pulled and handled as a + GitHub issue. +- **A bare prompt** (`{"prompt": "…"}`) → the seed seeds `title`/`goal` from the + prompt and handles it interactively (optional gaps like acceptance are left open, + and degrade cleanly to unset when run headless — no TTY hang). +- **A structured task** (`title` + `body`) → a non-interactive job request. + +The `issue` carried on a oneshot job is a **negative local work-id** used only for +the engineer's clone/branch naming — it is *not* a GitHub issue. The build phase +honours the negative marker: `admin:publish` still deploys and `consolidate_pr` +still opens ONE PR, but the issue-keyed GitHub mutations (`intake_invoice`'s label +state machine, the `Closes #` trailer) are skipped. This replaces the old +fabricated-GitHub-issue hack. + For more than one task, interview each, and confirm the **order** — the feeder runs them sequentially, each fully through the pipeline before the next. @@ -81,8 +101,21 @@ Run the feeder, which processes the tasks sequentially and streams each phase: python3 app/scripts/oneshot_feed.py --repo owner/repo # dry-run python3 app/scripts/oneshot_feed.py --engine websitewf -v # trace python3 app/scripts/oneshot_feed.py --repo owner/repo --live # real model +# demo: create+seed the target repo from a template first, then run live with the +# full phase-by-phase debug trace streamed (audience-visible), tee'd to a log. +python3 app/scripts/oneshot_feed.py --repo owner/repo --live -v \ + --provision owner/repo --template ~/path/to/template |& tee oneshot-demo.log ``` +`--provision owner/repo --template DIR` ensures the target repo exists and is +seeded (via `app/scripts/demo/provision-from-template.sh`) **before** the pipeline +clones it, so `engineer:act_clone` has a cloneable, deployable base. `admin:prepare_env` +then sees the repo already exists and leaves it untouched (idempotent). + +`-v` sets `DISPATCH_DEBUG=1` and streams the engine's phase-by-phase action trace — +run it this way for a live demo so the audience can watch each controller/action +fire. Run it as a background task (or `tee` to a log) so the trace is scrollable. + Stream the output. For each task report whether the tick completed (`ok=`) and the deliverables produced; on a failure, surface the detail/error the feeder prints. diff --git a/app/scripts/demo/dogblog-oneshot.json b/app/scripts/demo/dogblog-oneshot.json new file mode 100644 index 0000000..0fc6606 --- /dev/null +++ b/app/scripts/demo/dogblog-oneshot.json @@ -0,0 +1,9 @@ +[ + { + "title": "Enhance interactive dog-blog components: like toggle, email validation, a11y labels", + "body": "## Goal\nThe three client-side components (LikeButton, CommentBox, NewsletterSignup) in `moonexpr/dog-blog-demo` already render interactively with basic `useState` — but each has a stub gap to close.\n\n## Research findings\n- Stack: Next.js 14, React 18, TypeScript, Tailwind. No form library, no state management beyond bare `useState`. All three already have `\"use client\"`.\n- LikeButton (`src/components/LikeButton.tsx`): increment-only; should toggle liked/unliked with `aria-pressed`; count is ephemeral per mount (no per-post persistence needed for demo); `postSlug` prop already present.\n- CommentBox (`src/components/CommentBox.tsx`): add-to-list + empty guard already work; needs a visible `