@revotools/cli 0.6.0 → 0.6.1

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.
Files changed (2) hide show
  1. package/dist/revo +118 -19
  2. package/package.json +1 -1
package/dist/revo CHANGED
@@ -8,7 +8,7 @@ set -euo pipefail
8
8
  # Exit cleanly on SIGPIPE (e.g., revo clone | grep, revo status | head)
9
9
  trap 'exit 0' PIPE
10
10
 
11
- REVO_VERSION="0.6.0"
11
+ REVO_VERSION="0.6.1"
12
12
 
13
13
 
14
14
  # === lib/ui.sh ===
@@ -481,6 +481,7 @@ YAML_REPO_URLS=()
481
481
  YAML_REPO_PATHS=()
482
482
  YAML_REPO_TAGS=()
483
483
  YAML_REPO_DEPS=()
484
+ YAML_REPO_BRANCHES=()
484
485
 
485
486
  yaml_parse() {
486
487
  local file="$1"
@@ -497,6 +498,7 @@ yaml_parse() {
497
498
  YAML_REPO_PATHS=()
498
499
  YAML_REPO_TAGS=()
499
500
  YAML_REPO_DEPS=()
501
+ YAML_REPO_BRANCHES=()
500
502
 
501
503
  if [[ ! -f "$file" ]]; then
502
504
  return 1
@@ -550,6 +552,7 @@ yaml_parse() {
550
552
  YAML_REPO_PATHS[$current_index]=$(yaml_path_from_url "$url")
551
553
  YAML_REPO_TAGS[$current_index]=""
552
554
  YAML_REPO_DEPS[$current_index]=""
555
+ YAML_REPO_BRANCHES[$current_index]=""
553
556
  YAML_REPO_COUNT=$((YAML_REPO_COUNT + 1))
554
557
  continue
555
558
  fi
@@ -573,6 +576,8 @@ yaml_parse() {
573
576
  deps_str="${deps_str//\"/}"
574
577
  deps_str="${deps_str//\'/}"
575
578
  YAML_REPO_DEPS[$current_index]="$deps_str"
579
+ elif [[ "$trimmed" =~ ^branch:[[:space:]]*(.+)$ ]]; then
580
+ YAML_REPO_BRANCHES[$current_index]="${BASH_REMATCH[1]}"
576
581
  fi
577
582
  fi
578
583
  fi
@@ -648,6 +653,12 @@ yaml_get_deps() {
648
653
  printf '%s' "${YAML_REPO_DEPS[$idx]:-}"
649
654
  }
650
655
 
656
+ # Get repo default branch by index (empty means use workspace default)
657
+ yaml_get_branch() {
658
+ local idx="$1"
659
+ printf '%s' "${YAML_REPO_BRANCHES[$idx]:-}"
660
+ }
661
+
651
662
  # Find repo index by name (path basename)
652
663
  # Usage: idx=$(yaml_find_by_name "backend")
653
664
  # Returns: index or -1 if not found
@@ -681,6 +692,7 @@ yaml_write() {
681
692
  local path="${YAML_REPO_PATHS[$i]}"
682
693
  local tags="${YAML_REPO_TAGS[$i]}"
683
694
  local deps="${YAML_REPO_DEPS[$i]:-}"
695
+ local branch="${YAML_REPO_BRANCHES[$i]:-}"
684
696
 
685
697
  printf ' - url: %s\n' "$url"
686
698
 
@@ -700,6 +712,11 @@ yaml_write() {
700
712
  if [[ -n "$deps" ]]; then
701
713
  printf ' depends_on: [%s]\n' "$deps"
702
714
  fi
715
+
716
+ # Write branch if it differs from the workspace default
717
+ if [[ -n "$branch" ]] && [[ "$branch" != "$YAML_DEFAULTS_BRANCH" ]]; then
718
+ printf ' branch: %s\n' "$branch"
719
+ fi
703
720
  done
704
721
 
705
722
  printf '\ndefaults:\n'
@@ -708,12 +725,13 @@ yaml_write() {
708
725
  }
709
726
 
710
727
  # Add a repo to the config
711
- # Usage: yaml_add_repo "url" "path" "tags" "deps"
728
+ # Usage: yaml_add_repo "url" "path" "tags" "deps" ["branch"]
712
729
  yaml_add_repo() {
713
730
  local url="$1"
714
731
  local path="${2:-}"
715
732
  local tags="${3:-}"
716
733
  local deps="${4:-}"
734
+ local branch="${5:-}"
717
735
 
718
736
  local idx=$YAML_REPO_COUNT
719
737
 
@@ -725,6 +743,7 @@ yaml_add_repo() {
725
743
  YAML_REPO_PATHS[$idx]="$path"
726
744
  YAML_REPO_TAGS[$idx]="$tags"
727
745
  YAML_REPO_DEPS[$idx]="$deps"
746
+ YAML_REPO_BRANCHES[$idx]="$branch"
728
747
 
729
748
  YAML_REPO_COUNT=$((YAML_REPO_COUNT + 1))
730
749
  }
@@ -826,6 +845,7 @@ config_init() {
826
845
  YAML_REPO_PATHS=()
827
846
  YAML_REPO_TAGS=()
828
847
  YAML_REPO_DEPS=()
848
+ YAML_REPO_BRANCHES=()
829
849
 
830
850
  # Create directory structure
831
851
  mkdir -p "$REVO_REPOS_DIR"
@@ -967,11 +987,25 @@ config_workspace_name() {
967
987
  printf '%s' "$YAML_WORKSPACE_NAME"
968
988
  }
969
989
 
970
- # Get default branch
990
+ # Get workspace default branch
971
991
  config_default_branch() {
972
992
  printf '%s' "$YAML_DEFAULTS_BRANCH"
973
993
  }
974
994
 
995
+ # Get effective default branch for a specific repo
996
+ # Falls back to workspace default if no per-repo branch is set
997
+ # Usage: branch=$(config_repo_default_branch "repo_index")
998
+ config_repo_default_branch() {
999
+ local idx="$1"
1000
+ local branch
1001
+ branch=$(yaml_get_branch "$idx")
1002
+ if [[ -n "$branch" ]]; then
1003
+ printf '%s' "$branch"
1004
+ else
1005
+ printf '%s' "$YAML_DEFAULTS_BRANCH"
1006
+ fi
1007
+ }
1008
+
975
1009
  # === lib/git.sh ===
976
1010
  # Revo CLI - Git Operations
977
1011
  # Wrapper functions for git commands with consistent error handling
@@ -1180,6 +1214,34 @@ git_remote_url() {
1180
1214
  git -C "$repo_dir" remote get-url origin 2>/dev/null
1181
1215
  }
1182
1216
 
1217
+ # Detect the default branch for a cloned repo
1218
+ # Tries symbolic-ref first, then falls back to checking main/master
1219
+ # Usage: branch=$(git_default_branch "repo_dir")
1220
+ git_default_branch() {
1221
+ local repo_dir="$1"
1222
+ local ref
1223
+
1224
+ # Best source: what the remote says HEAD points to
1225
+ ref=$(git -C "$repo_dir" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null)
1226
+ if [[ -n "$ref" ]]; then
1227
+ printf '%s' "${ref##*/}"
1228
+ return 0
1229
+ fi
1230
+
1231
+ # Fallback: check which of main/master exists
1232
+ if git -C "$repo_dir" rev-parse --verify origin/main >/dev/null 2>&1; then
1233
+ printf '%s' "main"
1234
+ return 0
1235
+ fi
1236
+ if git -C "$repo_dir" rev-parse --verify origin/master >/dev/null 2>&1; then
1237
+ printf '%s' "master"
1238
+ return 0
1239
+ fi
1240
+
1241
+ # Last resort: whatever branch we're on
1242
+ git -C "$repo_dir" rev-parse --abbrev-ref HEAD 2>/dev/null
1243
+ }
1244
+
1183
1245
  # Check if branch exists (local or remote)
1184
1246
  # Usage: if git_branch_exists "repo_dir" "branch_name"; then ...
1185
1247
  git_branch_exists() {
@@ -1733,8 +1795,10 @@ cmd_init() {
1733
1795
  fi
1734
1796
 
1735
1797
  tags=$(_init_auto_tags "$dir" "$name")
1736
- yaml_add_repo "$remote" "$path" "$tags" ""
1737
- ui_step_done "Detected:" "$name → $remote"
1798
+ local branch
1799
+ branch=$(git_default_branch "$dir")
1800
+ yaml_add_repo "$remote" "$path" "$tags" "" "$branch"
1801
+ ui_step_done "Detected:" "$name → $remote (branch: $branch)"
1738
1802
  detected_count=$((detected_count + 1))
1739
1803
  done <<< "$_INIT_FOUND_DIRS"
1740
1804
 
@@ -1839,8 +1903,10 @@ cmd_detect() {
1839
1903
  ln -s "../$name" "repos/$name"
1840
1904
  fi
1841
1905
 
1842
- yaml_add_repo "$remote" "$name" "$tags" ""
1843
- ui_step_done "Found:" "$name ($remote)"
1906
+ local branch
1907
+ branch=$(git_default_branch "$d")
1908
+ yaml_add_repo "$remote" "$name" "$tags" "" "$branch"
1909
+ ui_step_done "Found:" "$name ($remote, branch: $branch)"
1844
1910
  found=$((found + 1))
1845
1911
  done
1846
1912
 
@@ -1860,8 +1926,10 @@ cmd_detect() {
1860
1926
  done
1861
1927
  [[ $already -eq 1 ]] && continue
1862
1928
  remote=$(cd "$d" && git remote get-url origin 2>/dev/null || echo "local://$d")
1863
- yaml_add_repo "$remote" "$name" "$name" ""
1864
- ui_step_done "Found:" "$name ($remote)"
1929
+ local branch
1930
+ branch=$(git_default_branch "$d")
1931
+ yaml_add_repo "$remote" "$name" "$name" "" "$branch"
1932
+ ui_step_done "Found:" "$name ($remote, branch: $branch)"
1865
1933
  found=$((found + 1))
1866
1934
  done
1867
1935
  fi
@@ -1966,7 +2034,13 @@ cmd_clone() {
1966
2034
  local clone_err
1967
2035
  if clone_err=$(git clone --quiet "$url" "$full_path" 2>&1); then
1968
2036
  ui_spinner_stop
1969
- ui_step_done "Cloned:" "$path"
2037
+ # Detect and store the repo's default branch
2038
+ local detected_branch
2039
+ detected_branch=$(git_default_branch "$full_path")
2040
+ if [[ -n "$detected_branch" ]]; then
2041
+ YAML_REPO_BRANCHES[$repo]="$detected_branch"
2042
+ fi
2043
+ ui_step_done "Cloned:" "$path (branch: ${detected_branch:-$YAML_DEFAULTS_BRANCH})"
1970
2044
  success_count=$((success_count + 1))
1971
2045
  else
1972
2046
  ui_spinner_error "Failed to clone: $path"
@@ -1977,9 +2051,12 @@ cmd_clone() {
1977
2051
  fi
1978
2052
  done <<< "$repos"
1979
2053
 
1980
- # Always regenerate the workspace CLAUDE.md after a clone batch so that
1981
- # newly cloned repos appear in the context immediately.
2054
+ # Persist any newly detected per-repo branches and regenerate CLAUDE.md
2055
+ # so newly cloned repos appear in the context immediately.
1982
2056
  if [[ $fail_count -eq 0 ]] && { [[ $success_count -gt 0 ]] || [[ $skip_count -gt 0 ]]; }; then
2057
+ if [[ $success_count -gt 0 ]]; then
2058
+ config_save
2059
+ fi
1983
2060
  context_regenerate_silent
1984
2061
  fi
1985
2062
 
@@ -2268,6 +2345,12 @@ cmd_checkout() {
2268
2345
  continue
2269
2346
  fi
2270
2347
 
2348
+ # Resolve "default" to each repo's own default branch
2349
+ local target="$branch_name"
2350
+ if [[ "$target" == "default" ]]; then
2351
+ target=$(config_repo_default_branch "$repo")
2352
+ fi
2353
+
2271
2354
  # Check for uncommitted changes
2272
2355
  if git_is_dirty "$full_path" && [[ $force -eq 0 ]]; then
2273
2356
  ui_step_error "Uncommitted changes: $path"
@@ -2277,15 +2360,15 @@ cmd_checkout() {
2277
2360
  fi
2278
2361
 
2279
2362
  # Check if branch exists
2280
- if ! git_branch_exists "$full_path" "$branch_name"; then
2281
- ui_step_error "Branch not found: $path"
2363
+ if ! git_branch_exists "$full_path" "$target"; then
2364
+ ui_step_error "Branch not found: $path ($target)"
2282
2365
  fail_count=$((fail_count + 1))
2283
2366
  continue
2284
2367
  fi
2285
2368
 
2286
2369
  # Checkout
2287
- if git_checkout "$full_path" "$branch_name"; then
2288
- ui_step_done "Checked out:" "$path → $branch_name"
2370
+ if git_checkout "$full_path" "$target"; then
2371
+ ui_step_done "Checked out:" "$path → $target"
2289
2372
  success_count=$((success_count + 1))
2290
2373
  else
2291
2374
  ui_step_error "Failed: $path - $GIT_ERROR"
@@ -2899,6 +2982,17 @@ _context_write_file() {
2899
2982
  url=$(yaml_get_url "$i")
2900
2983
  full_path="$REVO_REPOS_DIR/$path"
2901
2984
 
2985
+ local branch
2986
+ branch=$(yaml_get_branch "$i")
2987
+
2988
+ # Backfill: detect default branch for cloned repos that don't have one stored
2989
+ if [[ -z "$branch" ]] && [[ -d "$full_path" ]]; then
2990
+ branch=$(git_default_branch "$full_path")
2991
+ if [[ -n "$branch" ]]; then
2992
+ YAML_REPO_BRANCHES[$i]="$branch"
2993
+ fi
2994
+ fi
2995
+
2902
2996
  {
2903
2997
  printf '### %s\n' "$path"
2904
2998
 
@@ -2906,6 +3000,9 @@ _context_write_file() {
2906
3000
  printf -- '- **Tags:** %s\n' "$tags"
2907
3001
  fi
2908
3002
  printf -- '- **Path:** repos/%s\n' "$path"
3003
+ if [[ -n "$branch" ]] && [[ "$branch" != "$YAML_DEFAULTS_BRANCH" ]]; then
3004
+ printf -- '- **Default branch:** %s\n' "$branch"
3005
+ fi
2909
3006
  if [[ -n "$deps" ]]; then
2910
3007
  printf -- '- **Depends on:** %s\n' "$deps"
2911
3008
  fi
@@ -3151,6 +3248,8 @@ cmd_context() {
3151
3248
 
3152
3249
  ui_spinner_start "Scanning $YAML_REPO_COUNT repositories..."
3153
3250
  _context_write_file "$output"
3251
+ # Persist any newly detected per-repo branches back to revo.yaml
3252
+ config_save
3154
3253
  ui_spinner_stop
3155
3254
  ui_step_done "Scanned:" "$YAML_REPO_COUNT repositories"
3156
3255
  ui_step_done "Wrote:" "CLAUDE.md"
@@ -3286,10 +3385,10 @@ cmd_feature() {
3286
3385
  printf '# Feature: %s\n' "$name"
3287
3386
  printf '\n'
3288
3387
  printf '## Status\n'
3289
- printf '- Created: %s\n' "$timestamp"
3290
- printf '- Branch: %s\n' "$branch"
3388
+ printf -- '- Created: %s\n' "$timestamp"
3389
+ printf -- '- Branch: %s\n' "$branch"
3291
3390
  if [[ -n "$tag" ]]; then
3292
- printf '- Tag filter: %s\n' "$tag"
3391
+ printf -- '- Tag filter: %s\n' "$tag"
3293
3392
  fi
3294
3393
  printf '\n'
3295
3394
  printf '## Repos\n'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revotools/cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Claude-first multi-repo workspace manager (fork of Mars)",
5
5
  "bin": {
6
6
  "revo": "./dist/revo"