claude-plugin-viban 1.0.26 → 1.0.28

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.
package/bin/viban CHANGED
@@ -584,13 +584,22 @@ _ESC=$'\e'
584
584
  pad_to_width() {
585
585
  local line="$1"
586
586
  local width="$2"
587
+ local precomputed_w="${3:-}"
587
588
  # Strip ANSI codes: ESC [ followed by numbers/semicolons, ending with letter
588
589
  local plain="${line//${_ESC}\[[0-9;]#[a-zA-Z]/}"
589
- # Calculate display width: char count + (bytes - chars) / 2 for CJK chars
590
- local char_count=${#plain} byte_count
591
- LC_ALL=C byte_count=${#plain}
592
- unset LC_ALL # Restore default locale to prevent affecting subsequent calls
593
- local display_w=$(( char_count + (byte_count - char_count) / 2 ))
590
+ local display_w
591
+ if [[ -n "$precomputed_w" ]]; then
592
+ display_w=$precomputed_w
593
+ else
594
+ local char_count=${#plain} byte_count
595
+ LC_ALL=C byte_count=${#plain}
596
+ unset LC_ALL
597
+ if [[ $byte_count -eq $char_count ]]; then
598
+ display_w=$char_count
599
+ else
600
+ display_w=$(( char_count + (byte_count - char_count) / 2 ))
601
+ fi
602
+ fi
594
603
  local pad=$((width - display_w))
595
604
  printf '%s' "$line"
596
605
  (( pad > 0 )) && printf "%${pad}s" ""
@@ -618,14 +627,63 @@ draw_board() {
618
627
  col2=("${(@f)$(build_column_lines "in_progress" $((col_sel == 1)) $c2 $max_h $col_w "$json_data")}")
619
628
  col3=("${(@f)$(build_column_lines "review" $((col_sel == 2)) $c3 $max_h $col_w "$json_data")}")
620
629
 
621
- # Merge line by line
622
- local i
630
+ # Batch compute display widths for all non-ASCII lines (single Python call)
631
+ # Build input: all lines from all 3 columns, ANSI-stripped
632
+ local -a all_plains
633
+ local -a all_widths
634
+ local _needs_python=0
635
+ local i _plain _cc _bc
636
+ for ((i=1; i<=max_h; i++)); do
637
+ for _col_line in "${col1[$i]}" "${col2[$i]}" "${col3[$i]}"; do
638
+ _plain="${_col_line//${_ESC}\[[0-9;]#[a-zA-Z]/}"
639
+ all_plains+=("$_plain")
640
+ _cc=${#_plain}
641
+ LC_ALL=C _bc=${#_plain}
642
+ unset LC_ALL
643
+ if [[ $_bc -eq $_cc ]]; then
644
+ all_widths+=($_cc)
645
+ else
646
+ all_widths+=(-1) # marker: needs Python
647
+ _needs_python=1
648
+ fi
649
+ done
650
+ done
651
+
652
+ if (( _needs_python )); then
653
+ # Single Python call to compute all non-ASCII widths
654
+ local _input="" _idx
655
+ for ((_idx=1; _idx<=${#all_plains[@]}; _idx++)); do
656
+ if [[ ${all_widths[$_idx]} -eq -1 ]]; then
657
+ _input+="${all_plains[$_idx]}"$'\n'
658
+ fi
659
+ done
660
+ local -a _py_results
661
+ _py_results=("${(@f)$(python3 -c "
662
+ import unicodedata,sys
663
+ for line in sys.stdin.read().rstrip('\n').split('\n'):
664
+ print(sum(2 if unicodedata.east_asian_width(c) in 'FW' else 1 for c in line))
665
+ " <<< "$_input")}")
666
+ # Map Python results back to width array
667
+ local _pi=1
668
+ for ((_idx=1; _idx<=${#all_widths[@]}; _idx++)); do
669
+ if [[ ${all_widths[$_idx]} -eq -1 ]]; then
670
+ all_widths[$_idx]=${_py_results[$_pi]}
671
+ ((_pi++))
672
+ fi
673
+ done
674
+ fi
675
+
676
+ # Merge line by line using precomputed widths
677
+ local _wi=1
623
678
  for ((i=1; i<=max_h; i++)); do
624
- pad_to_width "${col1[$i]}" $col_w
679
+ pad_to_width "${col1[$i]}" $col_w "${all_widths[$_wi]}"
680
+ ((_wi++))
625
681
  printf "${A_DIM}│${A_RESET}"
626
- pad_to_width "${col2[$i]}" $col_w
682
+ pad_to_width "${col2[$i]}" $col_w "${all_widths[$_wi]}"
683
+ ((_wi++))
627
684
  printf "${A_DIM}│${A_RESET}"
628
- pad_to_width "${col3[$i]}" $col_w
685
+ pad_to_width "${col3[$i]}" $col_w "${all_widths[$_wi]}"
686
+ ((_wi++))
629
687
  printf '\033[K\n'
630
688
  done
631
689
  }
@@ -1080,6 +1138,7 @@ cmd_priority() {
1080
1138
  cmd_add() {
1081
1139
  init_json
1082
1140
  [[ -z "$1" ]] && { echo "Usage: viban add \"title\" [\"description\"] [priority] [type] [attachments...]"; exit 1; }
1141
+ local title="$1"
1083
1142
  local id=$(get_next_id) now=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
1084
1143
  local desc="${2:-}"
1085
1144
  local priority="${3:-P3}"
@@ -1099,7 +1158,7 @@ cmd_add() {
1099
1158
  # Order is only assigned when manually moved
1100
1159
  local tmpjson=$(mktemp)
1101
1160
  printf '%s' "$desc" > "$tmpjson"
1102
- jq --arg id "$id" --arg title "$1" --rawfile desc "$tmpjson" --arg priority "$priority" --arg issue_type "$issue_type" --argjson attachments "$attachments_json" --arg now "$now" '
1161
+ jq --arg id "$id" --arg title "$title" --rawfile desc "$tmpjson" --arg priority "$priority" --arg issue_type "$issue_type" --argjson attachments "$attachments_json" --arg now "$now" '
1103
1162
  .next_id = ((.next_id // 0) + 1) |
1104
1163
  .issues += [{
1105
1164
  id:($id|tonumber),
package/commands/setup.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Install viban dependencies (zsh, gum, jq) automatically"
2
+ description: "Install viban dependencies and configure project workflow via interview"
3
3
  ---
4
4
 
5
5
  # /setup - Install Dependencies
@@ -125,6 +125,137 @@ You can now use:
125
125
  /task Create structured issue
126
126
  ```
127
127
 
128
+ ### Step 6: Workflow Setup Introduction
129
+
130
+ After dependencies are installed, explain to the user:
131
+
132
+ ```
133
+ ╭──────────────────────────────────────────────────╮
134
+ │ Workflow Setup (Optional) │
135
+ ╰──────────────────────────────────────────────────╯
136
+
137
+ /viban:assign uses your project's CLAUDE.md workflow
138
+ as the TOP PRIORITY when resolving issues.
139
+
140
+ Without a workflow, a default 4-step process is used.
141
+ Let's set up a custom workflow for this project now.
142
+ ```
143
+
144
+ Ask the user with AskUserQuestion whether they want to configure a workflow now or skip.
145
+
146
+ - **"Configure workflow"** → Continue to Step 7
147
+ - **"Skip"** → End setup
148
+
149
+ ### Step 7: Workflow Interview
150
+
151
+ Use AskUserQuestion for each question. Collect all answers before generating.
152
+
153
+ **Q1. Project Type**
154
+ - header: "Project"
155
+ - options:
156
+ - "Web Frontend" (React, Vue, Svelte, etc.)
157
+ - "Web Backend" (API server, microservice)
158
+ - "CLI / Library"
159
+ - "Fullstack" (frontend + backend)
160
+ - multiSelect: false
161
+
162
+ **Q2. Build & Test Command**
163
+ - header: "Build/Test"
164
+ - options:
165
+ - "`npm run build && npm test`"
166
+ - "`pnpm build && pnpm test`"
167
+ - "`pytest`"
168
+ - "`cargo build && cargo test`"
169
+ - multiSelect: false
170
+ - (User can select "Other" to type a custom command)
171
+
172
+ **Q3. Verification Method**
173
+ - header: "Verify"
174
+ - options:
175
+ - "Browser test (Playwright / Chrome DevTools)"
176
+ - "API endpoint test (curl / WebFetch)"
177
+ - "CLI output check"
178
+ - "No manual verification (tests are enough)"
179
+ - multiSelect: true
180
+
181
+ **Q4. Commit Convention**
182
+ - header: "Commits"
183
+ - options:
184
+ - "Conventional Commits (`feat:`, `fix:`, `chore:`, etc.)"
185
+ - "Free-form messages"
186
+ - multiSelect: false
187
+ - (User can select "Other" to type a custom convention)
188
+
189
+ **Q5. Additional Rules (Optional)**
190
+ - Ask with AskUserQuestion:
191
+ - header: "Rules"
192
+ - question: "Any additional project-specific rules? (e.g. 'always update CHANGELOG', 'use Korean commit messages')"
193
+ - options:
194
+ - "No additional rules"
195
+ - "Let me type rules"
196
+ - multiSelect: false
197
+ - If user selects "Let me type rules", collect their free-text input.
198
+
199
+ ### Step 8: Generate CLAUDE.md Workflow
200
+
201
+ Based on interview answers, generate (or append to) the project root `CLAUDE.md`.
202
+
203
+ **If CLAUDE.md does not exist**: Create it with the workflow section.
204
+ **If CLAUDE.md exists but has no `## Issue Resolution Workflow`**: Append the section.
205
+ **If CLAUDE.md already has `## Issue Resolution Workflow`**: Ask user whether to overwrite or skip.
206
+
207
+ Generated template:
208
+
209
+ ```markdown
210
+ ## Issue Resolution Workflow
211
+
212
+ > This workflow is automatically applied when running `/viban:assign`.
213
+
214
+ ### Step 1: Analyze
215
+ - Read issue description via `viban get {id}`
216
+ - Find relevant code files
217
+ - Understand the root cause
218
+
219
+ ### Step 2: Implement
220
+ - Make minimal, focused changes
221
+ - {ADDITIONAL_RULES from Q5, if any}
222
+
223
+ ### Step 3: Verify
224
+ - {VERIFICATION_METHODS from Q3}
225
+
226
+ ### Step 4: Build & Test
227
+ - Run: `{BUILD_TEST_COMMAND from Q2}`
228
+
229
+ ### Step 5: Commit & PR
230
+ - Commit convention: {CONVENTION from Q4}
231
+ - Create PR via `gh pr create`
232
+
233
+ ### Step 6: Complete
234
+ - Run `viban review {id}` to move to human review
235
+ ```
236
+
237
+ **Template variable mapping:**
238
+
239
+ | Variable | Source | Example |
240
+ |----------|--------|---------|
241
+ | `{VERIFICATION_METHODS}` | Q3 answers joined as bullet list | `- Browser test with Playwright` |
242
+ | `{BUILD_TEST_COMMAND}` | Q2 answer | `npm run build && npm test` |
243
+ | `{CONVENTION}` | Q4 answer | `Conventional Commits (feat:, fix:, etc.)` |
244
+ | `{ADDITIONAL_RULES}` | Q5 answer (omit line if empty) | `- Always update CHANGELOG.md` |
245
+
246
+ After writing CLAUDE.md, confirm:
247
+
248
+ ```
249
+ ╭──────────────────────────────────────────────────╮
250
+ │ Workflow saved to CLAUDE.md! ✨ │
251
+ ╰──────────────────────────────────────────────────╯
252
+
253
+ /viban:assign will now follow your custom workflow.
254
+ You can edit CLAUDE.md anytime to adjust it.
255
+ ```
256
+
257
+ ---
258
+
128
259
  ## Error Handling
129
260
 
130
261
  - **Homebrew not found on macOS**: Prompt user to install Homebrew first
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-plugin-viban",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "Terminal Kanban TUI for AI-human collaborative issue tracking",
5
5
  "main": "bin/viban",
6
6
  "bin": {
@@ -22,7 +22,7 @@ declare -a CHORES=()
22
22
  declare -a OTHERS=()
23
23
 
24
24
  # Parse commits
25
- while IFS= read -r line; do
25
+ while IFS= read -r line || [[ -n "$line" ]]; do
26
26
  [[ -z "$line" ]] && continue
27
27
 
28
28
  # Extract commit message (remove hash prefix if present)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: setup
3
- description: "Install viban dependencies (zsh, gum, jq) automatically"
3
+ description: "Install viban dependencies and configure project workflow via interview"
4
4
  ---
5
5
 
6
6
  # /setup - Install Dependencies
@@ -126,6 +126,137 @@ You can now use:
126
126
  /task Create structured issue
127
127
  ```
128
128
 
129
+ ### Step 6: Workflow Setup Introduction
130
+
131
+ After dependencies are installed, explain to the user:
132
+
133
+ ```
134
+ ╭──────────────────────────────────────────────────╮
135
+ │ Workflow Setup (Optional) │
136
+ ╰──────────────────────────────────────────────────╯
137
+
138
+ /viban:assign uses your project's CLAUDE.md workflow
139
+ as the TOP PRIORITY when resolving issues.
140
+
141
+ Without a workflow, a default 4-step process is used.
142
+ Let's set up a custom workflow for this project now.
143
+ ```
144
+
145
+ Ask the user with AskUserQuestion whether they want to configure a workflow now or skip.
146
+
147
+ - **"Configure workflow"** → Continue to Step 7
148
+ - **"Skip"** → End setup
149
+
150
+ ### Step 7: Workflow Interview
151
+
152
+ Use AskUserQuestion for each question. Collect all answers before generating.
153
+
154
+ **Q1. Project Type**
155
+ - header: "Project"
156
+ - options:
157
+ - "Web Frontend" (React, Vue, Svelte, etc.)
158
+ - "Web Backend" (API server, microservice)
159
+ - "CLI / Library"
160
+ - "Fullstack" (frontend + backend)
161
+ - multiSelect: false
162
+
163
+ **Q2. Build & Test Command**
164
+ - header: "Build/Test"
165
+ - options:
166
+ - "`npm run build && npm test`"
167
+ - "`pnpm build && pnpm test`"
168
+ - "`pytest`"
169
+ - "`cargo build && cargo test`"
170
+ - multiSelect: false
171
+ - (User can select "Other" to type a custom command)
172
+
173
+ **Q3. Verification Method**
174
+ - header: "Verify"
175
+ - options:
176
+ - "Browser test (Playwright / Chrome DevTools)"
177
+ - "API endpoint test (curl / WebFetch)"
178
+ - "CLI output check"
179
+ - "No manual verification (tests are enough)"
180
+ - multiSelect: true
181
+
182
+ **Q4. Commit Convention**
183
+ - header: "Commits"
184
+ - options:
185
+ - "Conventional Commits (`feat:`, `fix:`, `chore:`, etc.)"
186
+ - "Free-form messages"
187
+ - multiSelect: false
188
+ - (User can select "Other" to type a custom convention)
189
+
190
+ **Q5. Additional Rules (Optional)**
191
+ - Ask with AskUserQuestion:
192
+ - header: "Rules"
193
+ - question: "Any additional project-specific rules? (e.g. 'always update CHANGELOG', 'use Korean commit messages')"
194
+ - options:
195
+ - "No additional rules"
196
+ - "Let me type rules"
197
+ - multiSelect: false
198
+ - If user selects "Let me type rules", collect their free-text input.
199
+
200
+ ### Step 8: Generate CLAUDE.md Workflow
201
+
202
+ Based on interview answers, generate (or append to) the project root `CLAUDE.md`.
203
+
204
+ **If CLAUDE.md does not exist**: Create it with the workflow section.
205
+ **If CLAUDE.md exists but has no `## Issue Resolution Workflow`**: Append the section.
206
+ **If CLAUDE.md already has `## Issue Resolution Workflow`**: Ask user whether to overwrite or skip.
207
+
208
+ Generated template:
209
+
210
+ ```markdown
211
+ ## Issue Resolution Workflow
212
+
213
+ > This workflow is automatically applied when running `/viban:assign`.
214
+
215
+ ### Step 1: Analyze
216
+ - Read issue description via `viban get {id}`
217
+ - Find relevant code files
218
+ - Understand the root cause
219
+
220
+ ### Step 2: Implement
221
+ - Make minimal, focused changes
222
+ - {ADDITIONAL_RULES from Q5, if any}
223
+
224
+ ### Step 3: Verify
225
+ - {VERIFICATION_METHODS from Q3}
226
+
227
+ ### Step 4: Build & Test
228
+ - Run: `{BUILD_TEST_COMMAND from Q2}`
229
+
230
+ ### Step 5: Commit & PR
231
+ - Commit convention: {CONVENTION from Q4}
232
+ - Create PR via `gh pr create`
233
+
234
+ ### Step 6: Complete
235
+ - Run `viban review {id}` to move to human review
236
+ ```
237
+
238
+ **Template variable mapping:**
239
+
240
+ | Variable | Source | Example |
241
+ |----------|--------|---------|
242
+ | `{VERIFICATION_METHODS}` | Q3 answers joined as bullet list | `- Browser test with Playwright` |
243
+ | `{BUILD_TEST_COMMAND}` | Q2 answer | `npm run build && npm test` |
244
+ | `{CONVENTION}` | Q4 answer | `Conventional Commits (feat:, fix:, etc.)` |
245
+ | `{ADDITIONAL_RULES}` | Q5 answer (omit line if empty) | `- Always update CHANGELOG.md` |
246
+
247
+ After writing CLAUDE.md, confirm:
248
+
249
+ ```
250
+ ╭──────────────────────────────────────────────────╮
251
+ │ Workflow saved to CLAUDE.md! ✨ │
252
+ ╰──────────────────────────────────────────────────╯
253
+
254
+ /viban:assign will now follow your custom workflow.
255
+ You can edit CLAUDE.md anytime to adjust it.
256
+ ```
257
+
258
+ ---
259
+
129
260
  ## Error Handling
130
261
 
131
262
  - **Homebrew not found on macOS**: Prompt user to install Homebrew first