voicecc 1.1.18 → 1.1.20

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.
@@ -120,53 +120,47 @@ function spawnLoginProcess(): Promise<string> {
120
120
  let resolved = false;
121
121
  let step = 0;
122
122
 
123
+ let loginSent = false;
124
+ let enterDebounce: ReturnType<typeof setTimeout> | null = null;
125
+
123
126
  child.onData((data: string) => {
124
127
  output += data;
125
128
  const clean = data.replace(/\x1b\[[^m]*m/g, "").replace(/\r/g, "").trim();
126
- if (clean) console.debug(`[auth/login] step=${step} data: ${clean.slice(0, 200)}`);
127
-
128
- // Step 0 → 1: Accept trust prompt
129
- if (step === 0 && /enter to confirm/i.test(output)) {
130
- step = 1;
131
- console.debug("[auth/login] step 1: accepting trust prompt");
132
- setTimeout(() => child.write("\r"), 500);
133
- }
129
+ if (clean) console.debug(`[auth/login] step=${step} loginSent=${loginSent} data: ${clean.slice(0, 200)}`);
134
130
 
135
- // Step 0 alternative: no trust prompt, already trusted — look for version string
136
- if (step === 0 && /v\d+\.\d+\.\d+/.test(output)) {
137
- step = 2;
138
- console.debug("[auth/login] step 2: no trust prompt, sending /login");
139
- setTimeout(() => child.write("/login\r"), 1000);
140
- }
131
+ if (resolved) return;
141
132
 
142
- // Step 1 2: Wait for main prompt after trust, send /login
143
- if (step === 1 && /v\d+\.\d+\.\d+/.test(output.slice(-2000))) {
144
- step = 2;
145
- console.debug("[auth/login] step 2: sending /login");
146
- setTimeout(() => child.write("/login\r"), 1000);
133
+ // ---- Always check for OAuth URL (can appear during setup or after /login) ----
134
+ const urlMatch = output.match(/(https:\/\/claude\.ai\/oauth\/authorize\S+)/);
135
+ if (urlMatch) {
136
+ resolved = true;
137
+ step = 4;
138
+ console.debug("[auth/login] URL captured");
139
+ pendingLogin = {
140
+ pty: child,
141
+ url: urlMatch[1],
142
+ createdAt: Date.now(),
143
+ };
144
+ resolve(urlMatch[1]);
145
+ return;
147
146
  }
148
147
 
149
- // Step 2 3: Select Claude Pro (first option)
150
- if (step === 2 && /claude.*pro|login.*method/i.test(output.slice(-500))) {
151
- step = 3;
152
- console.debug("[auth/login] step 3: selecting Claude Pro");
153
- setTimeout(() => child.write("\r"), 1000);
148
+ // ---- Dismiss any selection prompt (❯) by pressing Enter ----
149
+ // Handles: trust, theme picker, login method, or any other setup prompt.
150
+ if (/❯/.test(data)) {
151
+ if (enterDebounce) clearTimeout(enterDebounce);
152
+ enterDebounce = setTimeout(() => {
153
+ console.debug("[auth/login] pressing Enter on selection prompt");
154
+ child.write("\r");
155
+ }, 800);
154
156
  }
155
157
 
156
- // Capture OAuth URL (can happen at step 2 or 3)
157
- if (step >= 2) {
158
- const urlMatch = output.match(/(https:\/\/claude\.ai\/oauth\/authorize\S+)/);
159
- if (urlMatch && !resolved) {
160
- resolved = true;
161
- step = 4;
162
- console.debug("[auth/login] step 4: URL captured");
163
- pendingLogin = {
164
- pty: child,
165
- url: urlMatch[1],
166
- createdAt: Date.now(),
167
- };
168
- resolve(urlMatch[1]);
169
- }
158
+ // ---- Detect the main REPL prompt and send /login ----
159
+ // Sparkle animation means we're in the main REPL, not setup.
160
+ if (!loginSent && /[✻✽✶✢]/.test(data)) {
161
+ loginSent = true;
162
+ console.debug("[auth/login] main prompt ready, sending /login");
163
+ setTimeout(() => child.write("/login\r"), 1000);
170
164
  }
171
165
  });
172
166
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "voicecc",
3
- "version": "1.1.18",
3
+ "version": "1.1.20",
4
4
  "description": "Voice mode plugin for Claude Code -- hands-free interaction via ElevenLabs STT/TTS and VAD",
5
5
  "type": "module",
6
6
  "bin": {