create-walle 0.4.1 → 0.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-walle",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Set up Wall-E — your personal digital twin",
5
5
  "bin": {
6
6
  "create-walle": "bin/create-walle.js"
@@ -311,34 +311,38 @@ function handleApi(req, res, url) {
311
311
  const apiKey = typeof data.api_key === 'string'
312
312
  ? data.api_key.replace(/[\r\n\s]/g, '').slice(0, 200)
313
313
  : '';
314
- // Gateway config (corporate Portkey/cybertron setups)
315
- const gw = data.gateway;
314
+ // Gateway config (corporate Portkey/cybertron setups) — sanitize values
315
+ let gw = null;
316
+ if (data.gateway && data.gateway.base_url) {
317
+ gw = {
318
+ base_url: String(data.gateway.base_url).replace(/[\r\n]/g, '').slice(0, 500),
319
+ auth_token: String(data.gateway.auth_token || 'sk-ant-api03-unused').replace(/[\r\n]/g, '').slice(0, 500),
320
+ custom_headers_b64: String(data.gateway.custom_headers_b64 || '').replace(/[\r\n\s]/g, '').slice(0, 2000),
321
+ };
322
+ }
316
323
  // Accept any non-empty key (Anthropic, Portkey, or other providers)
317
324
  const envPath = path.resolve(__dirname, '..', '.env');
318
325
  const lines = [];
319
- // Read existing .env, strip lines we're about to replace
320
- const stripPatterns = [/^#?\s*WALLE_OWNER_NAME=/, /^#?\s*ANTHROPIC_API_KEY=/, /^#?\s*ANTHROPIC_BASE_URL=/, /^#?\s*ANTHROPIC_AUTH_TOKEN=/, /^#?\s*ANTHROPIC_CUSTOM_HEADERS_B64=/];
326
+ // Build set of keys we're about to write
327
+ const keysToReplace = new Set();
328
+ if (ownerName) keysToReplace.add('WALLE_OWNER_NAME');
329
+ if (apiKey) keysToReplace.add('ANTHROPIC_API_KEY');
330
+ if (gw) { keysToReplace.add('ANTHROPIC_BASE_URL'); keysToReplace.add('ANTHROPIC_AUTH_TOKEN'); keysToReplace.add('ANTHROPIC_CUSTOM_HEADERS_B64'); }
331
+ // Read existing .env, keep lines that aren't being replaced
321
332
  try {
322
333
  const existing = fs.readFileSync(envPath, 'utf8');
323
334
  for (const line of existing.split('\n')) {
324
- const shouldStrip = (apiKey || gw) && stripPatterns.some(p => p.test(line));
325
- if (!shouldStrip || (!apiKey && !gw)) lines.push(line);
326
- else if (!ownerName || !line.match(/WALLE_OWNER_NAME/)) {
327
- // Only strip if we have a replacement
328
- if (stripPatterns.some(p => p.test(line))) continue;
329
- lines.push(line);
330
- }
331
- }
332
- // Also strip owner name line if we have a new one
333
- if (ownerName) {
334
- const idx = lines.findIndex(l => /^#?\s*WALLE_OWNER_NAME=/.test(l));
335
- if (idx >= 0) lines.splice(idx, 1);
335
+ const m = line.match(/^\s*#?\s*([A-Z_]+)\s*=/);
336
+ if (m && keysToReplace.has(m[1])) continue; // skip — will re-add below
337
+ lines.push(line);
336
338
  }
337
339
  } catch { lines.push('# Wall-E configuration'); lines.push(''); }
338
- // Add values
340
+ // Strip trailing blank lines
341
+ while (lines.length > 0 && lines[lines.length - 1].trim() === '') lines.pop();
342
+ lines.push('');
343
+ // Add new values
339
344
  if (ownerName) {
340
- const insertIdx = lines.findIndex(l => !l.startsWith('#') && l.trim() !== '') || lines.length;
341
- lines.splice(insertIdx, 0, `WALLE_OWNER_NAME=${ownerName}`);
345
+ lines.push(`WALLE_OWNER_NAME=${ownerName}`);
342
346
  process.env.WALLE_OWNER_NAME = ownerName;
343
347
  }
344
348
  if (gw) {
@@ -13,6 +13,33 @@ try {
13
13
  });
14
14
  } catch {}
15
15
 
16
+ // Auto-detect corporate Claude Code gateway (devbox) if not already configured.
17
+ // The devbox `claude` wrapper stores auth headers at ~/.devbox/secrets/claude/auth_headers
18
+ // but only injects them as env vars when running `claude` directly.
19
+ // This lets Wall-E use the same gateway when started from a regular terminal.
20
+ // Skip if already configured with real credentials; detect if missing or only has dummy token
21
+ const _hasRealKey = process.env.ANTHROPIC_API_KEY && process.env.ANTHROPIC_API_KEY !== 'sk-ant-api03-unused';
22
+ if (!process.env.ANTHROPIC_CUSTOM_HEADERS_B64 && !_hasRealKey) {
23
+ try {
24
+ const _authFile = path.join(process.env.HOME, '.devbox', 'secrets', 'claude', 'auth_headers');
25
+ const _headers = fs.readFileSync(_authFile, 'utf8').trim();
26
+ if (_headers) {
27
+ process.env.ANTHROPIC_CUSTOM_HEADERS_B64 = Buffer.from(_headers).toString('base64');
28
+ if (!process.env.ANTHROPIC_CUSTOM_HEADERS) process.env.ANTHROPIC_CUSTOM_HEADERS = _headers;
29
+ if (!process.env.ANTHROPIC_AUTH_TOKEN) process.env.ANTHROPIC_AUTH_TOKEN = 'sk-ant-api03-unused';
30
+ // Detect gateway URL from devbox claude wrapper
31
+ if (!process.env.ANTHROPIC_BASE_URL) {
32
+ try {
33
+ const _claudeScript = fs.readFileSync(path.join(process.env.HOME, '.devbox', 'ai', 'claude', 'claude'), 'utf8');
34
+ const _vpnMatch = _claudeScript.match(/VPN_CHECK_URL="(https?:\/\/[^"]+)"/);
35
+ if (_vpnMatch) process.env.ANTHROPIC_BASE_URL = _vpnMatch[1] + '/v1';
36
+ } catch {}
37
+ }
38
+ console.log('[brain] Auto-detected devbox Claude gateway auth');
39
+ }
40
+ } catch {}
41
+ }
42
+
16
43
  const DATA_DIR = process.env.WALL_E_DATA_DIR || path.join(process.env.HOME, '.walle', 'data');
17
44
  const DEFAULT_DB_PATH = path.join(DATA_DIR, 'wall-e-brain.db');
18
45
  const BACKUP_DIR = path.join(DATA_DIR, 'backups');
@@ -1,5 +1,4 @@
1
1
  'use strict';
2
- const http = require('http');
3
2
  const crypto = require('crypto');
4
3
  const fs = require('fs');
5
4
  const path = require('path');