main
Raw Download raw file

tissue new

Create a new issue in the tissue tracking system.

Tissue Commands

# Interactive creation (prompted metadata, skipable)
tissue new

# Create issue with inline options (skips prompts)
tissue new --title "Fix memory leak in parser" --priority high --tags "bug,performance"

# Push to remote on completion of edit
tissue new --push

# Quick issue creation, editor doesn't open, --push is set to true by default with --quick
tissue new "TODO: Add unit tests for auth module" --quick

Manual Workflow (bash + git)

Basic issue creation

# Switch to issues worktree
cd ../issues

# Generate next issue number
ISSUE_NUM=$(printf "%03d" $(($(ls -1 *.md 2>/dev/null | grep -v README | wc -l) + 1)))
TITLE="Fix memory leak"

# Create safe filename
SAFE_TITLE=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd '[:alnum:]-')
ISSUE_FILE="${ISSUE_NUM}_${SAFE_TITLE}.md"

# Create minimal markdown file with empty frontmatter
echo -e "---\n---\n\n# $TITLE\n\n## Description\n\n## Notes" > "$ISSUE_FILE"

# Build frontmatter using yq
yq --front-matter '.id = "issue-'$(uuidgen | tr '[:upper:]' '[:lower:]')'"' -i "$ISSUE_FILE"
yq --front-matter '.title = "'"$TITLE"'"' -i "$ISSUE_FILE"
yq --front-matter '.status = "open"' -i "$ISSUE_FILE"
yq --front-matter '.priority = "medium"' -i "$ISSUE_FILE"
yq --front-matter '.tags = []' -i "$ISSUE_FILE"
yq --front-matter '.created = now' -i "$ISSUE_FILE"
yq --front-matter '.updated = now' -i "$ISSUE_FILE"
yq --front-matter '.author = "'$(git config user.name)'"' -i "$ISSUE_FILE"
yq --front-matter '.assignee = null' -i "$ISSUE_FILE"

# Open in editor
${EDITOR:-vim} "$ISSUE_FILE"

# Update timestamp after editing
yq --front-matter '.updated = now' -i "$ISSUE_FILE"

# Commit
git add "$ISSUE_FILE"
git commit -m "Add issue #${ISSUE_NUM}: ${TITLE}"

Interactive creation with prompts

# Interactive issue creation
create_issue_interactive() {
    # Prompt for metadata
    read -p "Title: " TITLE
    read -p "Priority (low/medium/high/critical): " PRIORITY
    read -p "Tags (comma-separated): " TAGS_INPUT
    read -p "Assignee (optional): " ASSIGNEE

    cd ../issues

    # Generate issue number
    ISSUE_NUM=$(printf "%03d" $(($(ls -1 *.md 2>/dev/null | grep -v README | wc -l) + 1)))

    # Create filename
    SAFE_TITLE=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd '[:alnum:]-')
    ISSUE_FILE="${ISSUE_NUM}_${SAFE_TITLE}.md"

    # Create minimal file
    echo -e "---\n---\n\n# $TITLE\n\n## Description\n\n## Notes" > "$ISSUE_FILE"

    # Build frontmatter
    yq --front-matter '.id = "issue-'$(uuidgen | tr '[:upper:]' '[:lower:]')'"' -i "$ISSUE_FILE"
    yq --front-matter '.title = "'"$TITLE"'"' -i "$ISSUE_FILE"
    yq --front-matter '.status = "open"' -i "$ISSUE_FILE"
    yq --front-matter '.priority = "'${PRIORITY:-medium}'"' -i "$ISSUE_FILE"

    # Handle tags as array
    if [ -n "$TAGS_INPUT" ]; then
        # Convert comma-separated to JSON array format
        TAGS_JSON=$(echo "$TAGS_INPUT" | jq -R 'split(",") | map(ltrimstr(" ") | rtrimstr(" "))')
        yq --front-matter ".tags = $TAGS_JSON" -i "$ISSUE_FILE"
    else
        yq --front-matter '.tags = []' -i "$ISSUE_FILE"
    fi

    yq --front-matter '.created = now' -i "$ISSUE_FILE"
    yq --front-matter '.updated = now' -i "$ISSUE_FILE"
    yq --front-matter '.author = "'$(git config user.name)'"' -i "$ISSUE_FILE"

    if [ -n "$ASSIGNEE" ]; then
        yq --front-matter '.assignee = "'"$ASSIGNEE"'"' -i "$ISSUE_FILE"
    else
        yq --front-matter '.assignee = null' -i "$ISSUE_FILE"
    fi

    # Open in editor
    ${EDITOR:-vim} "$ISSUE_FILE"

    # Update timestamp after editing
    yq --front-matter '.updated = now' -i "$ISSUE_FILE"

    # Commit
    git add "$ISSUE_FILE"
    git commit -m "Add issue #${ISSUE_NUM}: ${TITLE}"

    echo "Created issue: $ISSUE_FILE"
}

create_issue_interactive

Quick issue creation

# Quick TODO creation
quick_issue() {
    TITLE="$1"
    cd ../issues

    # Generate filename
    NUM=$(printf "%03d" $(($(ls -1 *.md 2>/dev/null | grep -v README | wc -l) + 1)))
    FILE="${NUM}_quick_$(date +%s).md"

    # Create minimal issue
    echo -e "---\n---\n\n# $TITLE" > "$FILE"

    # Set all fields at once using yq
    yq --front-matter '
        .id = "quick-'$(date +%s)'" |
        .title = "'"$TITLE"'" |
        .status = "open" |
        .priority = "low" |
        .tags = ["todo"] |
        .created = now |
        .updated = now |
        .author = "'$(git config user.name)'"
    ' -i "$FILE"

    # Commit and push
    git add "$FILE" && git commit -m "Quick issue: $TITLE" && git push
    echo "Created: $FILE"
}

quick_issue "TODO: Add unit tests"

What tissue does for you:

  1. Automatically generates unique issue IDs
  2. Provides interactive prompts with validation
  3. Enforces consistent frontmatter structure
  4. Handles safe filename generation
  5. Templates for different issue types
  6. Automatic git operations (add, commit, push)
  7. Validates metadata before saving
  8. Maintains consistent timestamp formats
  9. Links to user configuration for defaults
  10. Supports batch operations and relationships