agentic-loop 1.0.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.
- package/.claude/commands/explain.md +114 -0
- package/.claude/commands/idea.md +398 -0
- package/.claude/commands/my-dna.md +122 -0
- package/.claude/commands/prd.md +286 -0
- package/.claude/commands/review.md +167 -0
- package/.claude/commands/sign.md +32 -0
- package/.claude/commands/styleguide.md +450 -0
- package/.claude/commands/tour.md +301 -0
- package/.claude/commands/vibe-check.md +116 -0
- package/.claude/commands/vibe-help.md +47 -0
- package/.claude/commands/vibe-list.md +203 -0
- package/.pre-commit-hooks.yaml +102 -0
- package/LICENSE +21 -0
- package/README.md +238 -0
- package/bin/agentic-loop.sh +24 -0
- package/bin/postinstall.sh +29 -0
- package/bin/ralph.sh +171 -0
- package/bin/vibe-check.js +19 -0
- package/dist/checks/check-any-types.d.ts +6 -0
- package/dist/checks/check-any-types.d.ts.map +1 -0
- package/dist/checks/check-any-types.js +73 -0
- package/dist/checks/check-any-types.js.map +1 -0
- package/dist/checks/check-commented-code.d.ts +6 -0
- package/dist/checks/check-commented-code.d.ts.map +1 -0
- package/dist/checks/check-commented-code.js +81 -0
- package/dist/checks/check-commented-code.js.map +1 -0
- package/dist/checks/check-console-error.d.ts +6 -0
- package/dist/checks/check-console-error.d.ts.map +1 -0
- package/dist/checks/check-console-error.js +41 -0
- package/dist/checks/check-console-error.js.map +1 -0
- package/dist/checks/check-debug-statements.d.ts +6 -0
- package/dist/checks/check-debug-statements.d.ts.map +1 -0
- package/dist/checks/check-debug-statements.js +120 -0
- package/dist/checks/check-debug-statements.js.map +1 -0
- package/dist/checks/check-deep-nesting.d.ts +6 -0
- package/dist/checks/check-deep-nesting.d.ts.map +1 -0
- package/dist/checks/check-deep-nesting.js +116 -0
- package/dist/checks/check-deep-nesting.js.map +1 -0
- package/dist/checks/check-docker-platform.d.ts +6 -0
- package/dist/checks/check-docker-platform.d.ts.map +1 -0
- package/dist/checks/check-docker-platform.js +42 -0
- package/dist/checks/check-docker-platform.js.map +1 -0
- package/dist/checks/check-dry-violations.d.ts +6 -0
- package/dist/checks/check-dry-violations.d.ts.map +1 -0
- package/dist/checks/check-dry-violations.js +124 -0
- package/dist/checks/check-dry-violations.js.map +1 -0
- package/dist/checks/check-empty-catch.d.ts +6 -0
- package/dist/checks/check-empty-catch.d.ts.map +1 -0
- package/dist/checks/check-empty-catch.js +111 -0
- package/dist/checks/check-empty-catch.js.map +1 -0
- package/dist/checks/check-function-length.d.ts +6 -0
- package/dist/checks/check-function-length.d.ts.map +1 -0
- package/dist/checks/check-function-length.js +152 -0
- package/dist/checks/check-function-length.js.map +1 -0
- package/dist/checks/check-hardcoded-ai-models.d.ts +10 -0
- package/dist/checks/check-hardcoded-ai-models.d.ts.map +1 -0
- package/dist/checks/check-hardcoded-ai-models.js +102 -0
- package/dist/checks/check-hardcoded-ai-models.js.map +1 -0
- package/dist/checks/check-hardcoded-urls.d.ts +6 -0
- package/dist/checks/check-hardcoded-urls.d.ts.map +1 -0
- package/dist/checks/check-hardcoded-urls.js +124 -0
- package/dist/checks/check-hardcoded-urls.js.map +1 -0
- package/dist/checks/check-magic-numbers.d.ts +6 -0
- package/dist/checks/check-magic-numbers.d.ts.map +1 -0
- package/dist/checks/check-magic-numbers.js +116 -0
- package/dist/checks/check-magic-numbers.js.map +1 -0
- package/dist/checks/check-secrets.d.ts +6 -0
- package/dist/checks/check-secrets.d.ts.map +1 -0
- package/dist/checks/check-secrets.js +138 -0
- package/dist/checks/check-secrets.js.map +1 -0
- package/dist/checks/check-snake-case-ts.d.ts +6 -0
- package/dist/checks/check-snake-case-ts.d.ts.map +1 -0
- package/dist/checks/check-snake-case-ts.js +78 -0
- package/dist/checks/check-snake-case-ts.js.map +1 -0
- package/dist/checks/check-todo-fixme.d.ts +6 -0
- package/dist/checks/check-todo-fixme.d.ts.map +1 -0
- package/dist/checks/check-todo-fixme.js +41 -0
- package/dist/checks/check-todo-fixme.js.map +1 -0
- package/dist/checks/check-unsafe-html.d.ts +6 -0
- package/dist/checks/check-unsafe-html.d.ts.map +1 -0
- package/dist/checks/check-unsafe-html.js +101 -0
- package/dist/checks/check-unsafe-html.js.map +1 -0
- package/dist/checks/index.d.ts +30 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +57 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +208 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/file-reader.d.ts +24 -0
- package/dist/utils/file-reader.d.ts.map +1 -0
- package/dist/utils/file-reader.js +146 -0
- package/dist/utils/file-reader.js.map +1 -0
- package/dist/utils/patterns.d.ts +27 -0
- package/dist/utils/patterns.d.ts.map +1 -0
- package/dist/utils/patterns.js +84 -0
- package/dist/utils/patterns.js.map +1 -0
- package/dist/utils/reporters.d.ts +21 -0
- package/dist/utils/reporters.d.ts.map +1 -0
- package/dist/utils/reporters.js +115 -0
- package/dist/utils/reporters.js.map +1 -0
- package/dist/utils/types.d.ts +71 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +5 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +83 -0
- package/ralph/api.sh +216 -0
- package/ralph/backup.sh +838 -0
- package/ralph/browser-verify/README.md +135 -0
- package/ralph/browser-verify/verify.ts +450 -0
- package/ralph/checks/check-fastapi-responses.py +155 -0
- package/ralph/hooks/hooks-config.json +72 -0
- package/ralph/hooks/inject-context.sh +44 -0
- package/ralph/hooks/install.sh +207 -0
- package/ralph/hooks/log-tools.sh +45 -0
- package/ralph/hooks/protect-prd.sh +27 -0
- package/ralph/hooks/save-learnings.sh +36 -0
- package/ralph/hooks/warn-debug.sh +54 -0
- package/ralph/hooks/warn-empty-catch.sh +63 -0
- package/ralph/hooks/warn-secrets.sh +89 -0
- package/ralph/hooks/warn-urls.sh +77 -0
- package/ralph/init.sh +515 -0
- package/ralph/loop.sh +730 -0
- package/ralph/playwright.sh +238 -0
- package/ralph/prd.sh +295 -0
- package/ralph/setup/feature-tour.sh +155 -0
- package/ralph/setup/quick-setup.sh +239 -0
- package/ralph/setup/tutorial.sh +159 -0
- package/ralph/setup/ui.sh +136 -0
- package/ralph/setup.sh +401 -0
- package/ralph/signs.sh +150 -0
- package/ralph/utils.sh +682 -0
- package/ralph/verify/browser.sh +324 -0
- package/ralph/verify/lint.sh +363 -0
- package/ralph/verify/review.sh +152 -0
- package/ralph/verify/tests.sh +81 -0
- package/ralph/verify.sh +268 -0
- package/templates/PROMPT.md +235 -0
- package/templates/config/fullstack.json +86 -0
- package/templates/config/go.json +81 -0
- package/templates/config/minimal.json +76 -0
- package/templates/config/node.json +81 -0
- package/templates/config/python.json +81 -0
- package/templates/config/rust.json +81 -0
- package/templates/examples/CLAUDE-django.md +174 -0
- package/templates/examples/CLAUDE-fastapi.md +270 -0
- package/templates/examples/CLAUDE-fastmcp.md +352 -0
- package/templates/examples/CLAUDE-fullstack.md +256 -0
- package/templates/examples/CLAUDE-node.md +246 -0
- package/templates/examples/CLAUDE-react.md +138 -0
- package/templates/optional/cursorrules.template +147 -0
- package/templates/optional/eslint.config.js +34 -0
- package/templates/optional/lint-staged.config.js +34 -0
- package/templates/optional/ruff.toml +125 -0
- package/templates/optional/vibe-check.yml +116 -0
- package/templates/optional/vscode-settings.json +127 -0
- package/templates/signs.json +46 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Path 2: Feature Tour (auto-demo) with skip options
|
|
3
|
+
|
|
4
|
+
# Get script directory
|
|
5
|
+
WIZARD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
|
|
7
|
+
feature_tour() {
|
|
8
|
+
source "$WIZARD_DIR/ui.sh"
|
|
9
|
+
source "$WIZARD_DIR/quick-setup.sh"
|
|
10
|
+
|
|
11
|
+
clear
|
|
12
|
+
show_logo
|
|
13
|
+
echo -e " ${BOLD}${EMOJI_MOVIE} Feature Tour${NC}\n"
|
|
14
|
+
echo -e " ${DIM}Watch what agentic-loop can do for your codebase.${NC}"
|
|
15
|
+
echo -e " ${DIM}Press 's' anytime to skip to setup.${NC}\n"
|
|
16
|
+
sleep 1
|
|
17
|
+
|
|
18
|
+
# Demo 1: vibe-check
|
|
19
|
+
demo_vibe_check
|
|
20
|
+
press_enter || { quick_setup; return; }
|
|
21
|
+
|
|
22
|
+
# Demo 2: Pre-commit hooks
|
|
23
|
+
demo_precommit
|
|
24
|
+
press_enter || { quick_setup; return; }
|
|
25
|
+
|
|
26
|
+
# Demo 3: Ralph autonomous loop
|
|
27
|
+
demo_ralph
|
|
28
|
+
press_enter || { quick_setup; return; }
|
|
29
|
+
|
|
30
|
+
# Demo 4: Claude Code skills
|
|
31
|
+
demo_skills
|
|
32
|
+
press_enter || { quick_setup; return; }
|
|
33
|
+
|
|
34
|
+
# Offer to install
|
|
35
|
+
echo ""
|
|
36
|
+
echo -e " ${BOLD}That's the tour! Ready to set up your project?${NC}\n"
|
|
37
|
+
|
|
38
|
+
if confirm "Install agentic-loop?"; then
|
|
39
|
+
quick_setup
|
|
40
|
+
else
|
|
41
|
+
echo -e "\n ${DIM}No problem! Run 'npx agentic-loop' anytime to set up.${NC}"
|
|
42
|
+
fi
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
demo_vibe_check() {
|
|
46
|
+
show_step 1 4 "vibe-check: Catch AI code issues"
|
|
47
|
+
|
|
48
|
+
echo -e " ${DIM}$ vibe-check src/example.ts${NC}\n"
|
|
49
|
+
sleep 0.5
|
|
50
|
+
|
|
51
|
+
# Simulated output with typewriter effect
|
|
52
|
+
typewrite " Scanning 1 file..." 0.03
|
|
53
|
+
sleep 0.3
|
|
54
|
+
echo ""
|
|
55
|
+
|
|
56
|
+
# Error
|
|
57
|
+
echo -e " ${RED}${EMOJI_CROSS}${NC} ${BOLD}src/example.ts:15${NC}"
|
|
58
|
+
echo -e " ${RED}[error]${NC} Hardcoded API URL detected"
|
|
59
|
+
echo -e " ${DIM}const url = \"https://api.example.com/users\"${NC}"
|
|
60
|
+
sleep 0.2
|
|
61
|
+
echo ""
|
|
62
|
+
|
|
63
|
+
# Warnings
|
|
64
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} ${BOLD}src/example.ts:23${NC}"
|
|
65
|
+
echo -e " ${YELLOW}[warn]${NC} Function too long (85 lines, max 50)"
|
|
66
|
+
sleep 0.2
|
|
67
|
+
echo ""
|
|
68
|
+
|
|
69
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} ${BOLD}src/example.ts:42${NC}"
|
|
70
|
+
echo -e " ${YELLOW}[warn]${NC} Using 'any' type"
|
|
71
|
+
sleep 0.2
|
|
72
|
+
echo ""
|
|
73
|
+
|
|
74
|
+
echo -e " Found ${RED}1 error${NC}, ${YELLOW}2 warnings${NC}"
|
|
75
|
+
echo ""
|
|
76
|
+
echo -e " ${DIM}vibe-check catches common AI-generated code issues:${NC}"
|
|
77
|
+
echo -e " ${DIM}- Hardcoded secrets and URLs${NC}"
|
|
78
|
+
echo -e " ${DIM}- Overly complex functions${NC}"
|
|
79
|
+
echo -e " ${DIM}- Missing error handling${NC}"
|
|
80
|
+
echo -e " ${DIM}- TypeScript type issues${NC}"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
demo_precommit() {
|
|
84
|
+
show_step 2 4 "Pre-commit hooks: Block bad commits"
|
|
85
|
+
|
|
86
|
+
echo -e " ${DIM}$ git commit -m \"add feature\"${NC}\n"
|
|
87
|
+
sleep 0.5
|
|
88
|
+
|
|
89
|
+
echo -e " ${GREEN}${EMOJI_CHECK}${NC} check-secrets............${GREEN}passed${NC}"
|
|
90
|
+
sleep 0.2
|
|
91
|
+
echo -e " ${RED}${EMOJI_CROSS}${NC} check-hardcoded-urls.....${RED}FAILED${NC}"
|
|
92
|
+
sleep 0.3
|
|
93
|
+
echo ""
|
|
94
|
+
echo -e " ${RED}Commit blocked!${NC} Fix the issue first."
|
|
95
|
+
echo ""
|
|
96
|
+
echo -e " ${DIM}Pre-commit hooks automatically run before each commit:${NC}"
|
|
97
|
+
echo -e " ${DIM}- Scans for hardcoded secrets (API keys, passwords)${NC}"
|
|
98
|
+
echo -e " ${DIM}- Detects hardcoded URLs that should be config${NC}"
|
|
99
|
+
echo -e " ${DIM}- Runs vibe-check quality scan${NC}"
|
|
100
|
+
echo ""
|
|
101
|
+
echo -e " ${DIM}Bad code never makes it into your repo.${NC}"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
demo_ralph() {
|
|
105
|
+
show_step 3 4 "Ralph: Autonomous development loop"
|
|
106
|
+
|
|
107
|
+
echo -e " ${DIM}$ ralph prd \"Add user authentication\"${NC}\n"
|
|
108
|
+
sleep 0.5
|
|
109
|
+
|
|
110
|
+
echo -e " ${CYAN}Claude:${NC} I have a few questions about this feature:"
|
|
111
|
+
sleep 0.2
|
|
112
|
+
echo -e " 1. What auth method? (OAuth, JWT, session-based)"
|
|
113
|
+
echo -e " 2. Need password reset flow?"
|
|
114
|
+
echo -e " 3. Any rate limiting requirements?"
|
|
115
|
+
echo -e " 4. Should failed logins be logged?"
|
|
116
|
+
echo ""
|
|
117
|
+
sleep 0.3
|
|
118
|
+
|
|
119
|
+
echo -e " ${DIM}After you answer, Ralph:${NC}"
|
|
120
|
+
echo -e " 1. Generates detailed user stories"
|
|
121
|
+
echo -e " 2. Creates testable acceptance criteria"
|
|
122
|
+
echo -e " 3. Runs in a loop until ALL tests pass"
|
|
123
|
+
echo -e " 4. Commits working code automatically"
|
|
124
|
+
echo ""
|
|
125
|
+
echo -e " ${DIM}You describe what you want. Ralph builds it.${NC}"
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
demo_skills() {
|
|
129
|
+
show_step 4 4 "Claude Code commands"
|
|
130
|
+
|
|
131
|
+
echo -e " ${BOLD}In Claude Code, type these commands:${NC}\n"
|
|
132
|
+
|
|
133
|
+
echo -e " ${CYAN}/idea${NC} Brainstorm → PRD → Ready for Ralph"
|
|
134
|
+
sleep 0.1
|
|
135
|
+
echo -e " ${CYAN}/vibe-help${NC} Quick reference cheatsheet"
|
|
136
|
+
sleep 0.1
|
|
137
|
+
echo -e " ${CYAN}/tour${NC} Interactive walkthrough"
|
|
138
|
+
sleep 0.1
|
|
139
|
+
echo -e " ${CYAN}/vibe-check${NC} Full code quality audit"
|
|
140
|
+
sleep 0.1
|
|
141
|
+
echo -e " ${CYAN}/review${NC} Code review with security checks"
|
|
142
|
+
sleep 0.1
|
|
143
|
+
echo -e " ${CYAN}/explain${NC} Explain code line by line"
|
|
144
|
+
sleep 0.1
|
|
145
|
+
echo -e " ${CYAN}/styleguide${NC} Generate design system reference"
|
|
146
|
+
echo ""
|
|
147
|
+
|
|
148
|
+
echo -e " ${DIM}These commands guide Claude through${NC}"
|
|
149
|
+
echo -e " ${DIM}the agentic-loop workflow.${NC}"
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
# If run directly, execute feature_tour
|
|
153
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
154
|
+
feature_tour
|
|
155
|
+
fi
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Path 1: Quick Setup for experienced users
|
|
3
|
+
|
|
4
|
+
# Get script directory
|
|
5
|
+
WIZARD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
VIBE_ROOT="$(cd "$WIZARD_DIR/../.." && pwd)"
|
|
7
|
+
|
|
8
|
+
quick_setup() {
|
|
9
|
+
clear
|
|
10
|
+
source "$WIZARD_DIR/ui.sh"
|
|
11
|
+
show_logo
|
|
12
|
+
|
|
13
|
+
# Detect project
|
|
14
|
+
local project_type
|
|
15
|
+
project_type=$(detect_project_type)
|
|
16
|
+
echo -e " Detected: ${GREEN}$project_type${NC} project\n"
|
|
17
|
+
|
|
18
|
+
# Show what will be installed
|
|
19
|
+
echo -e " ${BOLD}This will set up:${NC}"
|
|
20
|
+
echo -e " ${CYAN}•${NC} Claude Code skills (11 slash commands)"
|
|
21
|
+
echo -e " ${CYAN}•${NC} Pre-commit hooks (security + quality)"
|
|
22
|
+
echo -e " ${CYAN}•${NC} Ralph autonomous loop"
|
|
23
|
+
echo -e " ${CYAN}•${NC} vibe-check CLI"
|
|
24
|
+
echo ""
|
|
25
|
+
|
|
26
|
+
# Non-interactive mode: skip prompts (CI, Claude Code, piped input)
|
|
27
|
+
if [[ ! -t 0 ]] || [[ -n "${CI:-}" ]] || [[ -n "${CLAUDE_CODE:-}" ]]; then
|
|
28
|
+
echo -e " ${DIM}(Non-interactive mode detected, auto-installing...)${NC}"
|
|
29
|
+
echo ""
|
|
30
|
+
do_install
|
|
31
|
+
show_completion
|
|
32
|
+
return
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Ask how they want to proceed
|
|
36
|
+
echo -e " ${BOLD}How would you like to proceed?${NC}"
|
|
37
|
+
echo ""
|
|
38
|
+
echo -e " ${GREEN}[1]${NC} ${EMOJI_ROCKET} ${BOLD}Quick install${NC}"
|
|
39
|
+
echo -e " ${DIM}Install everything now, explore later${NC}"
|
|
40
|
+
echo ""
|
|
41
|
+
echo -e " ${GREEN}[2]${NC} ${EMOJI_MOVIE} ${BOLD}Take a tour${NC}"
|
|
42
|
+
echo -e " ${DIM}Walk through each feature with Claude${NC}"
|
|
43
|
+
echo ""
|
|
44
|
+
|
|
45
|
+
local choice
|
|
46
|
+
while true; do
|
|
47
|
+
echo -ne " Press ${GREEN}1${NC} or ${GREEN}2${NC} (or ${DIM}q${NC} to quit): "
|
|
48
|
+
read -r -n 1 choice
|
|
49
|
+
echo ""
|
|
50
|
+
case "$choice" in
|
|
51
|
+
1)
|
|
52
|
+
echo ""
|
|
53
|
+
do_install
|
|
54
|
+
show_completion
|
|
55
|
+
return
|
|
56
|
+
;;
|
|
57
|
+
2)
|
|
58
|
+
echo ""
|
|
59
|
+
echo -e " ${CYAN}Great!${NC} After setup, run ${BOLD}/tour${NC} in Claude Code"
|
|
60
|
+
echo -e " ${DIM}for an interactive walkthrough of all features.${NC}"
|
|
61
|
+
echo ""
|
|
62
|
+
sleep 2
|
|
63
|
+
do_install
|
|
64
|
+
show_completion_with_tour
|
|
65
|
+
return
|
|
66
|
+
;;
|
|
67
|
+
q|Q)
|
|
68
|
+
echo -e "\n ${DIM}Setup cancelled. Run 'npx agentic-loop' anytime.${NC}"
|
|
69
|
+
return 1
|
|
70
|
+
;;
|
|
71
|
+
*)
|
|
72
|
+
echo -e " ${RED}Invalid choice${NC}"
|
|
73
|
+
;;
|
|
74
|
+
esac
|
|
75
|
+
done
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
do_install() {
|
|
79
|
+
install_claude_skills
|
|
80
|
+
install_precommit_hooks
|
|
81
|
+
install_ralph
|
|
82
|
+
configure_mcp
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
show_completion_with_tour() {
|
|
86
|
+
echo ""
|
|
87
|
+
echo -e " ${GREEN}┌─────────────────────────────────┐${NC}"
|
|
88
|
+
echo -e " ${GREEN}│ Setup complete! ${EMOJI_PARTY} │${NC}"
|
|
89
|
+
echo -e " ${GREEN}└─────────────────────────────────┘${NC}"
|
|
90
|
+
echo ""
|
|
91
|
+
echo -e " ${BOLD}Next step:${NC} Open Claude Code and run:"
|
|
92
|
+
echo ""
|
|
93
|
+
echo -e " ${CYAN}/tour${NC}"
|
|
94
|
+
echo ""
|
|
95
|
+
echo -e " ${DIM}This will walk you through all the features.${NC}"
|
|
96
|
+
echo ""
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
detect_project_type() {
|
|
100
|
+
# Django + React (AllThrive pattern)
|
|
101
|
+
[[ -d "frontend" && -d "core" ]] && echo "django-react" && return
|
|
102
|
+
# Django alone
|
|
103
|
+
[[ -f "manage.py" ]] && echo "django" && return
|
|
104
|
+
# Rust
|
|
105
|
+
[[ -f "Cargo.toml" ]] && echo "rust" && return
|
|
106
|
+
# Go
|
|
107
|
+
[[ -f "go.mod" ]] && echo "go" && return
|
|
108
|
+
# Python
|
|
109
|
+
[[ -f "pyproject.toml" || -f "requirements.txt" ]] && echo "python" && return
|
|
110
|
+
# Node/TypeScript
|
|
111
|
+
[[ -f "package.json" ]] && echo "node" && return
|
|
112
|
+
# Minimal/unknown
|
|
113
|
+
echo "minimal"
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
install_claude_skills() {
|
|
117
|
+
echo -e " ${CYAN}Installing Claude skills...${NC}"
|
|
118
|
+
|
|
119
|
+
mkdir -p .claude/commands
|
|
120
|
+
|
|
121
|
+
# Copy all command files from agentic-loop
|
|
122
|
+
if [[ -d "$VIBE_ROOT/.claude/commands" ]]; then
|
|
123
|
+
cp -r "$VIBE_ROOT/.claude/commands/"* .claude/commands/ 2>/dev/null || true
|
|
124
|
+
local count=$(ls -1 .claude/commands/*.md 2>/dev/null | wc -l | tr -d ' ')
|
|
125
|
+
echo -e " ${GREEN}${EMOJI_CHECK}${NC} $count slash commands installed"
|
|
126
|
+
else
|
|
127
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} No command templates found"
|
|
128
|
+
fi
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
install_precommit_hooks() {
|
|
132
|
+
echo -e " ${CYAN}Setting up pre-commit hooks...${NC}"
|
|
133
|
+
|
|
134
|
+
if [[ ! -f .pre-commit-config.yaml ]]; then
|
|
135
|
+
cat > .pre-commit-config.yaml << 'EOF'
|
|
136
|
+
repos:
|
|
137
|
+
- repo: https://github.com/allthriveai/agentic-loop
|
|
138
|
+
rev: v1.0.0
|
|
139
|
+
hooks:
|
|
140
|
+
- id: check-secrets
|
|
141
|
+
name: Check for hardcoded secrets
|
|
142
|
+
- id: check-hardcoded-urls
|
|
143
|
+
name: Check for hardcoded URLs
|
|
144
|
+
- id: vibe-check-quality
|
|
145
|
+
name: AI code quality check
|
|
146
|
+
EOF
|
|
147
|
+
echo -e " ${GREEN}${EMOJI_CHECK}${NC} Created .pre-commit-config.yaml"
|
|
148
|
+
else
|
|
149
|
+
echo -e " ${DIM}Skipped: .pre-commit-config.yaml already exists${NC}"
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
if command -v pre-commit &>/dev/null; then
|
|
153
|
+
if [[ -d ".git" ]]; then
|
|
154
|
+
pre-commit install > /dev/null 2>&1
|
|
155
|
+
echo -e " ${GREEN}${EMOJI_CHECK}${NC} Hooks installed"
|
|
156
|
+
else
|
|
157
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} Not a git repo, run 'pre-commit install' after git init"
|
|
158
|
+
fi
|
|
159
|
+
else
|
|
160
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} pre-commit not found"
|
|
161
|
+
echo -e " Run: ${CYAN}pip install pre-commit && pre-commit install${NC}"
|
|
162
|
+
fi
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
install_ralph() {
|
|
166
|
+
echo -e " ${CYAN}Initializing Ralph...${NC}"
|
|
167
|
+
|
|
168
|
+
# Delegate to ralph init via the CLI
|
|
169
|
+
if [[ -f "$VIBE_ROOT/bin/ralph.sh" ]]; then
|
|
170
|
+
# Only init if not already initialized
|
|
171
|
+
if [[ ! -d ".ralph" ]]; then
|
|
172
|
+
if "$VIBE_ROOT/bin/ralph.sh" init > /dev/null 2>&1; then
|
|
173
|
+
echo -e " ${GREEN}${EMOJI_CHECK}${NC} Ralph initialized"
|
|
174
|
+
else
|
|
175
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} Ralph init failed (you can run 'ralph init' later)"
|
|
176
|
+
fi
|
|
177
|
+
else
|
|
178
|
+
echo -e " ${DIM}Skipped: Ralph already initialized${NC}"
|
|
179
|
+
fi
|
|
180
|
+
else
|
|
181
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} Ralph not available in this installation"
|
|
182
|
+
fi
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
configure_mcp() {
|
|
186
|
+
echo -e " ${CYAN}Configuring MCP servers...${NC}"
|
|
187
|
+
|
|
188
|
+
local claude_json="$HOME/.claude.json"
|
|
189
|
+
|
|
190
|
+
# Check for jq
|
|
191
|
+
if ! command -v jq &>/dev/null; then
|
|
192
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} jq not found, skipping MCP config"
|
|
193
|
+
echo -e " Install: ${CYAN}brew install jq${NC} or ${CYAN}apt install jq${NC}"
|
|
194
|
+
return
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
# Create claude.json if it doesn't exist
|
|
198
|
+
[[ ! -f "$claude_json" ]] && echo '{}' > "$claude_json"
|
|
199
|
+
|
|
200
|
+
# Check if chrome-devtools is already configured
|
|
201
|
+
if jq -e '.mcpServers["chrome-devtools"]' "$claude_json" > /dev/null 2>&1; then
|
|
202
|
+
echo -e " ${DIM}Skipped: Chrome DevTools MCP already configured${NC}"
|
|
203
|
+
return
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
# Add Chrome DevTools MCP
|
|
207
|
+
local tmp=$(mktemp)
|
|
208
|
+
jq '.mcpServers["chrome-devtools"] = {
|
|
209
|
+
"command": "npx",
|
|
210
|
+
"args": ["-y", "@anthropic-ai/mcp-server-chrome-devtools@0.0.5"]
|
|
211
|
+
}' "$claude_json" > "$tmp" && mv "$tmp" "$claude_json"
|
|
212
|
+
|
|
213
|
+
echo -e " ${GREEN}${EMOJI_CHECK}${NC} Chrome DevTools MCP configured"
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
show_completion() {
|
|
217
|
+
echo ""
|
|
218
|
+
echo -e " ${GREEN}┌─────────────────────────────────┐${NC}"
|
|
219
|
+
echo -e " ${GREEN}│ Setup complete! ${EMOJI_PARTY} │${NC}"
|
|
220
|
+
echo -e " ${GREEN}└─────────────────────────────────┘${NC}"
|
|
221
|
+
echo ""
|
|
222
|
+
echo -e " ${BOLD}Try these commands:${NC}"
|
|
223
|
+
echo ""
|
|
224
|
+
echo -e " ${CYAN}vibe-check .${NC} Scan your code for issues"
|
|
225
|
+
echo -e " ${CYAN}ralph prd \"idea\"${NC} Start autonomous development"
|
|
226
|
+
echo -e " ${CYAN}ralph check${NC} Run all quality checks"
|
|
227
|
+
echo ""
|
|
228
|
+
echo -e " ${BOLD}In Claude Code:${NC}"
|
|
229
|
+
echo ""
|
|
230
|
+
echo -e " ${CYAN}/help${NC} See available commands"
|
|
231
|
+
echo -e " ${CYAN}/prd${NC} Generate requirements"
|
|
232
|
+
echo -e " ${CYAN}/review${NC} Code review changes"
|
|
233
|
+
echo ""
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
# If sourced, export functions; if run directly, execute quick_setup
|
|
237
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
238
|
+
quick_setup
|
|
239
|
+
fi
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Path 3: New to Claude Code tutorial
|
|
3
|
+
|
|
4
|
+
# Get script directory
|
|
5
|
+
WIZARD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
|
|
7
|
+
tutorial() {
|
|
8
|
+
source "$WIZARD_DIR/ui.sh"
|
|
9
|
+
source "$WIZARD_DIR/quick-setup.sh"
|
|
10
|
+
|
|
11
|
+
clear
|
|
12
|
+
show_logo
|
|
13
|
+
echo -e " ${BOLD}${EMOJI_BOOK} Welcome to Claude Code!${NC}\n"
|
|
14
|
+
echo -e " ${DIM}This tutorial will teach you the basics.${NC}"
|
|
15
|
+
echo -e " ${DIM}Press 's' at any time to skip to setup.${NC}\n"
|
|
16
|
+
|
|
17
|
+
press_enter || { quick_setup; return; }
|
|
18
|
+
|
|
19
|
+
# Lesson 1: What is Claude Code
|
|
20
|
+
lesson_what_is_claude
|
|
21
|
+
press_enter || { quick_setup; return; }
|
|
22
|
+
|
|
23
|
+
# Lesson 2: Slash commands
|
|
24
|
+
lesson_slash_commands
|
|
25
|
+
press_enter || { quick_setup; return; }
|
|
26
|
+
|
|
27
|
+
# Lesson 3: MCP servers
|
|
28
|
+
lesson_mcp
|
|
29
|
+
press_enter || { quick_setup; return; }
|
|
30
|
+
|
|
31
|
+
# Lesson 4: agentic-loop integration
|
|
32
|
+
lesson_integration
|
|
33
|
+
press_enter || { quick_setup; return; }
|
|
34
|
+
|
|
35
|
+
# Complete - offer setup
|
|
36
|
+
echo ""
|
|
37
|
+
echo -e " ${GREEN}${EMOJI_PARTY} Tutorial complete!${NC}\n"
|
|
38
|
+
echo -e " You now know the basics of Claude Code."
|
|
39
|
+
echo -e " Let's set up agentic-loop for your project.\n"
|
|
40
|
+
|
|
41
|
+
quick_setup
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
lesson_what_is_claude() {
|
|
45
|
+
clear
|
|
46
|
+
show_logo
|
|
47
|
+
show_step 1 4 "What is Claude Code?"
|
|
48
|
+
|
|
49
|
+
echo -e " Claude Code is ${BOLD}Anthropic's official CLI${NC} for Claude AI."
|
|
50
|
+
echo ""
|
|
51
|
+
echo -e " It's an AI coding assistant that can:"
|
|
52
|
+
echo ""
|
|
53
|
+
echo -e " ${CYAN}•${NC} Read and understand your entire codebase"
|
|
54
|
+
echo -e " ${CYAN}•${NC} Write and edit code across multiple files"
|
|
55
|
+
echo -e " ${CYAN}•${NC} Run terminal commands (with your permission)"
|
|
56
|
+
echo -e " ${CYAN}•${NC} Browse the web for documentation"
|
|
57
|
+
echo -e " ${CYAN}•${NC} Use tools via MCP (Model Context Protocol)"
|
|
58
|
+
echo ""
|
|
59
|
+
echo -e " ${BOLD}How to use it:${NC}"
|
|
60
|
+
echo ""
|
|
61
|
+
echo -e " ${DIM}\$ claude${NC}"
|
|
62
|
+
echo -e " ${CYAN}Claude:${NC} How can I help you today?"
|
|
63
|
+
echo ""
|
|
64
|
+
echo -e " ${DIM}\$ claude \"explain this function\"${NC}"
|
|
65
|
+
echo -e " ${CYAN}Claude:${NC} This function does..."
|
|
66
|
+
echo ""
|
|
67
|
+
echo -e " ${DIM}Try it: Open a new terminal and type 'claude'${NC}"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
lesson_slash_commands() {
|
|
71
|
+
clear
|
|
72
|
+
show_logo
|
|
73
|
+
show_step 2 4 "Slash Commands"
|
|
74
|
+
|
|
75
|
+
echo -e " Slash commands are ${BOLD}shortcuts for common tasks${NC}."
|
|
76
|
+
echo ""
|
|
77
|
+
echo -e " ${BOLD}Built-in commands:${NC}"
|
|
78
|
+
echo ""
|
|
79
|
+
echo -e " ${CYAN}/help${NC} Show all available commands"
|
|
80
|
+
echo -e " ${CYAN}/clear${NC} Clear conversation history"
|
|
81
|
+
echo -e " ${CYAN}/compact${NC} Summarize context to save tokens"
|
|
82
|
+
echo -e " ${CYAN}/cost${NC} Show token usage and cost"
|
|
83
|
+
echo ""
|
|
84
|
+
echo -e " ${BOLD}Custom commands${NC} (from ${DIM}.claude/commands/${NC}):"
|
|
85
|
+
echo ""
|
|
86
|
+
echo -e " ${CYAN}/idea${NC} Brainstorm → PRD → Ready for Ralph"
|
|
87
|
+
echo -e " ${CYAN}/vibe-check${NC} Code quality audit"
|
|
88
|
+
echo -e " ${CYAN}/review${NC} Code review with security checks"
|
|
89
|
+
echo ""
|
|
90
|
+
echo -e " Custom commands are markdown files with prompts."
|
|
91
|
+
echo -e " agentic-loop installs 7 pre-built commands."
|
|
92
|
+
echo ""
|
|
93
|
+
echo -e " ${DIM}Try it: In Claude Code, type '/vibe-help' for the cheatsheet${NC}"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
lesson_mcp() {
|
|
97
|
+
clear
|
|
98
|
+
show_logo
|
|
99
|
+
show_step 3 4 "MCP Servers (Tools)"
|
|
100
|
+
|
|
101
|
+
echo -e " ${BOLD}MCP${NC} = Model Context Protocol"
|
|
102
|
+
echo ""
|
|
103
|
+
echo -e " MCP lets Claude use ${BOLD}external tools${NC}."
|
|
104
|
+
echo ""
|
|
105
|
+
echo -e " ${BOLD}Example: Chrome DevTools MCP${NC}"
|
|
106
|
+
echo ""
|
|
107
|
+
echo -e " ${CYAN}•${NC} Navigate to URLs in a browser"
|
|
108
|
+
echo -e " ${CYAN}•${NC} Take screenshots of pages"
|
|
109
|
+
echo -e " ${CYAN}•${NC} Inspect page elements"
|
|
110
|
+
echo -e " ${CYAN}•${NC} Check console for errors"
|
|
111
|
+
echo ""
|
|
112
|
+
echo -e " This means Claude can ${BOLD}verify your UI changes${NC}"
|
|
113
|
+
echo -e " actually work in a real browser."
|
|
114
|
+
echo ""
|
|
115
|
+
echo -e " ${BOLD}Config location:${NC} ${DIM}~/.claude.json${NC}"
|
|
116
|
+
echo ""
|
|
117
|
+
cat << 'EOF'
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"chrome-devtools": {
|
|
121
|
+
"command": "npx",
|
|
122
|
+
"args": ["-y", "@anthropic-ai/mcp-server-chrome-devtools"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
EOF
|
|
127
|
+
echo ""
|
|
128
|
+
echo -e " ${DIM}agentic-loop configures this automatically.${NC}"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
lesson_integration() {
|
|
132
|
+
clear
|
|
133
|
+
show_logo
|
|
134
|
+
show_step 4 4 "agentic-loop Integration"
|
|
135
|
+
|
|
136
|
+
echo -e " ${BOLD}agentic-loop${NC} adds superpowers to Claude Code:"
|
|
137
|
+
echo ""
|
|
138
|
+
echo -e " ${BOLD}1. The Workflow (/idea → Ralph → Ship)${NC}"
|
|
139
|
+
echo -e " ${DIM}Brainstorm ideas, generate PRDs, execute autonomously${NC}"
|
|
140
|
+
echo ""
|
|
141
|
+
echo -e " ${BOLD}2. Code Quality (/vibe-check)${NC}"
|
|
142
|
+
echo -e " ${DIM}Catches AI-generated code issues before commit${NC}"
|
|
143
|
+
echo ""
|
|
144
|
+
echo -e " ${BOLD}3. Pre-commit Hooks${NC}"
|
|
145
|
+
echo -e " ${DIM}Automatically blocks problematic commits${NC}"
|
|
146
|
+
echo ""
|
|
147
|
+
echo -e " ${BOLD}4. Slash Commands (7 included)${NC}"
|
|
148
|
+
echo -e " ${DIM}/idea, /vibe-help, /tour, /vibe-check, /review, /explain, /styleguide${NC}"
|
|
149
|
+
echo ""
|
|
150
|
+
echo -e " ${BOLD}5. MCP Configuration${NC}"
|
|
151
|
+
echo -e " ${DIM}Chrome DevTools for visual verification${NC}"
|
|
152
|
+
echo ""
|
|
153
|
+
echo -e " ${DIM}All of this installs with: npm install agentic-loop${NC}"
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# If run directly, execute tutorial
|
|
157
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
158
|
+
tutorial
|
|
159
|
+
fi
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# UI utilities: colors, ASCII art, prompts
|
|
3
|
+
|
|
4
|
+
# Colors
|
|
5
|
+
RED='\033[0;31m'
|
|
6
|
+
GREEN='\033[0;32m'
|
|
7
|
+
YELLOW='\033[1;33m'
|
|
8
|
+
BLUE='\033[0;34m'
|
|
9
|
+
CYAN='\033[0;36m'
|
|
10
|
+
MAGENTA='\033[0;35m'
|
|
11
|
+
BOLD='\033[1m'
|
|
12
|
+
DIM='\033[2m'
|
|
13
|
+
NC='\033[0m'
|
|
14
|
+
|
|
15
|
+
# Emoji support check
|
|
16
|
+
EMOJI_ROCKET="🚀"
|
|
17
|
+
EMOJI_MOVIE="🎬"
|
|
18
|
+
EMOJI_BOOK="📚"
|
|
19
|
+
EMOJI_CHECK="✓"
|
|
20
|
+
EMOJI_CROSS="✗"
|
|
21
|
+
EMOJI_WARN="⚠"
|
|
22
|
+
EMOJI_PARTY="🎉"
|
|
23
|
+
|
|
24
|
+
show_logo() {
|
|
25
|
+
echo -e "${CYAN}"
|
|
26
|
+
cat << 'EOF'
|
|
27
|
+
|
|
28
|
+
╦ ╦╦╔╗ ╔═╗ ┬ ╔╦╗╦ ╦╦═╗╦╦ ╦╔═╗
|
|
29
|
+
╚╗╔╝║╠╩╗║╣ ┌┼─ ║ ╠═╣╠╦╝║╚╗╔╝║╣
|
|
30
|
+
╚╝ ╩╚═╝╚═╝ └┘ ╩ ╩ ╩╩╚═╩ ╚╝ ╚═╝
|
|
31
|
+
|
|
32
|
+
EOF
|
|
33
|
+
echo -e "${NC}"
|
|
34
|
+
echo -e " ${DIM}Tools to help you thrive with agentic coding${NC}"
|
|
35
|
+
echo -e " ${DIM}by AllThrive.ai${NC}"
|
|
36
|
+
echo -e " ${DIM}─────────────────────────────────${NC}"
|
|
37
|
+
echo ""
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
show_welcome() {
|
|
41
|
+
echo -e " ${BOLD}Welcome!${NC} How would you like to get started?"
|
|
42
|
+
echo ""
|
|
43
|
+
echo -e " ${GREEN}[1]${NC} ${EMOJI_ROCKET} ${BOLD}Quick Setup${NC}"
|
|
44
|
+
echo -e " ${DIM}I know what I'm doing, just configure my project${NC}"
|
|
45
|
+
echo ""
|
|
46
|
+
echo -e " ${GREEN}[2]${NC} ${EMOJI_MOVIE} ${BOLD}Feature Tour${NC}"
|
|
47
|
+
echo -e " ${DIM}Show me what agentic-loop can do (auto-demo)${NC}"
|
|
48
|
+
echo ""
|
|
49
|
+
echo -e " ${GREEN}[3]${NC} ${EMOJI_BOOK} ${BOLD}New to Claude Code${NC}"
|
|
50
|
+
echo -e " ${DIM}Teach me the basics (interactive tutorial)${NC}"
|
|
51
|
+
echo ""
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
prompt_menu() {
|
|
55
|
+
local choice
|
|
56
|
+
while true; do
|
|
57
|
+
echo -ne " Press ${GREEN}1${NC}, ${GREEN}2${NC}, or ${GREEN}3${NC} (or ${DIM}q${NC} to quit): "
|
|
58
|
+
read -r -n 1 choice
|
|
59
|
+
echo ""
|
|
60
|
+
case "$choice" in
|
|
61
|
+
1|2|3|q|Q) echo "$choice"; return ;;
|
|
62
|
+
*) echo -e " ${RED}Invalid choice${NC}" ;;
|
|
63
|
+
esac
|
|
64
|
+
done
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Typewriter effect for demos
|
|
68
|
+
typewrite() {
|
|
69
|
+
local text="$1" delay="${2:-0.02}"
|
|
70
|
+
for ((i=0; i<${#text}; i++)); do
|
|
71
|
+
echo -n "${text:$i:1}"
|
|
72
|
+
sleep "$delay"
|
|
73
|
+
done
|
|
74
|
+
echo ""
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Progress indicator
|
|
78
|
+
show_step() {
|
|
79
|
+
local current="$1" total="$2" desc="$3"
|
|
80
|
+
echo -e "\n ${CYAN}[$current/$total]${NC} ${BOLD}$desc${NC}\n"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# Continue prompt with skip option
|
|
84
|
+
# Returns 0 to continue, 1 to skip to setup
|
|
85
|
+
press_enter() {
|
|
86
|
+
echo ""
|
|
87
|
+
echo -ne " ${DIM}Press Enter to continue, or 's' to skip to setup...${NC} "
|
|
88
|
+
read -r -n 1 key
|
|
89
|
+
echo ""
|
|
90
|
+
[[ "$key" == "s" || "$key" == "S" ]] && return 1
|
|
91
|
+
return 0
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Print success message
|
|
95
|
+
print_success() {
|
|
96
|
+
echo -e " ${GREEN}${EMOJI_CHECK}${NC} $1"
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Print error message
|
|
100
|
+
print_error() {
|
|
101
|
+
echo -e " ${RED}${EMOJI_CROSS}${NC} $1"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Print warning message
|
|
105
|
+
print_warning() {
|
|
106
|
+
echo -e " ${YELLOW}${EMOJI_WARN}${NC} $1"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# Print info message
|
|
110
|
+
print_info() {
|
|
111
|
+
echo -e " ${CYAN}→${NC} $1"
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# Spinner for long operations
|
|
115
|
+
spin() {
|
|
116
|
+
local pid=$1
|
|
117
|
+
local delay=0.1
|
|
118
|
+
local spinstr='|/-\'
|
|
119
|
+
while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
|
|
120
|
+
local temp=${spinstr#?}
|
|
121
|
+
printf " [%c] " "$spinstr"
|
|
122
|
+
local spinstr=$temp${spinstr%"$temp"}
|
|
123
|
+
sleep $delay
|
|
124
|
+
printf "\b\b\b\b\b\b"
|
|
125
|
+
done
|
|
126
|
+
printf " \b\b\b\b\b\b"
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
# Confirmation prompt
|
|
130
|
+
confirm() {
|
|
131
|
+
local prompt="${1:-Proceed?}"
|
|
132
|
+
echo -ne " $prompt ${GREEN}[Y/n]${NC} "
|
|
133
|
+
read -r -n 1 confirm
|
|
134
|
+
echo ""
|
|
135
|
+
[[ "$confirm" != "n" && "$confirm" != "N" ]]
|
|
136
|
+
}
|