-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask-new.sh
More file actions
executable file
·115 lines (95 loc) · 2.94 KB
/
task-new.sh
File metadata and controls
executable file
·115 lines (95 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
TASKS_DIR="$ROOT_DIR/tasks"
CONF="$ROOT_DIR/repos.conf"
if [[ ! -f "$CONF" ]]; then
echo "Error: repos.conf not found. Create it with one repo directory name per line."
exit 1
fi
# Read repo list from config (skip blank lines and comments)
mapfile -t VALID_REPOS < <(grep -v '^\s*#' "$CONF" | grep -v '^\s*$')
if [[ ${#VALID_REPOS[@]} -eq 0 ]]; then
echo "Error: repos.conf is empty. Add one repo directory name per line."
exit 1
fi
usage() {
echo "Usage: $0 <task-name> [repo ...]"
echo ""
echo "Create an isolated workspace with git worktrees for parallel Claude Code work."
echo ""
echo " task-name Branch and directory name (e.g. add-webhooks)"
echo " repo One or more of: ${VALID_REPOS[*]}"
echo " If omitted, creates worktrees for all repos."
echo ""
echo "Examples:"
echo " $0 add-webhooks ${VALID_REPOS[0]}"
if [[ ${#VALID_REPOS[@]} -ge 2 ]]; then
echo " $0 big-refactor ${VALID_REPOS[0]} ${VALID_REPOS[1]}"
fi
echo " $0 full-refactor # all repos"
exit 1
}
[[ $# -lt 1 ]] && usage
TASK_NAME="$1"
shift
# Validate task name
if [[ "$TASK_NAME" =~ [^a-zA-Z0-9_-] ]]; then
echo "Error: task name must only contain alphanumeric characters, hyphens, and underscores."
exit 1
fi
TASK_DIR="$TASKS_DIR/$TASK_NAME"
if [[ -d "$TASK_DIR" ]]; then
echo "Error: workspace '$TASK_NAME' already exists at $TASK_DIR"
exit 1
fi
# If no repos specified, use all
if [[ $# -eq 0 ]]; then
repos=("${VALID_REPOS[@]}")
else
repos=("$@")
fi
# Validate repo names
for repo in "${repos[@]}"; do
found=false
for valid in "${VALID_REPOS[@]}"; do
[[ "$repo" == "$valid" ]] && found=true && break
done
if ! $found; then
echo "Error: unknown repo '$repo'. Valid repos: ${VALID_REPOS[*]}"
exit 1
fi
done
# Create workspace
mkdir -p "$TASK_DIR"
echo "Creating workspace: $TASK_DIR"
echo ""
# Create worktrees
for repo in "${repos[@]}"; do
src="$ROOT_DIR/$repo"
dest="$TASK_DIR/$repo"
if [[ ! -d "$src/.git" ]]; then
echo "Warning: $src is not a git repo, skipping."
continue
fi
echo " $repo -> branch '$TASK_NAME'"
git -C "$src" worktree add "$dest" -b "$TASK_NAME" 2>&1 | sed 's/^/ /'
done
# Symlink root CLAUDE.md if it exists
if [[ -f "$ROOT_DIR/CLAUDE.md" ]]; then
ln -s "$ROOT_DIR/CLAUDE.md" "$TASK_DIR/CLAUDE.md"
fi
# Copy .claude config (Claude Code project settings)
if [[ -d "$ROOT_DIR/.claude" ]]; then
cp -r "$ROOT_DIR/.claude" "$TASK_DIR/.claude"
# Remove plans/memory from the copy — those should stay per-session
rm -rf "$TASK_DIR/.claude/plans" "$TASK_DIR/.claude/memory"
fi
echo ""
echo "Workspace ready: $TASK_DIR"
echo ""
echo "Contents:"
ls -1 "$TASK_DIR" | sed 's/^/ /'
echo ""
echo "To use: open Claude Code in $TASK_DIR"
echo "To clean up: ./task-done.sh $TASK_NAME"