From just-ship
Shapes fuzzy ideas into concrete tickets, epics, or spikes via a 3-turn conversation using only business-level questions. For unclear directions or exploration.
npx claudepluginhub yves-s/just-ship --plugin just-shipThis skill uses the workspace's default tool permissions.
When the intake classifier (T-875) lands on **conversation** — the user's direction is unclear, business context is missing, or they're exploring ("should we…", "I'm not sure…") — the Sidekick enters this mode. It is deliberately short: at most 3 turns, and every session ends with a created artifact. No open-ended chats.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
When the intake classifier (T-875) lands on conversation — the user's direction is unclear, business context is missing, or they're exploring ("should we…", "I'm not sure…") — the Sidekick enters this mode. It is deliberately short: at most 3 turns, and every session ends with a created artifact. No open-ended chats.
The point is not to be helpful-sounding. The point is to capture the idea as a workable artifact without pushing PM ceremony onto the user.
| Turn | What happens |
|---|---|
| 1 | User's first message arrives here. The Sidekick either asks one business question (question) or, if the idea is already clear enough, finalises immediately (finalize). |
| 2 | Same mechanics: one more business question, or finalise. |
| 3 | Finalise only. No further questions are allowed. If the idea is still fuzzy, the Sidekick creates a Spike ticket that documents the open question verbatim (transcript included) so a later pass can resolve it. |
If the model attempts a fourth question, the endpoint forces a Spike fallback. The user can always come back with more context and start a fresh session; they never get stuck in a loop.
The Sidekick is allowed to ask about business signals. It is banned from asking implementation questions.
| Topic | Example question |
|---|---|
| Target audience | "Für wen genau ist das — User, Admins, oder beide?" |
| Timing / urgency | "Muss das noch vor Launch stehen oder danach?" |
| Scope | "Ist das eine Änderung oder mehrere zusammen?" |
| Replaces vs augments | "Soll das die bestehende Suche ersetzen oder daneben leben?" |
| Success criteria | "Was merkt der User konkret, wenn das da ist?" |
| Topic | Forbidden pattern |
|---|---|
| Stack / framework | "React oder Vue?", "Welches Framework?" |
| Database / storage | "Postgres oder SQLite?", "Welche DB?" |
| Hosting / deployment | "Wo hosten wir das?", "Coolify oder Vercel?" |
| Component patterns | "Modal oder Bottom-Sheet?", "Kanban oder Liste?" |
| Visual / typography | "Welche Farbe?", "Welche Schrift?" |
| Layout / IA | "Sidebar oder Topbar?", "Welche Navigation?" |
| API shape | "REST oder GraphQL?", "Welcher Endpoint?" |
| Auth / caching | "Welcher Auth-Flow?", "Cachen wir das?" |
| Empty / loading states | "Brauchen wir einen Empty-State?" (answer is always yes — the team designs one) |
If a draft question fits any forbidden pattern, the Sidekick replaces it with a business question or moves straight to finalise.
One question per turn. If two things need clarity, pick the more load-bearing one.
During finalisation — when the Sidekick decides ticket/epic/spike and builds the body — it may internally route through product-cto (architecture, ops, security strategy) and design-lead (product structure, UX, interaction patterns). Their outputs flow into the artifact body (e.g. inferred Acceptance Criteria, inferred Out-of-Scope lines). The user never sees this routing — only the Sidekick's final wrap message and the artifact link.
At finalise time the Sidekick picks one of three shapes:
| Kind | When |
|---|---|
ticket | The 3 turns narrowed this to a single concrete change with a clear outcome. |
epic | The result is multi-part — 2 to 5 related child tickets sharing a feature name. |
spike | After 3 turns, direction is still fuzzy. Document the open question(s), tag the ticket spike + sidekick-converse, and let a future pass pick it up. |
A Spike on turn 3 is not a failure — it is the structured fallback. Open loops are forbidden; Spike tickets close them.
session_id back so the server can resume the conversation (the user can close the tab and come back).Endpoint: POST /api/sidekick/converse on the Engine server.
Request (first turn — no session_id):
{
"project_id": "uuid",
"user_text": "string (<=4000 chars)",
"board_url": "https://board.just-ship.io",
"project_context": {
"projectName": "just-ship",
"projectType": "framework"
}
}
Request (subsequent turns):
{
"session_id": "uuid returned on turn 1",
"project_id": "uuid",
"user_text": "the next user message",
"board_url": "https://board.just-ship.io"
}
Response — continue (turns 1 or 2, model asked a question):
{
"status": "continue",
"session_id": "uuid",
"turn": 1,
"assistant_text": "Für wen genau ist das — User oder Admins?"
}
HTTP 200.
Response — final (any turn 1–3, model finalised):
{
"status": "final",
"session_id": "uuid",
"turn": 3,
"assistant_text": "Alles klar — kurze Zusammenfassung. Ich lege Ticket an. https://board.../t/500",
"artifact_kind": "ticket",
"artifact": {
"category": "ticket",
"ticket": { "number": 500, "id": "…", "title": "…", "url": "…" }
}
}
HTTP 201 (something was created).
For artifact_kind: "epic", artifact contains epic, children, and optionally failed_children. For artifact_kind: "spike", artifact.category is ticket and artifact.ticket has the Spike with tags ["spike", "sidekick-converse"].
Auth: X-Pipeline-Key header.
Rate limit: 30 requests per minute per project_id — one session uses up to 3 calls.
Errors:
400 — validation: missing/empty user_text, missing project_id, text over length.401 — missing/invalid X-Pipeline-Key.429 — rate limit exceeded.502 — Board API upstream failure during artifact creation.500 — internal failure. The session stays alive so the caller can retry.continue: show assistant_text verbatim as a chat bubble.final:
ticket / epic: show assistant_text (already includes the URL).spike: show assistant_text + a short follow-up like "Kannst dir das Spike-Ticket anschauen, wenn du bereit bist, die Richtung zu klären."The assistant_text on final ALWAYS ends with the artifact URL. Do not strip it.
Every turn logs (Pino structured): sessionId, turn, projectId, durationMs. Finalise turns additionally log artifactKind, category, number, childrenCount. Errors log err, sessionId, turn.
Sentry receives: model-call failures, parse failures, artifact-creation failures.
FORBIDDEN_QUESTION_TOPICS and asserts the system prompt bans each pattern.