vibepup 1.0.1 → 1.0.2

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/README.md CHANGED
@@ -57,6 +57,11 @@ bun add -g vibepup
57
57
  vibepup --tui
58
58
  ```
59
59
 
60
+ ### 1e. Free setup (one command)
61
+ ```bash
62
+ vibepup free
63
+ ```
64
+
60
65
  ### 2. Fetch!
61
66
  Go to any empty folder and tell Vibepup what to build.
62
67
 
@@ -94,7 +99,13 @@ vibepup --tui
94
99
  TUI mode provides a Bubble Tea interface with puppy animation, quick mode selection, and a clean launch experience.
95
100
 
96
101
  ## ⚙️ Configuration
97
- Vibepup works out of the box. If `opencode` is missing, Vibepup will try to install it on Linux/macOS and then guide you. You can also set up a free tier:
102
+ Vibepup works out of the box. For the easiest free-tier bootstrap, run:
103
+
104
+ ```bash
105
+ vibepup free
106
+ ```
107
+
108
+ If `opencode` is missing, Vibepup will try to install it on Linux/macOS and then guide you. You can also set up a free tier manually:
98
109
 
99
110
  ```bash
100
111
  npm install -g opencode-antigravity-auth
package/lib/ralph.sh CHANGED
@@ -68,9 +68,14 @@ trap "pkill -P $$; exit" SIGINT SIGTERM
68
68
  # --- Parse Args ---
69
69
  MODE="default"
70
70
  PROJECT_IDEA=""
71
+ FREE_MODE="false"
71
72
 
72
73
  while [[ "$#" -gt 0 ]]; do
73
74
  case $1 in
75
+ free)
76
+ FREE_MODE="true"
77
+ shift
78
+ ;;
74
79
  new)
75
80
  MODE="new"
76
81
  PROJECT_IDEA="$2"
@@ -85,6 +90,11 @@ echo "🐾 Vibepup v1.0 (CLI Mode)"
85
90
  echo " Engine: $ENGINE_DIR"
86
91
  echo " Context: $PROJECT_DIR"
87
92
 
93
+ echo " Tips:"
94
+ echo " - Run 'vibepup free' for free-tier setup"
95
+ echo " - Run 'vibepup new ""My idea""' to bootstrap a project"
96
+ echo " - Run 'vibepup --tui' for a guided interface"
97
+
88
98
  type -p opencode >/dev/null 2>&1 || {
89
99
  if command -v curl >/dev/null 2>&1; then
90
100
  UNAME=$(uname -s)
@@ -96,15 +106,39 @@ type -p opencode >/dev/null 2>&1 || {
96
106
  }
97
107
 
98
108
  if ! command -v opencode >/dev/null 2>&1; then
99
- echo " opencode not found. Vibepup requires opencode to run."
100
- echo " Install with one of:"
101
- echo " - curl -fsSL https://opencode.ai/install | bash"
102
- echo " - npm install -g opencode-ai"
103
- echo " - brew install anomalyco/tap/opencode"
104
- echo " Free-tier option:"
105
- echo " - npm install -g opencode-antigravity-auth"
106
- echo " - opencode auth login antigravity"
107
- exit 127
109
+ if [[ "$FREE_MODE" == "true" ]]; then
110
+ echo "🔧 Free setup: installing opencode..."
111
+ if command -v npm >/dev/null 2>&1; then
112
+ npm install -g opencode-ai opencode-antigravity-auth || true
113
+ else
114
+ echo " npm not found. Install Node.js or use:"
115
+ echo " curl -fsSL https://opencode.ai/install | bash"
116
+ exit 127
117
+ fi
118
+ else
119
+ echo "❌ opencode not found. Vibepup requires opencode to run."
120
+ echo " Install with one of:"
121
+ echo " - curl -fsSL https://opencode.ai/install | bash"
122
+ echo " - npm install -g opencode-ai"
123
+ echo " - brew install anomalyco/tap/opencode"
124
+ echo " Free-tier option:"
125
+ echo " - vibepup free"
126
+ exit 127
127
+ fi
128
+ fi
129
+
130
+ if [[ "$FREE_MODE" == "true" ]]; then
131
+ echo "✨ Vibepup Free Setup"
132
+ echo " 1) Installing auth plugin"
133
+ if command -v npm >/dev/null 2>&1; then
134
+ npm install -g opencode-antigravity-auth || true
135
+ fi
136
+ echo " 2) Starting Google auth"
137
+ opencode auth login antigravity || true
138
+ echo " 3) Refreshing models"
139
+ opencode models --refresh || true
140
+ echo "✅ Free setup complete. Run 'vibepup --watch' next."
141
+ exit 0
108
142
  fi
109
143
 
110
144
  # --- Smart Model Discovery ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibepup",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A loyal, DX-first split-brain agent harness with cyberpunk vibes.",
5
5
  "bin": {
6
6
  "vibepup": "bin/ralph.js"
package/tui/main.go CHANGED
@@ -30,7 +30,9 @@ type model struct {
30
30
  frame int
31
31
  args []string
32
32
  form *huh.Form
33
+ newForm *huh.Form
33
34
  selected string
35
+ newIdea string
34
36
  spring harmonica.Spring
35
37
  pos float64
36
38
  velocity float64
@@ -54,10 +56,20 @@ func initialModel() model {
54
56
  huh.NewOption("Watch (recommended)", "watch"),
55
57
  huh.NewOption("Run 5 iterations", "run"),
56
58
  huh.NewOption("New project from idea", "new"),
59
+ huh.NewOption("Free setup (opencode + auth)", "free"),
57
60
  ).
58
61
  Value(&m.selected),
59
62
  ),
60
63
  )
64
+ m.newForm = huh.NewForm(
65
+ huh.NewGroup(
66
+ huh.NewInput().
67
+ Title("Describe your project idea").
68
+ Prompt("Idea: ").
69
+ Placeholder("A vibe-coded project").
70
+ Value(&m.newIdea),
71
+ ),
72
+ )
61
73
 
62
74
  return m
63
75
  }
@@ -71,6 +83,10 @@ func (m model) Init() tea.Cmd {
71
83
 
72
84
  func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
73
85
  switch msg := msg.(type) {
86
+ case tea.KeyMsg:
87
+ if msg.String() == "ctrl+c" || msg.String() == "esc" {
88
+ return m, tea.Quit
89
+ }
74
90
  case time.Time:
75
91
  switch m.state {
76
92
  case stateSplash:
@@ -92,24 +108,36 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
92
108
  m.pos, m.velocity = m.spring.Update(m.pos, m.velocity, m.targetPos)
93
109
  return m, tea.Tick(time.Millisecond*80, func(t time.Time) tea.Msg { return t })
94
110
  }
95
- case tea.KeyMsg:
96
- if m.state == stateSetup {
97
- var cmd tea.Cmd
98
- fm, cmd := m.form.Update(msg)
99
- m.form = fm.(*huh.Form)
100
- if m.form.State == huh.StateCompleted {
101
- m.state = stateRunning
102
- return m, launchCmd(m.selected, m.args)
103
- }
104
- return m, cmd
105
- }
106
111
  }
107
112
 
108
- if m.state == stateSetup {
113
+ switch m.state {
114
+ case stateSetup:
109
115
  fm, cmd := m.form.Update(msg)
110
116
  m.form = fm.(*huh.Form)
117
+ if m.form.State == huh.StateCompleted {
118
+ if m.selected == "new" {
119
+ m.state = stateRunning
120
+ return m, m.newForm.Init()
121
+ }
122
+ m.state = stateRunning
123
+ return m, launchCmd(m.selected, m.args)
124
+ }
111
125
  return m, cmd
126
+ case stateRunning:
127
+ if m.selected == "new" {
128
+ fm, cmd := m.newForm.Update(msg)
129
+ m.newForm = fm.(*huh.Form)
130
+ if m.newForm.State == huh.StateCompleted {
131
+ idea := strings.TrimSpace(m.newIdea)
132
+ if idea == "" {
133
+ idea = "A vibe-coded project"
134
+ }
135
+ return m, launchCmd("new", append([]string{idea}, m.args...))
136
+ }
137
+ return m, cmd
138
+ }
112
139
  }
140
+
113
141
  return m, nil
114
142
  }
115
143
 
@@ -181,12 +209,22 @@ func (m model) View() string {
181
209
  return boxStyle.Render(
182
210
  lipgloss.JoinVertical(lipgloss.Left,
183
211
  lipgloss.NewStyle().Foreground(babyBlue).Bold(true).Render("♥ Setup Phase"),
212
+ lipgloss.NewStyle().Foreground(gray).Render("Tip: choose Free setup to auto-configure opencode"),
184
213
  "",
185
214
  m.form.View(),
186
215
  ),
187
216
  )
188
-
189
217
  case stateRunning:
218
+ if m.selected == "new" {
219
+ return boxStyle.Render(
220
+ lipgloss.JoinVertical(lipgloss.Left,
221
+ lipgloss.NewStyle().Foreground(babyBlue).Bold(true).Render("♥ New Project"),
222
+ lipgloss.NewStyle().Foreground(gray).Render("Describe what you want Vibepup to build"),
223
+ "",
224
+ m.newForm.View(),
225
+ ),
226
+ )
227
+ }
190
228
  status := lipgloss.NewStyle().Foreground(hotPink).Bold(true).Render("♥ Vibepup is Working ♥")
191
229
  mode := lipgloss.NewStyle().Foreground(babyBlue).Render("MODE: " + strings.ToUpper(m.selected))
192
230
  spinner := sparkles[m.frame%len(sparkles)]