Initial commit
This commit is contained in:
22
.claude-plugin/plugin.json
Normal file
22
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "workflows",
|
||||
"description": "Operational tooling for development workflows - git worktree management with AI context tracking",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Joe Seymour",
|
||||
"email": "zhongweili@tubi.tv"
|
||||
},
|
||||
"skills": [
|
||||
"./skills/working-tree"
|
||||
],
|
||||
"agents": [
|
||||
"./agents/consultant.md"
|
||||
],
|
||||
"commands": [
|
||||
"./commands/adopt.md",
|
||||
"./commands/destroy.md",
|
||||
"./commands/list.md",
|
||||
"./commands/new.md",
|
||||
"./commands/status.md"
|
||||
]
|
||||
}
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# workflows
|
||||
|
||||
Operational tooling for development workflows - git worktree management with AI context tracking
|
||||
1006
agents/consultant.md
Normal file
1006
agents/consultant.md
Normal file
File diff suppressed because it is too large
Load Diff
758
commands/adopt.md
Normal file
758
commands/adopt.md
Normal file
@@ -0,0 +1,758 @@
|
||||
---
|
||||
description: Add .ai-context.json metadata to an existing worktree
|
||||
argument-hint: [--mode <mode>] [--description "<text>"]
|
||||
allowed-tools: Bash, Write, Read
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# /adopt:working-tree
|
||||
|
||||
Generate `.ai-context.json` and `README.working-tree.md` for existing worktree lacking metadata.
|
||||
|
||||
## ARGUMENT SPECIFICATION
|
||||
|
||||
```
|
||||
SYNTAX: /adopt:working-tree [--mode <mode>] [--description "<text>"]
|
||||
|
||||
OPTIONAL:
|
||||
--mode <mode>
|
||||
Type: enum[main, feature, bugfix, experiment, review]
|
||||
Default: inferred from branch-name (see MODE_INFERENCE_ALGORITHM)
|
||||
Validation: must match exactly one of the enum values
|
||||
|
||||
--description "<text>"
|
||||
Type: string (quoted if contains spaces)
|
||||
Default: "" (empty string)
|
||||
Validation: any string, no restrictions
|
||||
```
|
||||
|
||||
## MODE_INFERENCE_ALGORITHM
|
||||
|
||||
APPLY rules sequentially, first match wins:
|
||||
|
||||
```python
|
||||
def infer_mode(branch_name: str) -> str:
|
||||
if branch_name.startswith("feature/"):
|
||||
return "feature"
|
||||
elif branch_name.startswith(("bugfix/", "fix/")):
|
||||
return "bugfix"
|
||||
elif branch_name.startswith(("exp/", "experiment/")):
|
||||
return "experiment"
|
||||
elif branch_name.startswith("review/"):
|
||||
return "review"
|
||||
elif branch_name in ("main", "master"):
|
||||
return "main"
|
||||
else:
|
||||
return "feature" # DEFAULT
|
||||
```
|
||||
|
||||
DETERMINISTIC: Given same branch_name, always produces same mode.
|
||||
|
||||
## EXECUTION PROTOCOL
|
||||
|
||||
Execute steps sequentially. Each step must complete successfully before proceeding.
|
||||
|
||||
### STEP 1: DETECT REPOSITORY INFO
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel 2>&1)
|
||||
EXIT_CODE_ROOT=$?
|
||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>&1)
|
||||
EXIT_CODE_BRANCH=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE_ROOT != 0 → ERROR PATTERN "not-in-git-repo"
|
||||
- IF EXIT_CODE_BRANCH != 0 → ERROR PATTERN "git-command-failed"
|
||||
- REPO_ROOT must be absolute path starting with /
|
||||
|
||||
DATA EXTRACTION:
|
||||
```bash
|
||||
WORKTREE_NAME=$(basename "$REPO_ROOT")
|
||||
```
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 2
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 2: CHECK EXISTING METADATA
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
METADATA_PATH="$REPO_ROOT/.ai-context.json"
|
||||
test -f "$METADATA_PATH"
|
||||
EXISTS=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- EXISTS is 0 (exists) or 1 (does not exist)
|
||||
|
||||
ACTION:
|
||||
- IF EXISTS == 0 → STEP 3 (check for overwrite)
|
||||
- IF EXISTS == 1 → STEP 4 (proceed with creation)
|
||||
|
||||
NEXT:
|
||||
- Conditional based on EXISTS value
|
||||
|
||||
### STEP 3: HANDLE EXISTING METADATA
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
EXISTING_JSON=$(cat "$METADATA_PATH" 2>&1)
|
||||
EXISTING_MODE=$(echo "$EXISTING_JSON" | jq -r '.mode // "unknown"' 2>&1)
|
||||
EXISTING_DESC=$(echo "$EXISTING_JSON" | jq -r '.description // ""' 2>&1)
|
||||
EXISTING_CREATED=$(echo "$EXISTING_JSON" | jq -r '.created // ""' 2>&1)
|
||||
```
|
||||
|
||||
DISPLAY TO USER:
|
||||
```
|
||||
Current worktree already has metadata:
|
||||
|
||||
Directory: {WORKTREE_NAME}
|
||||
Branch: {CURRENT_BRANCH}
|
||||
Mode: {EXISTING_MODE}
|
||||
Created: {EXISTING_CREATED}
|
||||
Description: {EXISTING_DESC or "None"}
|
||||
|
||||
Do you want to overwrite this metadata?
|
||||
```
|
||||
|
||||
USER DECISION (use AskUserQuestion):
|
||||
- Option 1: "Keep existing metadata" → TERMINATE (no changes)
|
||||
- Option 2: "Overwrite with new metadata" → STEP 4 (proceed)
|
||||
- Option 3: "Cancel" → TERMINATE (no changes)
|
||||
|
||||
NEXT:
|
||||
- IF user selects overwrite → STEP 4
|
||||
- IF user selects keep/cancel → TERMINATE
|
||||
|
||||
### STEP 4: PARSE AND VALIDATE ARGUMENTS
|
||||
|
||||
PARSE:
|
||||
```bash
|
||||
# Parse --mode flag (if present)
|
||||
if [[ "$@" =~ --mode[[:space:]]+([a-z]+) ]]; then
|
||||
MODE_ARG="${BASH_REMATCH[1]}"
|
||||
else
|
||||
MODE_ARG=""
|
||||
fi
|
||||
|
||||
# Parse --description flag (if present)
|
||||
if [[ "$@" =~ --description[[:space:]]+\"([^\"]+)\" ]]; then
|
||||
DESCRIPTION="${BASH_REMATCH[1]}"
|
||||
elif [[ "$@" =~ --description[[:space:]]+([^[:space:]]+) ]]; then
|
||||
DESCRIPTION="${BASH_REMATCH[1]}"
|
||||
else
|
||||
DESCRIPTION=""
|
||||
fi
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF MODE_ARG not empty AND MODE_ARG not in [main, feature, bugfix, experiment, review] → ERROR PATTERN "invalid-mode"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 5
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 5: DETERMINE MODE
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
if [ -n "$MODE_ARG" ]; then
|
||||
# Explicit mode provided
|
||||
MODE="$MODE_ARG"
|
||||
else
|
||||
# Infer from branch name using MODE_INFERENCE_ALGORITHM
|
||||
case "$CURRENT_BRANCH" in
|
||||
feature/*)
|
||||
MODE="feature"
|
||||
;;
|
||||
bugfix/*|fix/*)
|
||||
MODE="bugfix"
|
||||
;;
|
||||
exp/*|experiment/*)
|
||||
MODE="experiment"
|
||||
;;
|
||||
review/*)
|
||||
MODE="review"
|
||||
;;
|
||||
main|master)
|
||||
MODE="main"
|
||||
;;
|
||||
*)
|
||||
MODE="feature"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- MODE must be exactly one of: main, feature, bugfix, experiment, review
|
||||
- MODE must not be empty
|
||||
|
||||
DATA:
|
||||
- MODE = final determined mode (explicit or inferred)
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 6
|
||||
- On failure → ABORT (should not occur if STEP 4 validation passed)
|
||||
|
||||
### STEP 6: GENERATE TIMESTAMP
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
CREATED_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
```
|
||||
|
||||
FORMAT: ISO 8601 UTC (example: 2025-11-23T12:34:56Z)
|
||||
|
||||
VALIDATION:
|
||||
- CREATED_TIMESTAMP must match pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 7
|
||||
- No failure case
|
||||
|
||||
### STEP 7: GENERATE .ai-context.json
|
||||
|
||||
CONTENT TEMPLATE:
|
||||
```json
|
||||
{
|
||||
"worktree": "{WORKTREE_NAME}",
|
||||
"branch": "{CURRENT_BRANCH}",
|
||||
"mode": "{MODE}",
|
||||
"created": "{CREATED_TIMESTAMP}",
|
||||
"description": "{DESCRIPTION}"
|
||||
}
|
||||
```
|
||||
|
||||
SUBSTITUTIONS:
|
||||
- {WORKTREE_NAME} = from STEP 1
|
||||
- {CURRENT_BRANCH} = from STEP 1
|
||||
- {MODE} = from STEP 5
|
||||
- {CREATED_TIMESTAMP} = from STEP 6
|
||||
- {DESCRIPTION} = from STEP 4 (empty string if not provided)
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
cat > "$REPO_ROOT/.ai-context.json" <<EOF
|
||||
{
|
||||
"worktree": "$WORKTREE_NAME",
|
||||
"branch": "$CURRENT_BRANCH",
|
||||
"mode": "$MODE",
|
||||
"created": "$CREATED_TIMESTAMP",
|
||||
"description": "$DESCRIPTION"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- File must be created at exact path: $REPO_ROOT/.ai-context.json
|
||||
- File must contain valid JSON
|
||||
- Verify with: `jq empty "$REPO_ROOT/.ai-context.json"`
|
||||
- IF jq fails → ERROR PATTERN "metadata-write-failed"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 8
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 8: GENERATE README.working-tree.md (IF MISSING)
|
||||
|
||||
CHECK:
|
||||
```bash
|
||||
README_PATH="$REPO_ROOT/README.working-tree.md"
|
||||
test -f "$README_PATH"
|
||||
README_EXISTS=$?
|
||||
```
|
||||
|
||||
ACTION:
|
||||
- IF README_EXISTS == 0 (exists) → SKIP to STEP 9 (don't overwrite)
|
||||
- IF README_EXISTS == 1 (missing) → Create README
|
||||
|
||||
CONTENT TEMPLATE:
|
||||
```markdown
|
||||
# Worktree: {WORKTREE_NAME}
|
||||
|
||||
**Branch:** `{CURRENT_BRANCH}`
|
||||
**Mode:** `{MODE}`
|
||||
**Created:** {CREATED_TIMESTAMP}
|
||||
|
||||
## Purpose
|
||||
|
||||
{DESCRIPTION_OR_DEFAULT}
|
||||
|
||||
## Mode Semantics
|
||||
|
||||
- **main**: Minimal changes, stable work only
|
||||
- **feature**: Active development, larger changes allowed
|
||||
- **bugfix**: Isolated, surgical fixes only
|
||||
- **experiment**: Prototypes, large swings, unsafe changes allowed
|
||||
- **review**: Documentation, analysis, audits
|
||||
|
||||
## About This Worktree
|
||||
|
||||
This directory is an independent Git worktree attached to the main repository.
|
||||
|
||||
- Main repo: {REPO_ROOT}
|
||||
- Worktree path: {REPO_ROOT}
|
||||
- Branch: {CURRENT_BRANCH}
|
||||
|
||||
See `.ai-context.json` for machine-readable metadata.
|
||||
```
|
||||
|
||||
SUBSTITUTIONS:
|
||||
- {WORKTREE_NAME} = from STEP 1
|
||||
- {CURRENT_BRANCH} = from STEP 1
|
||||
- {MODE} = from STEP 5
|
||||
- {CREATED_TIMESTAMP} = from STEP 6
|
||||
- {DESCRIPTION_OR_DEFAULT} = DESCRIPTION if not empty, else "No description provided"
|
||||
- {REPO_ROOT} = from STEP 1
|
||||
|
||||
EXECUTE (only if README_EXISTS == 1):
|
||||
```bash
|
||||
DESCRIPTION_TEXT="${DESCRIPTION:-No description provided}"
|
||||
cat > "$REPO_ROOT/README.working-tree.md" <<EOF
|
||||
# Worktree: $WORKTREE_NAME
|
||||
|
||||
**Branch:** \`$CURRENT_BRANCH\`
|
||||
**Mode:** \`$MODE\`
|
||||
**Created:** $CREATED_TIMESTAMP
|
||||
|
||||
## Purpose
|
||||
|
||||
$DESCRIPTION_TEXT
|
||||
|
||||
## Mode Semantics
|
||||
|
||||
- **main**: Minimal changes, stable work only
|
||||
- **feature**: Active development, larger changes allowed
|
||||
- **bugfix**: Isolated, surgical fixes only
|
||||
- **experiment**: Prototypes, large swings, unsafe changes allowed
|
||||
- **review**: Documentation, analysis, audits
|
||||
|
||||
## About This Worktree
|
||||
|
||||
This directory is an independent Git worktree attached to the main repository.
|
||||
|
||||
- Main repo: $REPO_ROOT
|
||||
- Worktree path: $REPO_ROOT
|
||||
- Branch: $CURRENT_BRANCH
|
||||
|
||||
See \`.ai-context.json\` for machine-readable metadata.
|
||||
EOF
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF created, file must exist at: $REPO_ROOT/README.working-tree.md
|
||||
- IF file creation failed → Warning (not fatal)
|
||||
|
||||
NEXT:
|
||||
- On success or skip → STEP 9
|
||||
- On failure → Warning (continue)
|
||||
|
||||
### STEP 9: OUTPUT SUCCESS SUMMARY
|
||||
|
||||
OUTPUT FORMAT (exact):
|
||||
```
|
||||
Adopted worktree successfully!
|
||||
|
||||
Directory: {WORKTREE_NAME}
|
||||
Branch: {CURRENT_BRANCH}
|
||||
Mode: {MODE}
|
||||
Description: {DESCRIPTION_OR_NONE}
|
||||
|
||||
Metadata files created:
|
||||
✓ .ai-context.json
|
||||
{README_STATUS}
|
||||
|
||||
Use /status:working-tree to view metadata anytime.
|
||||
```
|
||||
|
||||
SUBSTITUTIONS:
|
||||
- {WORKTREE_NAME} = from STEP 1
|
||||
- {CURRENT_BRANCH} = from STEP 1
|
||||
- {MODE} = from STEP 5
|
||||
- {DESCRIPTION_OR_NONE} = DESCRIPTION if not empty, else "None"
|
||||
- {README_STATUS} = "✓ README.working-tree.md (created)" if created, "- README.working-tree.md (already exists)" if skipped
|
||||
|
||||
NEXT:
|
||||
- TERMINATE (success)
|
||||
|
||||
## ERROR PATTERNS
|
||||
|
||||
### PATTERN: not-in-git-repo
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git rev-parse --show-toplevel exit code != 0
|
||||
- INDICATORS: stderr contains "not a git repository"
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Not in a git repository
|
||||
|
||||
Run this command from within a git repository.
|
||||
|
||||
To create a new worktree with metadata:
|
||||
/create:working-tree <branch-name>
|
||||
```
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: git-command-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: Any git command (except rev-parse --show-toplevel) returns non-zero exit code
|
||||
- CAPTURE: stderr from git command
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to read git information
|
||||
|
||||
Git error: {GIT_STDERR}
|
||||
|
||||
Check that:
|
||||
- You're in a git repository
|
||||
- Git is installed and working
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {GIT_STDERR} = captured stderr
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: invalid-mode
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: MODE_ARG provided but not in [main, feature, bugfix, experiment, review]
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Invalid mode '{MODE_ARG}'
|
||||
|
||||
Valid modes: main, feature, bugfix, experiment, review
|
||||
|
||||
Example:
|
||||
/adopt:working-tree --mode feature --description "new feature work"
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {MODE_ARG} = the invalid mode provided
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: metadata-write-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: .ai-context.json write fails or invalid JSON (STEP 7)
|
||||
- CHECK: jq validation fails
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to write .ai-context.json
|
||||
|
||||
Write error: {ERROR_MESSAGE}
|
||||
|
||||
Check that:
|
||||
- You have write permission in this directory
|
||||
- Disk space is available
|
||||
- No file conflicts exist
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {ERROR_MESSAGE} = error message from write operation
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: readme-write-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: README.working-tree.md write fails (STEP 8)
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Warning: Failed to write README.working-tree.md
|
||||
|
||||
The .ai-context.json was created successfully.
|
||||
|
||||
You can manually create the README if needed.
|
||||
```
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: false (warning, not critical)
|
||||
- CLEANUP: none
|
||||
- FALLBACK: Continue without README
|
||||
|
||||
## TOOL PERMISSION MATRIX
|
||||
|
||||
| Tool | Pattern | Permission | Pre-Check | Post-Check | On-Deny-Action |
|
||||
|------|---------|------------|-----------|------------|----------------|
|
||||
| Bash | git:* | ALLOW | command_safe | validate_output | N/A |
|
||||
| Bash | date:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | test:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | basename:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | cat > *.json | ALLOW | dir_writable | valid_json | N/A |
|
||||
| Bash | cat > *.md | ALLOW | dir_writable | N/A | N/A |
|
||||
| Bash | jq:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | rm:* | DENY | N/A | N/A | ABORT "Destructive operation" |
|
||||
| Bash | sudo:* | DENY | N/A | N/A | ABORT "Elevated privileges" |
|
||||
| Write | $REPO_ROOT/.ai-context.json | ALLOW | dir_exists | valid_json | N/A |
|
||||
| Write | $REPO_ROOT/README.working-tree.md | ALLOW | dir_exists | N/A | N/A |
|
||||
| Write | **/.env* | DENY | N/A | N/A | ABORT "Secrets file" |
|
||||
| Read | $REPO_ROOT/.ai-context.json | ALLOW | file_exists | N/A | N/A |
|
||||
|
||||
SECURITY CONSTRAINTS:
|
||||
- Can only write to current worktree directory (REPO_ROOT)
|
||||
- Cannot modify files outside current worktree
|
||||
- Cannot execute destructive operations
|
||||
- All file writes must be to metadata files only
|
||||
|
||||
## TEST CASES
|
||||
|
||||
### TC001: Adopt worktree without metadata
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository at /Users/dev/myapp
|
||||
- Current branch: feature/login
|
||||
- File does NOT exist: /Users/dev/myapp/.ai-context.json
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/adopt:working-tree
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → REPO_ROOT="/Users/dev/myapp", WORKTREE_NAME="myapp", CURRENT_BRANCH="feature/login"
|
||||
2. STEP 2 → EXISTS=1 (no metadata)
|
||||
3. STEP 4 → MODE_ARG="", DESCRIPTION=""
|
||||
4. STEP 5 → MODE="feature" (inferred from "feature/" prefix)
|
||||
5. STEP 6 → Generate timestamp
|
||||
6. STEP 7 → Write .ai-context.json
|
||||
7. STEP 8 → README_EXISTS=1, create README
|
||||
8. STEP 9 → Output summary
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Adopted worktree successfully!
|
||||
|
||||
Directory: myapp
|
||||
Branch: feature/login
|
||||
Mode: feature
|
||||
Description: None
|
||||
|
||||
Metadata files created:
|
||||
✓ .ai-context.json
|
||||
✓ README.working-tree.md (created)
|
||||
|
||||
Use /status:working-tree to view metadata anytime.
|
||||
```
|
||||
|
||||
VALIDATION COMMANDS:
|
||||
```bash
|
||||
# Verify .ai-context.json created
|
||||
test -f /Users/dev/myapp/.ai-context.json && echo "PASS" || echo "FAIL"
|
||||
jq -r '.mode' /Users/dev/myapp/.ai-context.json | grep "feature" && echo "PASS" || echo "FAIL"
|
||||
|
||||
# Verify README created
|
||||
test -f /Users/dev/myapp/README.working-tree.md && echo "PASS" || echo "FAIL"
|
||||
```
|
||||
|
||||
### TC002: Adopt with explicit mode and description
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository at /Users/dev/myapp
|
||||
- Current branch: main
|
||||
- No existing metadata
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/adopt:working-tree --mode main --description "Primary development branch"
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-2. Standard detection
|
||||
3. STEP 4 → MODE_ARG="main", DESCRIPTION="Primary development branch"
|
||||
4. STEP 5 → MODE="main" (explicit, not inferred)
|
||||
5-8. Standard flow
|
||||
|
||||
EXPECTED .ai-context.json:
|
||||
```json
|
||||
{
|
||||
"worktree": "myapp",
|
||||
"branch": "main",
|
||||
"mode": "main",
|
||||
"created": "2025-11-23T12:34:56Z",
|
||||
"description": "Primary development branch"
|
||||
}
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
```bash
|
||||
jq -r '.mode' .ai-context.json | grep "main" && echo "PASS" || echo "FAIL"
|
||||
jq -r '.description' .ai-context.json | grep "Primary development branch" && echo "PASS" || echo "FAIL"
|
||||
```
|
||||
|
||||
### TC003: Metadata already exists - user keeps existing
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository at /Users/dev/myapp
|
||||
- File exists: /Users/dev/myapp/.ai-context.json with valid data
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/adopt:working-tree --mode experiment
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → Detect repo
|
||||
2. STEP 2 → EXISTS=0 (metadata exists)
|
||||
3. STEP 3 → Display existing metadata, ask user
|
||||
4. USER SELECTS "Keep existing metadata"
|
||||
5. TERMINATE (no changes)
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Current worktree already has metadata:
|
||||
|
||||
Directory: myapp
|
||||
Branch: feature/login
|
||||
Mode: feature
|
||||
Created: 2025-11-20T10:00:00Z
|
||||
Description: Original description
|
||||
|
||||
Do you want to overwrite this metadata?
|
||||
```
|
||||
|
||||
POSTCONDITIONS:
|
||||
- .ai-context.json unchanged
|
||||
- No files modified
|
||||
|
||||
### TC004: Metadata already exists - user overwrites
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository with existing .ai-context.json
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/adopt:working-tree --mode experiment --description "New description"
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-2. Detect repo, metadata exists
|
||||
3. STEP 3 → Display existing, ask user
|
||||
4. USER SELECTS "Overwrite with new metadata"
|
||||
5-9. Continue with creation (new timestamp, new mode, new description)
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Current worktree already has metadata:
|
||||
[existing data shown]
|
||||
|
||||
Do you want to overwrite this metadata?
|
||||
|
||||
[User confirms overwrite]
|
||||
|
||||
Adopted worktree successfully!
|
||||
|
||||
Directory: myapp
|
||||
Branch: feature/login
|
||||
Mode: experiment
|
||||
Description: New description
|
||||
|
||||
Metadata files created:
|
||||
✓ .ai-context.json
|
||||
- README.working-tree.md (already exists)
|
||||
|
||||
Use /status:working-tree to view metadata anytime.
|
||||
```
|
||||
|
||||
### TC005: README already exists
|
||||
|
||||
PRECONDITIONS:
|
||||
- No .ai-context.json
|
||||
- README.working-tree.md already exists
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/adopt:working-tree
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-7. Standard flow, create .ai-context.json
|
||||
8. STEP 8 → README_EXISTS=0 (exists), skip creation
|
||||
9. STEP 9 → Output shows README skipped
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Adopted worktree successfully!
|
||||
|
||||
Directory: myapp
|
||||
Branch: feature/login
|
||||
Mode: feature
|
||||
Description: None
|
||||
|
||||
Metadata files created:
|
||||
✓ .ai-context.json
|
||||
- README.working-tree.md (already exists)
|
||||
|
||||
Use /status:working-tree to view metadata anytime.
|
||||
```
|
||||
|
||||
## USE CASES
|
||||
|
||||
### UC001: Adopting main repository
|
||||
When working in main repo without worktrees:
|
||||
```bash
|
||||
cd ~/myapp
|
||||
/adopt:working-tree --mode main --description "Primary development branch"
|
||||
```
|
||||
|
||||
### UC002: Adopting manually created worktree
|
||||
If worktree created without /create:working-tree:
|
||||
```bash
|
||||
cd ../myapp-feature-something
|
||||
/adopt:working-tree
|
||||
```
|
||||
|
||||
### UC003: Adding description later
|
||||
If worktree created without description:
|
||||
```bash
|
||||
/adopt:working-tree --description "Working on user authentication refactor"
|
||||
```
|
||||
(Will prompt to overwrite existing metadata)
|
||||
|
||||
### UC004: Correcting mode
|
||||
If mode was inferred incorrectly:
|
||||
```bash
|
||||
/adopt:working-tree --mode experiment
|
||||
```
|
||||
(Will prompt to overwrite existing metadata)
|
||||
|
||||
## RELATED COMMANDS
|
||||
|
||||
- /status:working-tree - View current metadata after adoption
|
||||
- /create:working-tree - Create new worktree with metadata from start
|
||||
- /list:working-tree - See all worktrees and their metadata status
|
||||
|
||||
## DELEGATION
|
||||
|
||||
For organizing worktree adoption strategy:
|
||||
```
|
||||
Task(
|
||||
subagent_type='working-tree-consultant',
|
||||
description='Worktree adoption strategy',
|
||||
prompt='[question about when/how to adopt worktrees]'
|
||||
)
|
||||
```
|
||||
673
commands/destroy.md
Normal file
673
commands/destroy.md
Normal file
@@ -0,0 +1,673 @@
|
||||
---
|
||||
description: Safely remove a git worktree and its metadata (preserves branch)
|
||||
argument-hint: <worktree-path>
|
||||
allowed-tools: Bash, Read
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# /destroy:working-tree
|
||||
|
||||
Safely remove git worktree directory and metadata files. Branch is preserved.
|
||||
|
||||
## ARGUMENT SPECIFICATION
|
||||
|
||||
```
|
||||
SYNTAX: /destroy:working-tree <worktree-path>
|
||||
|
||||
REQUIRED:
|
||||
<worktree-path>
|
||||
Type: path (absolute or relative)
|
||||
Validation: Must be registered git worktree
|
||||
Examples: "../myapp-feature-login", "/Users/dev/myapp-feature-login"
|
||||
```
|
||||
|
||||
## EXECUTION PROTOCOL
|
||||
|
||||
Execute steps sequentially. Each step must complete successfully before proceeding.
|
||||
|
||||
### STEP 1: VALIDATE AND RESOLVE WORKTREE PATH
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
# Resolve to absolute path
|
||||
if [[ "$WORKTREE_PATH_ARG" = /* ]]; then
|
||||
WORKTREE_PATH="$WORKTREE_PATH_ARG"
|
||||
else
|
||||
WORKTREE_PATH=$(cd "$(dirname "$WORKTREE_PATH_ARG")" && pwd)/$(basename "$WORKTREE_PATH_ARG")
|
||||
fi
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF WORKTREE_PATH_ARG is empty → ERROR PATTERN "missing-path"
|
||||
- WORKTREE_PATH must be absolute after resolution
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 2
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 2: CHECK PATH EXISTS
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
test -e "$WORKTREE_PATH"
|
||||
EXISTS=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXISTS != 0 → ERROR PATTERN "path-not-exist"
|
||||
|
||||
NEXT:
|
||||
- On EXISTS == 0 → STEP 3
|
||||
- On EXISTS != 0 → ABORT
|
||||
|
||||
### STEP 3: GET ALL WORKTREES AND VALIDATE
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
WORKTREE_LIST=$(git worktree list --porcelain 2>&1)
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → ERROR PATTERN "git-command-failed"
|
||||
|
||||
PARSE WORKTREE_LIST:
|
||||
```bash
|
||||
# Extract all worktree paths and branches
|
||||
# Format: worktree /path\nHEAD hash\nbranch refs/heads/name\n\n
|
||||
CURRENT_MAIN=$(echo "$WORKTREE_LIST" | head -1 | cut -d' ' -f2)
|
||||
IS_MAIN_REPO=false
|
||||
|
||||
if [ "$WORKTREE_PATH" = "$CURRENT_MAIN" ]; then
|
||||
IS_MAIN_REPO=true
|
||||
fi
|
||||
|
||||
# Find worktree entry for target path
|
||||
WORKTREE_ENTRY=$(echo "$WORKTREE_LIST" | grep -A 3 "^worktree $WORKTREE_PATH$")
|
||||
IS_REGISTERED=$(echo "$WORKTREE_ENTRY" | wc -l)
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF IS_MAIN_REPO == true → ERROR PATTERN "cannot-destroy-main"
|
||||
- IF IS_REGISTERED == 0 → ERROR PATTERN "not-a-worktree"
|
||||
|
||||
DATA EXTRACTION:
|
||||
```bash
|
||||
BRANCH_REF=$(echo "$WORKTREE_ENTRY" | grep "^branch " | cut -d' ' -f2)
|
||||
BRANCH_NAME=$(echo "$BRANCH_REF" | sed 's|refs/heads/||')
|
||||
```
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 4
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 4: CHECK FOR UNCOMMITTED CHANGES
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
cd "$WORKTREE_PATH"
|
||||
GIT_STATUS=$(git status --porcelain 2>&1)
|
||||
STATUS_EXIT=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF STATUS_EXIT != 0 → Warning (worktree may be corrupted, allow removal)
|
||||
|
||||
DETECTION:
|
||||
```bash
|
||||
if [ -n "$GIT_STATUS" ]; then
|
||||
HAS_CHANGES=true
|
||||
else
|
||||
HAS_CHANGES=false
|
||||
fi
|
||||
```
|
||||
|
||||
ACTION:
|
||||
- IF HAS_CHANGES == false → STEP 5 (proceed directly)
|
||||
- IF HAS_CHANGES == true → Display warning, ask user confirmation
|
||||
|
||||
USER DECISION (if HAS_CHANGES == true):
|
||||
```
|
||||
⚠ Warning: Uncommitted changes detected
|
||||
|
||||
Modified files:
|
||||
{GIT_STATUS output}
|
||||
|
||||
These changes will be lost if you proceed.
|
||||
|
||||
Recommendations:
|
||||
1. Commit changes: cd {WORKTREE_PATH} && git commit -am "message"
|
||||
2. Stash changes: cd {WORKTREE_PATH} && git stash
|
||||
3. Proceed anyway (changes will be lost)
|
||||
|
||||
Proceed with removal? (This will permanently delete uncommitted work)
|
||||
```
|
||||
|
||||
Use AskUserQuestion:
|
||||
- Option 1: "Cancel removal" → TERMINATE (no changes)
|
||||
- Option 2: "Proceed with removal (discard changes)" → STEP 5
|
||||
|
||||
NEXT:
|
||||
- IF user cancels → TERMINATE
|
||||
- IF user proceeds OR no changes → STEP 5
|
||||
|
||||
### STEP 5: REMOVE WORKTREE
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
git worktree remove --force "$WORKTREE_PATH" 2>&1
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → ERROR PATTERN "worktree-removal-failed"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 6
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 6: PRUNE STALE REFERENCES
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
git worktree prune 2>&1
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → Warning (not fatal, removal succeeded)
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 7
|
||||
- On warning → STEP 7 (continue)
|
||||
|
||||
### STEP 7: OUTPUT SUCCESS SUMMARY
|
||||
|
||||
OUTPUT FORMAT (exact):
|
||||
```
|
||||
✓ Worktree removed successfully
|
||||
|
||||
Path: {WORKTREE_PATH}
|
||||
Branch: {BRANCH_NAME}
|
||||
|
||||
Branch '{BRANCH_NAME}' has been preserved.
|
||||
|
||||
To delete the branch as well:
|
||||
git branch -d {BRANCH_NAME} # Safe delete (only if merged)
|
||||
git branch -D {BRANCH_NAME} # Force delete (even if unmerged)
|
||||
|
||||
To delete remote branch:
|
||||
git push origin --delete {BRANCH_NAME}
|
||||
```
|
||||
|
||||
SUBSTITUTIONS:
|
||||
- {WORKTREE_PATH} = from STEP 1
|
||||
- {BRANCH_NAME} = from STEP 3
|
||||
|
||||
NEXT:
|
||||
- TERMINATE (success)
|
||||
|
||||
## ERROR PATTERNS
|
||||
|
||||
### PATTERN: missing-path
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: WORKTREE_PATH_ARG is empty (no argument provided)
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Missing worktree path
|
||||
|
||||
Usage:
|
||||
/destroy:working-tree <worktree-path>
|
||||
|
||||
Example:
|
||||
/destroy:working-tree ../myapp-feature-login
|
||||
|
||||
To see all worktrees:
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: path-not-exist
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: Provided path does not exist (STEP 2)
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Path does not exist
|
||||
|
||||
Path: {WORKTREE_PATH}
|
||||
|
||||
The specified path doesn't exist. Check for typos.
|
||||
|
||||
To list existing worktrees:
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {WORKTREE_PATH} = provided path
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: git-command-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git worktree list command fails (STEP 3)
|
||||
- CAPTURE: stderr from git command
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to list worktrees
|
||||
|
||||
Git error: {GIT_STDERR}
|
||||
|
||||
Check that:
|
||||
- You're in a git repository
|
||||
- Git is installed and working
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {GIT_STDERR} = captured stderr
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: cannot-destroy-main
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: Target path matches main repository path (STEP 3)
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Cannot destroy main repository
|
||||
|
||||
The path '{WORKTREE_PATH}' is the main repository, not a worktree.
|
||||
|
||||
To remove worktrees, use paths like:
|
||||
/destroy:working-tree ../myapp-feature-branch
|
||||
/destroy:working-tree ../myapp-bugfix-something
|
||||
|
||||
To see all worktrees:
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {WORKTREE_PATH} = main repository path
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: not-a-worktree
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: Path exists but is not registered as git worktree (STEP 3)
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Not a registered git worktree
|
||||
|
||||
Path: {WORKTREE_PATH}
|
||||
|
||||
This path is not a git worktree. To see all worktrees:
|
||||
/list:working-tree
|
||||
|
||||
Valid worktree paths look like:
|
||||
/Users/dev/myapp-feature-login
|
||||
../myapp-bugfix-auth
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {WORKTREE_PATH} = provided path
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: worktree-removal-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git worktree remove fails (STEP 5)
|
||||
- CAPTURE: stderr from git worktree remove
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to remove worktree
|
||||
|
||||
Git error: {GIT_STDERR}
|
||||
|
||||
This can happen if:
|
||||
- Worktree is locked
|
||||
- Permission issues
|
||||
- Worktree is corrupted
|
||||
|
||||
Try:
|
||||
- Check file permissions
|
||||
- Run: git worktree prune
|
||||
- Manually remove directory and run: git worktree prune
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {GIT_STDERR} = captured stderr
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
## TOOL PERMISSION MATRIX
|
||||
|
||||
| Tool | Pattern | Permission | Pre-Check | Post-Check | On-Deny-Action |
|
||||
|------|---------|------------|-----------|------------|----------------|
|
||||
| Bash | git worktree:* | ALLOW | command_safe | validate_output | N/A |
|
||||
| Bash | git status:* | ALLOW | command_safe | N/A | N/A |
|
||||
| Bash | git branch:* | DENY | N/A | N/A | ABORT "Cannot delete branches automatically" |
|
||||
| Bash | cd:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | test:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | pwd:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | dirname:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | basename:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | grep:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | sed:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | cut:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | wc:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | head:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | rm:* | DENY | N/A | N/A | ABORT "Use git worktree remove" |
|
||||
| Bash | sudo:* | DENY | N/A | N/A | ABORT "Elevated privileges" |
|
||||
| Read | * | DENY | N/A | N/A | ABORT "Destroy is read-only except git" |
|
||||
| Write | * | DENY | N/A | N/A | ABORT "Destroy does not write files" |
|
||||
|
||||
SECURITY CONSTRAINTS:
|
||||
- Can ONLY remove worktrees via git worktree remove
|
||||
- CANNOT delete branches (user must do manually)
|
||||
- CANNOT use rm/rmdir (git manages removal)
|
||||
- MUST check for uncommitted changes
|
||||
- MUST prevent main repository deletion
|
||||
|
||||
## TEST CASES
|
||||
|
||||
### TC001: Remove worktree with no uncommitted changes
|
||||
|
||||
PRECONDITIONS:
|
||||
- Worktree exists at /Users/dev/myapp-feature-login
|
||||
- Branch: feature/login
|
||||
- No uncommitted changes
|
||||
- Not the main repository
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/destroy:working-tree /Users/dev/myapp-feature-login
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → WORKTREE_PATH="/Users/dev/myapp-feature-login"
|
||||
2. STEP 2 → EXISTS=0 (path exists)
|
||||
3. STEP 3 → IS_MAIN_REPO=false, IS_REGISTERED>0, BRANCH_NAME="feature/login"
|
||||
4. STEP 4 → HAS_CHANGES=false (no uncommitted changes)
|
||||
5. STEP 5 → git worktree remove succeeds
|
||||
6. STEP 6 → git worktree prune succeeds
|
||||
7. STEP 7 → Output summary
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
✓ Worktree removed successfully
|
||||
|
||||
Path: /Users/dev/myapp-feature-login
|
||||
Branch: feature/login
|
||||
|
||||
Branch 'feature/login' has been preserved.
|
||||
|
||||
To delete the branch as well:
|
||||
git branch -d feature/login # Safe delete (only if merged)
|
||||
git branch -D feature/login # Force delete (even if unmerged)
|
||||
|
||||
To delete remote branch:
|
||||
git push origin --delete feature/login
|
||||
```
|
||||
|
||||
VALIDATION COMMANDS:
|
||||
```bash
|
||||
# Verify worktree no longer exists
|
||||
test ! -e /Users/dev/myapp-feature-login && echo "PASS" || echo "FAIL"
|
||||
|
||||
# Verify branch still exists
|
||||
git show-ref --verify refs/heads/feature/login && echo "PASS" || echo "FAIL"
|
||||
|
||||
# Verify not in worktree list
|
||||
git worktree list | grep -v "feature-login" && echo "PASS" || echo "FAIL"
|
||||
```
|
||||
|
||||
### TC002: Remove worktree with uncommitted changes - user proceeds
|
||||
|
||||
PRECONDITIONS:
|
||||
- Worktree exists at /Users/dev/myapp-bugfix-auth
|
||||
- Has uncommitted changes: Modified src/auth.ts
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/destroy:working-tree /Users/dev/myapp-bugfix-auth
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-3. Standard detection
|
||||
4. STEP 4 → HAS_CHANGES=true
|
||||
5. Display warning with git status output
|
||||
6. USER SELECTS "Proceed with removal (discard changes)"
|
||||
7. STEP 5 → git worktree remove --force succeeds
|
||||
8. STEP 6-7 → Standard cleanup and output
|
||||
|
||||
EXPECTED OUTPUT (includes warning):
|
||||
```
|
||||
⚠ Warning: Uncommitted changes detected
|
||||
|
||||
Modified files:
|
||||
M src/auth.ts
|
||||
|
||||
These changes will be lost if you proceed.
|
||||
|
||||
Recommendations:
|
||||
1. Commit changes: cd /Users/dev/myapp-bugfix-auth && git commit -am "message"
|
||||
2. Stash changes: cd /Users/dev/myapp-bugfix-auth && git stash
|
||||
3. Proceed anyway (changes will be lost)
|
||||
|
||||
Proceed with removal? (This will permanently delete uncommitted work)
|
||||
|
||||
[User confirms]
|
||||
|
||||
✓ Worktree removed successfully
|
||||
|
||||
Path: /Users/dev/myapp-bugfix-auth
|
||||
Branch: bugfix/auth
|
||||
|
||||
Branch 'bugfix/auth' has been preserved.
|
||||
|
||||
To delete the branch as well:
|
||||
git branch -d bugfix/auth # Safe delete (only if merged)
|
||||
git branch -D bugfix/auth # Force delete (even if unmerged)
|
||||
|
||||
To delete remote branch:
|
||||
git push origin --delete bugfix/auth
|
||||
```
|
||||
|
||||
### TC003: Remove worktree with uncommitted changes - user cancels
|
||||
|
||||
PRECONDITIONS:
|
||||
- Worktree with uncommitted changes
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/destroy:working-tree /Users/dev/myapp-feature-test
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-4. Detect changes
|
||||
5. Display warning
|
||||
6. USER SELECTS "Cancel removal"
|
||||
7. TERMINATE (no changes)
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
⚠ Warning: Uncommitted changes detected
|
||||
|
||||
[warning displayed]
|
||||
|
||||
Proceed with removal?
|
||||
|
||||
[User cancels]
|
||||
|
||||
Removal cancelled. No changes made.
|
||||
```
|
||||
|
||||
POSTCONDITIONS:
|
||||
- Worktree still exists
|
||||
- No files modified
|
||||
|
||||
### TC004: Attempt to destroy main repository
|
||||
|
||||
PRECONDITIONS:
|
||||
- Main repository at /Users/dev/myapp
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/destroy:working-tree /Users/dev/myapp
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → Resolve path
|
||||
2. STEP 2 → Path exists
|
||||
3. STEP 3 → IS_MAIN_REPO=true
|
||||
4. ERROR PATTERN "cannot-destroy-main"
|
||||
5. ABORT
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Error: Cannot destroy main repository
|
||||
|
||||
The path '/Users/dev/myapp' is the main repository, not a worktree.
|
||||
|
||||
To remove worktrees, use paths like:
|
||||
/destroy:working-tree ../myapp-feature-branch
|
||||
/destroy:working-tree ../myapp-bugfix-something
|
||||
|
||||
To see all worktrees:
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
POSTCONDITIONS:
|
||||
- Main repository untouched
|
||||
- No changes made
|
||||
|
||||
### TC005: Path does not exist
|
||||
|
||||
PRECONDITIONS:
|
||||
- Path /Users/dev/nonexistent does not exist
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/destroy:working-tree /Users/dev/nonexistent
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → Resolve path
|
||||
2. STEP 2 → EXISTS=1 (does not exist)
|
||||
3. ERROR PATTERN "path-not-exist"
|
||||
4. ABORT
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Error: Path does not exist
|
||||
|
||||
Path: /Users/dev/nonexistent
|
||||
|
||||
The specified path doesn't exist. Check for typos.
|
||||
|
||||
To list existing worktrees:
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
### TC006: Not a git worktree
|
||||
|
||||
PRECONDITIONS:
|
||||
- Directory /Users/dev/random-dir exists but is not a git worktree
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/destroy:working-tree /Users/dev/random-dir
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-2. Resolve and verify path exists
|
||||
3. STEP 3 → IS_REGISTERED=0 (not in worktree list)
|
||||
4. ERROR PATTERN "not-a-worktree"
|
||||
5. ABORT
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Error: Not a registered git worktree
|
||||
|
||||
Path: /Users/dev/random-dir
|
||||
|
||||
This path is not a git worktree. To see all worktrees:
|
||||
/list:working-tree
|
||||
|
||||
Valid worktree paths look like:
|
||||
/Users/dev/myapp-feature-login
|
||||
../myapp-bugfix-auth
|
||||
```
|
||||
|
||||
## SAFETY FEATURES
|
||||
|
||||
### PROTECTED OPERATIONS
|
||||
- CANNOT remove main repository
|
||||
- WARNS about uncommitted changes
|
||||
- REQUIRES confirmation for destructive operations
|
||||
- PRESERVES branch by default
|
||||
|
||||
### BRANCH DELETION GUIDANCE
|
||||
|
||||
Command provides guidance but NEVER auto-deletes branches:
|
||||
|
||||
**Safe delete** (only if merged):
|
||||
```bash
|
||||
git branch -d <branch-name>
|
||||
```
|
||||
|
||||
**Force delete** (even if unmerged):
|
||||
```bash
|
||||
git branch -D <branch-name>
|
||||
```
|
||||
|
||||
**Remote branch delete**:
|
||||
```bash
|
||||
git push origin --delete <branch-name>
|
||||
```
|
||||
|
||||
## RELATED COMMANDS
|
||||
|
||||
- /list:working-tree - See all worktrees before deciding what to remove
|
||||
- /status:working-tree - Check current worktree before removing
|
||||
- /create:working-tree - Create new worktree after removal
|
||||
|
||||
## DELEGATION
|
||||
|
||||
For guidance on when to remove worktrees:
|
||||
```
|
||||
Task(
|
||||
subagent_type='working-tree-consultant',
|
||||
description='Worktree removal strategy',
|
||||
prompt='[question about when/how to safely remove worktrees]'
|
||||
)
|
||||
```
|
||||
514
commands/list.md
Normal file
514
commands/list.md
Normal file
@@ -0,0 +1,514 @@
|
||||
---
|
||||
description: List all git worktrees with their associated .ai-context metadata
|
||||
allowed-tools: Bash, Read, Glob
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# /list:working-tree
|
||||
|
||||
Enumerate all git worktrees and display metadata from `.ai-context.json`.
|
||||
|
||||
## ARGUMENT SPECIFICATION
|
||||
|
||||
```
|
||||
SYNTAX: /list:working-tree
|
||||
|
||||
NO ARGUMENTS
|
||||
```
|
||||
|
||||
## EXECUTION PROTOCOL
|
||||
|
||||
Execute steps sequentially. Each step must complete successfully before proceeding.
|
||||
|
||||
### STEP 1: GET CURRENT WORKTREE
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
CURRENT_ROOT=$(git rev-parse --show-toplevel 2>&1)
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → ERROR PATTERN "not-in-git-repo"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 2
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 2: LIST ALL WORKTREES
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
WORKTREE_LIST=$(git worktree list --porcelain 2>&1)
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → ERROR PATTERN "git-command-failed"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 3
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 3: PARSE WORKTREES
|
||||
|
||||
PARSE FORMAT:
|
||||
```
|
||||
worktree /path/to/worktree
|
||||
HEAD commit-hash
|
||||
branch refs/heads/branch-name
|
||||
|
||||
worktree /another/path
|
||||
HEAD commit-hash
|
||||
branch refs/heads/another-branch
|
||||
```
|
||||
|
||||
PARSING ALGORITHM:
|
||||
```python
|
||||
worktrees = []
|
||||
current_entry = {}
|
||||
|
||||
for line in WORKTREE_LIST.split("\n"):
|
||||
if line.startswith("worktree "):
|
||||
if current_entry:
|
||||
worktrees.append(current_entry)
|
||||
current_entry = {"path": line.split(" ", 1)[1]}
|
||||
elif line.startswith("branch refs/heads/"):
|
||||
current_entry["branch"] = line.split("/")[-1]
|
||||
elif line == "":
|
||||
if current_entry:
|
||||
worktrees.append(current_entry)
|
||||
current_entry = {}
|
||||
|
||||
if current_entry:
|
||||
worktrees.append(current_entry)
|
||||
```
|
||||
|
||||
DATA EXTRACTED:
|
||||
- List of worktree entries, each with:
|
||||
- path: absolute path to worktree
|
||||
- branch: branch name (without refs/heads/)
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 4
|
||||
- No failure case (empty list is valid)
|
||||
|
||||
### STEP 4: READ METADATA FOR EACH WORKTREE
|
||||
|
||||
FOR EACH worktree in worktrees:
|
||||
```bash
|
||||
METADATA_PATH="$worktree_path/.ai-context.json"
|
||||
test -f "$METADATA_PATH"
|
||||
HAS_METADATA=$?
|
||||
|
||||
if [ $HAS_METADATA -eq 0 ]; then
|
||||
METADATA=$(cat "$METADATA_PATH" 2>&1)
|
||||
MODE=$(echo "$METADATA" | jq -r '.mode // "(invalid)"' 2>&1)
|
||||
DESCRIPTION=$(echo "$METADATA" | jq -r '.description // ""' 2>&1)
|
||||
|
||||
# Validate JSON
|
||||
if [ $? -ne 0 ]; then
|
||||
MODE="(invalid json)"
|
||||
DESCRIPTION=""
|
||||
fi
|
||||
else
|
||||
MODE="(no metadata)"
|
||||
DESCRIPTION="-"
|
||||
fi
|
||||
```
|
||||
|
||||
DATA STRUCTURE:
|
||||
```
|
||||
worktree_data = [
|
||||
{
|
||||
"path": "/path/to/worktree",
|
||||
"branch": "feature/login",
|
||||
"mode": "feature",
|
||||
"description": "OAuth refactor",
|
||||
"is_current": true/false,
|
||||
"has_metadata": true/false
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
CURRENT DETECTION:
|
||||
- IF worktree_path == CURRENT_ROOT → is_current = true
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 5
|
||||
- Continue even if individual metadata reads fail
|
||||
|
||||
### STEP 5: FORMAT AND DISPLAY TABLE
|
||||
|
||||
TABLE FORMAT:
|
||||
```
|
||||
Git Worktrees
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Path Branch Mode Description
|
||||
───────────────────────────────────────────────────────────────────────────────
|
||||
{INDICATOR} {PATH} {BRANCH} {MODE} {DESCRIPTION}
|
||||
...
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
Total: {COUNT} worktrees ({WITH_META} with metadata, {WITHOUT_META} without)
|
||||
|
||||
{TIP_IF_MISSING_METADATA}
|
||||
```
|
||||
|
||||
FORMATTING RULES:
|
||||
- INDICATOR: "→" if is_current, else " " (2 spaces)
|
||||
- PATH: Truncate to 30 chars if longer, add "..." suffix
|
||||
- BRANCH: Truncate to 20 chars if longer
|
||||
- MODE: Truncate to 12 chars
|
||||
- DESCRIPTION: Truncate to 40 chars if longer, add "..."
|
||||
- Align columns with padding
|
||||
|
||||
PADDING ALGORITHM:
|
||||
```python
|
||||
def pad_column(text, width):
|
||||
if len(text) > width:
|
||||
return text[:width-3] + "..."
|
||||
return text + " " * (width - len(text))
|
||||
```
|
||||
|
||||
TIP LOGIC:
|
||||
- IF any worktree has has_metadata == false:
|
||||
- Display: "Tip: Use /adopt:working-tree to add metadata to worktrees that lack it"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 6
|
||||
- No failure case
|
||||
|
||||
### STEP 6: COUNT AND SUMMARIZE
|
||||
|
||||
COUNTS:
|
||||
```bash
|
||||
TOTAL=$(echo "$worktrees" | wc -l)
|
||||
WITH_META=$(count worktrees where has_metadata == true)
|
||||
WITHOUT_META=$(count worktrees where has_metadata == false)
|
||||
```
|
||||
|
||||
SUMMARY LINE:
|
||||
```
|
||||
Total: {TOTAL} worktrees ({WITH_META} with metadata, {WITHOUT_META} without)
|
||||
```
|
||||
|
||||
SPECIAL CASES:
|
||||
- IF TOTAL == 1 AND WITHOUT_META == 1:
|
||||
- Summary: "Total: 1 worktree (main repository only)"
|
||||
- Tip: "To create a new worktree: /create:working-tree <branch-name>"
|
||||
|
||||
NEXT:
|
||||
- TERMINATE (success)
|
||||
|
||||
## ERROR PATTERNS
|
||||
|
||||
### PATTERN: not-in-git-repo
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git rev-parse --show-toplevel exit code != 0
|
||||
- INDICATORS: stderr contains "not a git repository"
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Not in a git repository
|
||||
|
||||
Run this command from within a git repository.
|
||||
```
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: git-command-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git worktree list command fails (STEP 2)
|
||||
- CAPTURE: stderr from git command
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to list worktrees
|
||||
|
||||
Git error: {GIT_STDERR}
|
||||
|
||||
Check that:
|
||||
- You're in a git repository
|
||||
- Git is installed and working
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {GIT_STDERR} = captured stderr
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: invalid-metadata-json
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: jq fails to parse .ai-context.json (STEP 4)
|
||||
- OCCURS: per-worktree, not fatal
|
||||
|
||||
RESPONSE:
|
||||
```
|
||||
Warning: Invalid .ai-context.json in {WORKTREE_PATH}
|
||||
|
||||
Displaying worktree without metadata. Consider:
|
||||
- Fixing the JSON manually
|
||||
- Running /adopt:working-tree in that worktree to regenerate
|
||||
```
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: false (warning only)
|
||||
- DISPLAY: Show worktree with MODE="(invalid json)"
|
||||
- CONTINUE: Process remaining worktrees
|
||||
|
||||
## TOOL PERMISSION MATRIX
|
||||
|
||||
| Tool | Pattern | Permission | Pre-Check | Post-Check | On-Deny-Action |
|
||||
|------|---------|------------|-----------|------------|----------------|
|
||||
| Bash | git worktree:* | ALLOW | command_safe | N/A | N/A |
|
||||
| Bash | git rev-parse:* | ALLOW | command_safe | N/A | N/A |
|
||||
| Bash | test:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | cat:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | jq:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | wc:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | grep:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | cut:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | sed:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | head:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | sudo:* | DENY | N/A | N/A | ABORT "Elevated privileges" |
|
||||
| Read | */.ai-context.json | ALLOW | N/A | N/A | N/A |
|
||||
| Write | * | DENY | N/A | N/A | ABORT "List is read-only" |
|
||||
| Edit | * | DENY | N/A | N/A | ABORT "List is read-only" |
|
||||
|
||||
SECURITY CONSTRAINTS:
|
||||
- Command is READ-ONLY
|
||||
- Cannot modify any files
|
||||
- Cannot execute destructive operations
|
||||
- Safe to run multiple times
|
||||
|
||||
## TEST CASES
|
||||
|
||||
### TC001: Multiple worktrees with metadata
|
||||
|
||||
PRECONDITIONS:
|
||||
- Main repository at /Users/dev/myapp
|
||||
- Worktree at /Users/dev/myapp-feature-api with metadata (mode: feature, description: "New API")
|
||||
- Worktree at /Users/dev/myapp-bugfix-auth with metadata (mode: bugfix, description: "Fix auth")
|
||||
- Currently in /Users/dev/myapp
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → CURRENT_ROOT="/Users/dev/myapp"
|
||||
2. STEP 2 → Get worktree list
|
||||
3. STEP 3 → Parse 3 worktrees
|
||||
4. STEP 4 → Read metadata for each
|
||||
5. STEP 5-6 → Format and display
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Git Worktrees
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Path Branch Mode Description
|
||||
───────────────────────────────────────────────────────────────────────────────
|
||||
→ /Users/dev/myapp main main Main development
|
||||
/Users/dev/myapp-feature... feature/api feature New API
|
||||
/Users/dev/myapp-bugfix-... bugfix/auth bugfix Fix auth
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
Total: 3 worktrees (3 with metadata)
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- Current worktree marked with →
|
||||
- All columns aligned
|
||||
- Counts correct
|
||||
|
||||
### TC002: Mixed metadata status
|
||||
|
||||
PRECONDITIONS:
|
||||
- Main repository without metadata
|
||||
- One worktree with metadata
|
||||
- One worktree without metadata
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Git Worktrees
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Path Branch Mode Description
|
||||
───────────────────────────────────────────────────────────────────────────────
|
||||
/Users/dev/myapp main (no metadata) -
|
||||
→ /Users/dev/myapp-feature... feature/new feature New feature work
|
||||
/Users/dev/old-checkout feature/abandoned (no metadata) -
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
Total: 3 worktrees (1 with metadata, 2 without)
|
||||
|
||||
Tip: Use /adopt:working-tree to add metadata to worktrees that lack it
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- Tip displayed because some worktrees lack metadata
|
||||
- (no metadata) shown for worktrees without .ai-context.json
|
||||
|
||||
### TC003: Only main repository
|
||||
|
||||
PRECONDITIONS:
|
||||
- Main repository only, no additional worktrees
|
||||
- No metadata file
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Git Worktrees
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Path Branch Mode Description
|
||||
───────────────────────────────────────────────────────────────────────────────
|
||||
→ /Users/dev/myapp main (no metadata) -
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
Total: 1 worktree (main repository only)
|
||||
|
||||
To create a new worktree: /create:working-tree <branch-name>
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- Special message for single worktree
|
||||
- Tip suggests creating worktree
|
||||
|
||||
### TC004: Invalid JSON in metadata file
|
||||
|
||||
PRECONDITIONS:
|
||||
- Worktree at /Users/dev/myapp-test
|
||||
- File exists: /Users/dev/myapp-test/.ai-context.json
|
||||
- File contains invalid JSON: `{invalid`
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-3. Standard flow
|
||||
4. STEP 4 → jq fails on invalid JSON
|
||||
5. Display warning
|
||||
6. Show worktree with MODE="(invalid json)"
|
||||
7. Continue with other worktrees
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Warning: Invalid .ai-context.json in /Users/dev/myapp-test
|
||||
|
||||
Displaying worktree without metadata. Consider:
|
||||
- Fixing the JSON manually
|
||||
- Running /adopt:working-tree in that worktree to regenerate
|
||||
|
||||
Git Worktrees
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Path Branch Mode Description
|
||||
───────────────────────────────────────────────────────────────────────────────
|
||||
→ /Users/dev/myapp-test feature/test (invalid json) -
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
Total: 1 worktree (0 with metadata, 1 without)
|
||||
|
||||
Tip: Use /adopt:working-tree to add metadata to worktrees that lack it
|
||||
```
|
||||
|
||||
### TC005: Long paths and descriptions
|
||||
|
||||
PRECONDITIONS:
|
||||
- Worktree with very long path: /Users/dev/myapp-feature-really-long-branch-name-that-exceeds-column-width
|
||||
- Description: "This is a very long description that exceeds the maximum column width and should be truncated"
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/list:working-tree
|
||||
```
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Git Worktrees
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Path Branch Mode Description
|
||||
───────────────────────────────────────────────────────────────────────────────
|
||||
→ /Users/dev/myapp-feature... feature/really-lo... feature This is a very long description that...
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
Total: 1 worktree (1 with metadata)
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- Long path truncated with "..."
|
||||
- Long branch truncated with "..."
|
||||
- Long description truncated with "..."
|
||||
- Columns remain aligned
|
||||
|
||||
## DISPLAY NOTES
|
||||
|
||||
### COLUMN WIDTHS
|
||||
|
||||
Fixed widths for consistent alignment:
|
||||
- Indicator: 2 chars ("→ " or " ")
|
||||
- Path: 30 chars
|
||||
- Branch: 20 chars
|
||||
- Mode: 13 chars
|
||||
- Description: remaining width (or 40 chars minimum)
|
||||
|
||||
### TRUNCATION STRATEGY
|
||||
|
||||
```python
|
||||
def truncate(text, max_width):
|
||||
if len(text) <= max_width:
|
||||
return text
|
||||
return text[:max_width-3] + "..."
|
||||
```
|
||||
|
||||
### BOX DRAWING
|
||||
|
||||
Use consistent box-drawing characters:
|
||||
- Top/bottom: `═` (double horizontal)
|
||||
- Separator: `─` (single horizontal)
|
||||
- No vertical bars (cleaner appearance)
|
||||
|
||||
## RELATED COMMANDS
|
||||
|
||||
- /status:working-tree - Show current worktree details
|
||||
- /create:working-tree - Create new worktree with metadata
|
||||
- /adopt:working-tree - Add metadata to existing worktree
|
||||
- /destroy:working-tree - Remove worktree
|
||||
|
||||
## DELEGATION
|
||||
|
||||
For organizing multiple worktrees strategically:
|
||||
```
|
||||
Task(
|
||||
subagent_type='working-tree-consultant',
|
||||
description='Worktree organization strategy',
|
||||
prompt='[question about managing multiple worktrees]'
|
||||
)
|
||||
```
|
||||
947
commands/new.md
Normal file
947
commands/new.md
Normal file
@@ -0,0 +1,947 @@
|
||||
---
|
||||
description: Create a new git worktree with branch and .ai-context.json metadata
|
||||
argument-hint: <branch-name> [--mode <mode>] [--description "<text>"]
|
||||
allowed-tools: Bash, Write, Read
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# /working-tree:new
|
||||
|
||||
Create new branch (if needed), attach git worktree, generate AI metadata files for isolated development.
|
||||
|
||||
## ARGUMENT SPECIFICATION
|
||||
|
||||
```
|
||||
SYNTAX: /working-tree:new <branch-name> [--mode <mode>] [--description "<text>"]
|
||||
|
||||
REQUIRED:
|
||||
<branch-name>
|
||||
Type: string
|
||||
Position: 1
|
||||
Validation: ^[a-zA-Z0-9/_-]+$
|
||||
Examples: "feature/login", "bugfix/timeout", "main"
|
||||
|
||||
OPTIONAL:
|
||||
--mode <mode>
|
||||
Type: enum[main, feature, bugfix, experiment, review]
|
||||
Default: inferred from branch-name (see MODE_INFERENCE_ALGORITHM)
|
||||
Validation: must match exactly one of the enum values
|
||||
|
||||
--description "<text>"
|
||||
Type: string (quoted if contains spaces)
|
||||
Default: "" (empty string)
|
||||
Validation: any string, no restrictions
|
||||
```
|
||||
|
||||
## MODE_INFERENCE_ALGORITHM
|
||||
|
||||
APPLY rules sequentially, first match wins:
|
||||
|
||||
```python
|
||||
def infer_mode(branch_name: str) -> str:
|
||||
if branch_name.startswith("feature/"):
|
||||
return "feature"
|
||||
elif branch_name.startswith(("bugfix/", "fix/")):
|
||||
return "bugfix"
|
||||
elif branch_name.startswith(("exp/", "experiment/")):
|
||||
return "experiment"
|
||||
elif branch_name.startswith("review/"):
|
||||
return "review"
|
||||
elif branch_name in ("main", "master"):
|
||||
return "main"
|
||||
else:
|
||||
return "feature" # DEFAULT
|
||||
```
|
||||
|
||||
DETERMINISTIC: Given same branch_name, always produces same mode.
|
||||
|
||||
## EXECUTION PROTOCOL
|
||||
|
||||
Execute steps sequentially. Each step must complete successfully before proceeding.
|
||||
|
||||
### STEP 1: DETECT REPOSITORY INFO
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel 2>&1)
|
||||
EXIT_CODE_ROOT=$?
|
||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>&1)
|
||||
EXIT_CODE_BRANCH=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE_ROOT != 0 → ERROR PATTERN "not-in-git-repo"
|
||||
- IF EXIT_CODE_BRANCH != 0 → ERROR PATTERN "git-command-failed"
|
||||
- REPO_ROOT must be absolute path starting with /
|
||||
|
||||
DATA EXTRACTION:
|
||||
```bash
|
||||
REPO_NAME=$(basename "$REPO_ROOT")
|
||||
PARENT_DIR=$(dirname "$REPO_ROOT")
|
||||
```
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 2
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 2: PARSE AND VALIDATE ARGUMENTS
|
||||
|
||||
PARSE:
|
||||
```bash
|
||||
# Extract branch name (first positional argument)
|
||||
BRANCH_NAME="$1"
|
||||
|
||||
# Parse --mode flag (if present)
|
||||
if [[ "$@" =~ --mode[[:space:]]+([a-z]+) ]]; then
|
||||
MODE_ARG="${BASH_REMATCH[1]}"
|
||||
else
|
||||
MODE_ARG=""
|
||||
fi
|
||||
|
||||
# Parse --description flag (if present)
|
||||
if [[ "$@" =~ --description[[:space:]]+\"([^\"]+)\" ]]; then
|
||||
DESCRIPTION="${BASH_REMATCH[1]}"
|
||||
elif [[ "$@" =~ --description[[:space:]]+([^[:space:]]+) ]]; then
|
||||
DESCRIPTION="${BASH_REMATCH[1]}"
|
||||
else
|
||||
DESCRIPTION=""
|
||||
fi
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF BRANCH_NAME is empty → ERROR PATTERN "missing-branch-name"
|
||||
- IF BRANCH_NAME !~ ^[a-zA-Z0-9/_-]+$ → ERROR PATTERN "invalid-branch-name"
|
||||
- IF MODE_ARG not empty AND MODE_ARG not in [main, feature, bugfix, experiment, review] → ERROR PATTERN "invalid-mode"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 3
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 3: DETERMINE MODE
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
if [ -n "$MODE_ARG" ]; then
|
||||
# Explicit mode provided
|
||||
MODE="$MODE_ARG"
|
||||
else
|
||||
# Infer from branch name using MODE_INFERENCE_ALGORITHM
|
||||
case "$BRANCH_NAME" in
|
||||
feature/*)
|
||||
MODE="feature"
|
||||
;;
|
||||
bugfix/*|fix/*)
|
||||
MODE="bugfix"
|
||||
;;
|
||||
exp/*|experiment/*)
|
||||
MODE="experiment"
|
||||
;;
|
||||
review/*)
|
||||
MODE="review"
|
||||
;;
|
||||
main|master)
|
||||
MODE="main"
|
||||
;;
|
||||
*)
|
||||
MODE="feature"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- MODE must be exactly one of: main, feature, bugfix, experiment, review
|
||||
- MODE must not be empty
|
||||
|
||||
DATA:
|
||||
- MODE = final determined mode (explicit or inferred)
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 4
|
||||
- On failure → ABORT (should not occur if STEP 2 validation passed)
|
||||
|
||||
### STEP 4: CHECK BRANCH EXISTENCE
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
git show-ref --verify --quiet refs/heads/$BRANCH_NAME
|
||||
BRANCH_EXISTS=$?
|
||||
```
|
||||
|
||||
BRANCH_EXISTS values:
|
||||
- 0 = branch exists
|
||||
- 1 = branch does not exist
|
||||
- Other = error
|
||||
|
||||
VALIDATION:
|
||||
- IF BRANCH_EXISTS not in [0, 1] → ERROR PATTERN "git-command-failed"
|
||||
|
||||
ACTION:
|
||||
- IF BRANCH_EXISTS == 1 (does not exist) → Create branch in STEP 5
|
||||
- IF BRANCH_EXISTS == 0 (exists) → Use existing branch, skip to STEP 6
|
||||
|
||||
NEXT:
|
||||
- On BRANCH_EXISTS == 0 → STEP 6
|
||||
- On BRANCH_EXISTS == 1 → STEP 5
|
||||
- On error → ABORT
|
||||
|
||||
### STEP 5: CREATE NEW BRANCH
|
||||
|
||||
EXECUTE (only if BRANCH_EXISTS == 1):
|
||||
```bash
|
||||
git branch "$BRANCH_NAME" 2>&1
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → ERROR PATTERN "branch-creation-failed"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 6
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 6: DERIVE WORKTREE DIRECTORY NAME
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
# Normalize branch name: replace / and _ with -, convert to lowercase
|
||||
NORMALIZED_BRANCH=$(echo "$BRANCH_NAME" | tr '/_' '-' | tr '[:upper:]' '[:lower:]')
|
||||
WORKTREE_NAME="${REPO_NAME}-${NORMALIZED_BRANCH}"
|
||||
WORKTREE_PATH="${PARENT_DIR}/${WORKTREE_NAME}"
|
||||
```
|
||||
|
||||
NORMALIZATION RULES:
|
||||
- Replace `/` with `-`
|
||||
- Replace `_` with `-`
|
||||
- Convert to lowercase
|
||||
|
||||
EXAMPLES:
|
||||
- myapp + feature/login → myapp-feature-login
|
||||
- api-server + bugfix/SESSION_timeout → api-server-bugfix-session-timeout
|
||||
|
||||
DATA:
|
||||
- WORKTREE_NAME = derived directory name
|
||||
- WORKTREE_PATH = absolute path to worktree location
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 7
|
||||
- No validation needed (pure transformation)
|
||||
|
||||
### STEP 7: CHECK FOR EXISTING WORKTREE ON BRANCH
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
EXISTING_WORKTREE=$(git worktree list --porcelain | grep -A 3 "^branch refs/heads/$BRANCH_NAME$" | grep "^worktree " | cut -d' ' -f2)
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXISTING_WORKTREE not empty → ERROR PATTERN "branch-has-worktree" with path=$EXISTING_WORKTREE
|
||||
|
||||
NEXT:
|
||||
- On EXISTING_WORKTREE empty → STEP 8
|
||||
- On EXISTING_WORKTREE not empty → ABORT
|
||||
|
||||
### STEP 8: CHECK TARGET DIRECTORY DOESN'T EXIST
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
test -e "$WORKTREE_PATH"
|
||||
DIR_EXISTS=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF DIR_EXISTS == 0 (directory exists) → ERROR PATTERN "directory-exists"
|
||||
|
||||
NEXT:
|
||||
- On DIR_EXISTS != 0 (does not exist) → STEP 9
|
||||
- On DIR_EXISTS == 0 (exists) → ABORT
|
||||
|
||||
### STEP 9: CREATE WORKTREE
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
git worktree add "$WORKTREE_PATH" "$BRANCH_NAME" 2>&1
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → ERROR PATTERN "worktree-creation-failed"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 10
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 10: GENERATE TIMESTAMP
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
CREATED_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
```
|
||||
|
||||
FORMAT: ISO 8601 UTC (example: 2025-11-23T12:34:56Z)
|
||||
|
||||
VALIDATION:
|
||||
- CREATED_TIMESTAMP must match pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 11
|
||||
- No failure case
|
||||
|
||||
### STEP 11: GENERATE .ai-context.json
|
||||
|
||||
CONTENT TEMPLATE:
|
||||
```json
|
||||
{
|
||||
"worktree": "{WORKTREE_NAME}",
|
||||
"branch": "{BRANCH_NAME}",
|
||||
"mode": "{MODE}",
|
||||
"created": "{CREATED_TIMESTAMP}",
|
||||
"description": "{DESCRIPTION}"
|
||||
}
|
||||
```
|
||||
|
||||
SUBSTITUTIONS:
|
||||
- {WORKTREE_NAME} = from STEP 6
|
||||
- {BRANCH_NAME} = from STEP 2
|
||||
- {MODE} = from STEP 3
|
||||
- {CREATED_TIMESTAMP} = from STEP 10
|
||||
- {DESCRIPTION} = from STEP 2 (empty string if not provided)
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
cat > "$WORKTREE_PATH/.ai-context.json" <<EOF
|
||||
{
|
||||
"worktree": "$WORKTREE_NAME",
|
||||
"branch": "$BRANCH_NAME",
|
||||
"mode": "$MODE",
|
||||
"created": "$CREATED_TIMESTAMP",
|
||||
"description": "$DESCRIPTION"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- File must be created at exact path: $WORKTREE_PATH/.ai-context.json
|
||||
- File must contain valid JSON
|
||||
- Verify with: `jq empty "$WORKTREE_PATH/.ai-context.json"`
|
||||
- IF jq fails → ERROR PATTERN "metadata-write-failed"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 12
|
||||
- On failure → ABORT (and cleanup worktree)
|
||||
|
||||
### STEP 12: GENERATE README.working-tree.md
|
||||
|
||||
CONTENT TEMPLATE:
|
||||
```markdown
|
||||
# Worktree: {WORKTREE_NAME}
|
||||
|
||||
**Branch:** `{BRANCH_NAME}`
|
||||
**Mode:** `{MODE}`
|
||||
**Created:** {CREATED_TIMESTAMP}
|
||||
|
||||
## Purpose
|
||||
|
||||
{DESCRIPTION_OR_DEFAULT}
|
||||
|
||||
## Mode Semantics
|
||||
|
||||
- **main**: Minimal changes, stable work only
|
||||
- **feature**: Active development, larger changes allowed
|
||||
- **bugfix**: Isolated, surgical fixes only
|
||||
- **experiment**: Prototypes, large swings, unsafe changes allowed
|
||||
- **review**: Documentation, analysis, audits
|
||||
|
||||
## About This Worktree
|
||||
|
||||
This directory is an independent Git worktree attached to the main repository.
|
||||
|
||||
- Main repo: {REPO_ROOT}
|
||||
- Worktree path: {WORKTREE_PATH}
|
||||
- Branch: {BRANCH_NAME}
|
||||
|
||||
See `.ai-context.json` for machine-readable metadata.
|
||||
```
|
||||
|
||||
SUBSTITUTIONS:
|
||||
- {WORKTREE_NAME} = from STEP 6
|
||||
- {BRANCH_NAME} = from STEP 2
|
||||
- {MODE} = from STEP 3
|
||||
- {CREATED_TIMESTAMP} = from STEP 10
|
||||
- {DESCRIPTION_OR_DEFAULT} = DESCRIPTION if not empty, else "No description provided"
|
||||
- {REPO_ROOT} = from STEP 1
|
||||
- {WORKTREE_PATH} = from STEP 6
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
DESCRIPTION_TEXT="${DESCRIPTION:-No description provided}"
|
||||
cat > "$WORKTREE_PATH/README.working-tree.md" <<EOF
|
||||
# Worktree: $WORKTREE_NAME
|
||||
|
||||
**Branch:** \`$BRANCH_NAME\`
|
||||
**Mode:** \`$MODE\`
|
||||
**Created:** $CREATED_TIMESTAMP
|
||||
|
||||
## Purpose
|
||||
|
||||
$DESCRIPTION_TEXT
|
||||
|
||||
## Mode Semantics
|
||||
|
||||
- **main**: Minimal changes, stable work only
|
||||
- **feature**: Active development, larger changes allowed
|
||||
- **bugfix**: Isolated, surgical fixes only
|
||||
- **experiment**: Prototypes, large swings, unsafe changes allowed
|
||||
- **review**: Documentation, analysis, audits
|
||||
|
||||
## About This Worktree
|
||||
|
||||
This directory is an independent Git worktree attached to the main repository.
|
||||
|
||||
- Main repo: $REPO_ROOT
|
||||
- Worktree path: $WORKTREE_PATH
|
||||
- Branch: $BRANCH_NAME
|
||||
|
||||
See \`.ai-context.json\` for machine-readable metadata.
|
||||
EOF
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- File must exist at: $WORKTREE_PATH/README.working-tree.md
|
||||
- IF file creation failed → ERROR PATTERN "readme-write-failed"
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 13
|
||||
- On failure → ABORT (and cleanup)
|
||||
|
||||
### STEP 13: OUTPUT SUCCESS SUMMARY
|
||||
|
||||
OUTPUT FORMAT (exact):
|
||||
```
|
||||
Created worktree successfully!
|
||||
|
||||
Path: {WORKTREE_PATH}
|
||||
Branch: {BRANCH_NAME}
|
||||
Mode: {MODE}
|
||||
Description: {DESCRIPTION_OR_NONE}
|
||||
|
||||
Metadata files created:
|
||||
✓ .ai-context.json
|
||||
✓ README.working-tree.md
|
||||
|
||||
To switch to this worktree:
|
||||
cd {WORKTREE_PATH}
|
||||
```
|
||||
|
||||
SUBSTITUTIONS:
|
||||
- {WORKTREE_PATH} = from STEP 6
|
||||
- {BRANCH_NAME} = from STEP 2
|
||||
- {MODE} = from STEP 3
|
||||
- {DESCRIPTION_OR_NONE} = DESCRIPTION if not empty, else "None"
|
||||
|
||||
NEXT:
|
||||
- TERMINATE (success)
|
||||
|
||||
## ERROR PATTERNS
|
||||
|
||||
### PATTERN: not-in-git-repo
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git rev-parse --show-toplevel exit code != 0
|
||||
- INDICATORS: stderr contains "not a git repository"
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Not in a git repository
|
||||
|
||||
Run this command from within a git repository.
|
||||
```
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none needed
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: missing-branch-name
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: BRANCH_NAME is empty string after parsing
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Missing required argument <branch-name>
|
||||
|
||||
Usage:
|
||||
/working-tree:new <branch-name> [--mode <mode>] [--description "<text>"]
|
||||
|
||||
Example:
|
||||
/working-tree:new feature/my-feature
|
||||
```
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: invalid-branch-name
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: BRANCH_NAME does not match ^[a-zA-Z0-9/_-]+$
|
||||
- INDICATORS: Contains invalid characters
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Invalid branch name '{BRANCH_NAME}'
|
||||
|
||||
Branch names must contain only:
|
||||
- Letters (a-z, A-Z)
|
||||
- Numbers (0-9)
|
||||
- Forward slashes (/)
|
||||
- Hyphens (-)
|
||||
- Underscores (_)
|
||||
|
||||
Example valid names:
|
||||
feature/login
|
||||
bugfix/timeout-issue
|
||||
exp/ai_integration
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {BRANCH_NAME} = the invalid branch name provided
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: invalid-mode
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: MODE_ARG provided but not in [main, feature, bugfix, experiment, review]
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Invalid mode '{MODE_ARG}'
|
||||
|
||||
Valid modes: main, feature, bugfix, experiment, review
|
||||
|
||||
Example:
|
||||
/working-tree:new my-branch --mode feature
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {MODE_ARG} = the invalid mode provided
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: git-command-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: Any git command (except specific patterns) returns non-zero exit code
|
||||
- CAPTURE: stderr from git command
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Git command failed
|
||||
|
||||
Git error: {GIT_STDERR}
|
||||
|
||||
Check that:
|
||||
- You're in a git repository
|
||||
- Git is installed and working
|
||||
- You have necessary permissions
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {GIT_STDERR} = captured stderr
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: Remove worktree if created
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: branch-creation-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git branch command fails (STEP 5)
|
||||
- CAPTURE: stderr from git branch
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to create branch '{BRANCH_NAME}'
|
||||
|
||||
Git error: {GIT_STDERR}
|
||||
|
||||
Check that:
|
||||
- Branch name is valid
|
||||
- You're not in detached HEAD state
|
||||
- You have permission to create branches
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {BRANCH_NAME} = attempted branch name
|
||||
- {GIT_STDERR} = captured stderr
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: branch-has-worktree
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git worktree list shows branch already has attached worktree (STEP 7)
|
||||
- CAPTURE: EXISTING_WORKTREE path
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Branch '{BRANCH_NAME}' already has a worktree at {EXISTING_WORKTREE}
|
||||
|
||||
Use one of:
|
||||
- /working-tree:list to see all worktrees
|
||||
- cd {EXISTING_WORKTREE} to use the existing worktree
|
||||
- /working-tree:destroy {EXISTING_WORKTREE} to remove it first
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {BRANCH_NAME} = branch with existing worktree
|
||||
- {EXISTING_WORKTREE} = path to existing worktree
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: directory-exists
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: Target directory already exists (STEP 8)
|
||||
- CHECK: test -e "$WORKTREE_PATH" returns 0
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Directory '{WORKTREE_PATH}' already exists
|
||||
|
||||
Choose a different branch name or remove the existing directory.
|
||||
|
||||
To remove:
|
||||
rm -rf {WORKTREE_PATH}
|
||||
|
||||
(Be careful - this will delete all contents)
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {WORKTREE_PATH} = path that already exists
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: none
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: worktree-creation-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git worktree add fails (STEP 9)
|
||||
- CAPTURE: stderr from git worktree add
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to create worktree
|
||||
|
||||
Git error: {GIT_STDERR}
|
||||
|
||||
Check that:
|
||||
- Parent directory is writable
|
||||
- Branch name is valid
|
||||
- No permission issues
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {GIT_STDERR} = captured stderr
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- CLEANUP: Attempt to remove partially created worktree
|
||||
- RETRY: false
|
||||
|
||||
### PATTERN: metadata-write-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: .ai-context.json write fails or invalid JSON (STEP 11)
|
||||
- CHECK: jq validation fails
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to write .ai-context.json
|
||||
|
||||
The worktree was created but metadata file generation failed.
|
||||
|
||||
Worktree location: {WORKTREE_PATH}
|
||||
|
||||
You can:
|
||||
1. Manually create .ai-context.json
|
||||
2. Use /working-tree:adopt to regenerate metadata
|
||||
3. Remove worktree with /working-tree:destroy {WORKTREE_PATH}
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {WORKTREE_PATH} = worktree path
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: false (worktree exists, metadata failed)
|
||||
- CLEANUP: none (leave worktree intact)
|
||||
- FALLBACK: User can manually fix or adopt
|
||||
|
||||
### PATTERN: readme-write-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: README.working-tree.md write fails (STEP 12)
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Warning: Failed to write README.working-tree.md
|
||||
|
||||
The worktree and .ai-context.json were created successfully.
|
||||
|
||||
Worktree location: {WORKTREE_PATH}
|
||||
|
||||
You can manually create the README if needed.
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {WORKTREE_PATH} = worktree path
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: false (warning, not critical)
|
||||
- CLEANUP: none
|
||||
- FALLBACK: Continue without README
|
||||
|
||||
## TOOL PERMISSION MATRIX
|
||||
|
||||
| Tool | Pattern | Permission | Pre-Check | Post-Check | On-Deny-Action |
|
||||
|------|---------|------------|-----------|------------|----------------|
|
||||
| Bash | git:* | ALLOW | command_safe | validate_output | N/A |
|
||||
| Bash | date:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | test:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | basename:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | dirname:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | tr:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | grep:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | cat > *.json | ALLOW | parent_dir_writable | valid_json | N/A |
|
||||
| Bash | cat > *.md | ALLOW | parent_dir_writable | N/A | N/A |
|
||||
| Bash | jq:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | rm -rf:* | DENY | N/A | N/A | ABORT "Destructive operation not allowed" |
|
||||
| Bash | sudo:* | DENY | N/A | N/A | ABORT "Elevated privileges" |
|
||||
| Write | $WORKTREE_PATH/.ai-context.json | ALLOW | dir_exists | valid_json | N/A |
|
||||
| Write | $WORKTREE_PATH/README.working-tree.md | ALLOW | dir_exists | N/A | N/A |
|
||||
| Write | **/.env* | DENY | N/A | N/A | ABORT "Secrets file" |
|
||||
| Read | * | DENY | N/A | N/A | ABORT "Command is write-only" |
|
||||
|
||||
SECURITY CONSTRAINTS:
|
||||
- Can only write to newly created worktree directory
|
||||
- Cannot modify existing files
|
||||
- Cannot remove directories (even on cleanup)
|
||||
- Git worktree add is safe (git manages cleanup)
|
||||
|
||||
## TEST CASES
|
||||
|
||||
### TC001: Create new feature branch worktree
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository at /Users/dev/myapp
|
||||
- Current branch: main
|
||||
- Branch "feature/login-refactor" does not exist
|
||||
- Directory /Users/dev/myapp-feature-login-refactor does not exist
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/working-tree:new feature/login-refactor
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → REPO_ROOT="/Users/dev/myapp", REPO_NAME="myapp", PARENT_DIR="/Users/dev"
|
||||
2. STEP 2 → BRANCH_NAME="feature/login-refactor", MODE_ARG="", DESCRIPTION=""
|
||||
3. STEP 3 → MODE="feature" (inferred from "feature/" prefix)
|
||||
4. STEP 4 → BRANCH_EXISTS=1 (does not exist)
|
||||
5. STEP 5 → Create branch "feature/login-refactor"
|
||||
6. STEP 6 → WORKTREE_NAME="myapp-feature-login-refactor", WORKTREE_PATH="/Users/dev/myapp-feature-login-refactor"
|
||||
7. STEP 7 → No existing worktree
|
||||
8. STEP 8 → Directory does not exist
|
||||
9. STEP 9 → Create worktree
|
||||
10. STEP 10 → Generate timestamp
|
||||
11. STEP 11 → Write .ai-context.json
|
||||
12. STEP 12 → Write README.working-tree.md
|
||||
13. STEP 13 → Output summary
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Created worktree successfully!
|
||||
|
||||
Path: /Users/dev/myapp-feature-login-refactor
|
||||
Branch: feature/login-refactor
|
||||
Mode: feature
|
||||
Description: None
|
||||
|
||||
Metadata files created:
|
||||
✓ .ai-context.json
|
||||
✓ README.working-tree.md
|
||||
|
||||
To switch to this worktree:
|
||||
cd /Users/dev/myapp-feature-login-refactor
|
||||
```
|
||||
|
||||
VALIDATION COMMANDS:
|
||||
```bash
|
||||
# Verify worktree created
|
||||
test -d /Users/dev/myapp-feature-login-refactor && echo "PASS" || echo "FAIL"
|
||||
|
||||
# Verify branch created
|
||||
git show-ref --verify refs/heads/feature/login-refactor && echo "PASS" || echo "FAIL"
|
||||
|
||||
# Verify .ai-context.json
|
||||
test -f /Users/dev/myapp-feature-login-refactor/.ai-context.json && echo "PASS" || echo "FAIL"
|
||||
jq -r '.mode' /Users/dev/myapp-feature-login-refactor/.ai-context.json | grep "feature" && echo "PASS" || echo "FAIL"
|
||||
|
||||
# Verify README
|
||||
test -f /Users/dev/myapp-feature-login-refactor/README.working-tree.md && echo "PASS" || echo "FAIL"
|
||||
```
|
||||
|
||||
### TC002: Create with explicit mode and description
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository at /Users/dev/myapp
|
||||
- Branch "my-experiment" does not exist
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/working-tree:new my-experiment --mode experiment --description "Testing new architecture"
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-2. Parse arguments → BRANCH_NAME="my-experiment", MODE_ARG="experiment", DESCRIPTION="Testing new architecture"
|
||||
3. STEP 3 → MODE="experiment" (explicit, not inferred)
|
||||
4-13. Standard flow
|
||||
|
||||
EXPECTED .ai-context.json:
|
||||
```json
|
||||
{
|
||||
"worktree": "myapp-my-experiment",
|
||||
"branch": "my-experiment",
|
||||
"mode": "experiment",
|
||||
"created": "2025-11-23T12:34:56Z",
|
||||
"description": "Testing new architecture"
|
||||
}
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
```bash
|
||||
jq -r '.mode' .ai-context.json | grep "experiment" && echo "PASS" || echo "FAIL"
|
||||
jq -r '.description' .ai-context.json | grep "Testing new architecture" && echo "PASS" || echo "FAIL"
|
||||
```
|
||||
|
||||
### TC003: Branch already has worktree
|
||||
|
||||
PRECONDITIONS:
|
||||
- Branch "feature/existing" already has worktree at /Users/dev/myapp-feature-existing
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/working-tree:new feature/existing
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-6. Standard detection and parsing
|
||||
7. STEP 7 → EXISTING_WORKTREE="/Users/dev/myapp-feature-existing"
|
||||
8. ERROR PATTERN "branch-has-worktree"
|
||||
9. ABORT
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Error: Branch 'feature/existing' already has a worktree at /Users/dev/myapp-feature-existing
|
||||
|
||||
Use one of:
|
||||
- /working-tree:list to see all worktrees
|
||||
- cd /Users/dev/myapp-feature-existing to use the existing worktree
|
||||
- /working-tree:destroy /Users/dev/myapp-feature-existing to remove it first
|
||||
```
|
||||
|
||||
POSTCONDITIONS:
|
||||
- No new worktree created
|
||||
- No new branch created
|
||||
- Existing worktree unchanged
|
||||
|
||||
### TC004: Invalid mode specified
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/working-tree:new test-branch --mode production
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → Detect repo
|
||||
2. STEP 2 → MODE_ARG="production"
|
||||
3. Validation fails: "production" not in [main, feature, bugfix, experiment, review]
|
||||
4. ERROR PATTERN "invalid-mode"
|
||||
5. ABORT
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Error: Invalid mode 'production'
|
||||
|
||||
Valid modes: main, feature, bugfix, experiment, review
|
||||
|
||||
Example:
|
||||
/working-tree:new my-branch --mode feature
|
||||
```
|
||||
|
||||
### TC005: Directory already exists
|
||||
|
||||
PRECONDITIONS:
|
||||
- Directory /Users/dev/myapp-feature-test already exists (not a worktree)
|
||||
|
||||
INPUT:
|
||||
```
|
||||
/working-tree:new feature/test
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1-7. Standard flow
|
||||
8. STEP 8 → DIR_EXISTS=0 (directory exists)
|
||||
9. ERROR PATTERN "directory-exists"
|
||||
10. ABORT
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Error: Directory '/Users/dev/myapp-feature-test' already exists
|
||||
|
||||
Choose a different branch name or remove the existing directory.
|
||||
|
||||
To remove:
|
||||
rm -rf /Users/dev/myapp-feature-test
|
||||
|
||||
(Be careful - this will delete all contents)
|
||||
```
|
||||
|
||||
## RELATED COMMANDS
|
||||
|
||||
- /working-tree:status - Show current worktree metadata
|
||||
- /working-tree:list - List all worktrees with metadata
|
||||
- /working-tree:adopt - Add metadata to existing worktree
|
||||
- /working-tree:destroy - Remove worktree safely
|
||||
|
||||
## DELEGATION
|
||||
|
||||
For complex worktree strategy or organization questions:
|
||||
```
|
||||
Task(
|
||||
subagent_type='working-tree-consultant',
|
||||
description='Worktree strategy consultation',
|
||||
prompt='[question about worktree organization, naming, or workflow]'
|
||||
)
|
||||
```
|
||||
466
commands/status.md
Normal file
466
commands/status.md
Normal file
@@ -0,0 +1,466 @@
|
||||
---
|
||||
description: Show metadata for the current git worktree from .ai-context.json
|
||||
allowed-tools: Bash, Read
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# /working-tree:status
|
||||
|
||||
Display current worktree AI context metadata and git information.
|
||||
|
||||
## EXECUTION PROTOCOL
|
||||
|
||||
Execute steps sequentially. Each step must complete successfully before proceeding.
|
||||
|
||||
### STEP 1: DETECT REPOSITORY ROOT
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel 2>&1)
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → ERROR PATTERN "not-in-git-repo"
|
||||
- REPO_ROOT must be absolute path starting with /
|
||||
- REPO_ROOT directory must exist
|
||||
|
||||
DATA EXTRACTION:
|
||||
- REPO_NAME = basename of REPO_ROOT
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 2
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 2: DETECT CURRENT BRANCH
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD 2>&1)
|
||||
EXIT_CODE=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF EXIT_CODE != 0 → ERROR PATTERN "git-command-failed"
|
||||
- BRANCH_NAME must not be empty string
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 3
|
||||
- On failure → ABORT
|
||||
|
||||
### STEP 3: CHECK METADATA FILE
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
METADATA_PATH="$REPO_ROOT/.ai-context.json"
|
||||
test -f "$METADATA_PATH"
|
||||
EXISTS=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- EXISTS is 0 (true) or 1 (false), no other values
|
||||
|
||||
NEXT:
|
||||
- IF EXISTS == 0 → STEP 4 (metadata exists)
|
||||
- IF EXISTS == 1 → STEP 5 (no metadata)
|
||||
|
||||
### STEP 4: READ AND PARSE METADATA
|
||||
|
||||
EXECUTE:
|
||||
```bash
|
||||
METADATA_JSON=$(cat "$METADATA_PATH" 2>&1)
|
||||
CAT_EXIT=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF CAT_EXIT != 0 → ERROR PATTERN "file-read-failed"
|
||||
|
||||
DATA EXTRACTION:
|
||||
```bash
|
||||
MODE=$(echo "$METADATA_JSON" | jq -r '.mode // "unknown"' 2>&1)
|
||||
JQ_EXIT_MODE=$?
|
||||
DESCRIPTION=$(echo "$METADATA_JSON" | jq -r '.description // ""' 2>&1)
|
||||
JQ_EXIT_DESC=$?
|
||||
CREATED=$(echo "$METADATA_JSON" | jq -r '.created // ""' 2>&1)
|
||||
JQ_EXIT_CREATED=$?
|
||||
```
|
||||
|
||||
VALIDATION:
|
||||
- IF JQ_EXIT_MODE != 0 → ERROR PATTERN "invalid-json"
|
||||
- MODE must be one of: main, feature, bugfix, experiment, review, unknown
|
||||
- DESCRIPTION can be empty string
|
||||
- CREATED should be ISO8601 format or empty
|
||||
|
||||
NEXT:
|
||||
- On success → STEP 6 (display with metadata)
|
||||
- On jq failure → ERROR PATTERN "invalid-json"
|
||||
|
||||
### STEP 5: DISPLAY NO METADATA
|
||||
|
||||
OUTPUT FORMAT (exact):
|
||||
```
|
||||
Worktree Status
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Directory: {REPO_NAME}
|
||||
Branch: {BRANCH_NAME}
|
||||
Mode: (no metadata)
|
||||
|
||||
⚠ No .ai-context.json found
|
||||
|
||||
This worktree doesn't have AI context metadata.
|
||||
|
||||
To add metadata to this worktree:
|
||||
/working-tree:adopt [--mode <mode>] [--description "<text>"]
|
||||
|
||||
To create a new worktree with metadata:
|
||||
/working-tree:new <branch-name>
|
||||
```
|
||||
|
||||
NEXT:
|
||||
- TERMINATE (success)
|
||||
|
||||
### STEP 6: DISPLAY WITH METADATA
|
||||
|
||||
OUTPUT FORMAT (exact):
|
||||
```
|
||||
Worktree Status
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Directory: {REPO_NAME}
|
||||
Branch: {BRANCH_NAME}
|
||||
Mode: {MODE}
|
||||
Created: {CREATED}
|
||||
|
||||
Purpose:
|
||||
{DESCRIPTION or "No description provided"}
|
||||
|
||||
───────────────────────────────────────────────────────────
|
||||
|
||||
Mode Semantics:
|
||||
main → Minimal changes, stable work only
|
||||
feature → Active development, larger changes allowed
|
||||
bugfix → Isolated, surgical fixes only
|
||||
experiment → Prototypes, large swings, unsafe changes allowed
|
||||
review → Documentation, analysis, audits
|
||||
|
||||
Metadata file: .ai-context.json
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {REPO_NAME} = extracted from STEP 1
|
||||
- {BRANCH_NAME} = extracted from STEP 2
|
||||
- {MODE} = extracted from STEP 4
|
||||
- {CREATED} = extracted from STEP 4
|
||||
- {DESCRIPTION} = extracted from STEP 4, if empty use "No description provided"
|
||||
|
||||
NEXT:
|
||||
- TERMINATE (success)
|
||||
|
||||
## ERROR PATTERNS
|
||||
|
||||
### PATTERN: not-in-git-repo
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git rev-parse --show-toplevel exit code != 0
|
||||
- INDICATORS: stderr contains "not a git repository" OR "not inside a work tree"
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Not in a git repository
|
||||
|
||||
Run this command from within a git repository.
|
||||
```
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- RETRY: false
|
||||
- FALLBACK: None
|
||||
|
||||
### PATTERN: git-command-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: git command exit code != 0 (excluding rev-parse --show-toplevel which uses "not-in-git-repo")
|
||||
- CAPTURE: stderr from failed git command
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to read git information
|
||||
|
||||
Git error: {GIT_STDERR}
|
||||
|
||||
Check that:
|
||||
- You're in a git repository
|
||||
- Git is installed and working
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {GIT_STDERR} = captured stderr from failed command
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- RETRY: false
|
||||
- FALLBACK: None
|
||||
|
||||
### PATTERN: invalid-json
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: jq command exit code != 0 when parsing .ai-context.json
|
||||
- CAPTURE: jq error message from stderr
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Warning: .ai-context.json exists but is invalid
|
||||
|
||||
JSON error: {JQ_ERROR}
|
||||
|
||||
The metadata file may be corrupted. Consider:
|
||||
- Fixing the JSON manually
|
||||
- Running /working-tree:adopt to regenerate
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {JQ_ERROR} = captured stderr from jq
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: false (warning, not error)
|
||||
- RETRY: false
|
||||
- FALLBACK: STEP 5 (display as if no metadata)
|
||||
|
||||
### PATTERN: file-read-failed
|
||||
|
||||
DETECTION:
|
||||
- TRIGGER: cat command on .ai-context.json fails despite file existence check passing
|
||||
- CAPTURE: stderr from cat command
|
||||
|
||||
RESPONSE (exact):
|
||||
```
|
||||
Error: Failed to read .ai-context.json
|
||||
|
||||
Read error: {CAT_ERROR}
|
||||
|
||||
Check file permissions on .ai-context.json
|
||||
```
|
||||
|
||||
TEMPLATE SUBSTITUTIONS:
|
||||
- {CAT_ERROR} = captured stderr from cat
|
||||
|
||||
CONTROL FLOW:
|
||||
- ABORT: true
|
||||
- RETRY: false
|
||||
- FALLBACK: None
|
||||
|
||||
## TOOL PERMISSION MATRIX
|
||||
|
||||
| Tool | Pattern | Permission | Pre-Check | Post-Check | On-Deny-Action |
|
||||
|------|---------|------------|-----------|------------|----------------|
|
||||
| Bash | git:* | ALLOW | command_safe | validate_output | N/A |
|
||||
| Bash | jq:* | ALLOW | command_safe | validate_json | N/A |
|
||||
| Bash | cat .ai-context.json | ALLOW | file_exists | validate_output | N/A |
|
||||
| Bash | test:* | ALLOW | N/A | N/A | N/A |
|
||||
| Bash | rm:* | DENY | N/A | N/A | ABORT "Destructive operation" |
|
||||
| Bash | sudo:* | DENY | N/A | N/A | ABORT "Elevated privileges" |
|
||||
| Read | .ai-context.json | ALLOW | file_exists | valid_json | N/A |
|
||||
| Write | ** | DENY | N/A | N/A | ABORT "Status is read-only" |
|
||||
| Edit | ** | DENY | N/A | N/A | ABORT "Status is read-only" |
|
||||
|
||||
SECURITY CONSTRAINTS:
|
||||
- This command is READ-ONLY
|
||||
- NO file modifications allowed
|
||||
- NO destructive operations allowed
|
||||
- Git commands limited to read operations (rev-parse, status, etc.)
|
||||
|
||||
## TEST CASES
|
||||
|
||||
### TC001: Worktree with valid metadata
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository at /path/to/myapp
|
||||
- Current branch: feature/login-refactor
|
||||
- File exists: /path/to/myapp/.ai-context.json
|
||||
- File contains valid JSON:
|
||||
```json
|
||||
{
|
||||
"mode": "feature",
|
||||
"description": "Refactor authentication flow to support OAuth2",
|
||||
"created": "2025-11-23T10:30:00Z",
|
||||
"branch": "feature/login-refactor"
|
||||
}
|
||||
```
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → REPO_ROOT="/path/to/myapp", REPO_NAME="myapp"
|
||||
2. STEP 2 → BRANCH_NAME="feature/login-refactor"
|
||||
3. STEP 3 → EXISTS=0 (metadata exists)
|
||||
4. STEP 4 → MODE="feature", DESCRIPTION="Refactor authentication flow to support OAuth2", CREATED="2025-11-23T10:30:00Z"
|
||||
5. STEP 6 → Display formatted output
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Worktree Status
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Directory: myapp
|
||||
Branch: feature/login-refactor
|
||||
Mode: feature
|
||||
Created: 2025-11-23T10:30:00Z
|
||||
|
||||
Purpose:
|
||||
Refactor authentication flow to support OAuth2
|
||||
|
||||
───────────────────────────────────────────────────────────
|
||||
|
||||
Mode Semantics:
|
||||
main → Minimal changes, stable work only
|
||||
feature → Active development, larger changes allowed
|
||||
bugfix → Isolated, surgical fixes only
|
||||
experiment → Prototypes, large swings, unsafe changes allowed
|
||||
review → Documentation, analysis, audits
|
||||
|
||||
Metadata file: .ai-context.json
|
||||
```
|
||||
|
||||
VALIDATION COMMANDS:
|
||||
```bash
|
||||
# Verify file exists
|
||||
test -f /path/to/myapp/.ai-context.json && echo "PASS" || echo "FAIL"
|
||||
|
||||
# Verify valid JSON
|
||||
jq empty /path/to/myapp/.ai-context.json && echo "PASS" || echo "FAIL"
|
||||
|
||||
# Verify mode field
|
||||
test "$(jq -r '.mode' /path/to/myapp/.ai-context.json)" = "feature" && echo "PASS" || echo "FAIL"
|
||||
```
|
||||
|
||||
### TC002: Worktree without metadata
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository at /path/to/myapp
|
||||
- Current branch: main
|
||||
- File does NOT exist: /path/to/myapp/.ai-context.json
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → REPO_ROOT="/path/to/myapp", REPO_NAME="myapp"
|
||||
2. STEP 2 → BRANCH_NAME="main"
|
||||
3. STEP 3 → EXISTS=1 (no metadata)
|
||||
4. STEP 5 → Display no-metadata output
|
||||
5. TERMINATE
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Worktree Status
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Directory: myapp
|
||||
Branch: main
|
||||
Mode: (no metadata)
|
||||
|
||||
⚠ No .ai-context.json found
|
||||
|
||||
This worktree doesn't have AI context metadata.
|
||||
|
||||
To add metadata to this worktree:
|
||||
/working-tree:adopt [--mode <mode>] [--description "<text>"]
|
||||
|
||||
To create a new worktree with metadata:
|
||||
/working-tree:new <branch-name>
|
||||
```
|
||||
|
||||
VALIDATION COMMANDS:
|
||||
```bash
|
||||
# Verify file does not exist
|
||||
test ! -f /path/to/myapp/.ai-context.json && echo "PASS" || echo "FAIL"
|
||||
```
|
||||
|
||||
### TC003: Invalid JSON in metadata file
|
||||
|
||||
PRECONDITIONS:
|
||||
- In git repository at /path/to/myapp
|
||||
- Current branch: feature/test
|
||||
- File exists: /path/to/myapp/.ai-context.json
|
||||
- File contains invalid JSON: `{invalid json}`
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → REPO_ROOT="/path/to/myapp"
|
||||
2. STEP 2 → BRANCH_NAME="feature/test"
|
||||
3. STEP 3 → EXISTS=0
|
||||
4. STEP 4 → jq fails with parse error
|
||||
5. ERROR PATTERN "invalid-json" → Warning displayed
|
||||
6. FALLBACK → STEP 5 (display as no metadata)
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Warning: .ai-context.json exists but is invalid
|
||||
|
||||
JSON error: parse error: Invalid numeric literal at line 1, column 10
|
||||
|
||||
The metadata file may be corrupted. Consider:
|
||||
- Fixing the JSON manually
|
||||
- Running /working-tree:adopt to regenerate
|
||||
|
||||
Worktree Status
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Directory: myapp
|
||||
Branch: feature/test
|
||||
Mode: (no metadata)
|
||||
|
||||
⚠ No .ai-context.json found
|
||||
|
||||
This worktree doesn't have AI context metadata.
|
||||
|
||||
To add metadata to this worktree:
|
||||
/working-tree:adopt [--mode <mode>] [--description "<text>"]
|
||||
|
||||
To create a new worktree with metadata:
|
||||
/working-tree:new <branch-name>
|
||||
```
|
||||
|
||||
VALIDATION COMMANDS:
|
||||
```bash
|
||||
# Verify file exists but is invalid
|
||||
test -f /path/to/myapp/.ai-context.json && echo "EXISTS"
|
||||
jq empty /path/to/myapp/.ai-context.json 2>&1 | grep -q "parse error" && echo "INVALID"
|
||||
```
|
||||
|
||||
### TC004: Not in git repository
|
||||
|
||||
PRECONDITIONS:
|
||||
- Current directory: /tmp (not a git repository)
|
||||
|
||||
EXPECTED EXECUTION FLOW:
|
||||
1. STEP 1 → git rev-parse fails with exit code 128
|
||||
2. ERROR PATTERN "not-in-git-repo" triggered
|
||||
3. ABORT
|
||||
|
||||
EXPECTED OUTPUT:
|
||||
```
|
||||
Error: Not in a git repository
|
||||
|
||||
Run this command from within a git repository.
|
||||
```
|
||||
|
||||
VALIDATION COMMANDS:
|
||||
```bash
|
||||
# Verify not in git repo
|
||||
cd /tmp
|
||||
git rev-parse --show-toplevel 2>&1 | grep -q "not a git repository" && echo "PASS" || echo "FAIL"
|
||||
```
|
||||
|
||||
## RELATED COMMANDS
|
||||
|
||||
- /working-tree:adopt - Add metadata to current worktree
|
||||
- /working-tree:new - Create new worktree with metadata
|
||||
- /working-tree:list - List all worktrees with metadata
|
||||
- /working-tree:destroy - Remove worktree safely
|
||||
|
||||
## DELEGATION
|
||||
|
||||
For complex worktree strategy questions or multi-worktree workflows:
|
||||
```
|
||||
Task(
|
||||
subagent_type='working-tree-consultant',
|
||||
description='Worktree strategy consultation',
|
||||
prompt='[detailed question about worktree organization]'
|
||||
)
|
||||
```
|
||||
81
plugin.lock.json
Normal file
81
plugin.lock.json
Normal file
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||
"pluginId": "gh:poindexter12/waypoint:workflows",
|
||||
"normalized": {
|
||||
"repo": null,
|
||||
"ref": "refs/tags/v20251128.0",
|
||||
"commit": "92efee163b7afb5ed7ea6e93b36803c40d5cc358",
|
||||
"treeHash": "b472bae5bfbf25e30f98a6fe9fc0d2a2e8772787fd7556f0b26f187d7dfb0cd1",
|
||||
"generatedAt": "2025-11-28T10:27:38.530955Z",
|
||||
"toolVersion": "publish_plugins.py@0.2.0"
|
||||
},
|
||||
"origin": {
|
||||
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||
"branch": "master",
|
||||
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||
},
|
||||
"manifest": {
|
||||
"name": "workflows",
|
||||
"description": "Operational tooling for development workflows - git worktree management with AI context tracking",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"content": {
|
||||
"files": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "e767f45542286c7e63fa5cb8607730dce0e6c747554c7a160ce4fd1624d27d7c"
|
||||
},
|
||||
{
|
||||
"path": "agents/consultant.md",
|
||||
"sha256": "8fea1df653175b728743e0153d00d9826627a1585858dd3a13ef9a6740d97ce7"
|
||||
},
|
||||
{
|
||||
"path": ".claude-plugin/plugin.json",
|
||||
"sha256": "c7f801e0ea1c66c212585f0157b77820605bb46bcdff3786518d94bc7ef30519"
|
||||
},
|
||||
{
|
||||
"path": "commands/new.md",
|
||||
"sha256": "4e6c64f35ef7f07897d73c9f50781d3030a5cbf4d30f41caf6f637373f26a758"
|
||||
},
|
||||
{
|
||||
"path": "commands/status.md",
|
||||
"sha256": "6b2fbd958333b5f87a2eeb4f6f907c5a0a355473562c713c7d137cddefcad573"
|
||||
},
|
||||
{
|
||||
"path": "commands/list.md",
|
||||
"sha256": "2f24e8d4e5db2756d67f51e7aa67069b6b58d605b97924da614cea8decf7b83c"
|
||||
},
|
||||
{
|
||||
"path": "commands/destroy.md",
|
||||
"sha256": "4974027ec09979ea4d0ec2e66c93257b8f3d912e68af856fcd35fc709280812c"
|
||||
},
|
||||
{
|
||||
"path": "commands/adopt.md",
|
||||
"sha256": "5bae28d568460ecfb78a0712e7d472b93f85d38fd8be4008bec09077ea515fcf"
|
||||
},
|
||||
{
|
||||
"path": "skills/working-tree/REFERENCE.md",
|
||||
"sha256": "9858b9903acc3cf105f5ae98c239a441f515bf40853999257e2d458b5bb80934"
|
||||
},
|
||||
{
|
||||
"path": "skills/working-tree/SKILL.md",
|
||||
"sha256": "c571339041dc5eed0e1d7f0877812339016d1933f7b1d5d2e89c7f13ec56c0ce"
|
||||
},
|
||||
{
|
||||
"path": "skills/working-tree/templates/README.working-tree.template",
|
||||
"sha256": "740fd4f46fe2e5a0a55047ed9f06e8ac63fdda915a054d8cdce4e5cce6e345ba"
|
||||
},
|
||||
{
|
||||
"path": "skills/working-tree/templates/ai-context.json.template",
|
||||
"sha256": "e7e56cad1c949ee49357993b3126cdc015af97c5f8ca81d51d65a52b2fde2df9"
|
||||
}
|
||||
],
|
||||
"dirSha256": "b472bae5bfbf25e30f98a6fe9fc0d2a2e8772787fd7556f0b26f187d7dfb0cd1"
|
||||
},
|
||||
"security": {
|
||||
"scannedAt": null,
|
||||
"scannerVersion": null,
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
1049
skills/working-tree/REFERENCE.md
Normal file
1049
skills/working-tree/REFERENCE.md
Normal file
File diff suppressed because it is too large
Load Diff
224
skills/working-tree/SKILL.md
Normal file
224
skills/working-tree/SKILL.md
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
name: worktree-guide
|
||||
description: Git worktree patterns, best practices, templates, and quick reference. Use when user asks about "worktree best practices", "worktree patterns", "git worktree help", "worktree template", "worktree mode semantics", "what are worktree modes", "explain worktree metadata", or needs guidance on worktree organization and workflows.
|
||||
---
|
||||
|
||||
# Git Worktree Guide
|
||||
|
||||
Quick reference and templates for git worktree workflows with AI metadata integration.
|
||||
|
||||
## Progressive Disclosure
|
||||
|
||||
### Initial Response
|
||||
|
||||
**Quick Overview:**
|
||||
|
||||
Git worktrees let you checkout multiple branches simultaneously in separate directories. Each worktree has AI metadata (`.ai-context.json`) that helps tools understand context.
|
||||
|
||||
**Quick Start:**
|
||||
- Create worktree: `/working-tree:new <branch-name>`
|
||||
- List worktrees: `/working-tree:list`
|
||||
- Check status: `/working-tree:status`
|
||||
- Remove worktree: `/working-tree:destroy <path>`
|
||||
- Add metadata: `/working-tree:adopt`
|
||||
|
||||
**What would you like to know more about?**
|
||||
1. Mode semantics (main, feature, bugfix, experiment, review)
|
||||
2. Metadata file structure and templates
|
||||
3. Comprehensive best practices guide
|
||||
4. Strategic organization patterns
|
||||
|
||||
### On Request
|
||||
|
||||
Based on what you ask for, I can show you:
|
||||
|
||||
**Mode Semantics** → Detailed explanation of each mode
|
||||
**Templates** → Ready-to-use metadata templates
|
||||
**Best Practices** → Full reference guide (REFERENCE.md)
|
||||
**Examples** → Specific workflow examples
|
||||
|
||||
## Mode Semantics Quick Reference
|
||||
|
||||
### main
|
||||
**Purpose:** Stable, production-ready code
|
||||
**Restrictions:** Minimal changes only, no experimentation
|
||||
**Use For:** Hotfixes, urgent production changes, stable baseline
|
||||
**AI Behavior:** Conservative suggestions, focus on safety
|
||||
|
||||
### feature
|
||||
**Purpose:** Active development of new features
|
||||
**Restrictions:** None, experimentation encouraged
|
||||
**Use For:** New features, enhancements, active work
|
||||
**AI Behavior:** Helpful, suggests improvements freely
|
||||
|
||||
### bugfix
|
||||
**Purpose:** Isolated, surgical bug fixes
|
||||
**Restrictions:** Minimal scope, no unrelated changes
|
||||
**Use For:** Specific bug fixes, targeted corrections
|
||||
**AI Behavior:** Focused on fix only, warns about scope creep
|
||||
|
||||
### experiment
|
||||
**Purpose:** Prototypes, spikes, research
|
||||
**Restrictions:** None, can be messy, expect to discard
|
||||
**Use For:** POCs, trying new technologies, A/B testing
|
||||
**AI Behavior:** Aggressive suggestions, OK with rough code
|
||||
|
||||
### review
|
||||
**Purpose:** Code review, auditing, documentation
|
||||
**Restrictions:** Read-only mindset, analysis only
|
||||
**Use For:** PR review, security audits, documentation work
|
||||
**AI Behavior:** Analytical, suggests improvements, no execution
|
||||
|
||||
## Metadata File Structure
|
||||
|
||||
### .ai-context.json
|
||||
|
||||
```json
|
||||
{
|
||||
"worktree": "directory-name",
|
||||
"branch": "branch-name",
|
||||
"mode": "main|feature|bugfix|experiment|review",
|
||||
"created": "2025-11-23T12:34:56Z",
|
||||
"description": "Purpose of this worktree"
|
||||
}
|
||||
```
|
||||
|
||||
**Fields:**
|
||||
- `worktree`: Directory name (not full path)
|
||||
- `branch`: Git branch name
|
||||
- `mode`: One of the 5 modes above
|
||||
- `created`: ISO 8601 UTC timestamp
|
||||
- `description`: Freeform text explaining purpose
|
||||
|
||||
### README.working-tree.md
|
||||
|
||||
Generated automatically with worktree details, mode semantics, and paths.
|
||||
|
||||
## Templates
|
||||
|
||||
### Available Templates
|
||||
|
||||
Located in `templates/` directory:
|
||||
1. `ai-context.json.template` - Metadata file template with examples
|
||||
2. `README.working-tree.template` - README template with placeholders
|
||||
|
||||
To view templates:
|
||||
- Ask "show me the metadata template"
|
||||
- Ask "show me the README template"
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Pattern 1: Feature Development
|
||||
```bash
|
||||
/working-tree:new feature/user-auth --mode feature --description "Implement OAuth2"
|
||||
```
|
||||
Work in isolation, merge when ready.
|
||||
|
||||
### Pattern 2: Production Hotfix
|
||||
```bash
|
||||
/working-tree:new bugfix/critical-security-fix --mode bugfix
|
||||
```
|
||||
Quick surgical fix, minimizes risk.
|
||||
|
||||
### Pattern 3: Experimentation
|
||||
```bash
|
||||
/working-tree:new exp/try-new-framework --mode experiment
|
||||
```
|
||||
Prototype freely, discard if needed.
|
||||
|
||||
### Pattern 4: Code Review
|
||||
```bash
|
||||
/working-tree:new review/pr-123 --mode review --description "Review user auth PR"
|
||||
```
|
||||
Review without disrupting current work.
|
||||
|
||||
## Supporting Files
|
||||
|
||||
- **REFERENCE.md**: Comprehensive guide with detailed best practices, naming conventions, workflows, and advanced patterns
|
||||
- **templates/ai-context.json.template**: Copy-paste template for manual metadata creation
|
||||
- **templates/README.working-tree.template**: Template for worktree README
|
||||
|
||||
## Quick Tips
|
||||
|
||||
**DO:**
|
||||
- Use descriptive branch names: `feature/user-dashboard`
|
||||
- Add descriptions to worktrees: `--description "User settings page"`
|
||||
- Run `/working-tree:list` regularly to see active work
|
||||
- Choose appropriate mode for context
|
||||
|
||||
**DON'T:**
|
||||
- Create worktree for same branch twice
|
||||
- Use generic names: `test`, `temp`, `new`
|
||||
- Forget to clean up: `/working-tree:destroy` when done
|
||||
- Ignore uncommitted changes before destroying
|
||||
|
||||
## For More Detail
|
||||
|
||||
**Comprehensive Guide:**
|
||||
Ask to see `REFERENCE.md` for:
|
||||
- Detailed mode usage guidelines
|
||||
- Naming conventions and patterns
|
||||
- Multi-worktree organization strategies
|
||||
- Troubleshooting common issues
|
||||
- Team collaboration workflows
|
||||
- CI/CD integration patterns
|
||||
|
||||
**Strategic Consulting:**
|
||||
For complex worktree organization questions, invoke the `working-tree-consultant` agent:
|
||||
- "Help me organize my worktrees"
|
||||
- "Review my worktree strategy"
|
||||
- "Migrate to worktree workflow"
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Quick Mode Check
|
||||
```
|
||||
User: What mode should I use for a prototype?
|
||||
|
||||
Skill: For prototypes, use **experiment** mode.
|
||||
|
||||
Experiment mode:
|
||||
- No restrictions, can be messy
|
||||
- AI will be aggressive with suggestions
|
||||
- Expect to discard if prototype fails
|
||||
- Good for POCs and spikes
|
||||
|
||||
Command:
|
||||
/working-tree:new exp/prototype-name --mode experiment --description "Testing new approach"
|
||||
```
|
||||
|
||||
### Example 2: Template Request
|
||||
```
|
||||
User: Show me the metadata template
|
||||
|
||||
Skill: Here's the .ai-context.json template:
|
||||
|
||||
[Shows content of templates/ai-context.json.template]
|
||||
|
||||
You can create this manually or use:
|
||||
- /working-tree:new to auto-generate when creating
|
||||
- /working-tree:adopt to auto-generate for existing worktree
|
||||
```
|
||||
|
||||
### Example 3: Best Practices Request
|
||||
```
|
||||
User: What are worktree best practices?
|
||||
|
||||
Skill: **Quick Best Practices:**
|
||||
|
||||
1. **Naming**: Use clear, structured names (myapp-feature-user-auth)
|
||||
2. **Modes**: Choose mode based on work type (see mode semantics above)
|
||||
3. **Cleanup**: Remove worktrees when done (/working-tree:destroy)
|
||||
4. **Metadata**: Always add descriptions
|
||||
5. **Organization**: One feature = one worktree
|
||||
|
||||
**Want more detail?**
|
||||
- See REFERENCE.md for comprehensive guide
|
||||
- Invoke working-tree-consultant for strategic advice
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- Commands: `/working-tree:new`, `/working-tree:list`, `/working-tree:status`, `/working-tree:destroy`, `/working-tree:adopt`
|
||||
- Agent: `working-tree-consultant` for strategic guidance
|
||||
- Documentation: See REFERENCE.md for comprehensive coverage
|
||||
310
skills/working-tree/templates/README.working-tree.template
Normal file
310
skills/working-tree/templates/README.working-tree.template
Normal file
@@ -0,0 +1,310 @@
|
||||
# Worktree: REPLACE_WITH_WORKTREE_NAME
|
||||
|
||||
**Branch:** `REPLACE_WITH_BRANCH_NAME`
|
||||
**Mode:** `REPLACE_WITH_MODE`
|
||||
**Created:** REPLACE_WITH_TIMESTAMP
|
||||
|
||||
## Purpose
|
||||
|
||||
REPLACE_WITH_DESCRIPTION (or "No description provided")
|
||||
|
||||
## Mode Semantics
|
||||
|
||||
- **main**: Minimal changes, stable work only
|
||||
- Use for: Production code, critical hotfixes
|
||||
- Restrictions: No experimentation, minimal scope
|
||||
- AI Behavior: Conservative, safety-focused
|
||||
|
||||
- **feature**: Active development, larger changes allowed
|
||||
- Use for: New features, enhancements, most development
|
||||
- Restrictions: None - be creative!
|
||||
- AI Behavior: Helpful, proactive suggestions
|
||||
|
||||
- **bugfix**: Isolated, surgical fixes only
|
||||
- Use for: Specific bug fixes, targeted corrections
|
||||
- Restrictions: Minimal scope, no unrelated changes
|
||||
- AI Behavior: Focused, warns about scope creep
|
||||
|
||||
- **experiment**: Prototypes, large swings, unsafe changes allowed
|
||||
- Use for: POCs, technology spikes, learning
|
||||
- Restrictions: None - can be messy
|
||||
- AI Behavior: Aggressive suggestions, OK with rough code
|
||||
|
||||
- **review**: Documentation, analysis, audits
|
||||
- Use for: Code review, security audits, understanding code
|
||||
- Restrictions: Read-only mindset
|
||||
- AI Behavior: Analytical, critical feedback
|
||||
|
||||
## About This Worktree
|
||||
|
||||
This directory is an independent Git worktree attached to the main repository.
|
||||
|
||||
- **Main repository:** REPLACE_WITH_MAIN_REPO_PATH
|
||||
- **Worktree path:** REPLACE_WITH_WORKTREE_PATH
|
||||
- **Branch:** REPLACE_WITH_BRANCH_NAME
|
||||
- **Git directory:** Linked to main repository `.git/`
|
||||
|
||||
### What is a Git Worktree?
|
||||
|
||||
A git worktree allows you to check out multiple branches simultaneously in separate directories. All worktrees share the same repository history but have independent working directories.
|
||||
|
||||
**Benefits:**
|
||||
- No need to `git stash` when switching contexts
|
||||
- Work on multiple features in parallel
|
||||
- Isolated dependencies and build artifacts
|
||||
- Fast context switching (just `cd` to different directory)
|
||||
|
||||
### Metadata Files
|
||||
|
||||
**`.ai-context.json`** (Machine-Readable)
|
||||
- JSON format for AI tools
|
||||
- Contains: worktree, branch, mode, created, description
|
||||
- Read automatically by Claude and other AI tools
|
||||
|
||||
**`README.working-tree.md`** (This File)
|
||||
- Human-readable documentation
|
||||
- Explains mode semantics and worktree info
|
||||
- Generated automatically by `/working-tree:new` or `/working-tree:adopt`
|
||||
|
||||
## Quick Commands
|
||||
|
||||
### View Status
|
||||
```bash
|
||||
/working-tree:status
|
||||
```
|
||||
Show metadata for current worktree.
|
||||
|
||||
### List All Worktrees
|
||||
```bash
|
||||
/working-tree:list
|
||||
```
|
||||
See all worktrees in this repository with their metadata.
|
||||
|
||||
### Remove This Worktree
|
||||
```bash
|
||||
cd REPLACE_WITH_MAIN_REPO_PATH
|
||||
/working-tree:destroy REPLACE_WITH_WORKTREE_PATH
|
||||
```
|
||||
Safely remove this worktree (preserves branch).
|
||||
|
||||
### Update Metadata
|
||||
```bash
|
||||
/working-tree:adopt --description "New description"
|
||||
```
|
||||
Update mode or description for this worktree.
|
||||
|
||||
## Workflow Tips
|
||||
|
||||
### Switching Between Worktrees
|
||||
```bash
|
||||
# From this worktree to another
|
||||
cd ../other-worktree-name
|
||||
|
||||
# Back to this worktree
|
||||
cd REPLACE_WITH_WORKTREE_PATH
|
||||
```
|
||||
|
||||
### Committing Changes
|
||||
```bash
|
||||
# Normal git workflow
|
||||
git add .
|
||||
git commit -m "Your commit message"
|
||||
git push origin REPLACE_WITH_BRANCH_NAME
|
||||
```
|
||||
|
||||
### Creating Pull Request
|
||||
```bash
|
||||
# After pushing commits
|
||||
git push origin REPLACE_WITH_BRANCH_NAME
|
||||
# Then create PR in GitHub/GitLab
|
||||
```
|
||||
|
||||
### When Done With This Worktree
|
||||
```bash
|
||||
# 1. Ensure all changes are committed
|
||||
git status
|
||||
|
||||
# 2. Push to remote
|
||||
git push origin REPLACE_WITH_BRANCH_NAME
|
||||
|
||||
# 3. Create and merge PR
|
||||
|
||||
# 4. Remove worktree
|
||||
cd REPLACE_WITH_MAIN_REPO_PATH
|
||||
/working-tree:destroy REPLACE_WITH_WORKTREE_PATH
|
||||
|
||||
# 5. Optionally delete branch after PR merge
|
||||
git branch -d REPLACE_WITH_BRANCH_NAME
|
||||
```
|
||||
|
||||
## Related Worktrees
|
||||
|
||||
Use `/working-tree:list` to see all active worktrees for this repository.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **Comprehensive Guide:** See `working-tree/skills/worktree-guide/REFERENCE.md`
|
||||
- **Templates:** See `working-tree/skills/worktree-guide/templates/`
|
||||
- **Strategic Guidance:** Invoke `working-tree-consultant` agent
|
||||
|
||||
---
|
||||
|
||||
**Auto-Generated:** This file was created automatically by the waypoint working-tree module.
|
||||
**Update:** Run `/working-tree:adopt` to regenerate this file with updated information.
|
||||
|
||||
|
||||
EXAMPLE COMPLETE FILE (Feature Development):
|
||||
|
||||
# Worktree: myapp-feature-user-auth
|
||||
|
||||
**Branch:** `feature/user-authentication`
|
||||
**Mode:** `feature`
|
||||
**Created:** 2025-11-23T10:30:00Z
|
||||
|
||||
## Purpose
|
||||
|
||||
Implement OAuth2 and JWT authentication with refresh token support
|
||||
|
||||
## Mode Semantics
|
||||
|
||||
- **main**: Minimal changes, stable work only
|
||||
- Use for: Production code, critical hotfixes
|
||||
- Restrictions: No experimentation, minimal scope
|
||||
- AI Behavior: Conservative, safety-focused
|
||||
|
||||
- **feature**: Active development, larger changes allowed
|
||||
- Use for: New features, enhancements, most development
|
||||
- Restrictions: None - be creative!
|
||||
- AI Behavior: Helpful, proactive suggestions
|
||||
|
||||
- **bugfix**: Isolated, surgical fixes only
|
||||
- Use for: Specific bug fixes, targeted corrections
|
||||
- Restrictions: Minimal scope, no unrelated changes
|
||||
- AI Behavior: Focused, warns about scope creep
|
||||
|
||||
- **experiment**: Prototypes, large swings, unsafe changes allowed
|
||||
- Use for: POCs, technology spikes, learning
|
||||
- Restrictions: None - can be messy
|
||||
- AI Behavior: Aggressive suggestions, OK with rough code
|
||||
|
||||
- **review**: Documentation, analysis, audits
|
||||
- Use for: Code review, security audits, understanding code
|
||||
- Restrictions: Read-only mindset
|
||||
- AI Behavior: Analytical, critical feedback
|
||||
|
||||
## About This Worktree
|
||||
|
||||
This directory is an independent Git worktree attached to the main repository.
|
||||
|
||||
- **Main repository:** /Users/joe/Code/myapp
|
||||
- **Worktree path:** /Users/joe/Code/myapp-feature-user-auth
|
||||
- **Branch:** feature/user-authentication
|
||||
- **Git directory:** Linked to main repository `.git/`
|
||||
|
||||
### What is a Git Worktree?
|
||||
|
||||
A git worktree allows you to check out multiple branches simultaneously in separate directories. All worktrees share the same repository history but have independent working directories.
|
||||
|
||||
**Benefits:**
|
||||
- No need to `git stash` when switching contexts
|
||||
- Work on multiple features in parallel
|
||||
- Isolated dependencies and build artifacts
|
||||
- Fast context switching (just `cd` to different directory)
|
||||
|
||||
### Metadata Files
|
||||
|
||||
**`.ai-context.json`** (Machine-Readable)
|
||||
- JSON format for AI tools
|
||||
- Contains: worktree, branch, mode, created, description
|
||||
- Read automatically by Claude and other AI tools
|
||||
|
||||
**`README.working-tree.md`** (This File)
|
||||
- Human-readable documentation
|
||||
- Explains mode semantics and worktree info
|
||||
- Generated automatically by `/working-tree:new` or `/working-tree:adopt`
|
||||
|
||||
## Quick Commands
|
||||
|
||||
### View Status
|
||||
```bash
|
||||
/working-tree:status
|
||||
```
|
||||
Show metadata for current worktree.
|
||||
|
||||
### List All Worktrees
|
||||
```bash
|
||||
/working-tree:list
|
||||
```
|
||||
See all worktrees in this repository with their metadata.
|
||||
|
||||
### Remove This Worktree
|
||||
```bash
|
||||
cd /Users/joe/Code/myapp
|
||||
/working-tree:destroy /Users/joe/Code/myapp-feature-user-auth
|
||||
```
|
||||
Safely remove this worktree (preserves branch).
|
||||
|
||||
### Update Metadata
|
||||
```bash
|
||||
/working-tree:adopt --description "New description"
|
||||
```
|
||||
Update mode or description for this worktree.
|
||||
|
||||
## Workflow Tips
|
||||
|
||||
### Switching Between Worktrees
|
||||
```bash
|
||||
# From this worktree to another
|
||||
cd ../myapp-feature-other
|
||||
|
||||
# Back to this worktree
|
||||
cd /Users/joe/Code/myapp-feature-user-auth
|
||||
```
|
||||
|
||||
### Committing Changes
|
||||
```bash
|
||||
# Normal git workflow
|
||||
git add .
|
||||
git commit -m "feat: add OAuth2 authentication provider"
|
||||
git push origin feature/user-authentication
|
||||
```
|
||||
|
||||
### Creating Pull Request
|
||||
```bash
|
||||
# After pushing commits
|
||||
git push origin feature/user-authentication
|
||||
# Then create PR in GitHub/GitLab
|
||||
```
|
||||
|
||||
### When Done With This Worktree
|
||||
```bash
|
||||
# 1. Ensure all changes are committed
|
||||
git status
|
||||
|
||||
# 2. Push to remote
|
||||
git push origin feature/user-authentication
|
||||
|
||||
# 3. Create and merge PR
|
||||
|
||||
# 4. Remove worktree
|
||||
cd /Users/joe/Code/myapp
|
||||
/working-tree:destroy /Users/joe/Code/myapp-feature-user-auth
|
||||
|
||||
# 5. Optionally delete branch after PR merge
|
||||
git branch -d feature/user-authentication
|
||||
```
|
||||
|
||||
## Related Worktrees
|
||||
|
||||
Use `/working-tree:list` to see all active worktrees for this repository.
|
||||
|
||||
## Documentation
|
||||
|
||||
- **Comprehensive Guide:** See `working-tree/skills/worktree-guide/REFERENCE.md`
|
||||
- **Templates:** See `working-tree/skills/worktree-guide/templates/`
|
||||
- **Strategic Guidance:** Invoke `working-tree-consultant` agent
|
||||
|
||||
---
|
||||
|
||||
**Auto-Generated:** This file was created automatically by the waypoint working-tree module.
|
||||
**Update:** Run `/working-tree:adopt` to regenerate this file with updated information.
|
||||
121
skills/working-tree/templates/ai-context.json.template
Normal file
121
skills/working-tree/templates/ai-context.json.template
Normal file
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"worktree": "REPLACE_WITH_DIRECTORY_NAME",
|
||||
"branch": "REPLACE_WITH_BRANCH_NAME",
|
||||
"mode": "CHOOSE_ONE: main|feature|bugfix|experiment|review",
|
||||
"created": "REPLACE_WITH_ISO8601_TIMESTAMP",
|
||||
"description": "REPLACE_WITH_PURPOSE_DESCRIPTION"
|
||||
}
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
Example 1 - Feature Development:
|
||||
{
|
||||
"worktree": "myapp-feature-user-auth",
|
||||
"branch": "feature/user-authentication",
|
||||
"mode": "feature",
|
||||
"created": "2025-11-23T10:30:00Z",
|
||||
"description": "Implement OAuth2 and JWT authentication with refresh tokens"
|
||||
}
|
||||
|
||||
Example 2 - Bug Fix:
|
||||
{
|
||||
"worktree": "api-server-bugfix-rate-limit",
|
||||
"branch": "bugfix/rate-limit-bypass",
|
||||
"mode": "bugfix",
|
||||
"created": "2025-11-23T14:15:00Z",
|
||||
"description": "Fix rate limiting bypass in authentication endpoint (issue #427)"
|
||||
}
|
||||
|
||||
Example 3 - Experiment:
|
||||
{
|
||||
"worktree": "myapp-exp-graphql",
|
||||
"branch": "exp/graphql-migration",
|
||||
"mode": "experiment",
|
||||
"created": "2025-11-23T09:00:00Z",
|
||||
"description": "Evaluate GraphQL migration feasibility and performance impact"
|
||||
}
|
||||
|
||||
Example 4 - Code Review:
|
||||
{
|
||||
"worktree": "myapp-review-pr-543",
|
||||
"branch": "review/pr-543-user-auth",
|
||||
"mode": "review",
|
||||
"created": "2025-11-23T16:45:00Z",
|
||||
"description": "Review PR #543 - User authentication refactor"
|
||||
}
|
||||
|
||||
Example 5 - Main/Production:
|
||||
{
|
||||
"worktree": "myapp",
|
||||
"branch": "main",
|
||||
"mode": "main",
|
||||
"created": "2025-11-23T08:00:00Z",
|
||||
"description": "Production baseline for critical hotfixes only"
|
||||
}
|
||||
|
||||
FIELD REFERENCE:
|
||||
|
||||
worktree:
|
||||
- Directory name only (not full path)
|
||||
- Should match your worktree directory name
|
||||
- Example: "myapp-feature-user-auth"
|
||||
|
||||
branch:
|
||||
- Full git branch name
|
||||
- Must match actual git branch
|
||||
- Example: "feature/user-authentication"
|
||||
- Common prefixes: feature/, bugfix/, exp/, review/
|
||||
|
||||
mode:
|
||||
- Must be one of: main, feature, bugfix, experiment, review
|
||||
- main: Production code, minimal changes only
|
||||
- feature: Active development, no restrictions
|
||||
- bugfix: Surgical fixes, focused scope
|
||||
- experiment: Prototypes, can be messy
|
||||
- review: Code review and analysis
|
||||
|
||||
created:
|
||||
- ISO 8601 format in UTC
|
||||
- Format: YYYY-MM-DDTHH:MM:SSZ
|
||||
- Must end with 'Z' (UTC timezone)
|
||||
- Example: "2025-11-23T10:30:00Z"
|
||||
- Generate with: date -u +"%Y-%m-%dT%H:%M:%SZ"
|
||||
|
||||
description:
|
||||
- Freeform text explaining purpose
|
||||
- Keep to one sentence if possible
|
||||
- Include issue numbers if applicable
|
||||
- Can be empty string: ""
|
||||
- Examples:
|
||||
- "Implement OAuth2 authentication"
|
||||
- "Fix session timeout bug (issue #427)"
|
||||
- "Prototype new GraphQL API"
|
||||
- ""
|
||||
|
||||
AUTOMATED GENERATION:
|
||||
|
||||
Instead of creating this file manually, use commands:
|
||||
/working-tree:new <branch-name> - Creates new worktree with metadata
|
||||
/working-tree:adopt - Adds metadata to existing worktree
|
||||
|
||||
These commands auto-generate this file with correct values.
|
||||
|
||||
VALIDATION:
|
||||
|
||||
Valid JSON:
|
||||
- Proper quotes (double quotes only)
|
||||
- Comma after each field except last
|
||||
- No trailing commas
|
||||
- Valid UTF-8
|
||||
|
||||
Common Mistakes:
|
||||
❌ Single quotes: {'worktree': 'name'}
|
||||
✅ Double quotes: {"worktree": "name"}
|
||||
|
||||
❌ Missing comma: {"worktree": "name" "branch": "main"}
|
||||
✅ Comma present: {"worktree": "name", "branch": "main"}
|
||||
|
||||
❌ Trailing comma: {"mode": "feature",}
|
||||
✅ No trailing comma: {"mode": "feature"}
|
||||
|
||||
Validate with: jq . .ai-context.json
|
||||
Reference in New Issue
Block a user