claude-plugin-viban 1.1.1 → 1.2.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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +69 -8
- package/bin/viban +103 -41
- package/commands/add.md +56 -51
- package/commands/assign.md +96 -115
- package/commands/sync.md +1 -1
- package/docs/CLAUDE.md +3 -4
- package/package.json +1 -1
- package/scripts/providers/github.sh +3 -2
- package/scripts/sync.sh +38 -1
- package/scripts/sync_create.sh +68 -0
- package/skills/add/SKILL.md +56 -51
- package/skills/assign/SKILL.md +96 -115
- package/skills/setup/SKILL.md +43 -21
- package/skills/sync/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,7 @@ This separation keeps your workflow clean and prevents context switching.
|
|
|
53
53
|
- python3 (macOS/Linux built-in)
|
|
54
54
|
- [gum](https://github.com/charmbracelet/gum)
|
|
55
55
|
- [jq](https://jqlang.github.io/jq/)
|
|
56
|
+
- [gh](https://cli.github.com/) (optional, for GitHub Issues sync)
|
|
56
57
|
|
|
57
58
|
> **Tip:** If using Claude Code, run `/viban:setup` to install all dependencies automatically.
|
|
58
59
|
|
|
@@ -122,6 +123,7 @@ viban assign [session-id] # Assign top backlog issue
|
|
|
122
123
|
viban review [id] # Move issue to review
|
|
123
124
|
viban done <id> # Mark issue as done
|
|
124
125
|
viban get <id> # Get issue details (JSON)
|
|
126
|
+
viban sync # Sync with external tracker
|
|
125
127
|
viban help # Show help message
|
|
126
128
|
```
|
|
127
129
|
|
|
@@ -175,6 +177,60 @@ Analyzes a problem and creates a properly structured viban issue:
|
|
|
175
177
|
- Feature requests
|
|
176
178
|
- Converting free-form descriptions to structured issues
|
|
177
179
|
|
|
180
|
+
#### `/viban:sync` - Sync with external tracker
|
|
181
|
+
|
|
182
|
+
Two-way sync between your viban board and an external issue tracker (currently GitHub Issues):
|
|
183
|
+
|
|
184
|
+
1. Checks sync configuration (or initializes on first run)
|
|
185
|
+
2. Shows a dry-run preview of changes
|
|
186
|
+
3. Asks for confirmation before syncing
|
|
187
|
+
4. Reports sync results
|
|
188
|
+
|
|
189
|
+
**Use cases:**
|
|
190
|
+
- Importing GitHub Issues into your local board
|
|
191
|
+
- Keeping remote issues in sync with local status changes
|
|
192
|
+
- Team collaboration where some members use GitHub and others use viban
|
|
193
|
+
|
|
194
|
+
## External Tracker Sync
|
|
195
|
+
|
|
196
|
+
viban can sync two-way with external issue trackers. Currently supported: **GitHub Issues**.
|
|
197
|
+
|
|
198
|
+
### Quick Start
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# First time: initialize sync (auto-detects provider from git remote)
|
|
202
|
+
viban sync --init
|
|
203
|
+
|
|
204
|
+
# Preview what will change
|
|
205
|
+
viban sync --dry-run
|
|
206
|
+
|
|
207
|
+
# Run sync
|
|
208
|
+
viban sync
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
> If using Claude Code, run `/viban:sync` for a guided experience with dry-run preview and confirmation.
|
|
212
|
+
|
|
213
|
+
### How It Works
|
|
214
|
+
|
|
215
|
+
- **First sync** imports all open remote issues as backlog cards with external IDs (e.g. `github:42`)
|
|
216
|
+
- **Subsequent syncs** pull remote changes and push local status updates
|
|
217
|
+
- **New local cards** are NOT pushed unless `--push-new` is specified (local-first default)
|
|
218
|
+
- **Conflicts** (both sides changed) resolve to remote-wins by default
|
|
219
|
+
|
|
220
|
+
### Status-to-Label Mapping
|
|
221
|
+
|
|
222
|
+
| viban status | GitHub label |
|
|
223
|
+
|-------------|-------------|
|
|
224
|
+
| `backlog` | *(no label)* |
|
|
225
|
+
| `in_progress` | `in-progress` |
|
|
226
|
+
| `review` | `review` |
|
|
227
|
+
| `done` | *(issue closed)* |
|
|
228
|
+
|
|
229
|
+
### Requirements
|
|
230
|
+
|
|
231
|
+
- [gh CLI](https://cli.github.com/) installed and authenticated (`gh auth login`)
|
|
232
|
+
- Repository must have a GitHub remote
|
|
233
|
+
|
|
178
234
|
## Configuration
|
|
179
235
|
|
|
180
236
|
### Data Location (viban.json)
|
|
@@ -184,18 +240,14 @@ viban stores issues in `viban.json` with the following priority:
|
|
|
184
240
|
| Priority | Location | When Used |
|
|
185
241
|
|----------|----------|-----------|
|
|
186
242
|
| 1 | `$VIBAN_DATA_DIR` | Explicit override via environment variable |
|
|
187
|
-
| 2 | `.
|
|
188
|
-
| 3 | `.viban/` | Non-git directories (fallback) |
|
|
243
|
+
| 2 | `.viban/` | Default (all projects) |
|
|
189
244
|
|
|
190
|
-
**
|
|
191
|
-
- Shared across git worktrees (parallel work sessions)
|
|
192
|
-
- Survives branch switches
|
|
193
|
-
- Single source of truth for the repository
|
|
245
|
+
**Auto-Migration:** If viban detects `viban.json` or `sync.json` in `.git/` (legacy location), it automatically moves them to `.viban/`.
|
|
194
246
|
|
|
195
|
-
**For
|
|
247
|
+
**For Any Project:**
|
|
196
248
|
```bash
|
|
197
249
|
# viban will automatically create .viban/viban.json in current directory
|
|
198
|
-
cd /path/to/
|
|
250
|
+
cd /path/to/project
|
|
199
251
|
viban add "First issue" "Description" P2 feat
|
|
200
252
|
# Creates: /path/to/non-git-project/.viban/viban.json
|
|
201
253
|
```
|
|
@@ -289,13 +341,22 @@ claude-plugin-viban/
|
|
|
289
341
|
│ └── viban # Main TUI/CLI script
|
|
290
342
|
├── docs/
|
|
291
343
|
│ └── CLAUDE.md # Claude Code integration guide
|
|
344
|
+
├── commands/
|
|
345
|
+
│ └── sync.md # /viban:sync command
|
|
292
346
|
├── scripts/
|
|
293
347
|
│ ├── check-deps.sh # Dependency checker
|
|
348
|
+
│ ├── sync.sh # Core sync engine (provider-agnostic)
|
|
349
|
+
│ ├── providers/
|
|
350
|
+
│ │ └── github.sh # GitHub Issues provider
|
|
294
351
|
│ └── tui_coprocess.py # Persistent Python coprocess for TUI rendering
|
|
295
352
|
├── skills/
|
|
296
353
|
│ ├── assign/SKILL.md # /viban:assign skill
|
|
297
354
|
│ ├── setup/SKILL.md # /viban:setup skill
|
|
355
|
+
│ ├── sync/SKILL.md # /viban:sync skill
|
|
298
356
|
│ └── task/SKILL.md # /viban:task skill
|
|
357
|
+
├── tests/
|
|
358
|
+
│ ├── run_all.zsh # Test runner
|
|
359
|
+
│ └── test_sync.zsh # Sync engine tests
|
|
299
360
|
├── LICENSE # MIT License
|
|
300
361
|
├── package.json # NPM package config
|
|
301
362
|
└── README.md # This file
|
package/bin/viban
CHANGED
|
@@ -121,6 +121,8 @@ IN_TUI=false
|
|
|
121
121
|
cleanup() {
|
|
122
122
|
# Skip cleanup in subshells — EXIT trap fires in $() command substitutions
|
|
123
123
|
[[ ${ZSH_SUBSHELL:-0} -gt 0 ]] && return
|
|
124
|
+
# Kill background sync if running
|
|
125
|
+
[[ -n "${_sync_pid:-}" ]] && kill "$_sync_pid" 2>/dev/null && wait "$_sync_pid" 2>/dev/null
|
|
124
126
|
_stop_coproc
|
|
125
127
|
printf '\033[?25h\033[0m'
|
|
126
128
|
stty echo 2>/dev/null
|
|
@@ -193,24 +195,14 @@ export TERM=${TERM:-xterm-256color}
|
|
|
193
195
|
# ============================================================
|
|
194
196
|
# Priority:
|
|
195
197
|
# 1. VIBAN_DATA_DIR env var (explicit override)
|
|
196
|
-
# 2.
|
|
197
|
-
# 3. Project root .viban/ directory (non-git projects)
|
|
198
|
+
# 2. Project root .viban/ directory
|
|
198
199
|
|
|
199
200
|
VIBAN_DATA_DIR="${VIBAN_DATA_DIR:-}"
|
|
200
201
|
VIBAN_IS_GIT_REPO=false
|
|
202
|
+
git rev-parse --git-dir &>/dev/null && VIBAN_IS_GIT_REPO=true
|
|
201
203
|
|
|
202
204
|
if [[ -z "$VIBAN_DATA_DIR" ]]; then
|
|
203
|
-
|
|
204
|
-
if _git_common="$(git rev-parse --git-common-dir 2>/dev/null)"; then
|
|
205
|
-
VIBAN_IS_GIT_REPO=true
|
|
206
|
-
if [[ -d "$_git_common" ]]; then
|
|
207
|
-
VIBAN_DATA_DIR="$(cd "$_git_common" && pwd)"
|
|
208
|
-
fi
|
|
209
|
-
fi
|
|
210
|
-
# Fallback: project root .viban directory
|
|
211
|
-
if [[ -z "$VIBAN_DATA_DIR" ]]; then
|
|
212
|
-
VIBAN_DATA_DIR="${PWD}/.viban"
|
|
213
|
-
fi
|
|
205
|
+
VIBAN_DATA_DIR="${PWD}/.viban"
|
|
214
206
|
fi
|
|
215
207
|
|
|
216
208
|
VIBAN_JSON="${VIBAN_DATA_DIR}/viban.json"
|
|
@@ -218,13 +210,16 @@ VIBAN_JSON="${VIBAN_DATA_DIR}/viban.json"
|
|
|
218
210
|
# Ensure data directory exists
|
|
219
211
|
mkdir -p "$VIBAN_DATA_DIR"
|
|
220
212
|
|
|
221
|
-
# Auto-migrate: .
|
|
222
|
-
if $
|
|
223
|
-
|
|
224
|
-
if [[ -f "$
|
|
225
|
-
mv "$
|
|
226
|
-
|
|
227
|
-
|
|
213
|
+
# Auto-migrate: .git/viban.json -> .viban/ (legacy location)
|
|
214
|
+
if _git_common="$(git rev-parse --git-common-dir 2>/dev/null)"; then
|
|
215
|
+
_git_dir="$(cd "$_git_common" && pwd)"
|
|
216
|
+
if [[ -f "${_git_dir}/viban.json" && ! -f "$VIBAN_JSON" ]]; then
|
|
217
|
+
mv "${_git_dir}/viban.json" "$VIBAN_JSON"
|
|
218
|
+
echo "✓ Migrated viban.json from .git/ to .viban/"
|
|
219
|
+
fi
|
|
220
|
+
if [[ -f "${_git_dir}/sync.json" && ! -f "${VIBAN_DATA_DIR}/sync.json" ]]; then
|
|
221
|
+
mv "${_git_dir}/sync.json" "${VIBAN_DATA_DIR}/sync.json"
|
|
222
|
+
echo "✓ Migrated sync.json from .git/ to .viban/"
|
|
228
223
|
fi
|
|
229
224
|
fi
|
|
230
225
|
|
|
@@ -336,8 +331,9 @@ init_json() {
|
|
|
336
331
|
if [[ ! -f "$VIBAN_JSON" ]]; then
|
|
337
332
|
local max_wt_id=0
|
|
338
333
|
if [[ -d "$VIBAN_DATA_DIR/worktrees" ]]; then
|
|
334
|
+
local wt_id
|
|
339
335
|
for d in "$VIBAN_DATA_DIR/worktrees/"*(/N); do
|
|
340
|
-
|
|
336
|
+
wt_id="${d:t}"
|
|
341
337
|
[[ "$wt_id" =~ ^[0-9]+$ ]] && (( wt_id > max_wt_id )) && max_wt_id=$wt_id
|
|
342
338
|
done
|
|
343
339
|
fi
|
|
@@ -700,14 +696,15 @@ build_column_lines() {
|
|
|
700
696
|
done <<< "$_batch_output"
|
|
701
697
|
else
|
|
702
698
|
# All-ASCII fast path - no Python needed
|
|
699
|
+
local _t _mw _fc _d
|
|
703
700
|
for (( _i=1; _i<=_n; _i++ )); do
|
|
704
|
-
|
|
701
|
+
_t="${_titles[$_i]}" _mw=${_title_max_ws[$_i]}
|
|
705
702
|
(( ${#_t} > _mw )) && _t="${_t:0:$_mw}"
|
|
706
703
|
_short_titles+=("$_t")
|
|
707
|
-
|
|
704
|
+
_fc="${_title_pfxs[$_i]}${_t}"
|
|
708
705
|
_title_cws+=(${#_fc})
|
|
709
706
|
|
|
710
|
-
|
|
707
|
+
_d="${_descs[$_i]}"
|
|
711
708
|
(( ${#_d} > _desc_max_w )) && _d="${_d:0:$_desc_max_w}"
|
|
712
709
|
_short_descs+=("$_d")
|
|
713
710
|
_desc_cws+=($((2 + ${#_d})))
|
|
@@ -717,29 +714,34 @@ build_column_lines() {
|
|
|
717
714
|
|
|
718
715
|
# --- Pass 3: Render cards ---
|
|
719
716
|
local shown=0
|
|
717
|
+
local id priority issue_type ext_id did
|
|
718
|
+
local spinner_prefix title_content title_pad
|
|
719
|
+
local desc_content desc_pad
|
|
720
|
+
local priority_tag priority_color type_tag type_color tags_w tags_pad
|
|
721
|
+
local border_color text_color desc_color
|
|
720
722
|
for (( _i=1; _i<=_n; _i++ )); do
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
723
|
+
id="${_ids[$_i]}"
|
|
724
|
+
priority="${_priorities[$_i]}"
|
|
725
|
+
issue_type="${_types[$_i]}"
|
|
726
|
+
ext_id="${_ext_ids[$_i]}"
|
|
727
|
+
did=$(display_id "$id" "$ext_id")
|
|
726
728
|
|
|
727
729
|
# Title line
|
|
728
|
-
|
|
730
|
+
spinner_prefix=""
|
|
729
731
|
[[ "$st" == "in_progress" ]] && spinner_prefix="${SPINNER_FRAMES[$((SPINNER_IDX % ${#SPINNER_FRAMES[@]} + 1))]} "
|
|
730
|
-
|
|
731
|
-
|
|
732
|
+
title_content=" ${spinner_prefix}${did} ${_short_titles[$_i]}"
|
|
733
|
+
title_pad=$((card_inner - ${_title_cws[$_i]}))
|
|
732
734
|
(( title_pad < 0 )) && title_pad=0
|
|
733
735
|
|
|
734
736
|
# Description line
|
|
735
|
-
|
|
736
|
-
|
|
737
|
+
desc_content=" ${_short_descs[$_i]}"
|
|
738
|
+
desc_pad=$((card_inner - ${_desc_cws[$_i]}))
|
|
737
739
|
(( desc_pad < 0 )) && desc_pad=0
|
|
738
740
|
|
|
739
741
|
# Priority and type tags
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
742
|
+
priority_tag="[$priority]"
|
|
743
|
+
priority_color="${PRIORITY_COLOR[$priority]:-$A_DIM}"
|
|
744
|
+
type_tag="" type_color="" tags_w=0
|
|
743
745
|
if [[ -n "$issue_type" ]]; then
|
|
744
746
|
type_tag="[${TYPE_LABEL[$issue_type]:-$issue_type}]"
|
|
745
747
|
type_color="${TYPE_COLOR[$issue_type]:-$A_DIM}"
|
|
@@ -747,11 +749,11 @@ build_column_lines() {
|
|
|
747
749
|
else
|
|
748
750
|
tags_w=${#priority_tag}
|
|
749
751
|
fi
|
|
750
|
-
|
|
752
|
+
tags_pad=$((card_inner - tags_w - 2))
|
|
751
753
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
754
|
+
border_color="$A_DIM"
|
|
755
|
+
text_color="$A_FG"
|
|
756
|
+
desc_color="$A_DIM"
|
|
755
757
|
if (( is_col_selected && shown == card_sel )); then
|
|
756
758
|
border_color="${A_SELECTED}"
|
|
757
759
|
text_color="${A_BOLD}${A_ACCENT}"
|
|
@@ -1044,7 +1046,17 @@ delete_issue() {
|
|
|
1044
1046
|
local id=$1
|
|
1045
1047
|
local repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
1046
1048
|
local wt_dir="$VIBAN_DATA_DIR/worktrees/$id"
|
|
1049
|
+
|
|
1050
|
+
# Determine branch name: prefer issue-{num} when external_id present
|
|
1047
1051
|
local branch="viban-$id"
|
|
1052
|
+
local _ext_id=$(get_ext_id "$id")
|
|
1053
|
+
if [[ -n "$_ext_id" && "$_ext_id" != "null" ]]; then
|
|
1054
|
+
local _issue_num="${_ext_id##*:}"
|
|
1055
|
+
if git -C "$repo_root" rev-parse --verify "issue-${_issue_num}" &>/dev/null 2>&1; then
|
|
1056
|
+
branch="issue-${_issue_num}"
|
|
1057
|
+
fi
|
|
1058
|
+
fi
|
|
1059
|
+
|
|
1048
1060
|
if [[ -d "$wt_dir" ]]; then
|
|
1049
1061
|
git -C "$repo_root" worktree remove "$wt_dir" --force 2>/dev/null
|
|
1050
1062
|
git -C "$repo_root" branch -D "$branch" 2>/dev/null
|
|
@@ -1058,6 +1070,11 @@ level1_columns() {
|
|
|
1058
1070
|
_start_coproc
|
|
1059
1071
|
local col=0 card=0
|
|
1060
1072
|
|
|
1073
|
+
# Auto-sync state (120 iterations × 0.5s timeout = ~60s interval)
|
|
1074
|
+
local _sync_counter=0
|
|
1075
|
+
local _SYNC_INTERVAL=120
|
|
1076
|
+
local _sync_pid=""
|
|
1077
|
+
|
|
1061
1078
|
# Hide cursor and disable input echo
|
|
1062
1079
|
stty -echo 2>/dev/null
|
|
1063
1080
|
printf '\033[?25l\033[2J\033[H'
|
|
@@ -1066,6 +1083,27 @@ level1_columns() {
|
|
|
1066
1083
|
update_term_cache
|
|
1067
1084
|
|
|
1068
1085
|
while true; do
|
|
1086
|
+
# Auto-sync: reap finished background sync
|
|
1087
|
+
if [[ -n "$_sync_pid" ]]; then
|
|
1088
|
+
if ! kill -0 "$_sync_pid" 2>/dev/null; then
|
|
1089
|
+
wait "$_sync_pid" 2>/dev/null
|
|
1090
|
+
_sync_pid=""
|
|
1091
|
+
fi
|
|
1092
|
+
fi
|
|
1093
|
+
|
|
1094
|
+
# Auto-sync: trigger when interval reached and sync configured
|
|
1095
|
+
((_sync_counter++)) || true
|
|
1096
|
+
if (( _sync_counter >= _SYNC_INTERVAL )) && [[ -z "$_sync_pid" && -f "$VIBAN_DATA_DIR/sync.json" ]]; then
|
|
1097
|
+
_sync_counter=0
|
|
1098
|
+
local _sync_provider
|
|
1099
|
+
_sync_provider=$(jq -r '.provider // ""' "$VIBAN_DATA_DIR/sync.json" 2>/dev/null)
|
|
1100
|
+
if [[ -n "$_sync_provider" && "$_sync_provider" != "null" ]]; then
|
|
1101
|
+
VIBAN_JSON="$VIBAN_JSON" VIBAN_DATA_DIR="$VIBAN_DATA_DIR" \
|
|
1102
|
+
VIBAN_PROVIDER="$_sync_provider" VIBAN_SCRIPT_DIR="$VIBAN_SCRIPT_DIR" \
|
|
1103
|
+
bash "$VIBAN_SCRIPT_DIR/scripts/sync.sh" --auto &
|
|
1104
|
+
_sync_pid=$!
|
|
1105
|
+
fi
|
|
1106
|
+
fi
|
|
1069
1107
|
# Cache JSON data once per frame
|
|
1070
1108
|
local json_data=$(cat "$VIBAN_JSON")
|
|
1071
1109
|
|
|
@@ -1417,6 +1455,20 @@ cmd_add() {
|
|
|
1417
1455
|
updated_at:$now
|
|
1418
1456
|
}]' "$VIBAN_JSON" > "$VIBAN_JSON.tmp" && mv "$VIBAN_JSON.tmp" "$VIBAN_JSON"
|
|
1419
1457
|
rm -f "$tmpjson"
|
|
1458
|
+
|
|
1459
|
+
# Auto-create remote issue if sync is configured and no ext_id provided
|
|
1460
|
+
if [[ -z "$ext_id" && -f "$VIBAN_DATA_DIR/sync.json" ]]; then
|
|
1461
|
+
local provider
|
|
1462
|
+
provider=$(jq -r '.provider // ""' "$VIBAN_DATA_DIR/sync.json" 2>/dev/null)
|
|
1463
|
+
if [[ -n "$provider" && "$provider" != "null" ]]; then
|
|
1464
|
+
local created_ext_id
|
|
1465
|
+
created_ext_id=$(VIBAN_JSON="$VIBAN_JSON" VIBAN_DATA_DIR="$VIBAN_DATA_DIR" \
|
|
1466
|
+
VIBAN_PROVIDER="$provider" VIBAN_SCRIPT_DIR="$VIBAN_SCRIPT_DIR" \
|
|
1467
|
+
bash "$VIBAN_SCRIPT_DIR/scripts/sync_create.sh" "$id" 2>/dev/null) || true
|
|
1468
|
+
[[ -n "$created_ext_id" ]] && ext_id="$created_ext_id"
|
|
1469
|
+
fi
|
|
1470
|
+
fi
|
|
1471
|
+
|
|
1420
1472
|
local type_info=""
|
|
1421
1473
|
[[ -n "$issue_type" ]] && type_info=" [$issue_type]"
|
|
1422
1474
|
local attach_info=""
|
|
@@ -1466,7 +1518,17 @@ cmd_done() {
|
|
|
1466
1518
|
# Cleanup worktree if exists
|
|
1467
1519
|
local repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
1468
1520
|
local wt_dir="$VIBAN_DATA_DIR/worktrees/$1"
|
|
1521
|
+
|
|
1522
|
+
# Determine branch name: prefer issue-{num} when external_id present
|
|
1469
1523
|
local branch="viban-$1"
|
|
1524
|
+
local _ext_id=$(get_ext_id "$1")
|
|
1525
|
+
if [[ -n "$_ext_id" && "$_ext_id" != "null" ]]; then
|
|
1526
|
+
local _issue_num="${_ext_id##*:}"
|
|
1527
|
+
if git -C "$repo_root" rev-parse --verify "issue-${_issue_num}" &>/dev/null 2>&1; then
|
|
1528
|
+
branch="issue-${_issue_num}"
|
|
1529
|
+
fi
|
|
1530
|
+
fi
|
|
1531
|
+
|
|
1470
1532
|
if [[ -d "$wt_dir" ]]; then
|
|
1471
1533
|
git -C "$repo_root" worktree remove "$wt_dir" --force 2>/dev/null
|
|
1472
1534
|
git -C "$repo_root" branch -D "$branch" 2>/dev/null
|
package/commands/add.md
CHANGED
|
@@ -4,78 +4,54 @@ description: "Register a problem as a viban issue"
|
|
|
4
4
|
|
|
5
5
|
# /add - Register Issue
|
|
6
6
|
|
|
7
|
-
Register a problem as a viban issue.
|
|
7
|
+
Register a problem as a viban issue. No codebase exploration, no solutions — symptoms only.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Input**: `$ARGUMENTS`
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Step 1: Clarify (only if vague)
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
If clear enough (who/what/where), skip to Step 2. Otherwise, one AskUserQuestion:
|
|
14
|
+
- header: "Problem", question: "Can you describe the symptom more specifically?"
|
|
15
|
+
- options: context-appropriate (e.g. "Error/crash", "Feature not working", "Performance issue", "Let me describe")
|
|
14
16
|
|
|
15
|
-
## Step
|
|
17
|
+
## Step 2: Priority & Type
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
Infer from description. Don't ask unless truly ambiguous.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
| Priority | Condition | Type | When |
|
|
22
|
+
|----------|-----------|------|------|
|
|
23
|
+
| P0 | System down, data loss | bug | Something broken |
|
|
24
|
+
| P1 | Feature broken, errors | feat | New functionality |
|
|
25
|
+
| P2 | Performance, warnings | chore | Maintenance, config |
|
|
26
|
+
| P3 | Improvements, refactoring | refactor | Code restructuring |
|
|
20
27
|
|
|
21
|
-
|
|
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
|
|
29
|
-
|
|
30
|
-
Goal: get a **one-sentence symptom** clear enough for an assignee to understand.
|
|
31
|
-
|
|
32
|
-
## Step 2: Determine Priority & Type
|
|
33
|
-
|
|
34
|
-
Infer from the description. Do NOT ask unless truly ambiguous.
|
|
35
|
-
|
|
36
|
-
| Condition | Priority |
|
|
37
|
-
|-----------|----------|
|
|
38
|
-
| System down, data loss | P0 |
|
|
39
|
-
| Feature broken, errors | P1 |
|
|
40
|
-
| Performance, warnings | P2 |
|
|
41
|
-
| Improvements, refactoring | P3 |
|
|
42
|
-
|
|
43
|
-
| Type | When |
|
|
44
|
-
|------|------|
|
|
45
|
-
| bug | Something is broken |
|
|
46
|
-
| feat | New functionality |
|
|
47
|
-
| chore | Maintenance, config |
|
|
48
|
-
| refactor | Code restructuring |
|
|
49
|
-
|
|
50
|
-
## Step 3: Check Workflow for Issue Numbering
|
|
28
|
+
## Step 3: Issue Numbering
|
|
51
29
|
|
|
52
30
|
```bash
|
|
53
31
|
[ -f ".viban/workflow.md" ] && cat ".viban/workflow.md"
|
|
54
32
|
```
|
|
55
33
|
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
34
|
+
- Workflow says **Manual** → ask user for external ID (e.g. `PROJ-42`)
|
|
35
|
+
- **Auto** or no workflow → let viban auto-assign
|
|
36
|
+
- ID in `$ARGUMENTS` → use it regardless
|
|
59
37
|
|
|
60
38
|
## Step 4: Register
|
|
61
39
|
|
|
62
|
-
Write the description to a temp file, then register:
|
|
63
|
-
|
|
64
40
|
```bash
|
|
65
41
|
cat > /tmp/viban-desc.md <<'VIBAN_EOF'
|
|
66
42
|
## Symptoms
|
|
67
|
-
{
|
|
68
|
-
{additional context
|
|
43
|
+
{one-sentence symptom}
|
|
44
|
+
{additional context, if any}
|
|
69
45
|
VIBAN_EOF
|
|
70
46
|
|
|
71
47
|
# Auto numbering (default)
|
|
72
48
|
viban add "{title}" --desc-file /tmp/viban-desc.md --priority {priority} --type {type}
|
|
73
49
|
|
|
74
|
-
# Manual numbering (when workflow specifies
|
|
50
|
+
# Manual numbering (when workflow specifies)
|
|
75
51
|
viban add "{title}" --desc-file /tmp/viban-desc.md --priority {priority} --type {type} --ext-id "{external_id}"
|
|
76
52
|
```
|
|
77
53
|
|
|
78
|
-
|
|
54
|
+
Use `<<'VIBAN_EOF'` (quoted) to prevent shell interpretation.
|
|
79
55
|
|
|
80
56
|
## Step 5: Report
|
|
81
57
|
|
|
@@ -86,9 +62,38 @@ Issue #{id} registered
|
|
|
86
62
|
Status: backlog
|
|
87
63
|
```
|
|
88
64
|
|
|
89
|
-
##
|
|
65
|
+
## Step 6: Suggest Plan Mode
|
|
66
|
+
|
|
67
|
+
**Skip** for trivial issues (typo, one-liner config, simple copy edit).
|
|
68
|
+
**Recommend** for everything else. Use AskUserQuestion:
|
|
69
|
+
|
|
70
|
+
- header: "Next step", question: "Want to start planning the solution now?"
|
|
71
|
+
- options:
|
|
72
|
+
- "Plan now (Recommended)" — Enter plan mode to analyze and design a solution
|
|
73
|
+
- "Later" — Just register, work on it later
|
|
74
|
+
|
|
75
|
+
**"Plan now"**: `EnterPlanMode` → after approval, save to `.viban/plans/{issue-id}.md`:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
mkdir -p .viban/plans
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```markdown
|
|
82
|
+
# Plan: {issue title}
|
|
83
|
+
> Issue #{id} | {priority} | {type} | Created: {timestamp}
|
|
84
|
+
|
|
85
|
+
{full plan content}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Report: `Plan saved to .viban/plans/{issue-id}.md — /viban:assign will auto-load it.`
|
|
89
|
+
|
|
90
|
+
**"Later"**: end skill.
|
|
91
|
+
|
|
92
|
+
> **Bias towards planning.** When in doubt, suggest plan mode.
|
|
93
|
+
|
|
94
|
+
## Rules
|
|
90
95
|
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
96
|
+
- No codebase exploration — assignee does that in `/viban:assign`
|
|
97
|
+
- No solution proposals — symptoms only
|
|
98
|
+
- Check duplicates first: `viban list`
|
|
99
|
+
- P0 is system-down only
|