voicecc 1.1.17 → 1.1.19

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.
@@ -13,7 +13,7 @@
13
13
  */
14
14
 
15
15
  import { Hono } from "hono";
16
- import { execFile } from "child_process";
16
+ import { execFile, execFileSync } from "child_process";
17
17
  import pty, { type IPty } from "node-pty";
18
18
  import { writeEnvKey } from "../../server/services/env.js";
19
19
 
@@ -80,7 +80,6 @@ async function getAuthStatus(): Promise<AuthStatus> {
80
80
  */
81
81
  function resolveClaudePath(): string {
82
82
  try {
83
- const { execFileSync } = require("child_process");
84
83
  return execFileSync("which", [CLAUDE_BIN]).toString().trim();
85
84
  } catch {
86
85
  return CLAUDE_BIN;
@@ -121,45 +120,63 @@ function spawnLoginProcess(): Promise<string> {
121
120
  let resolved = false;
122
121
  let step = 0;
123
122
 
123
+ let loginSent = false;
124
+ let enterDebounce: ReturnType<typeof setTimeout> | null = null;
125
+
124
126
  child.onData((data: string) => {
125
127
  output += data;
128
+ const clean = data.replace(/\x1b\[[^m]*m/g, "").replace(/\r/g, "").trim();
129
+ if (clean) console.debug(`[auth/login] step=${step} data: ${clean.slice(0, 200)}`);
126
130
 
127
- // Step 0 1: Accept trust prompt
128
- if (step === 0 && /enter to confirm/i.test(output)) {
129
- step = 1;
130
- console.debug("[auth/login] step 1: accepting trust prompt");
131
- setTimeout(() => child.write("\r"), 500);
132
- }
133
-
134
- // Step 1 → 2: Wait for main prompt, send /login
135
- if (step === 1 && /v\d+\.\d+\.\d+/.test(output.slice(-2000))) {
136
- step = 2;
137
- console.debug("[auth/login] step 2: sending /login");
138
- setTimeout(() => child.write("/login\r"), 1000);
139
- }
140
-
141
- // Step 2 → 3: Select Claude Pro (first option)
142
- if (step === 2 && /claude.*pro|login.*method/i.test(output.slice(-500))) {
143
- step = 3;
144
- console.debug("[auth/login] step 3: selecting Claude Pro");
145
- setTimeout(() => child.write("\r"), 1000);
146
- }
147
-
148
- // Step 3 → done: Capture OAuth URL
149
- if (step >= 2) {
131
+ // ---- Check for OAuth URL first (can appear at any point after /login) ----
132
+ if (loginSent) {
150
133
  const urlMatch = output.match(/(https:\/\/claude\.ai\/oauth\/authorize\S+)/);
151
134
  if (urlMatch && !resolved) {
152
135
  resolved = true;
153
136
  step = 4;
154
- console.debug("[auth/login] step 4: URL captured");
137
+ console.debug("[auth/login] URL captured");
155
138
  pendingLogin = {
156
139
  pty: child,
157
140
  url: urlMatch[1],
158
141
  createdAt: Date.now(),
159
142
  };
160
143
  resolve(urlMatch[1]);
144
+ return;
161
145
  }
162
146
  }
147
+
148
+ if (resolved) return;
149
+
150
+ // ---- Before /login: dismiss any setup prompt by pressing Enter ----
151
+ // The CLI may show trust, theme picker, or other selection prompts.
152
+ // They all show ❯ with numbered options. We debounce to avoid spamming.
153
+ if (!loginSent) {
154
+ // Detect the main input prompt: sparkle animation = CLI is ready
155
+ if (/[✻✽✶✢]/.test(data)) {
156
+ loginSent = true;
157
+ console.debug("[auth/login] main prompt ready, sending /login");
158
+ setTimeout(() => child.write("/login\r"), 1000);
159
+ return;
160
+ }
161
+
162
+ // Any selection prompt (❯ followed by numbered items): press Enter
163
+ if (/❯/.test(data)) {
164
+ if (enterDebounce) clearTimeout(enterDebounce);
165
+ enterDebounce = setTimeout(() => {
166
+ console.debug("[auth/login] dismissing selection prompt");
167
+ child.write("\r");
168
+ }, 800);
169
+ }
170
+ }
171
+
172
+ // ---- After /login: dismiss the login method picker ----
173
+ if (loginSent && step < 4 && /❯/.test(data)) {
174
+ if (enterDebounce) clearTimeout(enterDebounce);
175
+ enterDebounce = setTimeout(() => {
176
+ console.debug("[auth/login] selecting first option in login picker");
177
+ child.write("\r");
178
+ }, 800);
179
+ }
163
180
  });
164
181
 
165
182
  child.onExit(({ exitCode }: { exitCode: number }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "voicecc",
3
- "version": "1.1.17",
3
+ "version": "1.1.19",
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": {