Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:08:16 +08:00
commit fc569e5620
38 changed files with 4997 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Apply transformation to multiple revisions
# Usage: jj-batch-desc <SED_SCRIPT_FILE> <REV1> [REV2...]
# Example: jj-batch-desc /tmp/replacements.sed abc xyz mno
set -euo pipefail
if [[ $# -lt 2 ]]; then
echo "Usage: jj-batch-desc <SED_SCRIPT_FILE> <REV1> [REV2...]" >&2
exit 1
fi
sed_script="$1"
shift
if [[ ! -f "$sed_script" ]]; then
echo "Error: sed script not found: $sed_script" >&2
exit 1
fi
for rev in "$@"; do
echo "Processing $rev..."
tmpfile="/tmp/jj_desc_${rev}_$$.txt"
jj log -r "$rev" -n1 --no-graph -T description > "$tmpfile"
sed -f "$sed_script" "$tmpfile" | jj desc -r "$rev" --stdin
rm -f "$tmpfile"
done
echo "✅ Processed $# revision(s)"

View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Create a named checkpoint before risky operations
# Usage: jj-checkpoint [NAME]
# Later restore with: jj op restore <op-id>
# NAME defaults to "checkpoint"
set -euo pipefail
name="${1:-checkpoint}"
# Get current operation ID
op_id=$(jj op log -n1 --no-graph -T 'self.id().short(12)')
echo "📍 Checkpoint '$name' at operation: $op_id"
echo " Restore with: jj op restore $op_id"
echo ""
echo " Current state:"
jj log -r @ -n1 -T 'change_id.shortest(8) ++ " " ++ description.first_line()'

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Transform revision description through a command
# Usage: jj-desc-transform <REV> <COMMAND...>
# Example: jj-desc-transform @ sed 's/foo/bar/'
# Example: jj-desc-transform mxyz awk '/^##/{print; next} {print " "$0}'
set -euo pipefail
if [[ $# -lt 2 ]]; then
echo "Usage: jj-desc-transform <REV> <COMMAND...>" >&2
exit 1
fi
rev="$1"
shift
jj log -r "$rev" -n1 --no-graph -T description | "$@" | jj desc -r "$rev" --stdin

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Find revisions with status flags
# Usage: jj-find-flagged [FLAG]
# FLAG: todo, wip, untested, broken, review (omit for all flagged)
set -euo pipefail
flag="${1:-}"
if [[ -n "$flag" ]]; then
# Use substring match instead of glob for specific flag
jj log -r "description(substring:\"[${flag}]\")"
else
# All flagged revisions - match common flags
jj log -r 'description(substring:"[todo]") | description(substring:"[wip]") | description(substring:"[untested]") | description(substring:"[broken]") | description(substring:"[review]")'
fi

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# Update status flag in revision description
# Usage: jj-flag-update <REV> <TO_FLAG>
# TO_FLAG is: todo, wip, untested, broken, review, or "done" (removes flag)
# Example: jj-flag-update @ wip
# Example: jj-flag-update mxyz done
#
# Automatically detects the current flag and replaces it.
set -euo pipefail
if [[ $# -ne 2 ]]; then
echo "Usage: jj-flag-update <REV> <TO_FLAG>" >&2
echo "Flags: todo, wip, untested, broken, review, done (done removes flag)" >&2
exit 1
fi
rev="$1"
to_flag="$2"
# Get current description
desc=$(jj log -r "$rev" -n1 --no-graph -T description)
# Detect current flag
current_flag=""
for flag in todo wip untested broken review; do
if [[ "$desc" =~ ^\[${flag}\] ]]; then
current_flag="$flag"
break
fi
done
if [[ -z "$current_flag" ]]; then
if [[ "$to_flag" == "done" ]]; then
# No flag to remove, nothing to do
exit 0
else
# No current flag - prepend the new one
echo "[${to_flag}] ${desc}" | jj desc -r "$rev" --stdin
exit 0
fi
fi
# Build sed pattern
if [[ "$to_flag" == "done" ]]; then
# Remove the flag (and trailing space)
sed_pattern="s/\[${current_flag}\] //"
else
sed_pattern="s/\[${current_flag}\]/[${to_flag}]/"
fi
echo "$desc" | sed "$sed_pattern" | jj desc -r "$rev" --stdin

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Create multiple parallel TODO branches from same parent
# Usage: jj-parallel-todos <PARENT> <TITLE1> <TITLE2> [TITLE3...]
# Example: jj-parallel-todos @ "Widget A" "Widget B" "Widget C"
set -euo pipefail
if [[ $# -lt 2 ]]; then
echo "Usage: jj-parallel-todos <PARENT> <TITLE1> <TITLE2> [TITLE3...]" >&2
exit 1
fi
parent="$1"
shift
for title in "$@"; do
jj new --no-edit "$parent" -m "[todo] ${title}"
done
echo "✅ Created $# parallel TODO branches from $parent"

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Get revision description only (for reading or piping)
# Usage: jj-show-desc [REV]
# REV defaults to @
set -euo pipefail
rev="${1:-@}"
jj log -r "$rev" -n1 --no-graph -T description

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Show detailed revision info with diff
# Usage: jj-show-detailed [REV]
# REV defaults to @
set -euo pipefail
rev="${1:-@}"
jj log -r "$rev" -n1 --no-graph -T builtin_log_detailed --git

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env bash
# Create empty TODO revision without editing (stays on current @)
# Usage: jj-todo-create <PARENT> <TITLE> [DESCRIPTION]
# Example: jj-todo-create @ "implement feature X" "detailed specs here"
set -euo pipefail
if [[ $# -lt 2 ]]; then
echo "Usage: jj-todo-create <PARENT> <TITLE> [DESCRIPTION]" >&2
exit 1
fi
parent="$1"
title="$2"
description="${3:-}"
if [[ -n "$description" ]]; then
msg="[todo] ${title}
${description}"
else
msg="[todo] ${title}"
fi
jj new --no-edit "$parent" -m "$msg"

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env bash
# Complete current TODO and optionally start the next one
# Usage: jj-todo-done [NEXT_REV]
#
# If NEXT_REV is provided, starts working on that revision.
# If not provided, lists possible next TODOs (children of current) and exits.
#
# Example:
# jj-todo-done # Complete current, show next options
# jj-todo-done abc123 # Complete current, start working on abc123
set -euo pipefail
SCRIPTS_DIR="$(dirname "$0")"
# Mark current as done (auto-detects current flag)
"$SCRIPTS_DIR/jj-flag-update" @ done
current=$(jj log -r @ --no-graph -T 'change_id.shortest(8)')
# Find children that are TODOs (have any flag)
children=$(jj log -r "children(@) & description(substring:\"[todo]\")" --no-graph -T 'change_id.shortest(8) ++ "\n"' 2>/dev/null || true)
if [[ -n "${1:-}" ]]; then
# User specified next revision
next="$1"
jj edit "$next"
"$SCRIPTS_DIR/jj-flag-update" @ wip
echo ""
echo "📋 Starting TODO:"
echo "─────────────────"
"$SCRIPTS_DIR/jj-show-desc" @
elif [[ -z "$children" ]]; then
echo "✅ Completed: $current"
echo ""
echo "No pending TODO children found. You may be done with this chain!"
echo ""
echo "Check remaining TODOs with:"
echo " jj-find-flagged todo"
elif [[ $(echo "$children" | wc -l) -eq 1 ]]; then
# Single child - start it automatically
next=$(echo "$children" | tr -d '[:space:]')
echo "✅ Completed: $current"
echo ""
jj edit "$next"
"$SCRIPTS_DIR/jj-flag-update" @ wip
echo ""
echo "📋 Starting TODO:"
echo "─────────────────"
"$SCRIPTS_DIR/jj-show-desc" @
else
# Multiple children - list them for user to choose
echo "✅ Completed: $current"
echo ""
echo "Multiple next TODOs available. Choose one:"
echo ""
while IFS= read -r child; do
[[ -z "$child" ]] && continue
title=$(jj log -r "$child" --no-graph -T 'description.first_line()' 2>/dev/null || echo "(no description)")
echo " $child $title"
done <<< "$children"
echo ""
echo "Run: jj-todo-done <change-id>"
fi