claude-plugin-viban 1.0.36 → 1.1.0

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viban",
3
- "version": "1.0.36",
3
+ "version": "1.1.0",
4
4
  "description": "Terminal Kanban TUI for AI-human collaborative issue tracking",
5
5
  "author": {
6
6
  "name": "happy-nut"
package/bin/viban CHANGED
@@ -35,7 +35,7 @@ check_dependencies() {
35
35
  }
36
36
 
37
37
  # Only check dependencies for interactive commands (not help)
38
- [[ "$1" != "help" && "$1" != "--help" && "$1" != "-h" ]] && check_dependencies
38
+ [[ "$1" != "help" && "$1" != "--help" && "$1" != "-h" && "$1" != "sync" ]] && check_dependencies
39
39
 
40
40
  # ============================================================
41
41
  # Auto-update Check (once per day, cached)
@@ -113,7 +113,7 @@ auto_update_check() {
113
113
 
114
114
  # Run auto-update for all commands except help/version/update itself
115
115
  case "$1" in
116
- help|--help|-h|--version|-v|update) ;;
116
+ help|--help|-h|--version|-v|update|sync) ;;
117
117
  *) auto_update_check "$@" ;;
118
118
  esac
119
119
 
@@ -246,7 +246,7 @@ EOF
246
246
 
247
247
  # Auto-initialize for commands that need data (not help/init)
248
248
  case "$1" in
249
- help|--help|-h|--version|-v|update|init) ;;
249
+ help|--help|-h|--version|-v|update|init|sync) ;;
250
250
  *) init_viban_json ;;
251
251
  esac
252
252
 
@@ -354,6 +354,12 @@ init_json() {
354
354
 
355
355
  get_next_id() { jq -r '.next_id // (([.issues[].id] | max // 0) + 1)' "$VIBAN_JSON"; }
356
356
 
357
+ # Display ID: show external_id if present, otherwise #id
358
+ display_id() { local id="$1" ext_id="${2:-}"; [[ -n "$ext_id" && "$ext_id" != "null" ]] && echo "$ext_id" || echo "#$id"; }
359
+
360
+ # Get external_id for an issue by internal id
361
+ get_ext_id() { jq -r --argjson id "$1" '.issues[]|select((.id|tonumber)==$id)|.external_id//""' "$VIBAN_JSON"; }
362
+
357
363
  # Calculate effective order for sorting (priority-based virtual order for cards without order)
358
364
  # Used internally for fractional indexing calculations
359
365
  # Cards with order: use actual order
@@ -403,7 +409,7 @@ add_issue() {
403
409
  local today=$(date +"%Y-%m-%d")
404
410
  cat > "$tmpfile" <<TEMPLATE
405
411
  # ─────────────────────────────────────────────
406
- # VIBAN Issue #$next_id
412
+ # VIBAN Issue #${next_id}
407
413
  # ─────────────────────────────────────────────
408
414
  # Title: $title
409
415
  # Priority: $priority
@@ -597,10 +603,13 @@ build_column_lines() {
597
603
  [[ "$st" == "review" ]] && sort_expr='sort_by(.updated_at) | reverse'
598
604
  local issues_data=$(printf '%s' "$json_data" | jq -r --arg s "$st" "
599
605
  .issues | map(select(.status==\$s)) | $sort_expr |
600
- .[] | \"\\(.id)\t\\(.title)\t\\((.description // \"\") | gsub(\"[\\n\\t\\r]\"; \" \"))\t\\(.priority // \"P3\")\t\\(.type // \"\")\"")
606
+ .[] | \"\\(.id)\t\\(.title)\t\\((.description // \"\") | gsub(\"[\\n\\t\\r]\"; \" \"))\t\\(.priority // \"P3\")\t\\(.type // \"\")\t\\(.external_id // \"\")\"")
601
607
  local count=0
602
- # Count lines without subprocess using zsh array splitting
603
- [[ -n "$issues_data" ]] && count=${#${(f)issues_data}}
608
+ # Count total issues (not capped) for overflow indicator
609
+ if [[ -n "$issues_data" ]]; then
610
+ local -a _count_arr=("${(f)issues_data}")
611
+ count=${#_count_arr[@]}
612
+ fi
604
613
 
605
614
  # Header centered in column
606
615
  local hdr_text="● $label"
@@ -623,14 +632,14 @@ build_column_lines() {
623
632
  local border=$(gen_border $card_inner)
624
633
 
625
634
  # --- Pass 1: Collect card data into arrays ---
626
- local -a _ids _titles _descs _priorities _types _title_max_ws _title_pfxs
635
+ local -a _ids _titles _descs _priorities _types _ext_ids _title_max_ws _title_pfxs
627
636
  local _has_nonascii=0
628
637
  local _desc_max_w=$((card_inner - 4))
629
638
  local _spinner_w=0
630
639
  [[ "$st" == "in_progress" ]] && _spinner_w=2
631
640
  local _cc _bc _pfx
632
641
 
633
- while IFS=$'\t' read -r _id _title _desc _priority _type; do
642
+ while IFS=$'\t' read -r _id _title _desc _priority _type _ext_id; do
634
643
  [[ -z "$_id" ]] && continue
635
644
  (( ${#_ids} >= CACHED_MAX_TASKS )) && break
636
645
  [[ -z "$_priority" || "$_priority" == "null" ]] && _priority="P3"
@@ -638,14 +647,15 @@ build_column_lines() {
638
647
  [[ "$_desc" == "null" ]] && _desc=""
639
648
 
640
649
  _ids+=("$_id"); _titles+=("$_title"); _descs+=("$_desc")
641
- _priorities+=("$_priority"); _types+=("$_type")
650
+ _priorities+=("$_priority"); _types+=("$_type"); _ext_ids+=("$_ext_id")
642
651
 
643
- # Per-card title width limit
644
- _title_max_ws+=($((card_inner - 4 - ${#_id} - _spinner_w - 1)))
652
+ # Per-card title width limit (use display ID length)
653
+ local _did; _did=$(display_id "$_id" "$_ext_id")
654
+ _title_max_ws+=($((card_inner - 4 - ${#_did} - _spinner_w)))
645
655
  # Prefix for width calc (X as spinner placeholder - same width 1 as braille chars)
646
656
  _pfx=" "
647
657
  (( _spinner_w )) && _pfx=" X "
648
- _title_pfxs+=("${_pfx}#${_id} ")
658
+ _title_pfxs+=("${_pfx}${_did} ")
649
659
 
650
660
  # Check for non-ASCII
651
661
  if (( ! _has_nonascii )); then
@@ -711,11 +721,13 @@ build_column_lines() {
711
721
  local id="${_ids[$_i]}"
712
722
  local priority="${_priorities[$_i]}"
713
723
  local issue_type="${_types[$_i]}"
724
+ local ext_id="${_ext_ids[$_i]}"
725
+ local did; did=$(display_id "$id" "$ext_id")
714
726
 
715
727
  # Title line
716
728
  local spinner_prefix=""
717
729
  [[ "$st" == "in_progress" ]] && spinner_prefix="${SPINNER_FRAMES[$((SPINNER_IDX % ${#SPINNER_FRAMES[@]} + 1))]} "
718
- local title_content=" ${spinner_prefix}#${id} ${_short_titles[$_i]}"
730
+ local title_content=" ${spinner_prefix}${did} ${_short_titles[$_i]}"
719
731
  local title_pad=$((card_inner - ${_title_cws[$_i]}))
720
732
  (( title_pad < 0 )) && title_pad=0
721
733
 
@@ -1158,7 +1170,7 @@ level1_columns() {
1158
1170
  stty echo 2>/dev/null
1159
1171
  # Clear footer line and show confirm
1160
1172
  printf '\033[%d;1H\033[K' "$CACHED_TERM_H"
1161
- if gum confirm "Delete #$id?" --affirmative "Yes" --negative "No" \
1173
+ if gum confirm "Delete $(display_id "$id" "$(get_ext_id "$id")")?" --affirmative "Yes" --negative "No" \
1162
1174
  --selected.foreground="#000000" --selected.background "${C[accent]}"; then
1163
1175
  delete_issue "$id"
1164
1176
  (( card > 0 )) && card=$((card - 1))
@@ -1193,13 +1205,15 @@ edit_issue() {
1193
1205
  local created=$(printf '%s' "$issue" | jq -r '.created_at')
1194
1206
  local priority=$(printf '%s' "$issue" | jq -r '.priority // "P3"')
1195
1207
  local issue_type=$(printf '%s' "$issue" | jq -r '.type // ""')
1208
+ local ext_id=$(printf '%s' "$issue" | jq -r '.external_id // ""')
1209
+ local did; did=$(display_id "$id" "$ext_id")
1196
1210
 
1197
1211
  local tmpfile=$(mktemp)
1198
1212
  local editor="${EDITOR:-${VISUAL:-vim}}"
1199
1213
 
1200
1214
  cat > "$tmpfile" <<TEMPLATE
1201
1215
  # ─────────────────────────────────────────────
1202
- # VIBAN Issue #$id
1216
+ # VIBAN Issue $did
1203
1217
  # ─────────────────────────────────────────────
1204
1218
  # Status: ${STATUS_LABEL[$ist]}
1205
1219
  # Created: ${created:0:10}
@@ -1310,7 +1324,7 @@ cmd_list() {
1310
1324
  echo ""
1311
1325
  for st in $VIBAN_STATUSES; do
1312
1326
  gum style --foreground "${STATUS_COLOR[$st]}" --bold "● ${STATUS_LABEL[$st]} ($(count_issues_by_status "$st"))"
1313
- get_issues_by_status "$st" | jq -r '.[]|" #\(.id) [\(.priority // "P3")]\(if .type then " [\(.type | ascii_upcase)]" else "" end) \(.title)"'
1327
+ get_issues_by_status "$st" | jq -r '.[]|" \(if .external_id then .external_id else "#\(.id)" end) [\(.priority // "P3")]\(if .type then " [\(.type | ascii_upcase)]" else "" end) \(.title)"'
1314
1328
  echo ""
1315
1329
  done
1316
1330
  }
@@ -1336,15 +1350,15 @@ cmd_priority() {
1336
1350
  '(.issues[]|select((.id|tonumber)==$id)) |= . + {priority:$priority,updated_at:$now}' \
1337
1351
  "$VIBAN_JSON" > "$VIBAN_JSON.tmp" && mv "$VIBAN_JSON.tmp" "$VIBAN_JSON"
1338
1352
 
1339
- echo "✓ #$id priority → $new_priority"
1353
+ echo "✓ $(display_id "$id" "$(get_ext_id "$id")") priority → $new_priority"
1340
1354
  }
1341
1355
 
1342
1356
  cmd_add() {
1343
1357
  init_json
1344
1358
  [[ -z "$1" ]] && { echo "Usage: viban add \"title\" [\"description\"] [priority] [type] [attachments...]"; exit 1; }
1345
1359
 
1346
- # Support both positional and named args (--title, --description, --priority, --type)
1347
- local title="" desc="" priority="P3" issue_type=""
1360
+ # Support both positional and named args (--title, --description, --priority, --type, --ext-id)
1361
+ local title="" desc="" priority="P3" issue_type="" ext_id=""
1348
1362
  local -a attachments=()
1349
1363
  local positional=()
1350
1364
 
@@ -1355,6 +1369,7 @@ cmd_add() {
1355
1369
  --desc-file) [[ -f "$2" ]] && desc="$(cat "$2")"; shift 2 ;;
1356
1370
  --priority) priority="$2"; shift 2 ;;
1357
1371
  --type) issue_type="$2"; shift 2 ;;
1372
+ --ext-id|--external-id) ext_id="$2"; shift 2 ;;
1358
1373
  --attach|--attachments) shift; while [[ $# -gt 0 && "$1" != --* ]]; do attachments+=("$1"); shift; done ;;
1359
1374
  --*) shift 2 2>/dev/null || shift ;; # skip unknown flags
1360
1375
  *) positional+=("$1"); shift ;;
@@ -1386,7 +1401,7 @@ cmd_add() {
1386
1401
  # Order is only assigned when manually moved
1387
1402
  local tmpjson=$(mktemp)
1388
1403
  printf '%s' "$desc" > "$tmpjson"
1389
- 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" '
1404
+ jq --arg id "$id" --arg title "$title" --rawfile desc "$tmpjson" --arg priority "$priority" --arg issue_type "$issue_type" --arg ext_id "$ext_id" --argjson attachments "$attachments_json" --arg now "$now" '
1390
1405
  .next_id = ((.next_id // 0) + 1) |
1391
1406
  .issues += [{
1392
1407
  id:($id|tonumber),
@@ -1395,6 +1410,7 @@ cmd_add() {
1395
1410
  status:"backlog",
1396
1411
  priority:$priority,
1397
1412
  type:(if $issue_type == "" then null else $issue_type end),
1413
+ external_id:(if $ext_id == "" then null else $ext_id end),
1398
1414
  attachments:$attachments,
1399
1415
  assigned_to:null,
1400
1416
  created_at:$now,
@@ -1405,7 +1421,7 @@ cmd_add() {
1405
1421
  [[ -n "$issue_type" ]] && type_info=" [$issue_type]"
1406
1422
  local attach_info=""
1407
1423
  [[ ${#attachments[@]} -gt 0 ]] && attach_info=" +${#attachments[@]} files"
1408
- echo "✓ #$id added ($priority)$type_info$attach_info"
1424
+ echo "✓ $(display_id "$id" "$ext_id") added ($priority)$type_info$attach_info"
1409
1425
  }
1410
1426
 
1411
1427
  cmd_assign() {
@@ -1414,16 +1430,18 @@ cmd_assign() {
1414
1430
  local issue=$(jq -r '.issues|map(select(.status=="backlog"))|sort_by(if .order != null then [0, .order] else [1, ({"P0":0,"P1":1,"P2":2,"P3":3}[.priority // "P3"] // 3), .id] end)|first' "$VIBAN_JSON")
1415
1431
  [[ "$issue" == "null" || -z "$issue" ]] && { echo "No backlog"; exit 1; }
1416
1432
  local id=$(printf '%s' "$issue" | jq -r '.id') now=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
1433
+ local ext_id=$(printf '%s' "$issue" | jq -r '.external_id // ""')
1417
1434
 
1418
1435
  # Update status to in_progress (no worktree - use branch workflow)
1419
1436
  jq --argjson id "$id" --arg s "$session" --arg now "$now" \
1420
1437
  '(.issues[]|select((.id|tonumber)==$id)) |= . + {status:"in_progress",assigned_to:$s,updated_at:$now}' \
1421
1438
  "$VIBAN_JSON" > "$VIBAN_JSON.tmp" && mv "$VIBAN_JSON.tmp" "$VIBAN_JSON"
1422
1439
 
1423
- # Set iTerm2 session name to issue number
1424
- printf '\033]1;#%s\007' "$id"
1440
+ # Set iTerm2 session name to issue display ID
1441
+ local did; did=$(display_id "$id" "$ext_id")
1442
+ printf '\033]1;%s\007' "$did"
1425
1443
 
1426
- echo "✓ #$id assigned"
1444
+ echo "✓ $did assigned"
1427
1445
  echo "$id"
1428
1446
  }
1429
1447
 
@@ -1439,7 +1457,7 @@ cmd_review() {
1439
1457
  # Clear iTerm2 session name
1440
1458
  printf '\033]1;\007'
1441
1459
 
1442
- echo "✓ #$id → review"
1460
+ echo "✓ $(display_id "$id" "$(get_ext_id "$id")") → review"
1443
1461
  }
1444
1462
 
1445
1463
  cmd_done() {
@@ -1461,7 +1479,7 @@ cmd_done() {
1461
1479
  # Clear iTerm2 session name
1462
1480
  printf '\033]1;\007'
1463
1481
 
1464
- echo "✓ #$1 completed & removed"
1482
+ echo "✓ $(display_id "$1" "$(get_ext_id "$1")") completed & removed"
1465
1483
  }
1466
1484
 
1467
1485
  cmd_get() { init_json; jq --argjson id "$1" '.issues[]|select((.id|tonumber)==$id)' "$VIBAN_JSON"; }
@@ -1489,7 +1507,7 @@ cmd_attach() {
1489
1507
  }
1490
1508
  ' "$VIBAN_JSON" > "$VIBAN_JSON.tmp" && mv "$VIBAN_JSON.tmp" "$VIBAN_JSON"
1491
1509
 
1492
- echo "✓ #$id: ${#files[@]} file(s) attached"
1510
+ echo "✓ $(display_id "$id" "$(get_ext_id "$id")"): ${#files[@]} file(s) attached"
1493
1511
  }
1494
1512
 
1495
1513
  cmd_migrate() {
@@ -1553,6 +1571,26 @@ cmd_migrate() {
1553
1571
  ' "$VIBAN_JSON"
1554
1572
  }
1555
1573
 
1574
+ cmd_sync() {
1575
+ local provider="${VIBAN_SYNC_PROVIDER:-}"
1576
+ # Auto-detect provider from existing sync.json or default to github
1577
+ if [[ -z "$provider" && -f "$VIBAN_DATA_DIR/sync.json" ]]; then
1578
+ provider=$(jq -r '.provider // "github"' "$VIBAN_DATA_DIR/sync.json")
1579
+ fi
1580
+ provider="${provider:-github}"
1581
+
1582
+ local provider_script="$VIBAN_SCRIPT_DIR/scripts/providers/${provider}.sh"
1583
+ if [[ ! -f "$provider_script" ]]; then
1584
+ echo "Error: Unknown sync provider '$provider'"
1585
+ echo "Available: $(ls "$VIBAN_SCRIPT_DIR/scripts/providers/" 2>/dev/null | sed 's/\.sh$//' | tr '\n' ' ')"
1586
+ exit 1
1587
+ fi
1588
+
1589
+ VIBAN_JSON="$VIBAN_JSON" VIBAN_DATA_DIR="$VIBAN_DATA_DIR" \
1590
+ VIBAN_PROVIDER="$provider" VIBAN_SCRIPT_DIR="$VIBAN_SCRIPT_DIR" \
1591
+ bash "$VIBAN_SCRIPT_DIR/scripts/sync.sh" "$@"
1592
+ }
1593
+
1556
1594
  main() {
1557
1595
  check_deps
1558
1596
  init_json
@@ -1567,6 +1605,7 @@ main() {
1567
1605
  edit) [[ -z "$2" ]] && { echo "Usage: viban edit <id>"; exit 1; }; edit_issue "$2";;
1568
1606
  priority) cmd_priority "$2" "$3";;
1569
1607
  migrate) cmd_migrate;;
1608
+ sync) shift; cmd_sync "$@";;
1570
1609
  --version|-v)
1571
1610
  # Get version from package.json
1572
1611
  if [[ -f "$VIBAN_SCRIPT_DIR/package.json" ]]; then
@@ -1598,6 +1637,7 @@ main() {
1598
1637
  echo " viban edit <id> Edit task in editor"
1599
1638
  echo " viban get <id> Get task details (JSON)"
1600
1639
  echo " viban migrate Migrate: extract type from title"
1640
+ echo " viban sync Sync with external issue tracker (GitHub, etc.)"
1601
1641
  echo " viban update Update to latest version (if available)"
1602
1642
  echo ""
1603
1643
  echo " Priority: P0=CRITICAL, P1=HIGH, P2=MEDIUM, P3=LOW"
package/commands/add.md CHANGED
@@ -1,257 +1,94 @@
1
1
  ---
2
- description: "Analyze problem and register as viban issue with evidence"
2
+ description: "Register a problem as a viban issue"
3
3
  ---
4
4
 
5
- # /add - Problem Analysis and Issue Registration
5
+ # /add - Register Issue
6
6
 
7
- Analyze problem situation and register as viban issue with file locations and evidence.
7
+ Register a problem as a viban issue. Keep it lightweight no codebase exploration, no heavy analysis.
8
8
 
9
- > **Core Principle**: Focus on **symptoms and problem definition**, not solutions.
10
- > Solutions are decided by the assignee after understanding full context.
9
+ > **Principle**: Clarify symptoms only if vague. Don't explore code or propose solutions.
11
10
 
12
- ## Input Verification
11
+ ## Input
13
12
 
14
13
  **User Input**: `$ARGUMENTS`
15
14
 
16
- If input is empty or unclear:
17
- 1. Use AskUserQuestion to ask about the problem
18
- 2. Proceed after receiving response
15
+ ## Step 1: Clarify (only if needed)
19
16
 
20
- ## Execution Steps
17
+ If the user's description is **clear enough** to register (who/what/where), skip to Step 2.
21
18
 
22
- ### Step 1: Problem Identification
19
+ If **vague or ambiguous**, concretize with one AskUserQuestion:
23
20
 
24
- Analyze the problem described by user:
25
- 1. **Identify symptoms**: Clearly define what the problem is
26
- 2. **Extract keywords**: Error messages, feature names, module names, etc.
27
- 3. **Determine priority**:
28
- | Condition | Priority |
29
- |-----------|----------|
30
- | System down, data loss | P0 |
31
- | Feature broken, errors | P1 |
32
- | Performance degradation, warnings | P2 |
33
- | Improvements, refactoring | P3 |
21
+ - header: "Problem"
22
+ - question: "Can you describe the symptom more specifically?"
23
+ - options based on context, e.g.:
24
+ - "Error/crash on specific action"
25
+ - "Feature not working as expected"
26
+ - "Performance issue"
27
+ - "Let me describe"
28
+ - multiSelect: false
34
29
 
35
- ### Step 2: Codebase Exploration
30
+ Goal: get a **one-sentence symptom** clear enough for an assignee to understand.
36
31
 
37
- **Required**: Must find code location related to the problem
32
+ ## Step 2: Determine Priority & Type
38
33
 
39
- 1. **Search by keywords**:
40
- ```bash
41
- # Search by error message or function name
42
- grep -r "keyword" . --include="*.py" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx"
43
- ```
34
+ Infer from the description. Do NOT ask unless truly ambiguous.
44
35
 
45
- 2. **Check related files**:
46
- - Find module where error occurred
47
- - Check stack trace files if available
48
- - For API endpoints: trace router → use case → domain
36
+ | Condition | Priority |
37
+ |-----------|----------|
38
+ | System down, data loss | P0 |
39
+ | Feature broken, errors | P1 |
40
+ | Performance, warnings | P2 |
41
+ | Improvements, refactoring | P3 |
49
42
 
50
- 3. **Collect location information**:
51
- - File path: relative to project root
52
- - Function/class name
53
- - Line number (if possible)
43
+ | Type | When |
44
+ |------|------|
45
+ | bug | Something is broken |
46
+ | feat | New functionality |
47
+ | chore | Maintenance, config |
48
+ | refactor | Code restructuring |
54
49
 
55
- ### Step 3: Issue Body Composition
56
-
57
- Write issue body in this format:
58
-
59
- ```markdown
60
- ## Symptoms
61
- One-sentence summary of what happened.
62
- - Frequency: (if known)
63
- - Affected features:
64
-
65
- ## Reproduction Steps
66
- 1. Step-by-step reproduction
67
- 2. ...
68
- 3. Environment: local/staging/production
69
-
70
- ## Expected Result
71
- - How it should work normally
72
-
73
- ## Actual Result
74
- - The problem that actually occurred
75
-
76
- ## Stack Trace (if available)
77
- ```
78
- Error log or stack trace
79
- ```
80
-
81
- ## Location
82
- - File: `path/to/file.ext`
83
- - Function/Class:
84
- - Line: (if known)
85
-
86
- ## Possible Cause (hypothesis)
87
- - Estimate which code/condition is causing the problem
88
- - List items to verify (not solutions)
89
-
90
- ## Meta Information
91
- - Registered: (current timestamp)
92
- - Reporter: user
93
- ```
94
-
95
- ### Step 4: Register viban Issue
96
-
97
- Write the description body to a temp file using a heredoc, then pass via `--desc-file`:
50
+ ## Step 3: Check Workflow for Issue Numbering
98
51
 
99
52
  ```bash
100
- cat > /tmp/viban-desc.md <<'VIBAN_EOF'
101
- ## Symptoms
102
- One-sentence summary...
103
-
104
- ## Reproduction Steps
105
- 1. ...
106
-
107
- ## Location
108
- - File: `path/to/file.ext`
109
- VIBAN_EOF
110
-
111
- viban add "{short_title}" --desc-file /tmp/viban-desc.md --priority {priority} --type {type}
53
+ [ -f ".viban/workflow.md" ] && cat ".viban/workflow.md"
112
54
  ```
113
55
 
114
- **Why heredoc?** Using `<<'VIBAN_EOF'` (single-quoted delimiter) prevents shell interpretation of backticks, `$`, parentheses, and other special characters in the description.
56
+ - If workflow says **Manual** issue numbering ask user for an external ID (e.g. `PROJ-42`)
57
+ - If workflow says **Auto** or no workflow exists → let viban auto-assign
58
+ - If user provided a specific ID in `$ARGUMENTS` → use it regardless of workflow
115
59
 
116
- **Parameters**:
117
- - `title`: Plain title (no tags) — first positional argument
118
- - `--desc-file`: Path to file containing issue body (Markdown)
119
- - `--priority`: P0, P1, P2, P3 (default: P3)
120
- - `--type`: bug, feat, chore, refactor
121
- - `--attach`: (optional) File paths to attach (screenshots, logs, etc.)
60
+ ## Step 4: Register
122
61
 
123
- **Examples**:
124
- ```bash
125
- # BUG issue
126
- cat > /tmp/viban-desc.md <<'VIBAN_EOF'
127
- ## Symptoms
128
- API responds with 504 after 30 seconds.
129
- - File: `src/api/handler.ts:42`
130
- VIBAN_EOF
131
- viban add "API response timeout" --desc-file /tmp/viban-desc.md --priority P1 --type bug
62
+ Write the description to a temp file, then register:
132
63
 
133
- # FEATURE issue
134
- cat > /tmp/viban-desc.md <<'VIBAN_EOF'
135
- ## Symptoms
136
- Users request dark mode support.
137
- VIBAN_EOF
138
- viban add "Dark mode support" --desc-file /tmp/viban-desc.md --priority P2 --type feat
139
-
140
- # With screenshot attachments
64
+ ```bash
141
65
  cat > /tmp/viban-desc.md <<'VIBAN_EOF'
142
66
  ## Symptoms
143
- Layout broken on mobile viewport.
67
+ {concretized one-sentence symptom from Step 1}
68
+ {additional context from user input, if any}
144
69
  VIBAN_EOF
145
- viban add "Layout broken on mobile" --desc-file /tmp/viban-desc.md --priority P1 --type bug --attach ./screenshots/mobile-bug.png
146
- ```
147
-
148
- ### Step 4a: Attaching Screenshots (Recommended for Visual Issues)
149
-
150
- For visual bugs (layout issues, UI glitches, rendering problems), attaching screenshots significantly helps:
151
-
152
- 1. **Take a screenshot** of the problem:
153
- - macOS: `Cmd + Shift + 4` (selection) or `Cmd + Shift + 3` (full screen)
154
- - Save to project directory: `./screenshots/` or `./.viban/attachments/`
155
-
156
- 2. **Attach during creation**:
157
- ```bash
158
- viban add "Button misaligned on dashboard" --desc-file /tmp/viban-desc.md --priority P1 --type bug --attach ./screenshots/button-issue.png
159
- ```
160
-
161
- 3. **Or attach to existing issue**:
162
- ```bash
163
- viban attach {issue_id} ./screenshots/screenshot1.png ./screenshots/screenshot2.png
164
- ```
165
-
166
- 4. **View attachments**:
167
- ```bash
168
- viban get {issue_id}
169
- ```
170
-
171
- > **Why attach screenshots?**
172
- > - Claude Code can read image files and understand visual context
173
- > - The assignee can see exactly what the problem looks like
174
- > - Reduces back-and-forth clarification
175
-
176
- ### Step 5: Report Results
177
-
178
- After registration, report to user:
179
-
180
- ```
181
- === viban Issue Registered ===
182
- - Issue ID: #{id}
183
- - Title: {title}
184
- - Type: {type}
185
- - Priority: {priority}
186
- - Location: {file_path}:{line}
187
- - Status: backlog
188
-
189
- Next steps:
190
- - `viban list` to view issue list
191
- - `viban start {id}` to start working
192
- ```
193
-
194
- ## When Input is Missing
195
70
 
196
- Use AskUserQuestion with these prompts:
71
+ # Auto numbering (default)
72
+ viban add "{title}" --desc-file /tmp/viban-desc.md --priority {priority} --type {type}
197
73
 
74
+ # Manual numbering (when workflow specifies manual)
75
+ viban add "{title}" --desc-file /tmp/viban-desc.md --priority {priority} --type {type} --ext-id "{external_id}"
198
76
  ```
199
- What problem should be registered as an issue?
200
77
 
201
- Please include:
202
- 1. What is the problem? (error message, unexpected behavior, etc.)
203
- 2. Where does it occur? (page, API, feature, etc.)
204
- 3. How to reproduce? (step-by-step)
205
- ```
206
-
207
- ## Example
78
+ **Why heredoc?** `<<'VIBAN_EOF'` prevents shell interpretation of backticks, `$`, etc.
208
79
 
209
- **Input**: "Charts not showing on backtest results page"
80
+ ## Step 5: Report
210
81
 
211
- **Analysis Process**:
212
- 1. Keywords: backtest, results, chart
213
- 2. Code exploration:
214
- ```bash
215
- grep -r "chart" . --include="*.tsx" --include="*.ts"
216
- ```
217
- 3. Related file found: `src/pages/backtest/results.tsx`
218
- 4. Check chart rendering logic
219
-
220
- **Registration Command**:
221
- ```bash
222
- cat > /tmp/viban-desc.md <<'VIBAN_EOF'
223
- ## Symptoms
224
- Backtest results chart not displayed when clicking chart tab.
225
- - File: `src/pages/backtest/results.tsx`
226
- VIBAN_EOF
227
- viban add "Backtest results chart not displayed" --desc-file /tmp/viban-desc.md --priority P1 --type bug
228
82
  ```
229
-
230
- **Registered Issue**:
83
+ Issue #{id} registered
84
+ Title: {title}
85
+ Priority: {priority} | Type: {type}
86
+ Status: backlog
231
87
  ```
232
- Title: Backtest results chart not displayed
233
- Priority: P1
234
- Type: bug
235
- Location: src/pages/backtest/results.tsx
236
- ```
237
-
238
- ## Important Notes
239
-
240
- - **Location Required**: Do not register without file path
241
- - **Evidence Required**: Do not register based on guesses without code exploration
242
- - **Avoid Solutions**: Do not write specific solutions (assignee decides)
243
- - **Check Duplicates**: Check existing issues before registration
244
- ```bash
245
- viban list
246
- ```
247
- - **Accurate Priority**: P0 only for system-down level, avoid over-estimation
248
-
249
- ## Final Step: Auto Update Check
250
88
 
251
- After completing issue registration, run:
252
-
253
- ```bash
254
- viban update
255
- ```
89
+ ## Notes
256
90
 
257
- This silently checks for updates and only outputs if an update is applied.
91
+ - **No codebase exploration** the assignee does that during `/viban:assign`
92
+ - **No solution proposals** — focus on symptoms only
93
+ - **Check duplicates** before registering: `viban list`
94
+ - **Don't over-prioritize** — P0 is system-down only