v0.2.0 759cc92

create-new-feature.sh RawHistoryFolder

1#!/usr/bin/env bash
2# Create a new feature with branch, directory structure, and template
3# Usage: ./create-new-feature.sh "feature description"
4#        ./create-new-feature.sh --json "feature description"
5
6set -e
7
8JSON_MODE=false
9
10# Collect non-flag args
11ARGS=()
12for arg in "$@"; do
13    case "$arg" in
14        --json)
15            JSON_MODE=true
16            ;;
17        --help|-h)
18            echo "Usage: $0 [--json] <feature_description>"; exit 0 ;;
19        *)
20            ARGS+=("$arg") ;;
21    esac
22done
23
24FEATURE_DESCRIPTION="${ARGS[*]}"
25if [ -z "$FEATURE_DESCRIPTION" ]; then
26        echo "Usage: $0 [--json] <feature_description>" >&2
27        exit 1
28fi
29
30# Get repository root
31REPO_ROOT=$(git rev-parse --show-toplevel)
32SPECS_DIR="$REPO_ROOT/specs"
33
34# Create specs directory if it doesn't exist
35mkdir -p "$SPECS_DIR"
36
37# Find the highest numbered feature directory
38HIGHEST=0
39if [ -d "$SPECS_DIR" ]; then
40    for dir in "$SPECS_DIR"/*; do
41        if [ -d "$dir" ]; then
42            dirname=$(basename "$dir")
43            number=$(echo "$dirname" | grep -o '^[0-9]\+' || echo "0")
44            number=$((10#$number))
45            if [ "$number" -gt "$HIGHEST" ]; then
46                HIGHEST=$number
47            fi
48        fi
49    done
50fi
51
52# Generate next feature number with zero padding
53NEXT=$((HIGHEST + 1))
54FEATURE_NUM=$(printf "%03d" "$NEXT")
55
56# Create branch name from description
57BRANCH_NAME=$(echo "$FEATURE_DESCRIPTION" | \
58    tr '[:upper:]' '[:lower:]' | \
59    sed 's/[^a-z0-9]/-/g' | \
60    sed 's/-\+/-/g' | \
61    sed 's/^-//' | \
62    sed 's/-$//')
63
64# Extract 2-3 meaningful words
65WORDS=$(echo "$BRANCH_NAME" | tr '-' '\n' | grep -v '^$' | head -3 | tr '\n' '-' | sed 's/-$//')
66
67# Final branch name
68BRANCH_NAME="${FEATURE_NUM}-${WORDS}"
69
70# Create and switch to new branch
71git checkout -b "$BRANCH_NAME"
72
73# Create feature directory
74FEATURE_DIR="$SPECS_DIR/$BRANCH_NAME"
75mkdir -p "$FEATURE_DIR"
76
77# Copy template if it exists
78TEMPLATE="$REPO_ROOT/templates/spec-template.md"
79SPEC_FILE="$FEATURE_DIR/spec.md"
80
81if [ -f "$TEMPLATE" ]; then
82    cp "$TEMPLATE" "$SPEC_FILE"
83else
84    echo "Warning: Template not found at $TEMPLATE" >&2
85    touch "$SPEC_FILE"
86fi
87
88if $JSON_MODE; then
89    printf '{"BRANCH_NAME":"%s","SPEC_FILE":"%s","FEATURE_NUM":"%s"}\n' \
90        "$BRANCH_NAME" "$SPEC_FILE" "$FEATURE_NUM"
91else
92    # Output results for the LLM to use (legacy key: value format)
93    echo "BRANCH_NAME: $BRANCH_NAME"
94    echo "SPEC_FILE: $SPEC_FILE"
95    echo "FEATURE_NUM: $FEATURE_NUM"
96fi

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close