name: bk-start description: BlueKiwi workflow execution skill. Selects a registered workflow and starts the first step immediately. This skill should be used when the user says "/bk-start", "/bk-run", "start workflow", "run workflow", "execute workflow", "run BlueKiwi", or wants to begin a registered instruction workflow. user_invocable: true
BlueKiwi Workflow Start
Select a registered workflow, create a task, and immediately execute the first step.
Argument Handling
Parse the argument string with this precedence (first match wins):
| Pattern | Meaning | Action |
|---|---|---|
| (none) | No argument | Fetch workflow list, ask user to select via AskUserQuestion. Also run Session Restore first. |
#<taskID> (starts with #, rest numeric) |
Resume a specific task | Skip workflow selection, jump straight to advance(task_id=N, peek=true) and continue that task |
<digits> only |
Workflow numeric ID | Skip the list UI, call start_workflow(workflow_id=N) directly |
<name> :: <prompt> |
Workflow name/ID + initial context | Match workflow by name or ID, pass everything after :: as context |
<name> |
Workflow name match | Fuzzy-match the workflow list, propose the best match as Recommended |
The :: separator can combine with #<taskID> or <ID> forms too (e.g. /bk-start 42 :: review PR #77).
Core Principles
- Instructions are internal agent directives. Never expose raw instruction text to the user.
- Never use system terms like "node", "node_type", "chain_nodes" with the user.
- Refer to steps as "step" only.
- All
outputwritten to the server must be in past-tense declarative form ("I analyzed...", "I generated...").
AskUserQuestion Parameter Rules
optionsmust have 2–4 entries.previewis a plain string. Use\nfor line breaks.headermust be 12 characters or fewer.multiSelectmust befalse.
Session Restore (Resume In-Progress or Timed-Out Task)
Step A — Mark zombie tasks
Call the sweep_stale_tasks MCP tool (defaults to timeout_minutes=120). This converts any running tasks idle for over 2 hours to timed_out so they can be surfaced for resume/cleanup in Step B.
Step B — Fetch existing tasks
Call list_tasks with status=running and again with status=timed_out.
Collect all results into a combined candidate list sorted by updated_at descending (most recent first).
If the list is empty → skip to workflow selection.
Step C — Build the task summary
For each candidate, compute age from updated_at to now.
Format: "Task #{id} — {workflow_name} (Step {current_step}/{total_steps}, {age}전)"
Example output:
미완료 태스크 2건이 있습니다:
① Task #31 — 코드 리뷰 워크플로 (Step 3/6, 3시간 전) [timed_out]
② Task #28 — 보안 점검 (Step 1/4, 30분 전) [running]
Step D — Ask what to do
Case 1: exactly 1 candidate
Ask via AskUserQuestion:
- header: "미완료 태스크"
- preview:
"Task #{id} — {workflow_name}\nStep {N}/{total} · {age}전 중단" - options (pick the most appropriate 3–4):
"이어서 진행"— resume this task"종료하고 새로 시작"— close this task then start fresh"닫지 않고 새로 시작"— leave as-is, open a new task- (only if status=running)
"계속 실행 중"— another agent is handling it, do nothing
Case 2: 2 or more candidates
Ask via AskUserQuestion:
- header: "미완료 태스크"
- preview: the task summary list built above
- options:
"가장 최근 태스크 이어서"— resume the most recent one"모두 종료하고 새로 시작"— close all candidates, then start fresh"새 태스크 시작 (기존 유지)"— leave existing as-is, open a new task
Step E — Execute the choice
"이어서 진행" / "가장 최근 태스크 이어서":
Call advance(task_id, peek=true), read task_context, then continue with the auto-advance loop.
"종료하고 새로 시작" / "모두 종료하고 새로 시작":
For each task to close, call complete_task(task_id, summary="사용자 요청으로 종료됨").
Confirm: "기존 태스크를 종료했습니다. 새 워크플로를 선택하세요." → proceed to workflow selection.
"닫지 않고 새로 시작" / "새 태스크 시작 (기존 유지)": Proceed to workflow selection without touching existing tasks.
execute_step Parameters
When calling execute_step:
Always provide:
context_snapshot(object): decisions made, key findings, next-step hints. The only reliable way to carry state across steps.model_id(string): current LLM model (e.g.claude-opus-4-6). Read from your system prompt.
Provide when known:
user_name(string)session_id,agent_id(strings): optional identifiers, server stores them for audit.
Do NOT send manually: provider_slug — the MCP server injects it from the connection handshake.
Record file/commit outputs in the artifacts array on the same call:
- File created:
{artifact_type: "file", title: "Design Doc", file_path: "docs/specs/design.md"} - Git commit:
{artifact_type: "git_commit", title: "Implementation", git_ref: "<hash>"} - URL:
{artifact_type: "url", title: "PR", url: "https://..."}
Session Metadata
When calling start_workflow, pass a session_meta JSON string carrying project context the server can't otherwise see. The MCP server auto-fills provider_slug from the client handshake, so you only need to supply what the agent knows:
{
"project_dir": "/Users/dante/workspace/project",
"user_name": "dante",
"model_id": "claude-opus-4-6",
"git_remote": "git@github.com:user/repo.git",
"git_branch": "main",
"os": "Darwin arm64",
"started_at": "<current UTC ISO timestamp>"
}
Collect git_remote / git_branch / os via short shell calls (git remote get-url origin, git branch --show-current, uname -s -m). model_id comes from your system prompt; user_name from whoami if unknown; started_at is the current UTC time. Do not walk the process tree to guess the agent name — the MCP handshake tells the server which client is connected.
Credential Handling (API Service Nodes)
If the advance response includes a credentials field, the node requires external API integration.
Execution Steps
1. Fetch and Select Workflow
Call list_workflows to retrieve the list.
No workflows exist: Ask via AskUserQuestion:
- header: "No workflows"
- "No workflows found. Would you like to create one now?"
- options: "Create new workflow" / "Cancel"
If "Create new workflow" → immediately invoke the bk-create skill. Pass the user's original argument (if any) as the goal so bk-create can pre-fill the design step. After bk-create completes and the workflow is registered, return here and proceed with Step 2 using the newly created workflow.
Single workflow: Skip the selection UI, just confirm:
- "Start the '{title}' workflow?" (AskUserQuestion: "Start" / "Cancel")
Multiple workflows: Show selection via AskUserQuestion.
If the user selects "Create new workflow" from the selection UI → invoke bk-create, then continue as above.
2. Create Task + Open Monitoring Page
Call start_workflow. Pass any argument as context.
Derive a short title (≤60 chars) from the user's goal and pass it alongside context. If the argument is already short, use it; otherwise distill it to a noun phrase (e.g. "Hermes AI 아티클 생성", not the full paragraph). The raw prompt becomes context; only the short label goes into title.
After start_workflow returns the task_id, open the monitoring page in the user's browser (open "${WEBUI_URL}/tasks/${TASK_ID}" on macOS, xdg-open on Linux — WEBUI_URL is the webui_url field in the response).
3. Execute First Step + Auto-Advance Loop
Read the first step's instruction as an internal directive and execute immediately.
After execution, save with execute_step, then check the response for next_action before calling advance.
Show roadmap at start (#20):
Starting: {workflow title} ({n} steps)
━━━━━━━━━━━━━━━━━━━━━━━━━
**1** → 2 → 3 → 4 → 5 → 6 → 7
━━━━━━━━━━━━━━━━━━━━━━━━━
📺 Live: ${WEBUI_URL}/tasks/${TASK_ID}
━━━━━━━━━━━━━━━━━━━━━━━━━
Auto-advance loop: if execute_step returns no next_action, proceed to the next step automatically. Show a brief inline update (✅ [{title}] done → continuing to next step…). Repeat until a gate step or hitl=true action step is reached — do not pause to ask the user to type /bk-next.
4. When Pausing
Check the next_action field in the execute_step response and handle accordingly:
HITL (next_action: "wait_for_human_approval")
Call request_approval, then immediately show the HITL approval AskUserQuestion (inline HITL approval). Do NOT stop and tell the user to type /bk-approve.
Gate step (no next_action, node_type=gate)
Write VS content text (titles, descriptions, option labels) in the user's language. The frame UI (Submit button, status) is auto-localized; only agent-authored content needs matching locale.
If
visual_selection: true:Compose a VS content fragment (inner HTML only — no
<html>/<head>/<body>, the frame is injected automatically). Component classes:bk-options,bk-cards,bk-checklist,bk-code-compare(selection);bk-slider,bk-input,bk-textarea,bk-ranking,bk-matrix(input);bk-split,bk-pros-cons,bk-mockup,bk-timeline(display).Required attributes (server validates these):
- Selection items (
.bk-option,.bk-card,.bk-check-item,.bk-code-option):data-value="<id>"on each item. Optionaldata-recommendedon the suggested choice. - Input components:
data-name="<id>"for keying the response.bk-slideralso needsdata-min,data-max,data-value, optionaldata-unit.bk-input/bk-textareaacceptdata-label,data-placeholder, optionaldata-requiredanddata-response-key="comment"(stores into top-levelcomment). - Per-item memo: add
data-requires-commentto force a memo before submit. Optionaldata-comment-name="<key>"stores it intoresponse.fields[<key>]. - Optional first line:
<!-- @bk size=sm|md|lg|xl|full -->(defaultsm).
Full catalog with template patterns and per-component examples: see
bk-create § VS Component Selection Guide.Minimal example:
<h2>Choose an approach</h2> <div class="bk-options"> <div class="bk-option" data-value="monolith" data-recommended> <div class="bk-option-letter">A</div> <div class="bk-option-body"> <h3>Monolith</h3> <p>Simple deployment</p> </div> </div> <div class="bk-option" data-value="microservices"> <div class="bk-option-letter">B</div> <div class="bk-option-body"> <h3>Microservices</h3> <p>Independent scaling</p> </div> </div> </div>- Selection items (
Call
set_visual_html(task_id, node_id, html)with the fragment.Open the VS deep link so the user sees the selection UI immediately:
open "${WEBUI_URL}/tasks/${TASK_ID}?step=${STEP_ORDER}&vs=true"Poll
get_web_response(task_id)every 3-5 seconds until a response arrives (max 120 seconds).The response is a JSON object (not a plain string). Parse it to read the user's choices and feedback:
{ "selections": ["monolith"], "values": { "budget": 70 }, "ranking": ["security", "ux"], "comment": "Keep this direction but tighten rollout scope", "fields": { "change_request": "Add a rollback plan" }, "option_comments": { "monolith": "Prefer this if we can phase deployment" } }selections: chosen option values (from bk-options, bk-cards, bk-checklist, bk-code-compare)values: numeric inputs (from bk-slider, keyed by data-name)ranking: ordered list (from bk-ranking)matrix: placement coordinates (from bk-matrix)comment: free-form global memo from bk-textarea/bk-input withdata-response-key="comment"(ordata-name="comment")fields: named text inputs from bk-input / bk-textarea, plus any option-level memo stored viadata-comment-nameoption_comments: per-option free-text notes attached to selected choices Only populated fields appear.
When forming the gate answer, never ignore free-text feedback:
- If
commentexists, summarize it in the gate output. - If
fields.change_requestor similar named fields exist, treat them as authoritative revision instructions. - If
option_commentsexists, preserve the mapping between the selected option and its note. - A response like "select B + add changes" must not be collapsed into just
"selections": ["b"].
- If
Use the parsed response to form the gate answer and call
advance.
If
visual_selection: false→ present the gate question to the user via AskUserQuestion. Use the response as gate answer, callexecute_stepwith the answer, thenadvance.
Attachments
Loop (next_action: "loop_back")
Execution flow:
- Read the instruction and execute one iteration (e.g., ask one clarifying question).
- Present the result/question to the user via AskUserQuestion.
- Based on user response, decide: is the termination condition met?
- NOT met → call
execute_step(loop_continue=true)→ server creates a new pending log on the same node → re-execute the loop step (go back to step 1) - Met → call
execute_step(loop_continue=false)→ loop ends → calladvanceto move to next step
- NOT met → call
Example — "Clarifying Questions" loop (loop_back_to=self):
Iteration 1: "Who is the primary user of this feature?" → user answers → purpose clear, constraints unclear → loop_continue=true
Iteration 2: "Are there tech stack limitations?" → user answers → constraints clear, success criteria unclear → loop_continue=true
Iteration 3: "What defines completion?" → user answers → all items clear → loop_continue=false → advance
Example — "Design Section Presentation" loop:
Iteration 1: Present architecture section → user "looks good" → more sections remain → loop_continue=true
Iteration 2: Present data flow section → user "needs revision" → revise and re-present → loop_continue=true
Iteration 3: Present final section → user approves → all sections done → loop_continue=false → advance
Loop + VS History Pattern
When a loop node uses visual_selection: true, each iteration presents a VS screen and collects a response. Use get_web_response(task_id, node_id) to access all previous iteration responses for that node:
{
"task_id": 19,
"node_id": 109,
"history": [
{
"iteration": 1,
"web_response": { "selections": ["a"] },
"created_at": "..."
},
{
"iteration": 2,
"web_response": {
"selections": ["b"],
"values": { "confidence": 80 },
"fields": { "change_request": "Need more detail on error handling" }
},
"created_at": "..."
}
]
}
Use the history to adapt subsequent VS screens - for example, pre-selecting the user's previous choice, adjusting slider defaults based on past values, carrying forward fields.change_request into the next revision prompt, or skipping already-confirmed items.
Web UI State Synchronization (웹 UI 상태 동기화)
1. Task cancelled — cancelled: true
Triggered by: heartbeat response OR advance(peek=true) returning status: "cancelled"
Action:
- Stop all execution immediately. Make no further MCP calls.
- Notify the user:
⚠️ 태스크가 웹 UI에서 중지되었습니다. Task #{id} — Step {N}에서 사용자에 의해 중단되었습니다. 다시 시작하려면 /bk-start를 실행하세요. - Do NOT call
complete_task,execute_step, oradvance.
2. Step rewound — rewound: true or error code STEP_REWOUND
Triggered by:
heartbeatresponse containsrewound: true(web UI rewound while step was running)execute_stepreturns HTTP 409 witherror_code: "STEP_REWOUND"(tried to save a cancelled step)
Action:
- Stop executing the current step immediately.
- Call
advance(task_id, peek=true)to get the new current step. - Notify the user briefly:
🔄 웹 UI에서 되감기가 실행되었습니다. Step {new_step}부터 재개합니다. - Re-execute from the new current step as if it was just assigned.
- The new step's
log_statuswill be"pending"— treat it normally.
3. Step log cancelled but task still running — log_status: "cancelled" + status: "running"
Triggered by: advance(peek=true) at the start of a step loop
This means the step was reset by a rewind. Action:
- Re-execute this step from scratch. Do not skip it.
- Do not treat this as a terminal error.
Polling cadence
- Call
heartbeatat least every 30 seconds during long-running steps. - Always check the response — never fire-and-forget heartbeats.
- At the start of each new step (before executing), verify
advance(peek=true)reflects the expected step. Ifcurrent_stepdiffers from what you expected, follow the server's value.
Graceful Interruption
Trigger phrases: stop, pause, cancel, abort, hold on, 잠깐, 중단, 그만, 멈춰, 정지, Ctrl+C. Treat any of these mid-workflow as a request to interrupt — do not silently abort, follow this prompt.
When the user explicitly asks to stop mid-workflow, ask how to handle it:
- Pause (resume later) — save a brief
context_snapshotviaexecute_stepso state is preserved, leave task asrunning. The server will auto-timed_outafter 2 hours;/bk-startcan resume it. - Cancel — call
cancel_task(task_id, reason). Task is markedcancelled; no furtherexecute_step/advancecalls. - Keep going — dismiss the prompt and continue the current step.
Skip this prompt if all steps are already complete and you're about to call complete_task anyway — the workflow is finishing naturally, not being interrupted.
Feedback Survey (before calling complete_task)
When the workflow finishes, run the feedback survey flow.
Follow the sequence: save_feedback → complete_task → suggest improvements.