bluekiwi 0.3.19 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,7 @@ export const BUNDLED_SKILLS = [
12
12
  "bk-instruction",
13
13
  "bk-credential",
14
14
  "bk-design",
15
+ "bk-import",
15
16
  "bk-improve",
16
17
  "bk-report",
17
18
  "bk-scan",
@@ -58,14 +58,14 @@ Ask via AskUserQuestion:
58
58
 
59
59
  ### Step 4: Design Workflow Structure
60
60
 
61
- Analyze the goal and design the nodes.
61
+ Analyze the goal and design the nodes. **Every node instruction must satisfy the Instruction Depth Standard below before proceeding to Step 5.**
62
62
 
63
63
  **Node structure example:**
64
64
 
65
65
  ```json
66
66
  {
67
67
  "title": "Clarify Goal",
68
- "instruction": "Analyze the user's stated goal and extract the 3 most important clarifying questions.",
68
+ "instruction": "## Goal Clarification\n\nExtract precise requirements before any work begins:\n\n1. Read the user's stated goal word by word and list every ambiguity.\n2. For each ambiguity, formulate one closed-ended question (yes/no or multiple choice).\n3. Ask the questions one at a time — never batch them.\n\n**Output**: A numbered list of confirmed constraints and success criteria.\n**Verification**: Every ambiguity is resolved; no open questions remain.",
69
69
  "node_type": "action",
70
70
  "hitl": false,
71
71
  "order": 1
@@ -184,6 +184,75 @@ Type `/bk-run` to execute it now.
184
184
  - Use `visual_selection: true` on `gate` nodes when the selection is best expressed visually — e.g., choosing a layout, picking a chart type, selecting a UI template. The agent must call `set_visual_html` with interactive HTML before executing the step; the user's click supplies the response.
185
185
  - For nodes requiring external API calls, specify `credential_id`. Create credentials first with `/bk-credential`.
186
186
 
187
+ ## Instruction Depth Standard
188
+
189
+ <HARD-RULE>
190
+ Before calling `create_workflow`, verify every node instruction satisfies ALL of the following:
191
+
192
+ 1. **Role/context** (first line or heading): who or what performs this step — e.g., "## Market Analyst", "You are acting as a senior code reviewer"
193
+ 2. **Numbered sub-steps**: at minimum 2 explicit steps describing HOW to perform the action, not just WHAT to produce
194
+ 3. **Output specification**: exactly what is produced — file path + format, structured data shape, or required fields
195
+ 4. **Verification**: one line stating how to confirm the step succeeded
196
+ 5. **Loop nodes only**: termination condition as the final line — "Termination: end when X"
197
+
198
+ **Minimum instruction length: 80 words.** If an instruction is shorter, it is not specific enough — expand it.
199
+ </HARD-RULE>
200
+
201
+ ### Anti-patterns → Prescriptive Rewrites
202
+
203
+ | ❌ Vague — do not write | ✅ Prescriptive — write this instead |
204
+ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
205
+ | "Analyze the data." | "Read the CSV at `data/input.csv`. Compute row count, null counts per column, and value distributions for numeric columns. Output a summary table to `data/eda-summary.md`." |
206
+ | "Review the results." | "Check each output against the success criteria from Step 1. Build a pass/fail table with one evidence line per criterion. Flag any criterion below threshold in red." |
207
+ | "Ask the user what to do." | "Present exactly 3 options via bk-options (sm): A) proceed as-is, B) revise the output, C) abort. Include a one-sentence consequence for each option." |
208
+ | "Generate a report." | "Create `docs/report-YYYY-MM-DD.md` with sections: Executive Summary (3 bullets), Findings (numbered, each with evidence), Recommendations (priority-ordered), Next Steps (owner + deadline)." |
209
+ | "Search the web." | "Run a web search for each of the 3 queries listed. For each result, record: source URL, publication date, key claim (1 sentence). Discard results older than 12 months." |
210
+
211
+ ### Instruction Templates by Node Type
212
+
213
+ **action — data / research step:**
214
+
215
+ ```
216
+ ## <Expert Role>
217
+
218
+ <One sentence: what this step accomplishes and why it matters here.>
219
+
220
+ 1. <First concrete action — tool call, file read, calculation>
221
+ 2. <Second concrete action — transformation, filtering, aggregation>
222
+ 3. <Third action if needed>
223
+
224
+ **Output**: <Exact file path or data structure>
225
+ **Verification**: <Command or check that confirms success>
226
+ ```
227
+
228
+ **gate — user decision:**
229
+
230
+ ```
231
+ <Brief context: what was just produced and what the user must decide.>
232
+
233
+ Present options using bk-options (size=sm):
234
+ - A) <Option> — <one-sentence consequence>
235
+ - B) <Option> — <one-sentence consequence>
236
+ - C) <Option> — <one-sentence consequence>
237
+
238
+ Mark the recommended option with `data-recommended`.
239
+ ```
240
+
241
+ **loop — iterative interaction:**
242
+
243
+ ```
244
+ ## <Role>
245
+
246
+ <What is being iterated and why iteration is needed.>
247
+
248
+ Each iteration:
249
+ 1. <What to present or ask>
250
+ 2. <How to process the response>
251
+ 3. <How to update state>
252
+
253
+ **Termination**: End when <specific, measurable condition>.
254
+ ```
255
+
187
256
  #### VS Component Selection Guide
188
257
 
189
258
  When designing a `visual_selection: true` gate node, specify which `bk-*` components the agent should use in the node instruction. This keeps VS screens consistent and prevents vague "make a selection UI" instructions.
@@ -1,48 +1,66 @@
1
1
  ---
2
2
  name: bk-help
3
- description: BlueKiwi help skill. Shows a formatted list of all available bk-* commands with descriptions and usage. Use when the user says "/bk-help", "bk help", "what bk commands are there", or asks about BlueKiwi commands.
3
+ description: BlueKiwi help skill. Shows a formatted list of all available bk-* commands with descriptions and usage examples. Use when the user says "/bk-help", "bk help", "what bk commands are there", or asks about BlueKiwi commands.
4
4
  user_invocable: true
5
5
  ---
6
6
 
7
7
  # BlueKiwi Help
8
8
 
9
- Output the following help text **exactly as formatted** (use markdown code-free output — render it as readable text, not a code block).
9
+ Detect the user's language and output the matching section below **exactly as formatted** (render as readable text, not a code block).
10
+
11
+ **Language detection — check in this order, use the first signal found:**
12
+
13
+ 1. **Conversation language**: the language the user wrote the current message in
14
+ 2. **System locale**: run `echo $LANG` or `locale` in shell — use the language portion (e.g. `ko` from `ko_KR.UTF-8`, `en` from `en_US.UTF-8`)
15
+ 3. **OS language**: check `defaults read -g AppleLanguages 2>/dev/null` (macOS) or `/etc/locale.conf` (Linux)
16
+ 4. **Fallback**: English
17
+
18
+ Map detected language to output:
19
+
20
+ - `ko` / `ko_KR` → **Korean** section
21
+ - Anything else → **English** section
10
22
 
11
23
  ---
12
24
 
25
+ ## Korean output
26
+
13
27
  ## BlueKiwi 명령어 도움말
14
28
 
15
29
  ### 실행
16
30
 
17
- | 명령어 | 설명 |
18
- | -------------------------------- | --------------------------------------------------- |
19
- | `/bk-start` | 워크플로 선택 후 즉시 실행. 미완료 태스크 복구 포함 |
20
- | `/bk-start <이름>` | 이름으로 워크플로 매칭 후 바로 실행 |
21
- | `/bk-start <ID>` | 워크플로 ID로 바로 실행 (숫자) |
22
- | `/bk-start #<태스크ID>` | 특정 태스크 직접 재개 |
23
- | `/bk-start <이름> :: <프롬프트>` | 워크플로 지정 + 초기 컨텍스트 전달 |
24
- | `/bk-next` | 실행 중인 태스크를 찾아 현재 스텝부터 재개 |
25
- | `/bk-approve` | 대기 중인 HITL 승인 처리 |
26
- | `/bk-rewind` | 이전 스텝으로 되돌리기 |
31
+ | 명령어 | 설명 | 사용 예시 |
32
+ | -------------------------------- | --------------------------------------------------- | --------------------------------------- |
33
+ | `/bk-start` | 워크플로 선택 후 즉시 실행. 미완료 태스크 복구 포함 | `/bk-start` |
34
+ | `/bk-start <이름>` | 이름으로 워크플로 매칭 후 바로 실행 | `/bk-start 시장조사` |
35
+ | `/bk-start <ID>` | 워크플로 ID로 바로 실행 (숫자) | `/bk-start 42` |
36
+ | `/bk-start #<태스크ID>` | 특정 태스크 직접 재개 | `/bk-start #108` |
37
+ | `/bk-start <이름> :: <프롬프트>` | 워크플로 지정 + 초기 컨텍스트 전달 | `/bk-start 코드리뷰 :: PR #77 리뷰해줘` |
38
+ | `/bk-next` | 실행 중인 태스크를 찾아 현재 스텝부터 재개 | `/bk-next` |
39
+ | `/bk-approve` | 대기 중인 HITL 승인 처리 | `/bk-approve` |
40
+ | `/bk-rewind` | 이전 스텝으로 되돌리기 | `/bk-rewind` |
27
41
 
28
42
  ### 설계 / 관리
29
43
 
30
- | 명령어 | 설명 |
31
- | ----------------- | ------------------------------------------ |
32
- | `/bk-design` | 자연어 목표로 새 워크플로 설계 및 등록 |
33
- | `/bk-improve` | 기존 워크플로 분석 개선 버전 생성 |
34
- | `/bk-version` | 버전 목록 조회, 활성화/비활성화, 버전 비교 |
35
- | `/bk-instruction` | 에이전트 인스트럭션 템플릿 생성·수정·삭제 |
36
- | `/bk-credential` | 외부 서비스 API 등록·수정·삭제 |
44
+ | 명령어 | 설명 | 사용 예시 |
45
+ | ----------------- | ------------------------------------------------- | ------------------------------------------------- |
46
+ | `/bk-design` | 자연어 목표로 새 워크플로 설계 및 등록 | `/bk-design 경쟁사 분석 워크플로 만들어줘` |
47
+ | `/bk-import` | GitHub / 로컬 스킬 / URL을 분석해 워크플로로 변환 | `/bk-import yamadashy/repomix` |
48
+ | | | `/bk-import bk-design` |
49
+ | | | `/bk-import https://example.com/runbook` |
50
+ | | | `/bk-import` (대화형 텍스트·JSON 붙여넣기 포함) |
51
+ | `/bk-improve` | 기존 워크플로 분석 후 개선 버전 생성 | `/bk-improve 시장조사` |
52
+ | `/bk-version` | 버전 목록 조회, 활성화/비활성화, 버전 비교 | `/bk-version` |
53
+ | `/bk-instruction` | 에이전트 인스트럭션 템플릿 생성·수정·삭제 | `/bk-instruction` |
54
+ | `/bk-credential` | 외부 서비스 API 키 등록·수정·삭제 | `/bk-credential` |
37
55
 
38
56
  ### 조회 / 공유
39
57
 
40
- | 명령어 | 설명 |
41
- | ------------ | ---------------------------------- |
42
- | `/bk-status` | 실행 중·완료된 태스크 현황 조회 |
43
- | `/bk-report` | 태스크 결과 구조화 리포트 생성 |
44
- | `/bk-share` | 워크플로·폴더를 그룹에 공유 |
45
- | `/bk-scan` | 로컬 저장소 보안·컴플라이언스 스캔 |
58
+ | 명령어 | 설명 | 사용 예시 |
59
+ | ------------ | ---------------------------------- | ------------------------------- |
60
+ | `/bk-status` | 실행 중·완료된 태스크 현황 조회 | `/bk-status` |
61
+ | `/bk-report` | 태스크 결과 구조화 리포트 생성 | `/bk-report` |
62
+ | `/bk-share` | 워크플로·폴더를 그룹에 공유 | `/bk-share 시장조사 → 마케팅팀` |
63
+ | `/bk-scan` | 로컬 저장소 보안·컴플라이언스 스캔 | `/bk-scan` |
46
64
 
47
65
  ---
48
66
 
@@ -51,3 +69,53 @@ Output the following help text **exactly as formatted** (use markdown code-free
51
69
  - `/bk-start`는 `/bk-run`의 상위 호환입니다 — 두 명령어 모두 동작합니다.
52
70
  - 태스크 재개가 필요하면 `/bk-start` (인자 없음) 또는 `/bk-start #<태스크ID>`를 사용하세요.
53
71
  - 도움말은 언제든 `/bk-help`로 다시 볼 수 있습니다.
72
+
73
+ ---
74
+
75
+ ## English output
76
+
77
+ ## BlueKiwi Command Reference
78
+
79
+ ### Execution
80
+
81
+ | Command | Description | Example |
82
+ | ------------------------------ | ------------------------------------------------------ | ---------------------------------------- |
83
+ | `/bk-start` | Pick a workflow and run it. Recovers incomplete tasks. | `/bk-start` |
84
+ | `/bk-start <name>` | Match workflow by name and run immediately | `/bk-start market-research` |
85
+ | `/bk-start <ID>` | Run workflow by numeric ID | `/bk-start 42` |
86
+ | `/bk-start #<taskID>` | Resume a specific task directly | `/bk-start #108` |
87
+ | `/bk-start <name> :: <prompt>` | Specify workflow + pass initial context | `/bk-start code-review :: review PR #77` |
88
+ | `/bk-next` | Find the active task and resume from the current step | `/bk-next` |
89
+ | `/bk-approve` | Process a pending HITL approval | `/bk-approve` |
90
+ | `/bk-rewind` | Roll back to the previous step | `/bk-rewind` |
91
+
92
+ ### Design / Management
93
+
94
+ | Command | Description | Example |
95
+ | ----------------- | ------------------------------------------------------------------- | ----------------------------------------------------- |
96
+ | `/bk-design` | Design and register a new workflow from a natural language goal | `/bk-design build a competitor analysis workflow` |
97
+ | `/bk-import` | Analyze a GitHub repo / local skill / URL and convert to a workflow | `/bk-import yamadashy/repomix` |
98
+ | | | `/bk-import bk-design` |
99
+ | | | `/bk-import https://example.com/runbook` |
100
+ | | | `/bk-import` (interactive — includes text/JSON paste) |
101
+ | `/bk-improve` | Analyze an existing workflow and generate an improved version | `/bk-improve market-research` |
102
+ | `/bk-version` | List versions, activate/deactivate, compare versions | `/bk-version` |
103
+ | `/bk-instruction` | Create, edit, or delete agent instruction templates | `/bk-instruction` |
104
+ | `/bk-credential` | Register, edit, or delete external service API keys | `/bk-credential` |
105
+
106
+ ### Monitoring / Sharing
107
+
108
+ | Command | Description | Example |
109
+ | ------------ | -------------------------------------------------- | -------------------------------------------- |
110
+ | `/bk-status` | View running and completed task status | `/bk-status` |
111
+ | `/bk-report` | Generate a structured report from task results | `/bk-report` |
112
+ | `/bk-share` | Share a workflow or folder with a group | `/bk-share market-research → marketing-team` |
113
+ | `/bk-scan` | Run a security and compliance scan on a local repo | `/bk-scan` |
114
+
115
+ ---
116
+
117
+ **Tips:**
118
+
119
+ - `/bk-start` is a superset of `/bk-run` — both commands work.
120
+ - To resume a task, use `/bk-start` (no args) or `/bk-start #<taskID>`.
121
+ - Run `/bk-help` anytime to see this reference again.
@@ -0,0 +1,224 @@
1
+ ---
2
+ name: bk-import
3
+ description: Analyzes an external resource (GitHub repo, local skill, URL, or text) and converts it into a BlueKiwi workflow registered directly on the server. Triggers when the user says "/bk-import", "import from github", "convert this skill to workflow", "create workflow from repo/url/skill", or pastes content they want turned into a workflow.
4
+ user_invocable: true
5
+ ---
6
+
7
+ # bk-import — External Resource to BlueKiwi Workflow
8
+
9
+ Analyze an external resource, extract its process logic, convert it into a structured BlueKiwi workflow, and register it directly via MCP.
10
+
11
+ ## Argument Handling
12
+
13
+ - `/bk-import` → Ask for the resource via AskUserQuestion.
14
+ - `/bk-import <resource>` → Start analysis from the provided resource.
15
+
16
+ ## Step 1: Parse Input
17
+
18
+ Determine the resource type from the argument:
19
+
20
+ | Type | Detection rule | Analysis method |
21
+ | ------------ | ------------------------------------------------ | ------------------------- |
22
+ | GitHub repo | `https://github.com/…` or `owner/repo` pattern | repomix `--remote` |
23
+ | Local skill | Matches `bk-*` name or `~/.claude/skills/…` path | Read `SKILL.md` + scripts |
24
+ | Local path | Starts with `/`, `./`, or `~/` | Read files directly |
25
+ | External URL | `http://` or `https://` (non-GitHub) | WebFetch |
26
+ | Text/JSON | Anything else | Direct parse |
27
+
28
+ If no argument, ask via AskUserQuestion:
29
+
30
+ - header: "Import from where?"
31
+ - "Which resource do you want to convert into a BlueKiwi workflow?"
32
+ - options: ["GitHub repo URL or owner/repo", "Local skill (e.g. bk-run)", "External URL", "Paste text or JSON"]
33
+
34
+ ## Step 2: Fetch & Analyze Content
35
+
36
+ ### GitHub Repository
37
+
38
+ ```bash
39
+ npx repomix@latest --remote <owner/repo> --compress --output /tmp/bk-import-<repo-name>.xml
40
+ ```
41
+
42
+ After packing, extract in order:
43
+
44
+ 1. File tree → identify architecture layers (API, UI, scripts, config)
45
+ 2. README.md → purpose, key steps, usage examples
46
+ 3. Main entry points (index, main, app) → sequential process logic
47
+ 4. Configuration files → decision points and branching options
48
+
49
+ Clean up when done: `rm /tmp/bk-import-<repo-name>.xml`
50
+
51
+ **If the repo URL points to a subdirectory** (e.g., `…/tree/main/packages/cli`), run repomix on the full repo then focus grep analysis on that path.
52
+
53
+ ### Local Skill
54
+
55
+ Resolve path:
56
+
57
+ - Bare name (e.g. `bk-run`) → `~/.claude/skills/bk-run/SKILL.md`
58
+ - Full path → read directly
59
+
60
+ Read `SKILL.md` completely. Also read any files under `scripts/` if present.
61
+
62
+ Extract:
63
+
64
+ - Numbered or headed execution steps → sequential actions
65
+ - Options/choices presented to the user → decision points
66
+ - "Repeat until" or loop patterns → iterative steps
67
+
68
+ ### External URL
69
+
70
+ ```
71
+ WebFetch <url>
72
+ ```
73
+
74
+ Extract the main process described: step sequences, decision criteria, iterative patterns.
75
+
76
+ ### Text / JSON Paste
77
+
78
+ If JSON: detect format (n8n workflow, GitHub Actions, etc.) and parse its nodes/steps/jobs structure.
79
+
80
+ If plain text: extract numbered or headed steps, conditionals, and loops.
81
+
82
+ ## Step 3: Extract Workflow Logic
83
+
84
+ From the analyzed content, identify and label each element:
85
+
86
+ **Sequential execution → `action` node candidates**
87
+
88
+ - "Do X, then Y" patterns
89
+ - Script / CLI execution steps
90
+ - Data fetching or transformation steps
91
+ - API calls, file generation, report writing
92
+
93
+ **Decision points → `gate` node candidates**
94
+
95
+ - User approval required before continuing
96
+ - "Choose between A or B" patterns
97
+ - Final review before an irreversible action
98
+
99
+ **Iterative patterns → `loop` node candidates**
100
+
101
+ - "Repeat until condition met"
102
+ - Q&A / clarification loops (ask one question, get answer, repeat)
103
+ - Review → feedback → revise cycles
104
+
105
+ **Human sign-off for risky actions → `hitl: true` on action nodes**
106
+
107
+ - Sending emails or external messages
108
+ - Deploying to production
109
+ - Deleting or overwriting data
110
+
111
+ ## Step 4: Design Nodes
112
+
113
+ Convert the extracted logic into BlueKiwi nodes. Apply the **Instruction Depth Standard** (same rules as bk-design) to every node:
114
+
115
+ <HARD-RULE>
116
+ Every node instruction must include ALL of the following:
117
+
118
+ 1. **Role/context** (1 line): who or what performs this step
119
+ 2. **Numbered sub-steps**: at least 2 explicit steps describing HOW — not just WHAT
120
+ 3. **Output specification**: exactly what is produced (file path, format, structure)
121
+ 4. **Verification**: how to confirm the step succeeded
122
+ 5. **Loop nodes only**: explicit termination condition on the last line
123
+
124
+ Minimum instruction length: 80 words. One-sentence summaries are rejected.
125
+ </HARD-RULE>
126
+
127
+ **Anti-patterns to avoid when writing instructions:**
128
+
129
+ | ❌ Do not write | ✅ Write instead |
130
+ | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
131
+ | "Analyze the repository." | "Read README.md and list top-level directories. For each dir, identify its role. Output a bullet-point component map covering tech stack, architecture pattern, and entry points." |
132
+ | "Review the results." | "Check output against the success criteria from Step 1. Present a pass/fail table with specific evidence per criterion. Flag any item below threshold." |
133
+ | "Ask the user." | "Present exactly 3 options via bk-options (sm): A) proceed, B) revise, C) cancel. Include a one-sentence consequence for each." |
134
+
135
+ **Node count target:** 4–8 nodes. If the source describes more than 10 distinct steps, group related micro-steps into single nodes.
136
+
137
+ ## Step 5: Present Proposed Structure
138
+
139
+ Display the proposed workflow to the user:
140
+
141
+ ```
142
+ 📦 Importing: <resource name>
143
+
144
+ Proposed workflow: <title>
145
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
146
+ 1. [Step Name] action
147
+ 2. [Step Name] gate ← user approval
148
+ 3. [Step Name] loop ↩ repeats until X
149
+ 4. [Step Name] action 🔒 hitl
150
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
151
+ <N> steps · source: <resource>
152
+ ```
153
+
154
+ Ask via AskUserQuestion:
155
+
156
+ - header: "Confirm import"
157
+ - "Create this workflow from <resource>?"
158
+ - options: ["Create", "Edit node structure", "Cancel"]
159
+
160
+ If "Edit" → accept modification input, redesign affected nodes, and re-present.
161
+
162
+ ## Step 6: Select Folder
163
+
164
+ Call `list_folders`. Ask via AskUserQuestion:
165
+
166
+ - header: "Save location"
167
+ - "Which folder should this workflow be saved in?"
168
+ - options: folder name list (up to 4) + "My Workspace (default)"
169
+
170
+ ## Step 7: Register via MCP
171
+
172
+ Call `create_workflow`:
173
+
174
+ ```json
175
+ {
176
+ "title": "<derived title — concise, action-oriented>",
177
+ "description": "<1–2 sentences: what this workflow does and when to use it>",
178
+ "version": "1.0",
179
+ "folder_id": <selected folder id>,
180
+ "nodes": [
181
+ {
182
+ "step_order": 1,
183
+ "node_type": "action",
184
+ "title": "...",
185
+ "instruction": "...",
186
+ "hitl": false,
187
+ "loop_back_to": null,
188
+ "visual_selection": false
189
+ }
190
+ ]
191
+ }
192
+ ```
193
+
194
+ ## Step 8: Report Result + Open in Browser
195
+
196
+ On success:
197
+
198
+ ```bash
199
+ open "${WEBUI_URL}/workflows/${WORKFLOW_ID}"
200
+ ```
201
+
202
+ `WEBUI_URL` = the `webui_url` field returned by `create_workflow`.
203
+
204
+ Display:
205
+
206
+ ```
207
+ ✅ Workflow imported
208
+ Name: <title> (ID: <id>)
209
+ Source: <resource>
210
+ Steps: <n>
211
+ 🔗 ${WEBUI_URL}/workflows/${WORKFLOW_ID}
212
+
213
+ Type /bk-run to execute it now.
214
+ ```
215
+
216
+ ## Node Type Quick Reference
217
+
218
+ | Type | Behavior | When to use |
219
+ | ---------------------------------- | -------------------------------------------- | ---------------------------------------------- |
220
+ | `action` | Auto-advances | Execution, data work, generation |
221
+ | `gate` | Pauses for user input | Approval, direction choice, review |
222
+ | `loop` | Repeats until termination condition | Q&A, iterative refinement, section review |
223
+ | `hitl: true` on `action` | Pauses after execution for explicit sign-off | Irreversible or security-sensitive actions |
224
+ | `visual_selection: true` on `gate` | Agent renders HTML; user clicks to choose | Visual A/B choices, layout picks, option cards |
@@ -5,8 +5,17 @@ import { createEmptyConfig, loadConfig, normalizeProfileName, saveConfig, upsert
5
5
  import { applyProfileToRuntimes } from "../runtime-sync.js";
6
6
  import { detectInstalledAdapters, getAllAdapters } from "../runtimes/detect.js";
7
7
  export async function acceptCommand(token, opts) {
8
- const profileName = normalizeProfileName(opts.profile);
8
+ let profileName = normalizeProfileName(opts.profile);
9
9
  const currentConfig = loadConfig() ?? createEmptyConfig();
10
+ if (process.stdin.isTTY && opts.profile === undefined) {
11
+ const profileAnswer = await prompts({
12
+ type: "text",
13
+ name: "profile",
14
+ message: "Profile name",
15
+ initial: profileName,
16
+ });
17
+ profileName = normalizeProfileName(profileAnswer.profile);
18
+ }
10
19
  console.log(pc.cyan("→ Validating invite..."));
11
20
  const validateRes = await fetch(`${opts.server}/api/invites/accept/${token}`);
12
21
  if (!validateRes.ok) {
@@ -37,30 +37,45 @@ function maskApiKey(key) {
37
37
  }
38
38
  export async function initCommand(options = {}) {
39
39
  const isNonInteractive = options.yes === true || process.stdin.isTTY !== true;
40
- const profileName = normalizeProfileName(options.profile);
40
+ let profileName = normalizeProfileName(options.profile);
41
41
  // Load existing config for pre-filling prompts
42
42
  const existingCfg = loadConfig() ?? createEmptyConfig();
43
- const existingProfile = getProfile(existingCfg, profileName);
43
+ let existingProfile = getProfile(existingCfg, profileName);
44
+ const activeProfile = getProfile(existingCfg, existingCfg.active_profile);
44
45
  let server = normalizeEnvValue(options.server) ??
45
46
  normalizeEnvValue(process.env.BLUEKIWI_API_URL) ??
46
47
  normalizeEnvValue(process.env.BLUEKIWI_SERVER);
47
48
  let apiKey = normalizeEnvValue(options.apiKey) ??
48
49
  normalizeEnvValue(process.env.BLUEKIWI_API_KEY);
49
- if (!isNonInteractive && (server === undefined || apiKey === undefined)) {
50
- const questions = [];
51
- if (server === undefined) {
52
- questions.push({
50
+ if (!isNonInteractive) {
51
+ if (options.profile === undefined) {
52
+ const profileAnswer = await prompts({
53
+ type: "text",
54
+ name: "profile",
55
+ message: "Profile name",
56
+ initial: profileName,
57
+ });
58
+ profileName = normalizeProfileName(profileAnswer.profile);
59
+ existingProfile = getProfile(existingCfg, profileName);
60
+ }
61
+ }
62
+ if (!isNonInteractive) {
63
+ if (options.server === undefined) {
64
+ const serverAnswer = await prompts({
53
65
  type: "text",
54
66
  name: "server",
55
67
  message: "BlueKiwi server URL",
56
- initial: existingProfile?.profile.server_url,
68
+ initial: existingProfile?.profile.server_url ??
69
+ activeProfile?.profile.server_url ??
70
+ server,
57
71
  });
72
+ server = normalizeEnvValue(serverAnswer.server) ?? server;
58
73
  }
59
74
  if (apiKey === undefined) {
60
75
  const maskedKey = existingProfile?.profile.api_key
61
76
  ? maskApiKey(existingProfile.profile.api_key)
62
77
  : undefined;
63
- questions.push({
78
+ const apiKeyAnswer = await prompts({
64
79
  type: "text",
65
80
  name: "apiKey",
66
81
  message: maskedKey
@@ -68,15 +83,7 @@ export async function initCommand(options = {}) {
68
83
  : "API key (bk_...)",
69
84
  initial: maskedKey,
70
85
  });
71
- }
72
- const answers = await prompts(questions);
73
- server ??= answers.server;
74
- // If user kept the masked key (just pressed Enter), restore original
75
- if (apiKey === undefined) {
76
- const entered = answers.apiKey;
77
- const maskedKey = existingProfile?.profile.api_key
78
- ? maskApiKey(existingProfile.profile.api_key)
79
- : undefined;
86
+ const entered = apiKeyAnswer.apiKey;
80
87
  if (entered && maskedKey && entered === maskedKey) {
81
88
  apiKey = existingProfile.profile.api_key;
82
89
  }
@@ -1,5 +1,5 @@
1
1
  import pc from "picocolors";
2
- import { clearConfig, loadConfig, removeProfile, saveConfig } from "../config.js";
2
+ import { clearConfig, loadConfig, removeProfile, saveConfig, } from "../config.js";
3
3
  import { getAllAdapters } from "../runtimes/detect.js";
4
4
  import { applyProfileToRuntimes } from "../runtime-sync.js";
5
5
  export async function logoutCommand(profileName) {
package/dist/config.js CHANGED
@@ -27,7 +27,9 @@ function normalizeProfileName(name) {
27
27
  }
28
28
  function isLegacyConfig(value) {
29
29
  const raw = value;
30
- return !!raw && typeof raw.server_url === "string" && typeof raw.api_key === "string";
30
+ return (!!raw &&
31
+ typeof raw.server_url === "string" &&
32
+ typeof raw.api_key === "string");
31
33
  }
32
34
  function normalizeProfile(name, raw) {
33
35
  if (!raw ||
package/dist/index.js CHANGED
@@ -24,41 +24,43 @@ const program = new Command();
24
24
  program
25
25
  .name("bluekiwi")
26
26
  .description("BlueKiwi CLI — connect your agent runtime to a BlueKiwi server")
27
- .version(pkg.version);
27
+ .helpOption("-h, --help", "display help for command")
28
+ .version(pkg.version, "-v, --version", "display version number");
28
29
  program
29
30
  .command("accept <token>")
30
- .requiredOption("--server <url>", "BlueKiwi server URL")
31
- .option("--profile <name>", "Profile name (default: default)")
32
- .option("--username <name>", "Username (non-interactive)")
33
- .option("--password <pass>", "Password (non-interactive)")
31
+ .requiredOption("-s, --server <url>", "BlueKiwi server URL")
32
+ .option("-p, --profile <name>", "Profile name (default: default)")
33
+ .option("-u, --username <name>", "Username (non-interactive)")
34
+ .option("-w, --password <pass>", "Password (non-interactive)")
34
35
  .action(acceptCommand);
35
36
  program
36
37
  .command("init")
37
- .option("--server <url>", "BlueKiwi server URL")
38
- .option("--api-key <key>", "API key (bk_...)")
39
- .option("--profile <name>", "Profile name (default: default)")
40
- .option("--runtime <name>", "Runtime to install into (repeatable, or comma-separated)", collectRuntimes, [])
41
- .option("--yes", "Suppress all prompts (non-interactive)")
38
+ .option("-s, --server <url>", "BlueKiwi server URL")
39
+ .option("-k, --api-key <key>", "API key (bk_...)")
40
+ .option("--apikey <key>", "Alias for --api-key")
41
+ .option("-p, --profile <name>", "Profile name (default: default)")
42
+ .option("-r, --runtime <name>", "Runtime to install into (repeatable, or comma-separated)", collectRuntimes, [])
43
+ .option("-y, --yes", "Suppress all prompts (non-interactive)")
42
44
  .action((opts) => initCommand({
43
45
  server: opts.server,
44
- apiKey: opts.apiKey,
46
+ apiKey: opts.apiKey ?? opts.apikey,
45
47
  runtimes: opts.runtime?.length ? opts.runtime : undefined,
46
48
  profile: opts.profile,
47
49
  yes: opts.yes,
48
50
  }));
49
51
  program
50
52
  .command("status")
51
- .option("--profile <name>", "Profile name (default: active profile)")
53
+ .option("-p, --profile <name>", "Profile name (default: active profile)")
52
54
  .action((opts) => statusCommand(opts.profile));
53
55
  program.command("upgrade").action(upgradeCommand);
54
56
  program
55
57
  .command("logout")
56
- .option("--profile <name>", "Remove only one profile")
58
+ .option("-p, --profile <name>", "Remove only one profile")
57
59
  .action((opts) => logoutCommand(opts.profile));
58
60
  program.command("runtimes").action(runtimesCommand.list);
59
61
  program
60
62
  .command("runtimes:add <name>")
61
- .option("--profile <name>", "Profile to install into runtimes and set active")
63
+ .option("-p, --profile <name>", "Profile to install into runtimes and set active")
62
64
  .action((name, opts) => runtimesCommand.add(name, opts.profile));
63
65
  program.command("runtimes:remove <name>").action(runtimesCommand.remove);
64
66
  program.command("profile").action(profileCommand.list);
@@ -66,6 +68,18 @@ program.command("profile:list").action(profileCommand.list);
66
68
  program.command("profile:use <name>").action(profileCommand.use);
67
69
  program.command("profile:remove <name>").action(profileCommand.remove);
68
70
  program.command("dev-link").action(devLinkCommand);
71
+ program.command("help [command]").action((command) => {
72
+ if (!command) {
73
+ program.outputHelp();
74
+ return;
75
+ }
76
+ const target = program.commands.find((cmd) => cmd.name() === command || cmd.aliases().includes(command));
77
+ if (!target) {
78
+ console.error(`Unknown command '${command}'`);
79
+ process.exit(1);
80
+ }
81
+ target.outputHelp();
82
+ });
69
83
  program.parseAsync(process.argv).catch((err) => {
70
84
  console.error(err.message);
71
85
  process.exit(1);
@@ -1,5 +1,5 @@
1
1
  import { BUNDLED_MCP_PATH, BUNDLED_SKILLS } from "./assets/index.js";
2
- import { requireProfile, } from "./config.js";
2
+ import { requireProfile } from "./config.js";
3
3
  import { getAllAdapters } from "./runtimes/detect.js";
4
4
  export function applyProfileToRuntimes(config, profileName, runtimeNames) {
5
5
  const { profile } = requireProfile(config, profileName);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bluekiwi",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "BlueKiwi CLI — install MCP client and skills into your agent runtime",
5
5
  "license": "MIT",
6
6
  "repository": {