create-walle 0.4.4 → 0.4.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-walle",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "Set up Wall-E — your personal digital twin",
5
5
  "bin": {
6
6
  "create-walle": "bin/create-walle.js"
@@ -208,40 +208,52 @@ function handleApi(req, res, url) {
208
208
  return;
209
209
  }
210
210
  if (url.pathname === '/api/setup/detect-key' && req.method === 'GET') {
211
+ // Detect API credentials from external sources (NOT .env — that's what we're trying to populate).
212
+ // Priority: 1) devbox auth file, 2) shell environment, 3) Claude Code keychain
213
+ const { execFileSync } = require('child_process');
211
214
  let key = '';
212
215
  let source = '';
213
- let gateway = null; // For corporate/Portkey gateway setups
214
-
215
- // 1. Check for corporate gateway setup (Portkey, cybertron, etc.)
216
- if (process.env.ANTHROPIC_BASE_URL && process.env.ANTHROPIC_CUSTOM_HEADERS_B64) {
217
- gateway = {
218
- base_url: process.env.ANTHROPIC_BASE_URL,
219
- auth_token: process.env.ANTHROPIC_AUTH_TOKEN || 'sk-ant-api03-unused',
220
- custom_headers_b64: process.env.ANTHROPIC_CUSTOM_HEADERS_B64,
221
- };
222
- source = 'Claude Code gateway (' + process.env.ANTHROPIC_BASE_URL.replace(/https?:\/\//, '').split('/')[0] + ')';
223
- }
216
+ let gateway = null;
224
217
 
225
- // 2. Check for direct API key in process.env
226
- if (!gateway && process.env.ANTHROPIC_API_KEY && process.env.ANTHROPIC_API_KEY.startsWith('sk-ant-')) {
227
- key = process.env.ANTHROPIC_API_KEY;
228
- source = 'environment variable';
218
+ // 1. Devbox corporate gateway (reads auth headers file directly)
219
+ if (process.platform === 'darwin') {
220
+ try {
221
+ const authFile = path.join(process.env.HOME, '.devbox', 'secrets', 'claude', 'auth_headers');
222
+ const headers = fs.readFileSync(authFile, 'utf8').trim();
223
+ if (headers) {
224
+ let baseUrl = '';
225
+ try {
226
+ const claudeScript = fs.readFileSync(path.join(process.env.HOME, '.devbox', 'ai', 'claude', 'claude'), 'utf8');
227
+ const m = claudeScript.match(/VPN_CHECK_URL="(https?:\/\/[^"]+)"/);
228
+ if (m) baseUrl = m[1] + '/v1';
229
+ } catch {}
230
+ if (baseUrl) {
231
+ gateway = {
232
+ base_url: baseUrl,
233
+ auth_token: 'sk-ant-api03-unused',
234
+ custom_headers_b64: Buffer.from(headers).toString('base64'),
235
+ };
236
+ source = 'Claude Code devbox (' + baseUrl.replace(/https?:\/\//, '').split('/')[0] + ')';
237
+ }
238
+ }
239
+ } catch {}
229
240
  }
230
241
 
231
- // 3. Try shell profile for direct API key
242
+ // 2. Shell environment (fresh from login shell, not inherited .env)
232
243
  if (!gateway && !key) {
233
244
  try {
234
- const { execFileSync } = require('child_process');
235
245
  const shell = process.env.SHELL || '/bin/zsh';
236
- const result = execFileSync(shell, ['-ilc', 'echo $ANTHROPIC_API_KEY'], { encoding: 'utf8', timeout: 3000 }).trim();
237
- if (result && result.startsWith('sk-ant-')) { key = result; source = 'shell profile'; }
246
+ const result = execFileSync(shell, ['-ilc', 'echo "$ANTHROPIC_API_KEY"'], { encoding: 'utf8', timeout: 5000 }).trim();
247
+ if (result && result.length > 5 && result !== 'sk-ant-api03-unused') {
248
+ key = result;
249
+ source = 'shell environment';
250
+ }
238
251
  } catch {}
239
252
  }
240
253
 
241
- // 4. Try Claude Code OAuth token from macOS Keychain
254
+ // 3. Claude Code OAuth token from macOS Keychain
242
255
  if (!gateway && !key && process.platform === 'darwin') {
243
256
  try {
244
- const { execFileSync } = require('child_process');
245
257
  const credJson = execFileSync('security', ['find-generic-password', '-s', 'Claude Code-credentials', '-w'], { encoding: 'utf8', timeout: 3000 }).trim();
246
258
  if (credJson) {
247
259
  const cred = JSON.parse(credJson);
@@ -253,11 +265,7 @@ function handleApi(req, res, url) {
253
265
  source = 'Claude Code (OAuth)';
254
266
  } else {
255
267
  res.writeHead(200, { 'Content-Type': 'application/json' });
256
- res.end(JSON.stringify({
257
- found: false,
258
- claude_code_expired: true,
259
- hint: 'Found Claude Code, but the OAuth token has expired. Run "claude" in your terminal once to refresh it, then click Detect again.'
260
- }));
268
+ res.end(JSON.stringify({ found: false, claude_code_expired: true, hint: 'Found Claude Code, but the OAuth token has expired. Run "claude" in your terminal once to refresh it, then click Detect again.' }));
261
269
  return;
262
270
  }
263
271
  }
@@ -271,7 +279,7 @@ function handleApi(req, res, url) {
271
279
  } else if (key) {
272
280
  res.end(JSON.stringify({ found: true, key, source }));
273
281
  } else {
274
- res.end(JSON.stringify({ found: false, hint: 'No API key found. Checked: environment variables, shell profile, Claude Code keychain. You can get a key at console.anthropic.com' }));
282
+ res.end(JSON.stringify({ found: false, hint: 'No API key found. Checked: devbox auth, shell environment, Claude Code keychain. Enter your key manually or get one at console.anthropic.com' }));
275
283
  }
276
284
  return;
277
285
  }