agileflow 2.72.0 → 2.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,42 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * clear-active-command.js - Clears active_command on session start
4
- *
5
- * This script runs on SessionStart to reset the active_command field
6
- * in session-state.json. This ensures that if a user starts a new chat
7
- * without running a command like /babysit, they won't get stale command
8
- * rules in their PreCompact output.
9
- *
10
- * Usage: Called automatically by SessionStart hook
11
- */
12
-
13
- const fs = require('fs');
14
- const path = require('path');
15
-
16
- function clearActiveCommand() {
17
- const sessionStatePath = path.join(process.cwd(), 'docs/09-agents/session-state.json');
18
-
19
- // Skip if session-state.json doesn't exist
20
- if (!fs.existsSync(sessionStatePath)) {
21
- return;
22
- }
23
-
24
- try {
25
- const sessionState = JSON.parse(fs.readFileSync(sessionStatePath, 'utf8'));
26
-
27
- // Only update if active_command was set
28
- if (sessionState.active_command && sessionState.active_command !== null) {
29
- sessionState.active_command = null;
30
- fs.writeFileSync(sessionStatePath, JSON.stringify(sessionState, null, 2) + '\n', 'utf8');
31
- console.log('Cleared active_command from previous session');
32
- }
33
- } catch (err) {
34
- // Silently ignore errors - don't break session start
35
- }
36
- }
37
-
38
- if (require.main === module) {
39
- clearActiveCommand();
40
- }
41
-
42
- module.exports = { clearActiveCommand };
@@ -1,76 +0,0 @@
1
- #!/bin/bash
2
- # AgileFlow Development Environment Initialization
3
- # Generated by AgileFlow session harness
4
- # This script sets up your development environment for consistent sessions
5
-
6
- set -e
7
-
8
- echo "🚀 Initializing development environment..."
9
-
10
- # Detect project type and install dependencies
11
- # This section will be customized based on your project
12
-
13
- # Node.js projects
14
- if [ -f "package-lock.json" ]; then
15
- echo "đŸ“Ļ Installing dependencies (npm ci)..."
16
- npm ci
17
- elif [ -f "yarn.lock" ]; then
18
- echo "đŸ“Ļ Installing dependencies (yarn)..."
19
- yarn install --frozen-lockfile
20
- elif [ -f "pnpm-lock.yaml" ]; then
21
- echo "đŸ“Ļ Installing dependencies (pnpm)..."
22
- pnpm install --frozen-lockfile
23
- elif [ -f "package.json" ]; then
24
- echo "đŸ“Ļ Installing dependencies (npm install)..."
25
- npm install
26
- fi
27
-
28
- # Python projects
29
- if [ -f "requirements.txt" ]; then
30
- echo "đŸ“Ļ Installing Python dependencies..."
31
- pip install -r requirements.txt
32
- fi
33
-
34
- if [ -f "poetry.lock" ]; then
35
- echo "đŸ“Ļ Installing Poetry dependencies..."
36
- poetry install
37
- fi
38
-
39
- # Rust projects
40
- if [ -f "Cargo.toml" ]; then
41
- echo "đŸ“Ļ Building Rust project..."
42
- cargo build
43
- fi
44
-
45
- # Go projects
46
- if [ -f "go.mod" ]; then
47
- echo "đŸ“Ļ Downloading Go modules..."
48
- go mod download
49
- fi
50
-
51
- # Run database migrations if applicable
52
- if [ -f "migrations/run.sh" ]; then
53
- echo "đŸ—„ī¸ Running database migrations..."
54
- bash migrations/run.sh
55
- fi
56
-
57
- if [ -d "prisma" ] && [ -f "package.json" ]; then
58
- if command -v npx &> /dev/null; then
59
- echo "đŸ—„ī¸ Running Prisma migrations..."
60
- npx prisma migrate deploy 2>/dev/null || echo "âš ī¸ Prisma migrations skipped"
61
- fi
62
- fi
63
-
64
- # Environment setup
65
- if [ -f ".env.example" ] && [ ! -f ".env" ]; then
66
- echo "âš™ī¸ Creating .env from .env.example..."
67
- cp .env.example .env
68
- echo "âš ī¸ Please configure .env with your settings"
69
- fi
70
-
71
- echo "✅ Environment initialization complete"
72
- echo ""
73
- echo "Next steps:"
74
- echo " - Run tests: Check environment.json for test_command"
75
- echo " - Start dev server: Check environment.json for dev_server.command"
76
- echo " - Review .env: Ensure environment variables are configured"
@@ -1,123 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # AgileFlow PreCompact Hook
4
- # Outputs critical context that should survive conversation compaction.
5
- #
6
-
7
- # Get current version from package.json
8
- VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "unknown")
9
-
10
- # Get current git branch
11
- BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
12
-
13
- # Get current story from status.json
14
- CURRENT_STORY=""
15
- WIP_COUNT=0
16
- if [ -f "docs/09-agents/status.json" ]; then
17
- CURRENT_STORY=$(node -p "
18
- const s = require('./docs/09-agents/status.json');
19
- const stories = Object.entries(s.stories || {})
20
- .filter(([,v]) => v.status === 'in_progress')
21
- .map(([k,v]) => k + ': ' + v.title)
22
- .join(', ');
23
- stories || 'None in progress';
24
- " 2>/dev/null || echo "Unable to read")
25
-
26
- WIP_COUNT=$(node -p "
27
- const s = require('./docs/09-agents/status.json');
28
- Object.values(s.stories || {}).filter(v => v.status === 'in_progress').length;
29
- " 2>/dev/null || echo "0")
30
- fi
31
-
32
- # Get practices list
33
- PRACTICES=""
34
- if [ -d "docs/02-practices" ]; then
35
- PRACTICES=$(ls docs/02-practices/*.md 2>/dev/null | head -8 | xargs -I {} basename {} .md | tr '\n' ',' | sed 's/,$//')
36
- fi
37
-
38
- # Get active epics
39
- EPICS=""
40
- if [ -d "docs/05-epics" ]; then
41
- EPICS=$(ls docs/05-epics/ 2>/dev/null | head -5 | tr '\n' ',' | sed 's/,$//')
42
- fi
43
-
44
- # Detect active commands and extract their Compact Summaries
45
- COMMAND_SUMMARIES=""
46
- if [ -f "docs/09-agents/session-state.json" ]; then
47
- ACTIVE_COMMANDS=$(node -p "
48
- const s = require('./docs/09-agents/session-state.json');
49
- (s.active_commands || []).map(c => c.name).join(' ');
50
- " 2>/dev/null || echo "")
51
-
52
- for ACTIVE_COMMAND in $ACTIVE_COMMANDS; do
53
- [ -z "$ACTIVE_COMMAND" ] && continue
54
-
55
- COMMAND_FILE=""
56
- if [ -f "packages/cli/src/core/commands/${ACTIVE_COMMAND}.md" ]; then
57
- COMMAND_FILE="packages/cli/src/core/commands/${ACTIVE_COMMAND}.md"
58
- elif [ -f ".agileflow/commands/${ACTIVE_COMMAND}.md" ]; then
59
- COMMAND_FILE=".agileflow/commands/${ACTIVE_COMMAND}.md"
60
- elif [ -f ".claude/commands/agileflow/${ACTIVE_COMMAND}.md" ]; then
61
- COMMAND_FILE=".claude/commands/agileflow/${ACTIVE_COMMAND}.md"
62
- fi
63
-
64
- if [ ! -z "$COMMAND_FILE" ]; then
65
- SUMMARY=$(node -e "
66
- const fs = require('fs');
67
- const content = fs.readFileSync('$COMMAND_FILE', 'utf8');
68
- const match = content.match(/<!-- COMPACT_SUMMARY_START[\\s\\S]*?-->([\\s\\S]*?)<!-- COMPACT_SUMMARY_END -->/);
69
- if (match) {
70
- console.log('## ACTIVE COMMAND: /agileflow:${ACTIVE_COMMAND}');
71
- console.log('');
72
- console.log(match[1].trim());
73
- }
74
- " 2>/dev/null || echo "")
75
-
76
- if [ ! -z "$SUMMARY" ]; then
77
- COMMAND_SUMMARIES="${COMMAND_SUMMARIES}
78
-
79
- ${SUMMARY}"
80
- fi
81
- fi
82
- done
83
- fi
84
-
85
- # Output context
86
- cat << EOF
87
- AGILEFLOW PROJECT CONTEXT (preserve during compact):
88
-
89
- ## Project Status
90
- - Project: AgileFlow v${VERSION}
91
- - Branch: ${BRANCH}
92
- - Active Stories: ${CURRENT_STORY}
93
- - WIP Count: ${WIP_COUNT}
94
-
95
- ## Key Files to Check After Compact
96
- - CLAUDE.md - Project system prompt with conventions
97
- - README.md - Project overview and setup
98
- - docs/09-agents/status.json - Story statuses and assignments
99
- - docs/02-practices/ - Codebase practices (${PRACTICES:-check folder})
100
-
101
- ## Active Epics
102
- ${EPICS:-Check docs/05-epics/ for epic files}
103
-
104
- ## Key Conventions (from CLAUDE.md)
105
- $(grep -A 15 "## Key\|## Critical\|## Important\|CRITICAL:" CLAUDE.md 2>/dev/null | head -20 || echo "- Read CLAUDE.md for project conventions")
106
-
107
- ## Recent Agent Activity
108
- $(tail -3 docs/09-agents/bus/log.jsonl 2>/dev/null | head -3 || echo "")
109
- EOF
110
-
111
- # Output active command summaries
112
- if [ ! -z "$COMMAND_SUMMARIES" ]; then
113
- echo "$COMMAND_SUMMARIES"
114
- fi
115
-
116
- cat << EOF
117
-
118
- ## Post-Compact Actions
119
- 1. Re-read CLAUDE.md if unsure about conventions
120
- 2. Check status.json for current story state
121
- 3. Review docs/02-practices/ for implementation patterns
122
- 4. Check git log for recent changes
123
- EOF
@@ -1,121 +0,0 @@
1
- #!/bin/bash
2
- # AgileFlow Session Resume Script
3
- # This script is called by the SessionStart hook to automatically resume sessions.
4
- # It replicates the functionality of /agileflow:session:resume as a shell script.
5
-
6
- set -e
7
-
8
- echo "🔄 Resuming AgileFlow Session..."
9
- echo ""
10
-
11
- # Load environment configuration
12
- if [ ! -f "docs/00-meta/environment.json" ]; then
13
- echo "âš ī¸ Session harness not initialized"
14
- echo " Run /agileflow:session:init to set up session management"
15
- exit 0
16
- fi
17
-
18
- # Extract configuration
19
- TEST_COMMAND=$(jq -r '.test_command // "echo \"No test command configured\""' docs/00-meta/environment.json 2>/dev/null)
20
- INIT_SCRIPT=$(jq -r '.init_script // "./docs/00-meta/init.sh"' docs/00-meta/environment.json 2>/dev/null)
21
- VERIFICATION_POLICY=$(jq -r '.verification_policy // "warn"' docs/00-meta/environment.json 2>/dev/null)
22
-
23
- # Step 1: Run initialization script
24
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
25
- echo "🚀 Running Initialization Script..."
26
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
27
- echo ""
28
-
29
- if [ -f "$INIT_SCRIPT" ] && [ -x "$INIT_SCRIPT" ]; then
30
- if bash "$INIT_SCRIPT"; then
31
- echo ""
32
- echo "✅ Initialization complete"
33
- else
34
- echo ""
35
- echo "âš ī¸ Initialization script failed (exit code $?)"
36
- echo " Continuing with test verification..."
37
- fi
38
- else
39
- echo "âš ī¸ Init script not found or not executable: $INIT_SCRIPT"
40
- echo " Skipping initialization"
41
- fi
42
-
43
- echo ""
44
-
45
- # Step 2: Run test verification
46
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
47
- echo "đŸ§Ē Running Test Verification..."
48
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
49
- echo ""
50
- echo "Command: $TEST_COMMAND"
51
- echo ""
52
-
53
- START_TIME=$(date +%s)
54
-
55
- if eval "$TEST_COMMAND"; then
56
- END_TIME=$(date +%s)
57
- DURATION=$((END_TIME - START_TIME))
58
- echo ""
59
- echo "✅ Tests passing (${DURATION}s)"
60
- TEST_STATUS="passing"
61
- else
62
- END_TIME=$(date +%s)
63
- DURATION=$((END_TIME - START_TIME))
64
- EXIT_CODE=$?
65
- echo ""
66
- echo "âš ī¸ Tests failing (exit code $EXIT_CODE, ${DURATION}s)"
67
- TEST_STATUS="failing"
68
-
69
- if [ "$VERIFICATION_POLICY" = "block" ]; then
70
- echo ""
71
- echo "❌ Verification policy: block"
72
- echo " Cannot proceed with failing tests"
73
- exit 1
74
- else
75
- echo ""
76
- echo "âš ī¸ Verification policy: warn"
77
- echo " You can proceed, but tests are failing"
78
- fi
79
- fi
80
-
81
- echo ""
82
-
83
- # Step 3: Load session context
84
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
85
- echo "📊 Session Summary"
86
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
87
- echo ""
88
-
89
- # Get baseline info
90
- BASELINE_COMMIT=$(jq -r '.baseline_commit // "Not established"' docs/00-meta/environment.json 2>/dev/null)
91
- BASELINE_DATE=$(jq -r '.baseline_established // "N/A"' docs/00-meta/environment.json 2>/dev/null)
92
-
93
- # Get current session info
94
- if [ -f "docs/09-agents/session-state.json" ]; then
95
- CURRENT_STORY=$(jq -r '.current_session.current_story // "None"' docs/09-agents/session-state.json 2>/dev/null)
96
- ACTIVE_AGENT=$(jq -r '.current_session.active_agent // "None"' docs/09-agents/session-state.json 2>/dev/null)
97
- else
98
- CURRENT_STORY="None"
99
- ACTIVE_AGENT="None"
100
- fi
101
-
102
- # Display summary
103
- echo "Baseline: ${BASELINE_COMMIT:0:7} ($BASELINE_DATE)"
104
- echo "Status: $TEST_STATUS"
105
- echo "Active Story: $CURRENT_STORY"
106
- echo "Active Agent: $ACTIVE_AGENT"
107
-
108
- # Get recent commits
109
- echo ""
110
- echo "Recent Activity:"
111
- if git log --oneline -3 2>/dev/null; then
112
- :
113
- else
114
- echo " (Git history unavailable)"
115
- fi
116
-
117
- echo ""
118
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
119
- echo "✅ Session Resumed - Ready to work! 🚀"
120
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
121
- echo ""
@@ -1,73 +0,0 @@
1
- #!/bin/bash
2
-
3
- # AgileFlow Token Validation Script
4
- # Safely checks if required MCP tokens are present in .env WITHOUT exposing them
5
- # Security-first approach: shows token lengths, never displays actual values
6
-
7
- echo "🔐 Token Validation (Secure Check - No Tokens Exposed)"
8
- echo "========================================================="
9
- echo ""
10
-
11
- # Check if .env exists
12
- if [ ! -f .env ]; then
13
- echo "❌ .env file NOT found"
14
- echo ""
15
- echo "To create .env, copy from template:"
16
- echo " cp .env.example .env"
17
- echo "Then edit .env and add your real tokens (DO NOT COMMIT)"
18
- exit 1
19
- fi
20
-
21
- echo "✅ .env file found"
22
- echo ""
23
-
24
- # Check GitHub token (secure - doesn't print value)
25
- if grep -q "^GITHUB_PERSONAL_ACCESS_TOKEN=" .env && ! grep -q "GITHUB_PERSONAL_ACCESS_TOKEN=$" .env; then
26
- TOKEN_VALUE=$(grep "^GITHUB_PERSONAL_ACCESS_TOKEN=" .env | cut -d'=' -f2)
27
- if [ -z "$TOKEN_VALUE" ] || [ "$TOKEN_VALUE" = "your_token_here" ] || [ "$TOKEN_VALUE" = "ghp_placeholder" ]; then
28
- echo "âš ī¸ GITHUB_PERSONAL_ACCESS_TOKEN is set but appears to be placeholder"
29
- echo " → Replace with real token (starts with ghp_)"
30
- else
31
- echo "✅ GITHUB_PERSONAL_ACCESS_TOKEN is set (length: ${#TOKEN_VALUE})"
32
- fi
33
- else
34
- echo "âš ī¸ GITHUB_PERSONAL_ACCESS_TOKEN not found in .env"
35
- fi
36
-
37
- echo ""
38
-
39
- # Check Notion token (secure - doesn't print value)
40
- if grep -q "^NOTION_TOKEN=" .env && ! grep -q "NOTION_TOKEN=$" .env; then
41
- TOKEN_VALUE=$(grep "^NOTION_TOKEN=" .env | cut -d'=' -f2)
42
- if [ -z "$TOKEN_VALUE" ] || [ "$TOKEN_VALUE" = "your_token_here" ] || [[ "$TOKEN_VALUE" == *"placeholder"* ]]; then
43
- echo "âš ī¸ NOTION_TOKEN is set but appears to be placeholder"
44
- echo " → Replace with real token (starts with ntn_ or secret_)"
45
- else
46
- echo "✅ NOTION_TOKEN is set (length: ${#TOKEN_VALUE})"
47
- fi
48
- else
49
- echo "â„šī¸ NOTION_TOKEN not found in .env (optional if Notion not enabled)"
50
- fi
51
-
52
- echo ""
53
- echo "🔒 Security Check:"
54
-
55
- # Check .gitignore for .mcp.json
56
- if grep -q '^\\.mcp\\.json$' .gitignore 2>/dev/null; then
57
- echo "✅ .mcp.json is in .gitignore"
58
- else
59
- echo "❌ .mcp.json NOT in .gitignore (CRITICAL - must exclude!)"
60
- fi
61
-
62
- # Check .gitignore for .env
63
- if grep -q '^\\.env$' .gitignore 2>/dev/null; then
64
- echo "✅ .env is in .gitignore"
65
- else
66
- echo "❌ .env NOT in .gitignore (CRITICAL - must exclude!)"
67
- fi
68
-
69
- echo ""
70
- echo "If you added new tokens to .env, remember to:"
71
- echo " 1. Verify .mcp.json and .env are in .gitignore (NEVER commit them!)"
72
- echo " 2. 🔴 RESTART Claude Code for MCP servers to load new tokens"
73
- echo " 3. Test MCP commands after restart"
@@ -1,111 +0,0 @@
1
- #!/bin/bash
2
- # AgileFlow Worktree Helper Script
3
- # Creates a git worktree with proper naming and guidance
4
-
5
- set -e # Exit on error
6
-
7
- # Color codes for output
8
- RED='\033[0;31m'
9
- GREEN='\033[0;32m'
10
- YELLOW='\033[1;33m'
11
- BLUE='\033[0;34m'
12
- NC='\033[0m' # No Color
13
-
14
- # Check if running in a git repository
15
- if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
16
- echo -e "${RED}Error: Not in a git repository${NC}"
17
- exit 1
18
- fi
19
-
20
- # Check for feature name argument
21
- if [ $# -eq 0 ]; then
22
- echo -e "${RED}Error: Feature name required${NC}"
23
- echo ""
24
- echo "Usage: $0 <feature-name> [base-branch]"
25
- echo ""
26
- echo "Examples:"
27
- echo " $0 authentication"
28
- echo " $0 payment-integration"
29
- echo " $0 hotfix-memory-leak main"
30
- echo " $0 experiment-graphql develop"
31
- echo ""
32
- exit 1
33
- fi
34
-
35
- FEATURE_NAME=$1
36
- BASE_BRANCH=${2:-main}
37
- BRANCH_NAME="feature/$FEATURE_NAME"
38
- REPO_NAME=$(basename "$(git rev-parse --show-toplevel)")
39
- WORKTREE_PATH="../${REPO_NAME}-${FEATURE_NAME}"
40
-
41
- # Check if base branch exists
42
- if ! git rev-parse --verify "$BASE_BRANCH" > /dev/null 2>&1; then
43
- echo -e "${RED}Error: Base branch '$BASE_BRANCH' does not exist${NC}"
44
- echo ""
45
- echo "Available branches:"
46
- git branch -a
47
- exit 1
48
- fi
49
-
50
- # Check if worktree path already exists
51
- if [ -d "$WORKTREE_PATH" ]; then
52
- echo -e "${RED}Error: Directory already exists: $WORKTREE_PATH${NC}"
53
- echo ""
54
- echo "Options:"
55
- echo " 1. Remove existing directory: rm -rf $WORKTREE_PATH"
56
- echo " 2. Use different feature name"
57
- echo " 3. List existing worktrees: git worktree list"
58
- exit 1
59
- fi
60
-
61
- # Check if branch already exists
62
- if git rev-parse --verify "$BRANCH_NAME" > /dev/null 2>&1; then
63
- echo -e "${YELLOW}Warning: Branch '$BRANCH_NAME' already exists${NC}"
64
- echo "Creating worktree from existing branch..."
65
- git worktree add "$WORKTREE_PATH" "$BRANCH_NAME"
66
- else
67
- echo -e "${BLUE}Creating new branch '$BRANCH_NAME' from '$BASE_BRANCH'${NC}"
68
- git worktree add -b "$BRANCH_NAME" "$WORKTREE_PATH" "$BASE_BRANCH"
69
- fi
70
-
71
- echo ""
72
- echo -e "${GREEN}✅ Worktree created successfully!${NC}"
73
- echo ""
74
- echo -e "${BLUE}📂 Location:${NC} $WORKTREE_PATH"
75
- echo -e "${BLUE}đŸŒŋ Branch:${NC} $BRANCH_NAME"
76
- echo -e "${BLUE}📌 Base:${NC} $BASE_BRANCH"
77
- echo ""
78
- echo -e "${GREEN}🤖 Next steps:${NC}"
79
- echo " 1. Open in new editor window:"
80
- echo -e " ${YELLOW}code $WORKTREE_PATH${NC}"
81
- echo ""
82
- echo " 2. Navigate to worktree:"
83
- echo -e " ${YELLOW}cd $WORKTREE_PATH${NC}"
84
- echo ""
85
- echo " 3. Start AgileFlow babysit:"
86
- echo -e " ${YELLOW}/babysit${NC}"
87
- echo ""
88
- echo -e "${YELLOW}âš ī¸ Important Reminders:${NC}"
89
- echo " â€ĸ Use this worktree for '$FEATURE_NAME' work only"
90
- echo " â€ĸ Avoid concurrent edits to the same epic/stories across worktrees"
91
- echo " â€ĸ Clean up when done: git worktree remove $WORKTREE_PATH"
92
- echo ""
93
- echo -e "${BLUE}📚 Documentation:${NC} docs/guides/worktrees.md"
94
- echo ""
95
- echo -e "${GREEN}Shared across worktrees:${NC}"
96
- echo " â€ĸ Git history (commits, branches)"
97
- echo " â€ĸ AgileFlow status.json and message bus"
98
- echo " â€ĸ All docs/ files (ADRs, epics, stories)"
99
- echo ""
100
- echo -e "${BLUE}Independent in this worktree:${NC}"
101
- echo " â€ĸ Working directory files (src/, etc.)"
102
- echo " â€ĸ Dependencies (node_modules/, .venv/, etc.)"
103
- echo " â€ĸ /babysit AI context"
104
- echo ""
105
-
106
- # List all worktrees
107
- echo -e "${BLUE}📋 All active worktrees:${NC}"
108
- git worktree list
109
- echo ""
110
-
111
- echo -e "${GREEN}Happy coding with preserved context! 🚀${NC}"