task-start
Comprehensive work session initialization orchestrator that validates environment, creates properly named branches, loads GitHub Issues, and prepares development environment for new tasks
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install arlenagreer-claude-configuration-docs-task-start
Repository
Skill path: skills/task-start
Comprehensive work session initialization orchestrator that validates environment, creates properly named branches, loads GitHub Issues, and prepares development environment for new tasks
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: arlenagreer.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install task-start into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/arlenagreer/claude_configuration_docs before adding task-start to shared team environments
- Use task-start for productivity workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: task-start
description: Comprehensive work session initialization orchestrator that validates environment, creates properly named branches, loads GitHub Issues, and prepares development environment for new tasks
category: productivity
version: 1.0.0
---
# Task-Start Skill
**Comprehensive work session initialization orchestrator** for consistent and reliable task startup.
## Purpose
Automate session-start workflows by:
- Validating git status and working directory cleanliness
- Checking and auto-fixing development environment (Docker, database, dependencies)
- Loading task information from GitHub Issues (highest priority or user-specified)
- Creating properly named feature branches from develop
- Logging session start timestamps
- Optionally invoking frontend-debug skill for GitHub Issue-based tasks
## When to Use
Trigger this skill when:
- Starting a new development task or feature
- Beginning work on a GitHub Issue
- Setting up environment for development session
- Need to ensure clean git state before starting work
- Keywords: "start task", "begin work", "new task", "start issue"
## Core Workflow
### Phase 1: Configuration Management
**Check for shared configuration file**:
1. Look for `.task_wrapup_skill_data.json` in current working directory
2. This file is shared with task-wrapup skill for consistency
3. If not found, create default configuration by prompting user for:
- Project name
- Default base branch (typically "development")
- Docker configuration (enabled, services, health check URL)
- GitHub integration settings
- Environment validation preferences
**Configuration location**: `.task_wrapup_skill_data.json` in project root
**Manage configuration**:
```bash
# Create new config (interactive)
scripts/config_manager.py create
# Create with project name
scripts/config_manager.py create --project-name "MyProject"
# Show current config
scripts/config_manager.py show
# Validate config
scripts/config_manager.py validate
# Get config file path
scripts/config_manager.py path
```
### Phase 2: Preflight Validation
**Execute preflight checks** using `scripts/preflight-checks.sh`:
1. **Verify git repository**: Ensure current directory is a git repository
2. **Check current branch**: Get current branch name for validation
3. **Protected branch check**: Abort if on main/master/production branches
4. **Working directory status**: Check for uncommitted changes
5. **Stash detection**: Warn about stashed work that may need attention
6. **Base branch verification**: Confirm on development or prepare to switch
**Exit codes**:
- `0`: All checks passed
- `1`: On protected branch (cannot start task)
- `2`: Uncommitted changes detected
- `3`: Stashed work detected
- `4`: Not a git repository
**Behavior**:
- Abort if on protected branch
- Warn and prompt user if uncommitted changes or stashes exist
- Prepare to switch to base branch if needed
**Environment variables**:
- `BASE_BRANCH`: Default base branch (default: "development")
- `PROTECTED_BRANCHES`: Space-separated protected branches (default: "main master production")
### Phase 3: Environment Health Checks
**Execute environment validation** using `scripts/environment-health.sh`:
#### Docker Validation
- Check if Docker daemon is running
- Verify container status
- **Auto-fix**: Start Docker services if configured and not running
- Test health endpoint if specified in config
- Wait for services to become ready
#### Database Validation
- Check for pending migrations (Rails-specific)
- **Auto-fix**: Run migrations automatically if configured
- Verify database connectivity
#### Dependencies Validation
- Check npm/yarn packages for outdated versions
- Check Ruby gems (bundler) status
- Alert on missing or outdated dependencies
- **Note**: Does not auto-update, only alerts
#### Environment Variables
- Verify .env files exist (.env, .env.development)
- Check critical environment variables are defined
- Warn about missing required variables
**Auto-fix behavior**:
- Docker services: Auto-start if `DOCKER_AUTO_START=true`
- Database migrations: Auto-run if `AUTO_MIGRATE=true`
- Dependencies: Alert only, no auto-fix
- Environment variables: Alert only, no auto-fix
**Exit codes**:
- `0`: All checks passed or auto-fixed
- `10`: Docker not running (auto-fix failed or disabled)
- `11`: Database not ready
- `12`: Pending migrations (auto-migrate disabled)
- `13`: Dependencies outdated
- `14`: Environment variables missing
**Environment variables**:
- `DOCKER_ENABLED`: Enable Docker checks (default: "true")
- `DOCKER_AUTO_START`: Auto-start Docker if not running (default: "true")
- `DOCKER_HEALTH_URL`: Health endpoint to test (default: "http://localhost:3000/health")
- `CHECK_MIGRATIONS`: Enable migration checks (default: "true")
- `AUTO_MIGRATE`: Auto-run migrations (default: "true")
- `CHECK_DEPS`: Enable dependency checks (default: "true")
### Phase 4: Task Resolution & GitHub Integration
**Determine task to work on**:
**If user provides task in initial prompt**:
- Use the user-provided task description or issue number directly
- Skip to Phase 5: Branch Creation
**If user does NOT provide task in initial prompt**:
- Present menu of options:
- **a) Specify task description**: User provides custom task description
- **b) Specify GitHub Issue Number**: User enters specific issue number to work on
- **c) Proceed with next most-critical outstanding GitHub Issue**: Auto-fetch highest priority open issue
- Wait for user selection before proceeding
**GitHub Issue fetching** using `scripts/github-issue-fetch.py`:
**Fetch specific issue**:
```bash
# By issue number
scripts/github-issue-fetch.py --issue 123
# With custom priority labels
scripts/github-issue-fetch.py --issue 123 --priority-labels critical high medium low
# JSON output
scripts/github-issue-fetch.py --issue 123 --format json
```
**Fetch highest priority issue**:
```bash
# Default priority order: urgent, high, medium, low
scripts/github-issue-fetch.py
# Custom priority order
scripts/github-issue-fetch.py --priority-labels critical blocker high
# JSON output for programmatic use
scripts/github-issue-fetch.py --format json
```
**Requirements**:
- GitHub CLI (`gh`) must be installed: `brew install gh`
- Must be authenticated: `gh auth login`
- Must be in a git repository with GitHub remote
**Issue data returned**:
```json
{
"number": 123,
"title": "Fix login button not responding",
"body": "Description of the issue...",
"labels": ["bug", "high", "frontend"],
"state": "OPEN",
"priority": "high"
}
```
**Display to user**:
- Show issue number and title
- Display priority level
- Show labels
- Display description (truncated if very long)
- Allow user to confirm or specify different task
### Phase 5: Branch Creation
**Create feature branch** using `scripts/branch-create.sh`:
**Branch naming convention**:
- Pattern: `feature/{issue-number}-{sanitized-description}`
- If no issue: `feature/{sanitized-description}`
- Max length: 50 characters
- Sanitization: lowercase, hyphens for spaces/special chars
**Examples**:
- With issue #123 "User Authentication": `feature/123-user-authentication`
- No issue "Password Reset": `feature/password-reset`
- Issue #456 "Fix Dashboard Loading Speed": `feature/456-fix-dashboard-loading-speed`
**Execution**:
```bash
# With task description only
scripts/branch-create.sh "user authentication"
# With GitHub issue number
scripts/branch-create.sh "user authentication" 123
# From GitHub issue object (automated)
scripts/branch-create.sh "$(echo $ISSUE_TITLE | head -c 30)" $ISSUE_NUMBER
```
**Behavior**:
1. Capture current branch as parent branch (for PR automation)
2. Switch to base branch (development) if not already there
3. Create new branch with sanitized name
4. Checkout new branch
5. Create session state file (`.task_session_state.json`) for PR automation
6. Display confirmation with branch name
**Session State File**:
The branch creation process automatically creates `.task_session_state.json` in the project root to enable automated pull request creation via the task-wrapup skill. This file tracks:
- Parent branch (for PR targeting)
- Feature branch name
- GitHub issue number and metadata (if available)
- Session creation timestamp
**Important**: `.task_session_state.json` should be added to `.gitignore` as it contains local session state.
**Environment variables**:
- `BRANCH_PREFIX`: Branch prefix (default: "feature")
- `MAX_LENGTH`: Max branch name length (default: 50)
- `BASE_BRANCH`: Base branch to create from (default: "development")
### Phase 6: Session Initialization
**Log session start**:
1. Record timestamp of session start
2. Record branch name created
3. Record task/issue reference
4. Store in session log (if configured)
**Session log structure** (if enabled):
```
.claude/sessions/2025-01-15-143022.md
# Session Start: 2025-01-15 14:30:22
**Branch**: feature/123-user-authentication
**Issue**: #123 - Fix login button not responding
**Priority**: high
**Started**: 2025-01-15 14:30:22
```
**Purpose**: Future time tracking, session analytics, work pattern analysis
### Phase 7: Frontend-Debug Skill Integration
**Invoke frontend-debug skill** (if applicable):
**Triggers**:
- Task is based on a GitHub Issue
- Issue has labels suggesting frontend work (bug, frontend, UI, etc.)
- Configuration enables auto-invoke (`integrations.frontend_debug_skill: true`)
- Configuration enables GitHub issue integration (`integrations.invoke_on_github_issue: true`)
**Invocation**:
```bash
# Pass issue number to frontend-debug skill
@~/.claude/skills/frontend-debug/SKILL.md --github-issue 123
```
**Behavior**:
- Frontend-debug skill loads issue details
- Begins systematic debugging workflow
- User continues with frontend-debug skill guidance
- Task-start skill completes successfully
**Note**: In the future, this will be replaced with a more general debugging skill that handles all issue types, not just frontend issues.
### Phase 8: Final Summary
**Display session initialization results**:
- ✅ Preflight checks passed
- ✅ Environment health validated (with auto-fixes applied)
- ✅ Task loaded: GitHub Issue #123 or user description
- ✅ Branch created: feature/123-user-authentication
- ✅ Session logged
- ✅ Frontend-debug skill invoked (if applicable)
**Ready to work**: Environment prepared and task context loaded
## Configuration Schema
Configuration shared with task-wrapup skill in `.task_wrapup_skill_data.json`:
```json
{
"schema_version": "1.0",
"project_name": "MyProject",
"created_at": "2025-01-15T10:30:00",
"last_updated": "2025-01-15T10:30:00",
"task_start": {
"default_base_branch": "development",
"protected_branches": ["main", "master", "production"],
"branch_naming": {
"prefix": "feature",
"include_issue_number": true,
"max_length": 50
},
"github": {
"enabled": true,
"default_behavior": "prompt_user",
"labels_priority_order": ["urgent", "high", "medium", "low"]
},
"environment": {
"docker": {
"enabled": true,
"auto_start": true,
"health_check_url": "http://localhost:3000/health",
"services": ["backend", "frontend", "db"]
},
"database": {
"check_migrations": true,
"auto_migrate": true
},
"dependencies": {
"check_updates": true,
"package_managers": ["npm", "bundler"]
},
"env_files": {
"required": [".env", ".env.development"],
"critical_vars": ["DATABASE_URL", "SECRET_KEY_BASE"]
}
},
"logging": {
"session_logs_dir": ".claude/sessions",
"track_start_time": true,
"create_session_file": false
},
"integrations": {
"frontend_debug_skill": true,
"invoke_on_github_issue": true
}
},
"summary_generation": { ... },
"communication": { ... },
"worklog": { ... },
"documentation": { ... }
}
```
## Usage Examples
### Basic Usage - Start New Task
```
User: "Start new task for user authentication"
```
The skill will:
1. Run preflight checks (git status, working directory)
2. Validate environment (Docker, DB, dependencies)
3. Prompt for task description if not provided
4. Create branch: `feature/user-authentication`
5. Display ready-to-work confirmation
### Start Task with GitHub Issue Number
```
User: "Start task for issue #123"
```
The skill will:
1. Run all validation checks
2. Fetch GitHub Issue #123 details
3. Display issue summary for confirmation
4. Create branch: `feature/123-{sanitized-title}`
5. Invoke frontend-debug skill if issue is frontend-related
### Start Task - Highest Priority Issue
```
User: "Start next task"
```
The skill will:
1. Run validation checks
2. Fetch highest priority open GitHub Issue
3. Display issue for user confirmation
4. Create appropriately named branch
5. Proceed with skill integration if applicable
### Manual Task Description
```
User: "Start task"
```
If no GitHub Issue specified:
1. Complete all validation
2. Prompt: "What task are you starting?"
3. User provides description
4. Create branch from description
5. Ready to work
## Error Handling
### Preflight Failures
**Protected Branch Error**:
```
❌ Cannot start new task from protected branch: main
New tasks must be started from development branch
```
**Action**: Switch to development manually or let skill switch automatically
**Uncommitted Changes**:
```
⚠️ Uncommitted changes detected:
M backend/app/models/user.rb
M frontend/src/components/Login.tsx
Please commit or stash changes before starting new task
```
**Action**: Commit changes or stash, then re-run skill
**Stashed Work**:
```
⚠️ 3 stashed change(s) detected:
stash@{0}: WIP on feature/old-task: abc123 work in progress
stash@{1}: WIP on feature/another: def456 more work
stash@{2}: WIP on develop: ghi789 old stash
Consider applying or clearing stashes before starting new task
```
**Action**: Review and clear stashes, or continue with warning
### Environment Failures
**Docker Not Running**:
```
⚠️ No Docker containers running
🔄 Attempting to start Docker services...
✅ Docker services started
```
**Auto-fix**: Starts services automatically if enabled
**Pending Migrations**:
```
⚠️ 5 pending migration(s) detected
🔄 Running migrations...
✅ Migrations complete
```
**Auto-fix**: Runs migrations automatically if enabled
**Outdated Dependencies**:
```
⚠️ 12 outdated npm package(s)
Run 'npm outdated' to see details
```
**Action**: User decides whether to update before proceeding
### GitHub Integration Failures
**GitHub CLI Not Installed**:
```
❌ GitHub CLI (gh) not installed or not authenticated
Install: brew install gh
Authenticate: gh auth login
```
**Fallback**: Prompt user for manual task description
**No Open Issues**:
```
⚠️ No open issues found
```
**Fallback**: Prompt user for manual task description
**Issue Closed**:
```
⚠️ Issue #123 is not open (state: CLOSED)
```
**Action**: User selects different issue or provides description
## Integration with Other Skills
### Task-Wrapup Skill
- **Shared configuration**: Uses same `.task_wrapup_skill_data.json` file
- **Complementary workflow**: task-start begins session, task-wrapup ends it
- **Session continuity**: Session logs can inform wrap-up summaries
### Frontend-Debug Skill
- **Auto-invocation**: Triggered for GitHub Issue-based frontend tasks
- **Issue context**: Passes issue number to debug skill
- **Seamless handoff**: User continues with debug workflow after initialization
### Contacts Skill
- **Future integration**: Potential for notifying team members when starting tasks
- **Not currently implemented**: Placeholder for future enhancement
## Bundled Scripts
### scripts/config_manager.py
**Purpose**: Manage shared configuration file
**Features**:
- Create new configuration (interactive or scripted)
- Load and validate existing configuration
- Compatible with task-wrapup skill configuration
- Schema validation and migration support
**CLI**:
```bash
python3 scripts/config_manager.py create [--project-name NAME] [--directory DIR]
python3 scripts/config_manager.py show [--directory DIR]
python3 scripts/config_manager.py validate [--directory DIR]
python3 scripts/config_manager.py path [--directory DIR]
```
### scripts/preflight-checks.sh
**Purpose**: Git and working directory validation
**Features**:
- Protected branch detection
- Working directory cleanliness check
- Stash detection and warning
- Base branch verification
- Non-destructive (read-only checks)
**Environment**: BASE_BRANCH, PROTECTED_BRANCHES
### scripts/environment-health.sh
**Purpose**: Development environment validation and auto-fixing
**Features**:
- Docker daemon and container checks with auto-start
- Database migration status with auto-migrate
- Dependency version checking (npm, bundler)
- Environment variable validation
- Intelligent auto-fix capabilities
**Environment**: DOCKER_ENABLED, DOCKER_AUTO_START, DOCKER_HEALTH_URL, CHECK_MIGRATIONS, AUTO_MIGRATE, CHECK_DEPS, CRITICAL_VARS
### scripts/github-issue-fetch.py
**Purpose**: GitHub Issue integration and priority detection
**Features**:
- Fetch specific issue by number
- Find highest priority open issue
- Priority detection from labels
- JSON and summary output formats
- GitHub CLI integration
**Requirements**: gh CLI installed and authenticated
### scripts/branch-create.sh
**Purpose**: Consistent branch naming and creation
**Features**:
- Automatic name sanitization
- Issue number integration
- Length constraints (50 chars)
- Lowercase normalization
- Base branch switching
**Environment**: BRANCH_PREFIX, MAX_LENGTH, BASE_BRANCH
## Best Practices
### Configuration Strategy
1. Create configuration once per project
2. Commit `.task_wrapup_skill_data.json` to version control if team-shared
3. Add to `.gitignore` if contains sensitive data
4. Update configuration as project needs evolve
### Workflow Integration
1. Always start tasks with this skill for consistency
2. Let auto-fix handle environment issues when safe
3. Review GitHub Issue before starting work
4. Use descriptive branch names even without issue numbers
5. Leverage frontend-debug skill integration for bug fixes
### Team Coordination
1. Establish team conventions for priority labels
2. Use consistent base branch across team
3. Document protected branches in configuration
4. Share configuration file structure for new projects
## Future Enhancements
### Planned Features
- General debugging skill integration (not just frontend)
- Team notification when starting tasks
- Time estimation integration
- Dependency auto-update option
- Multiple branch naming conventions
- Jira/Linear integration alongside GitHub
### Potential Improvements
- IDE integration for automatic environment setup
- Serena memory integration for context loading
- Task dependency checking
- Automated code review prep
- Integration with /sc:load for project context
---
**Author**: Claude Code SuperClaude Framework
**License**: MIT
**Repository**: ~/.claude/skills/task-start/
**Version**: 1.0.0
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### scripts/config_manager.py
```python
#!/usr/bin/env python3
"""
Configuration manager for task-start skill.
Shares configuration file with task-wrapup skill (.task_wrapup_skill_data.json).
"""
import json
import os
import sys
from datetime import datetime
from pathlib import Path
from typing import Dict, Any, Optional
CONFIG_FILENAME = ".task_wrapup_skill_data.json"
SCHEMA_VERSION = "1.0"
class ConfigManager:
"""Manages shared configuration file for task-start and task-wrapup skills."""
def __init__(self, project_dir: str = "."):
self.project_dir = Path(project_dir).resolve()
self.config_path = self.project_dir / CONFIG_FILENAME
def exists(self) -> bool:
"""Check if config file exists."""
return self.config_path.exists()
def load(self) -> Dict[str, Any]:
"""Load configuration from file."""
if not self.exists():
raise FileNotFoundError(f"Config file not found: {self.config_path}")
with open(self.config_path, 'r') as f:
return json.load(f)
def save(self, config: Dict[str, Any]) -> None:
"""Save configuration to file."""
config['last_updated'] = datetime.now().isoformat()
with open(self.config_path, 'w') as f:
json.dump(config, f, indent=2)
def create_default(self, project_name: str, **kwargs) -> Dict[str, Any]:
"""Create default configuration structure."""
now = datetime.now().isoformat()
config = {
"schema_version": SCHEMA_VERSION,
"project_name": project_name,
"created_at": now,
"last_updated": now,
# Task-start specific configuration
"task_start": {
"default_base_branch": "development",
"protected_branches": ["main", "master", "production"],
"branch_naming": {
"prefix": "feature",
"include_issue_number": True,
"max_length": 50
},
"github": {
"enabled": True,
"default_behavior": "fetch_highest_priority",
"labels_priority_order": ["urgent", "high", "medium", "low"]
},
"environment": {
"docker": {
"enabled": True,
"auto_start": True,
"health_check_url": "http://localhost:3000/health",
"services": ["backend", "frontend", "db"]
},
"database": {
"check_migrations": True,
"auto_migrate": True
},
"dependencies": {
"check_updates": True,
"package_managers": ["npm", "bundler"]
},
"env_files": {
"required": [".env", ".env.development"],
"critical_vars": ["DATABASE_URL", "SECRET_KEY_BASE"]
}
},
"logging": {
"session_logs_dir": ".claude/sessions",
"track_start_time": True,
"create_session_file": False
},
"integrations": {
"frontend_debug_skill": True,
"invoke_on_github_issue": True
}
},
# Shared configuration (used by task-wrapup)
"summary_generation": kwargs.get("summary_generation", {
"strategy": "hybrid",
"sources": {
"git_commits": True,
"todo_tasks": True,
"serena_memory": True,
"file_changes": True
}
}),
"communication": kwargs.get("communication", {
"email": {"enabled": False, "recipients": []},
"sms": {"enabled": False, "recipients": []},
"slack": {"enabled": False, "channel": ""}
}),
"worklog": kwargs.get("worklog", {
"enabled": False,
"prompt_for_duration": True
}),
"documentation": kwargs.get("documentation", {
"enabled": True,
"auto_update": True,
"paths": ["README.md", "CHANGELOG.md"]
})
}
return config
def prompt_for_config(self) -> Dict[str, Any]:
"""Interactive configuration creation."""
print("📋 Task-Start Configuration Setup")
print("=" * 50)
# Project name
project_name = input("Project name: ").strip()
if not project_name:
print("❌ Project name is required")
sys.exit(1)
# Base branch
base_branch = input("Default base branch [development]: ").strip() or "development"
# Docker configuration
docker_enabled = input("Is this a dockerized project? [Y/n]: ").strip().lower() != 'n'
docker_config = {}
if docker_enabled:
docker_config = {
"enabled": True,
"auto_start": input("Auto-start Docker services? [Y/n]: ").strip().lower() != 'n',
"health_check_url": input("Health check URL [http://localhost:3000/health]: ").strip() or "http://localhost:3000/health",
"services": input("Docker services (comma-separated) [backend,frontend,db]: ").strip().split(',') or ["backend", "frontend", "db"]
}
else:
docker_config = {"enabled": False}
# GitHub integration
github_enabled = input("Enable GitHub integration? [Y/n]: ").strip().lower() != 'n'
# Create config
config = self.create_default(project_name)
config["task_start"]["default_base_branch"] = base_branch
config["task_start"]["environment"]["docker"] = docker_config
config["task_start"]["github"]["enabled"] = github_enabled
return config
def validate(self, config: Dict[str, Any]) -> tuple[bool, list[str]]:
"""Validate configuration structure."""
errors = []
# Check required top-level fields
required_fields = ["schema_version", "project_name", "created_at"]
for field in required_fields:
if field not in config:
errors.append(f"Missing required field: {field}")
# Check task_start section
if "task_start" not in config:
errors.append("Missing task_start configuration section")
else:
task_start = config["task_start"]
# Check required task_start fields
if "default_base_branch" not in task_start:
errors.append("Missing task_start.default_base_branch")
if "environment" not in task_start:
errors.append("Missing task_start.environment section")
return len(errors) == 0, errors
def main():
"""CLI interface for configuration management."""
import argparse
parser = argparse.ArgumentParser(description="Manage task-start configuration")
parser.add_argument("command", choices=["create", "show", "validate", "path"],
help="Command to execute")
parser.add_argument("--directory", default=".", help="Project directory")
parser.add_argument("--project-name", help="Project name (for create)")
args = parser.parse_args()
manager = ConfigManager(args.directory)
if args.command == "create":
if manager.exists():
print(f"⚠️ Config file already exists: {manager.config_path}")
overwrite = input("Overwrite? [y/N]: ").strip().lower() == 'y'
if not overwrite:
print("❌ Cancelled")
sys.exit(0)
if args.project_name:
config = manager.create_default(args.project_name)
else:
config = manager.prompt_for_config()
manager.save(config)
print(f"✅ Configuration created: {manager.config_path}")
elif args.command == "show":
if not manager.exists():
print(f"❌ Config file not found: {manager.config_path}")
sys.exit(1)
config = manager.load()
print(json.dumps(config, indent=2))
elif args.command == "validate":
if not manager.exists():
print(f"❌ Config file not found: {manager.config_path}")
sys.exit(1)
config = manager.load()
valid, errors = manager.validate(config)
if valid:
print("✅ Configuration is valid")
else:
print("❌ Configuration validation failed:")
for error in errors:
print(f" - {error}")
sys.exit(1)
elif args.command == "path":
print(manager.config_path)
if __name__ == "__main__":
main()
```
### scripts/github-issue-fetch.py
```python
#!/usr/bin/env python3
"""
GitHub issue fetcher for task-start skill.
Fetches highest priority issue or specific issue by number.
"""
import json
import os
import sys
import subprocess
from typing import Optional, Dict, Any, List
# Priority order for labels (highest to lowest)
DEFAULT_PRIORITY_LABELS = ["urgent", "high", "medium", "low"]
class GitHubIssueFetcher:
"""Fetches GitHub issues using gh CLI."""
def __init__(self, priority_labels: Optional[List[str]] = None):
self.priority_labels = priority_labels or DEFAULT_PRIORITY_LABELS
def check_gh_cli(self) -> bool:
"""Check if gh CLI is installed and authenticated."""
try:
subprocess.run(
["gh", "auth", "status"],
check=True,
capture_output=True,
text=True
)
return True
except (subprocess.CalledProcessError, FileNotFoundError):
return False
def get_issue(self, issue_number: Optional[int] = None) -> Optional[Dict[str, Any]]:
"""
Get specific issue by number or highest priority open issue.
Args:
issue_number: Specific issue number, or None for highest priority
Returns:
Issue dict with keys: number, title, body, labels, state
"""
if not self.check_gh_cli():
print("❌ GitHub CLI (gh) not installed or not authenticated", file=sys.stderr)
print(" Install: brew install gh", file=sys.stderr)
print(" Authenticate: gh auth login", file=sys.stderr)
return None
try:
if issue_number:
# Fetch specific issue
result = subprocess.run(
["gh", "issue", "view", str(issue_number), "--json",
"number,title,body,labels,state"],
capture_output=True,
text=True,
check=True
)
issue = json.loads(result.stdout)
if issue.get("state") != "OPEN":
print(f"⚠️ Issue #{issue_number} is not open (state: {issue.get('state')})", file=sys.stderr)
return None
return self._format_issue(issue)
else:
# Fetch all open issues
result = subprocess.run(
["gh", "issue", "list", "--state", "open", "--json",
"number,title,body,labels,state", "--limit", "100"],
capture_output=True,
text=True,
check=True
)
issues = json.loads(result.stdout)
if not issues:
print("⚠️ No open issues found", file=sys.stderr)
return None
# Find highest priority issue
highest_priority = self._find_highest_priority(issues)
return highest_priority
except subprocess.CalledProcessError as e:
print(f"❌ Failed to fetch GitHub issue: {e.stderr}", file=sys.stderr)
return None
except json.JSONDecodeError as e:
print(f"❌ Failed to parse GitHub response: {e}", file=sys.stderr)
return None
def _format_issue(self, issue: Dict[str, Any]) -> Dict[str, Any]:
"""Format issue data for consistent structure."""
label_names = [label.get("name", "") for label in issue.get("labels", [])]
return {
"number": issue["number"],
"title": issue["title"],
"body": issue.get("body", ""),
"labels": label_names,
"state": issue.get("state", "OPEN"),
"priority": self._get_priority_level(label_names)
}
def _get_priority_level(self, labels: List[str]) -> str:
"""Determine priority level from labels."""
for priority in self.priority_labels:
if priority in labels:
return priority
return "none"
def _find_highest_priority(self, issues: List[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
"""Find highest priority issue from list."""
if not issues:
return None
# Format all issues
formatted = [self._format_issue(issue) for issue in issues]
# Sort by priority level
def priority_key(issue):
priority = issue.get("priority", "none")
try:
return self.priority_labels.index(priority)
except ValueError:
return len(self.priority_labels) # No priority label = lowest
sorted_issues = sorted(formatted, key=priority_key)
return sorted_issues[0] if sorted_issues else None
def format_summary(self, issue: Dict[str, Any]) -> str:
"""Format issue for display to user."""
lines = [
"=" * 60,
f"📋 GitHub Issue #{issue['number']}",
"=" * 60,
f"Title: {issue['title']}",
f"Priority: {issue['priority'].upper() if issue['priority'] != 'none' else 'None'}",
f"Labels: {', '.join(issue['labels']) if issue['labels'] else 'None'}",
"",
"Description:",
"-" * 60,
issue['body'][:500] + ("..." if len(issue['body']) > 500 else ""),
"=" * 60,
]
return "\n".join(lines)
def main():
"""CLI interface."""
import argparse
parser = argparse.ArgumentParser(description="Fetch GitHub issues")
parser.add_argument("--issue", "-i", type=int, help="Specific issue number")
parser.add_argument("--priority-labels", nargs="+", help="Priority labels in order")
parser.add_argument("--format", choices=["json", "summary"], default="summary",
help="Output format")
args = parser.parse_args()
# Initialize fetcher
fetcher = GitHubIssueFetcher(priority_labels=args.priority_labels)
# Fetch issue
issue = fetcher.get_issue(issue_number=args.issue)
if not issue:
sys.exit(1)
# Output
if args.format == "json":
print(json.dumps(issue, indent=2))
else:
print(fetcher.format_summary(issue))
if __name__ == "__main__":
main()
```
### scripts/branch-create.sh
```bash
#!/usr/bin/env bash
#
# Branch creation script for task-start skill
# Creates properly named feature branches
#
set -e
# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
BRANCH_PREFIX="${BRANCH_PREFIX:-feature}"
MAX_LENGTH="${MAX_LENGTH:-50}"
BASE_BRANCH="${BASE_BRANCH:-development}"
# Function to sanitize branch name
sanitize_name() {
local name="$1"
# Convert to lowercase
name=$(echo "$name" | tr '[:upper:]' '[:lower:]')
# Replace spaces and special chars with hyphens
name=$(echo "$name" | sed 's/[^a-z0-9-]/-/g')
# Remove multiple consecutive hyphens
name=$(echo "$name" | sed 's/-\+/-/g')
# Remove leading/trailing hyphens
name=$(echo "$name" | sed 's/^-//;s/-$//')
# Truncate to max length
if [ ${#name} -gt $MAX_LENGTH ]; then
name="${name:0:$MAX_LENGTH}"
# Remove trailing hyphen if truncation created one
name=$(echo "$name" | sed 's/-$//')
fi
echo "$name"
}
# Function to create branch name
create_branch_name() {
local issue_number="$1"
local description="$2"
local sanitized_desc=$(sanitize_name "$description")
if [ -n "$issue_number" ]; then
echo "${BRANCH_PREFIX}/${issue_number}-${sanitized_desc}"
else
echo "${BRANCH_PREFIX}/${sanitized_desc}"
fi
}
# Function to switch to base branch
switch_to_base() {
local current_branch=$(git branch --show-current)
if [ "$current_branch" != "$BASE_BRANCH" ]; then
echo -e "${BLUE}🔄 Switching to base branch: $BASE_BRANCH${NC}"
git checkout "$BASE_BRANCH"
fi
}
# Function to create and checkout new branch
create_and_checkout() {
local branch_name="$1"
echo -e "${BLUE}🌿 Creating branch: $branch_name${NC}"
# Create and checkout new branch
git checkout -b "$branch_name"
echo -e "${GREEN}✅ Branch created and checked out: $branch_name${NC}"
echo
echo "Current branch: $(git branch --show-current)"
}
# Function to create session state file
create_session_state() {
local feature_branch="$1"
local parent_branch="$2"
local issue_number="$3"
local project_root=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
local state_file="${project_root}/.task_session_state.json"
echo -e "${BLUE}📝 Creating session state...${NC}"
# Generate ISO 8601 UTC timestamp
local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# Build JSON (handle optional issue_number)
if [ -n "$issue_number" ]; then
cat > "$state_file" <<EOF
{
"schema_version": "1.0",
"created_at": "$timestamp",
"feature_branch": "$feature_branch",
"parent_branch": "$parent_branch",
"issue_number": $issue_number,
"github_issue": null
}
EOF
else
cat > "$state_file" <<EOF
{
"schema_version": "1.0",
"created_at": "$timestamp",
"feature_branch": "$feature_branch",
"parent_branch": "$parent_branch",
"issue_number": null,
"github_issue": null
}
EOF
fi
if [ -f "$state_file" ]; then
echo -e "${GREEN}✅ Session state created: $state_file${NC}"
else
echo -e "${YELLOW}⚠️ Warning: Failed to create session state${NC}"
fi
}
# Main script
if [ $# -lt 1 ]; then
echo "Usage: $0 <description> [issue-number]"
echo
echo "Examples:"
echo " $0 'user authentication'"
echo " $0 'user authentication' 123"
exit 1
fi
DESCRIPTION="$1"
ISSUE_NUMBER="${2:-}"
# Generate branch name
BRANCH_NAME=$(create_branch_name "$ISSUE_NUMBER" "$DESCRIPTION")
echo "📋 Branch Configuration:"
echo " Description: $DESCRIPTION"
echo " Issue Number: ${ISSUE_NUMBER:-None}"
echo " Branch Name: $BRANCH_NAME"
echo
# Capture parent branch before switching
PARENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "$BASE_BRANCH")
# Switch to base branch if needed
switch_to_base
# Create and checkout new branch
create_and_checkout "$BRANCH_NAME"
# Create session state file for PR automation
create_session_state "$BRANCH_NAME" "$PARENT_BRANCH" "$ISSUE_NUMBER"
```
### scripts/preflight-checks.sh
```bash
#!/usr/bin/env bash
#
# Preflight checks for task-start skill
# Validates git status, working directory, and branch state
#
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
BASE_BRANCH="${BASE_BRANCH:-development}"
PROTECTED_BRANCHES="${PROTECTED_BRANCHES:-main master production}"
# Exit codes
EXIT_SUCCESS=0
EXIT_PROTECTED_BRANCH=1
EXIT_UNCOMMITTED_CHANGES=2
EXIT_STASHED_WORK=3
EXIT_NOT_GIT_REPO=4
echo "🔍 Running preflight checks..."
echo
# Check if we're in a git repository
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo -e "${RED}❌ Not a git repository${NC}"
exit $EXIT_NOT_GIT_REPO
fi
# Get current branch
CURRENT_BRANCH=$(git branch --show-current)
echo "📍 Current branch: $CURRENT_BRANCH"
# Check if on protected branch
for protected in $PROTECTED_BRANCHES; do
if [ "$CURRENT_BRANCH" = "$protected" ]; then
echo -e "${RED}❌ Cannot start new task from protected branch: $protected${NC}"
echo -e " New tasks must be started from $BASE_BRANCH branch"
exit $EXIT_PROTECTED_BRANCH
fi
done
echo -e "${GREEN}✅ Not on protected branch${NC}"
# Check for uncommitted changes
if ! git diff --quiet || ! git diff --cached --quiet; then
echo -e "${YELLOW}⚠️ Uncommitted changes detected:${NC}"
git status --short
echo
echo "Please commit or stash changes before starting new task"
exit $EXIT_UNCOMMITTED_CHANGES
fi
echo -e "${GREEN}✅ No uncommitted changes${NC}"
# Check for stashed work
STASH_COUNT=$(git stash list | wc -l | tr -d ' ')
if [ "$STASH_COUNT" -gt 0 ]; then
echo -e "${YELLOW}⚠️ $STASH_COUNT stashed change(s) detected:${NC}"
git stash list | head -3
echo
echo "Consider applying or clearing stashes before starting new task"
exit $EXIT_STASHED_WORK
fi
echo -e "${GREEN}✅ No stashed work${NC}"
# Check if on base branch
if [ "$CURRENT_BRANCH" != "$BASE_BRANCH" ]; then
echo -e "${YELLOW}⚠️ Not on base branch ($BASE_BRANCH)${NC}"
echo " Will switch to $BASE_BRANCH before creating new branch"
else
echo -e "${GREEN}✅ On base branch ($BASE_BRANCH)${NC}"
fi
echo
echo -e "${GREEN}✅ All preflight checks passed${NC}"
exit $EXIT_SUCCESS
```
### scripts/environment-health.sh
```bash
#!/usr/bin/env bash
#
# Environment health checks for task-start skill
# Validates Docker, database, dependencies, and environment variables
#
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Configuration from environment or defaults
DOCKER_ENABLED="${DOCKER_ENABLED:-true}"
DOCKER_AUTO_START="${DOCKER_AUTO_START:-true}"
DOCKER_HEALTH_URL="${DOCKER_HEALTH_URL:-http://localhost:3000/health}"
CHECK_MIGRATIONS="${CHECK_MIGRATIONS:-true}"
AUTO_MIGRATE="${AUTO_MIGRATE:-true}"
CHECK_DEPS="${CHECK_DEPS:-true}"
# Exit codes
EXIT_SUCCESS=0
EXIT_DOCKER_NOT_RUNNING=10
EXIT_DB_NOT_READY=11
EXIT_MIGRATIONS_PENDING=12
EXIT_DEPS_OUTDATED=13
EXIT_ENV_MISSING=14
echo "🏥 Running environment health checks..."
echo
# Function to check Docker status
check_docker() {
if [ "$DOCKER_ENABLED" != "true" ]; then
echo "⏭️ Docker checks skipped (not enabled)"
return 0
fi
echo "🐳 Checking Docker status..."
if ! command -v docker-compose &> /dev/null && ! command -v docker &> /dev/null; then
echo -e "${YELLOW}⚠️ Docker not found (skipping Docker checks)${NC}"
return 0
fi
# Check if Docker daemon is running
if ! docker info &> /dev/null; then
echo -e "${RED}❌ Docker daemon not running${NC}"
return $EXIT_DOCKER_NOT_RUNNING
fi
# Check if containers are running
if command -v docker-compose &> /dev/null; then
RUNNING_CONTAINERS=$(docker-compose ps --services --filter "status=running" 2>/dev/null | wc -l | tr -d ' ')
else
RUNNING_CONTAINERS=$(docker ps --format '{{.Names}}' | wc -l | tr -d ' ')
fi
if [ "$RUNNING_CONTAINERS" -eq 0 ]; then
echo -e "${YELLOW}⚠️ No Docker containers running${NC}"
if [ "$DOCKER_AUTO_START" = "true" ]; then
echo -e "${BLUE}🔄 Attempting to start Docker services...${NC}"
if command -v docker-compose &> /dev/null; then
docker-compose up -d
else
echo -e "${YELLOW}⚠️ docker-compose not found, cannot auto-start${NC}"
return $EXIT_DOCKER_NOT_RUNNING
fi
# Wait a bit for services to start
echo "⏳ Waiting for services to start..."
sleep 5
# Re-check
if command -v docker-compose &> /dev/null; then
RUNNING_CONTAINERS=$(docker-compose ps --services --filter "status=running" 2>/dev/null | wc -l | tr -d ' ')
fi
if [ "$RUNNING_CONTAINERS" -eq 0 ]; then
echo -e "${RED}❌ Failed to start Docker services${NC}"
return $EXIT_DOCKER_NOT_RUNNING
fi
echo -e "${GREEN}✅ Docker services started${NC}"
else
echo " Auto-start disabled. Please start Docker manually:"
echo " docker-compose up -d"
return $EXIT_DOCKER_NOT_RUNNING
fi
else
echo -e "${GREEN}✅ Docker containers running: $RUNNING_CONTAINERS${NC}"
fi
# Check health endpoint if specified
if [ -n "$DOCKER_HEALTH_URL" ]; then
echo "🔍 Checking health endpoint: $DOCKER_HEALTH_URL"
if curl -sf "$DOCKER_HEALTH_URL" > /dev/null 2>&1; then
echo -e "${GREEN}✅ Health check passed${NC}"
else
echo -e "${YELLOW}⚠️ Health check failed (services may still be starting)${NC}"
fi
fi
return 0
}
# Function to check database migrations
check_database() {
if [ "$CHECK_MIGRATIONS" != "true" ]; then
echo "⏭️ Database checks skipped"
return 0
fi
echo
echo "🗄️ Checking database migrations..."
# Try Rails migrations check
if [ -f "bin/rails" ] || [ -f "Gemfile" ]; then
echo "📋 Checking Rails migrations..."
# Check for pending migrations
if command -v docker-compose &> /dev/null; then
PENDING=$(docker-compose exec -T backend rails db:migrate:status 2>/dev/null | grep -c "^\s*down" || true)
else
PENDING=$(rails db:migrate:status 2>/dev/null | grep -c "^\s*down" || true)
fi
if [ "$PENDING" -gt 0 ]; then
echo -e "${YELLOW}⚠️ $PENDING pending migration(s) detected${NC}"
if [ "$AUTO_MIGRATE" = "true" ]; then
echo -e "${BLUE}🔄 Running migrations...${NC}"
if command -v docker-compose &> /dev/null; then
docker-compose exec -T backend rails db:migrate
else
rails db:migrate
fi
echo -e "${GREEN}✅ Migrations complete${NC}"
else
echo " Auto-migrate disabled. Please run:"
echo " docker-compose exec backend rails db:migrate"
return $EXIT_MIGRATIONS_PENDING
fi
else
echo -e "${GREEN}✅ No pending migrations${NC}"
fi
else
echo "⏭️ No Rails detected, skipping migration check"
fi
return 0
}
# Function to check dependencies
check_dependencies() {
if [ "$CHECK_DEPS" != "true" ]; then
echo "⏭️ Dependency checks skipped"
return 0
fi
echo
echo "📦 Checking dependencies..."
# Check npm/yarn
if [ -f "package.json" ]; then
echo "🔍 Checking npm/yarn packages..."
if command -v npm &> /dev/null; then
OUTDATED=$(npm outdated 2>/dev/null | tail -n +2 | wc -l | tr -d ' ')
if [ "$OUTDATED" -gt 0 ]; then
echo -e "${YELLOW}⚠️ $OUTDATED outdated npm package(s)${NC}"
echo " Run 'npm outdated' to see details"
else
echo -e "${GREEN}✅ npm packages up to date${NC}"
fi
fi
fi
# Check bundler
if [ -f "Gemfile" ]; then
echo "🔍 Checking Ruby gems..."
if command -v bundle &> /dev/null; then
if bundle check &> /dev/null; then
echo -e "${GREEN}✅ Ruby gems satisfied${NC}"
else
echo -e "${YELLOW}⚠️ Missing or outdated gems${NC}"
echo " Run 'bundle install' or 'docker-compose exec backend bundle install'"
fi
fi
fi
return 0
}
# Function to check environment variables
check_environment() {
echo
echo "🔐 Checking environment variables..."
# Check for .env files
if [ -f ".env" ]; then
echo -e "${GREEN}✅ .env file found${NC}"
else
echo -e "${YELLOW}⚠️ .env file not found${NC}"
fi
if [ -f ".env.development" ]; then
echo -e "${GREEN}✅ .env.development file found${NC}"
else
echo -e "${YELLOW}⚠️ .env.development file not found (may be optional)${NC}"
fi
# Check critical environment variables (if .env exists)
if [ -f ".env" ]; then
CRITICAL_VARS="${CRITICAL_VARS:-DATABASE_URL SECRET_KEY_BASE}"
MISSING_VARS=()
for var in $CRITICAL_VARS; do
if ! grep -q "^${var}=" .env 2>/dev/null; then
MISSING_VARS+=("$var")
fi
done
if [ ${#MISSING_VARS[@]} -gt 0 ]; then
echo -e "${YELLOW}⚠️ Missing critical environment variables:${NC}"
for var in "${MISSING_VARS[@]}"; do
echo " - $var"
done
else
echo -e "${GREEN}✅ Critical environment variables present${NC}"
fi
fi
return 0
}
# Run all checks
FAILED=0
check_docker || FAILED=$?
check_database || FAILED=$?
check_dependencies || FAILED=$?
check_environment || FAILED=$?
echo
if [ $FAILED -eq 0 ]; then
echo -e "${GREEN}✅ All environment health checks passed${NC}"
else
echo -e "${YELLOW}⚠️ Some health checks failed (code: $FAILED)${NC}"
echo " Fix issues above or continue with caution"
fi
exit $FAILED
```