aquaman-proxy 0.6.0 → 0.7.0

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.
Files changed (72) hide show
  1. package/README.md +10 -9
  2. package/dist/cli/index.js +104 -87
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/core/audit/index.d.ts +5 -0
  5. package/dist/core/audit/index.d.ts.map +1 -0
  6. package/dist/core/audit/index.js +5 -0
  7. package/dist/core/audit/index.js.map +1 -0
  8. package/dist/core/audit/logger.d.ts +53 -0
  9. package/dist/core/audit/logger.d.ts.map +1 -0
  10. package/dist/core/audit/logger.js +262 -0
  11. package/dist/core/audit/logger.js.map +1 -0
  12. package/dist/core/credentials/backends/keepassxc.d.ts +45 -0
  13. package/dist/core/credentials/backends/keepassxc.d.ts.map +1 -0
  14. package/dist/core/credentials/backends/keepassxc.js +229 -0
  15. package/dist/core/credentials/backends/keepassxc.js.map +1 -0
  16. package/dist/core/credentials/backends/onepassword.d.ts +38 -0
  17. package/dist/core/credentials/backends/onepassword.d.ts.map +1 -0
  18. package/dist/core/credentials/backends/onepassword.js +218 -0
  19. package/dist/core/credentials/backends/onepassword.js.map +1 -0
  20. package/dist/core/credentials/backends/vault.d.ts +56 -0
  21. package/dist/core/credentials/backends/vault.d.ts.map +1 -0
  22. package/dist/core/credentials/backends/vault.js +206 -0
  23. package/dist/core/credentials/backends/vault.js.map +1 -0
  24. package/dist/core/credentials/index.d.ts +8 -0
  25. package/dist/core/credentials/index.d.ts.map +1 -0
  26. package/dist/core/credentials/index.js +8 -0
  27. package/dist/core/credentials/index.js.map +1 -0
  28. package/dist/core/credentials/store.d.ts +102 -0
  29. package/dist/core/credentials/store.d.ts.map +1 -0
  30. package/dist/core/credentials/store.js +289 -0
  31. package/dist/core/credentials/store.js.map +1 -0
  32. package/dist/core/index.d.ts +14 -0
  33. package/dist/core/index.d.ts.map +1 -0
  34. package/dist/core/index.js +18 -0
  35. package/dist/core/index.js.map +1 -0
  36. package/dist/core/types.d.ts +81 -0
  37. package/dist/core/types.d.ts.map +1 -0
  38. package/dist/core/types.js +11 -0
  39. package/dist/core/types.js.map +1 -0
  40. package/dist/core/utils/config.d.ts +19 -0
  41. package/dist/core/utils/config.d.ts.map +1 -0
  42. package/dist/core/utils/config.js +136 -0
  43. package/dist/core/utils/config.js.map +1 -0
  44. package/dist/core/utils/hash.d.ts +27 -0
  45. package/dist/core/utils/hash.d.ts.map +1 -0
  46. package/dist/core/utils/hash.js +348 -0
  47. package/dist/core/utils/hash.js.map +1 -0
  48. package/dist/core/utils/index.d.ts +6 -0
  49. package/dist/core/utils/index.d.ts.map +1 -0
  50. package/dist/core/utils/index.js +6 -0
  51. package/dist/core/utils/index.js.map +1 -0
  52. package/dist/daemon.d.ts +4 -19
  53. package/dist/daemon.d.ts.map +1 -1
  54. package/dist/daemon.js +24 -101
  55. package/dist/daemon.js.map +1 -1
  56. package/dist/index.d.ts +2 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +2 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/migration/openclaw-migrator.d.ts +1 -1
  61. package/dist/migration/openclaw-migrator.d.ts.map +1 -1
  62. package/dist/oauth-token-cache.d.ts +1 -1
  63. package/dist/oauth-token-cache.d.ts.map +1 -1
  64. package/dist/openclaw/env-writer.d.ts +7 -7
  65. package/dist/openclaw/env-writer.d.ts.map +1 -1
  66. package/dist/openclaw/env-writer.js +8 -13
  67. package/dist/openclaw/env-writer.js.map +1 -1
  68. package/dist/openclaw/integration.d.ts +5 -3
  69. package/dist/openclaw/integration.d.ts.map +1 -1
  70. package/dist/openclaw/integration.js +7 -14
  71. package/dist/openclaw/integration.js.map +1 -1
  72. package/package.json +7 -3
package/README.md CHANGED
@@ -8,15 +8,16 @@ Credential isolation proxy and CLI for [aquaman](https://github.com/tech4242/aqu
8
8
  Agent / OpenClaw Gateway Aquaman Proxy
9
9
  ┌──────────────────────┐ ┌──────────────────────┐
10
10
  │ │ │ │
11
- │ ANTHROPIC_BASE_URL │──request────>│ Keychain / 1Pass / │
12
- │ = localhost:8081 Vault / Encrypted │
13
- │<─response────│
14
- │ fetch() interceptor │──channel────>│ + Auth injected: │
15
- │ redirects channel │ traffic │ header / url-path │
11
+ │ ANTHROPIC_BASE_URL │══ Unix ════>│ Keychain / 1Pass / │
12
+ │ = aquaman.local │ Domain │ Vault / Encrypted │
13
+ │<═ Socket ═══│
14
+ │ fetch() interceptor │══ (UDS) ══=>│ + Auth injected: │
15
+ │ redirects channel │ │ header / url-path │
16
16
  │ API traffic │ │ basic / oauth │
17
17
  │ │ │ │
18
- │ No credentials. │ │ │
19
- Nothing to steal. │ │
18
+ │ No credentials. │ ~/.aquaman/ │ │
19
+ No open ports. proxy.sock │ │
20
+ │ Nothing to steal. │ (chmod 600) │ │
20
21
  └──────────────────────┘ └───┬──────────┬───────┘
21
22
  │ │
22
23
  │ ▼
@@ -28,7 +29,7 @@ Agent / OpenClaw Gateway Aquaman Proxy
28
29
  slack.com/api ...
29
30
  ```
30
31
 
31
- This package is the right side. A reverse proxy that intercepts API requests and injects credentials from secure backends. 23 builtin services, four auth modes.
32
+ This package is the right side. A reverse proxy that listens on a Unix domain socket (`~/.aquaman/proxy.sock`) and injects credentials from secure backends. No TCP port, no network exposure. 23 builtin services, four auth modes.
32
33
 
33
34
  ## Quick Start
34
35
 
@@ -54,7 +55,7 @@ Standalone:
54
55
  npm install -g aquaman-proxy
55
56
  aquaman init
56
57
  aquaman credentials add anthropic api_key
57
- aquaman daemon
58
+ aquaman daemon # listens on ~/.aquaman/proxy.sock
58
59
  ```
59
60
 
60
61
  Troubleshooting: `aquaman doctor`
package/dist/cli/index.js CHANGED
@@ -9,10 +9,10 @@
9
9
  * - Custom service registry: YAML-based service config
10
10
  */
11
11
  import { Command } from 'commander';
12
- import * as crypto from 'node:crypto';
13
12
  import * as path from 'node:path';
14
13
  import * as fs from 'node:fs';
15
- import { loadConfig, getConfigDir, ensureConfigDir, getDefaultConfig, expandPath, createAuditLogger, createCredentialStore, generateSelfSignedCert, saveConfig } from 'aquaman-core';
14
+ import * as http from 'node:http';
15
+ import { loadConfig, getConfigDir, ensureConfigDir, getDefaultConfig, expandPath, createAuditLogger, createCredentialStore, saveConfig } from '../core/index.js';
16
16
  import { fileURLToPath } from 'node:url';
17
17
  import { createCredentialProxy } from '../daemon.js';
18
18
  import { createServiceRegistry, ServiceRegistry } from '../service-registry.js';
@@ -83,8 +83,7 @@ program
83
83
  if (options.dryRun) {
84
84
  console.log('Dry run - would start with this configuration:\n');
85
85
  console.log('Credential proxy:');
86
- console.log(` Port: ${config.credentials.proxyPort}`);
87
- console.log(` TLS: ${config.credentials.tls?.enabled ? 'enabled' : 'disabled'}`);
86
+ console.log(` Socket: ${path.join(getConfigDir(), 'proxy.sock')}`);
88
87
  console.log(` Backend: ${config.credentials.backend}`);
89
88
  console.log(` Services: ${config.credentials.proxiedServices.join(', ')}`);
90
89
  console.log('');
@@ -127,14 +126,12 @@ program
127
126
  // Initialize service registry
128
127
  const serviceRegistry = createServiceRegistry({ configPath: config.services.configPath });
129
128
  // Start credential proxy
130
- const bindAddr = config.credentials.bindAddress || '127.0.0.1';
129
+ const socketPath = path.join(getConfigDir(), 'proxy.sock');
131
130
  const credentialProxy = createCredentialProxy({
132
- port: config.credentials.proxyPort,
133
- bindAddress: bindAddr,
131
+ socketPath,
134
132
  store: credentialStore,
135
133
  allowedServices: config.credentials.proxiedServices,
136
134
  serviceRegistry,
137
- tls: config.credentials.tls,
138
135
  onRequest: (info) => {
139
136
  auditLogger.logCredentialAccess('system', 'system', {
140
137
  service: info.service,
@@ -145,8 +142,7 @@ program
145
142
  }
146
143
  });
147
144
  await credentialProxy.start();
148
- const protocol = credentialProxy.isTlsEnabled() ? 'https' : 'http';
149
- console.log(`Credential proxy started on ${protocol}://${bindAddr}:${config.credentials.proxyPort}`);
145
+ console.log(`Credential proxy started on ${socketPath}`);
150
146
  if (options.launch !== false && config.openclaw.autoLaunch) {
151
147
  // Get services for OpenClaw integration
152
148
  const services = serviceRegistry.getAll().filter(s => config.credentials.proxiedServices.includes(s.name));
@@ -225,6 +221,11 @@ program
225
221
  process.kill(pid, 'SIGKILL');
226
222
  }
227
223
  removePidFile();
224
+ const sockPath = path.join(getConfigDir(), 'proxy.sock');
225
+ try {
226
+ fs.unlinkSync(sockPath);
227
+ }
228
+ catch { /* already removed */ }
228
229
  console.log('Daemon stopped.');
229
230
  }
230
231
  catch (err) {
@@ -235,8 +236,7 @@ program
235
236
  program
236
237
  .command('daemon')
237
238
  .description('Run the credential proxy daemon (for advanced users)')
238
- .option('--token <token>', 'Client authentication token (reads AQUAMAN_CLIENT_TOKEN env if not set)')
239
- .action(async (options) => {
239
+ .action(async () => {
240
240
  // Check if daemon is already running
241
241
  const existingPid = readPidFile();
242
242
  if (existingPid && isProcessRunning(existingPid)) {
@@ -244,6 +244,7 @@ program
244
244
  process.exit(1);
245
245
  }
246
246
  const config = loadConfig();
247
+ const socketPath = path.join(getConfigDir(), 'proxy.sock');
247
248
  console.log('Starting aquaman credential proxy daemon...\n');
248
249
  // Initialize audit logger
249
250
  const auditLogger = createAuditLogger({
@@ -274,18 +275,12 @@ program
274
275
  }
275
276
  // Initialize service registry
276
277
  const serviceRegistry = createServiceRegistry({ configPath: config.services.configPath });
277
- // Client token: CLI flag → env var → none
278
- const daemonClientToken = options.token || process.env.AQUAMAN_CLIENT_TOKEN || undefined;
279
278
  // Start credential proxy
280
- const bindAddr = config.credentials.bindAddress || '127.0.0.1';
281
279
  const credentialProxy = createCredentialProxy({
282
- port: config.credentials.proxyPort,
283
- bindAddress: bindAddr,
280
+ socketPath,
284
281
  store: credentialStore,
285
282
  allowedServices: config.credentials.proxiedServices,
286
283
  serviceRegistry,
287
- tls: config.credentials.tls,
288
- clientToken: daemonClientToken,
289
284
  onRequest: (info) => {
290
285
  auditLogger.logCredentialAccess('system', 'system', {
291
286
  service: info.service,
@@ -298,9 +293,7 @@ program
298
293
  await credentialProxy.start();
299
294
  // Write PID file
300
295
  writePidFile();
301
- const protocol = credentialProxy.isTlsEnabled() ? 'https' : 'http';
302
- console.log(`Credential proxy: ${protocol}://${bindAddr}:${config.credentials.proxyPort}`);
303
- console.log(`Client auth: ${daemonClientToken ? 'enabled' : 'disabled'}`);
296
+ console.log(`Credential proxy: ${socketPath}`);
304
297
  console.log(`Audit logging: ${config.audit.enabled ? 'enabled' : 'disabled'}`);
305
298
  console.log(`Credential backend: ${config.credentials.backend}`);
306
299
  console.log(`PID file: ${getPidFile()}`);
@@ -311,6 +304,10 @@ program
311
304
  console.log('\nShutting down daemon...');
312
305
  await credentialProxy.stop();
313
306
  removePidFile();
307
+ try {
308
+ fs.unlinkSync(socketPath);
309
+ }
310
+ catch { /* already removed */ }
314
311
  process.exit(0);
315
312
  };
316
313
  process.on('SIGINT', shutdown);
@@ -320,13 +317,9 @@ program
320
317
  program
321
318
  .command('plugin-mode')
322
319
  .description('Run in plugin mode (managed by OpenClaw plugin)')
323
- .option('--port <port>', 'Port to listen on', '8081')
324
- .option('--token <token>', 'Client authentication token (generated if not provided)')
325
- .option('--ipc', 'Use IPC instead of HTTP for communication')
326
- .action(async (options) => {
320
+ .action(async () => {
327
321
  const config = loadConfig();
328
- const port = parseInt(options.port, 10);
329
- const clientToken = options.token || crypto.randomBytes(32).toString('hex');
322
+ const socketPath = path.join(getConfigDir(), 'proxy.sock');
330
323
  // Initialize credential store
331
324
  let credentialStore;
332
325
  try {
@@ -348,21 +341,31 @@ program
348
341
  console.error('Fix the backend configuration and retry. Run: aquaman doctor');
349
342
  process.exit(1);
350
343
  }
344
+ // Initialize audit logger
345
+ const auditLogger = createAuditLogger({
346
+ logDir: config.audit.logDir,
347
+ enabled: config.audit.enabled
348
+ });
349
+ await auditLogger.initialize();
351
350
  // Initialize service registry
352
351
  const serviceRegistry = createServiceRegistry({ configPath: config.services.configPath });
353
352
  // Start credential proxy
354
353
  const credentialProxy = createCredentialProxy({
355
- port,
356
- bindAddress: config.credentials.bindAddress || '127.0.0.1',
354
+ socketPath,
357
355
  store: credentialStore,
358
356
  allowedServices: config.credentials.proxiedServices,
359
357
  serviceRegistry,
360
- tls: config.credentials.tls,
361
- clientToken
358
+ onRequest: (info) => {
359
+ auditLogger.logCredentialAccess('system', 'system', {
360
+ service: info.service,
361
+ operation: 'use',
362
+ success: !info.error,
363
+ error: info.error
364
+ });
365
+ }
362
366
  });
363
367
  await credentialProxy.start();
364
- const protocol = credentialProxy.isTlsEnabled() ? 'https' : 'http';
365
- // Build host map from service registry for the plugin's fetch interceptor
368
+ // Build host map from service registry for the plugin's interceptor
366
369
  const hostMap = serviceRegistry.buildHostMap();
367
370
  const hostMapObj = {};
368
371
  for (const [pattern, serviceName] of hostMap) {
@@ -371,18 +374,19 @@ program
371
374
  // Output connection info as JSON for plugin to parse
372
375
  const connectionInfo = {
373
376
  ready: true,
374
- port: credentialProxy.getPort(),
375
- protocol,
376
- baseUrl: `${protocol}://127.0.0.1:${credentialProxy.getPort()}`,
377
+ socketPath,
377
378
  services: config.credentials.proxiedServices,
378
379
  backend: config.credentials.backend,
379
- token: clientToken,
380
380
  hostMap: hostMapObj
381
381
  };
382
382
  console.log(JSON.stringify(connectionInfo));
383
383
  // Handle shutdown
384
384
  const shutdown = async () => {
385
385
  await credentialProxy.stop();
386
+ try {
387
+ fs.unlinkSync(socketPath);
388
+ }
389
+ catch { /* already removed */ }
386
390
  process.exit(0);
387
391
  };
388
392
  process.on('SIGINT', shutdown);
@@ -400,7 +404,7 @@ program
400
404
  const registry = createServiceRegistry({ configPath: config.services.configPath });
401
405
  const services = registry.getAll().filter(s => config.credentials.proxiedServices.includes(s.name));
402
406
  const integration = createOpenClawIntegration(config, services);
403
- const env = await integration.configureOpenClaw(config.credentials.proxyPort, config.credentials.tls?.enabled ?? false);
407
+ const env = await integration.configureOpenClaw();
404
408
  if (options.dryRun || options.method === 'env') {
405
409
  console.log('Environment variables for OpenClaw:\n');
406
410
  for (const [key, value] of Object.entries(env)) {
@@ -418,7 +422,6 @@ program
418
422
  .command('init')
419
423
  .description('Initialize aquaman configuration')
420
424
  .option('--force', 'Overwrite existing configuration')
421
- .option('--no-tls', 'Skip TLS certificate generation')
422
425
  .action(async (options) => {
423
426
  ensureConfigDir();
424
427
  const configPath = path.join(getConfigDir(), 'config.yaml');
@@ -434,30 +437,6 @@ program
434
437
  const auditDir = path.join(getConfigDir(), 'audit');
435
438
  fs.mkdirSync(auditDir, { recursive: true });
436
439
  console.log(`Created ${auditDir}`);
437
- // Generate TLS certificates if enabled
438
- if (options.tls !== false && config.credentials.tls?.autoGenerate) {
439
- const certsDir = path.join(getConfigDir(), 'certs');
440
- fs.mkdirSync(certsDir, { recursive: true });
441
- const certPath = config.credentials.tls.certPath || path.join(certsDir, 'proxy.crt');
442
- const keyPath = config.credentials.tls.keyPath || path.join(certsDir, 'proxy.key');
443
- if (!fs.existsSync(certPath) || options.force) {
444
- console.log('Generating TLS certificates...');
445
- try {
446
- const { cert, key } = generateSelfSignedCert('aquaman-proxy', 365);
447
- fs.writeFileSync(certPath, cert, { mode: 0o644 });
448
- fs.writeFileSync(keyPath, key, { mode: 0o600 });
449
- console.log(`Created ${certPath}`);
450
- console.log(`Created ${keyPath}`);
451
- }
452
- catch (error) {
453
- console.error('Warning: Failed to generate TLS certificates:', error);
454
- console.log('TLS will be disabled. Run "aquaman init --force" to retry.');
455
- }
456
- }
457
- else {
458
- console.log('TLS certificates already exist (use --force to regenerate)');
459
- }
460
- }
461
440
  console.log('\nNext steps:');
462
441
  console.log('1. Add your API keys: aquaman credentials add anthropic api_key');
463
442
  console.log('2. Start the proxy: aquaman start');
@@ -588,11 +567,10 @@ program
588
567
  }
589
568
  }
590
569
  }
591
- // 2. Run init internally (create dirs, config, no TLS by default)
570
+ // 2. Run init internally (create dirs, config)
592
571
  ensureConfigDir();
593
572
  const config = getDefaultConfig();
594
573
  config.credentials.backend = backend;
595
- config.credentials.tls = { enabled: false };
596
574
  fs.writeFileSync(configPath, yamlStringify(config), 'utf-8');
597
575
  // Create audit directory
598
576
  const auditDir = path.join(configDir, 'audit');
@@ -761,10 +739,8 @@ program
761
739
  openclawConfig.plugins.entries['aquaman-plugin'] = {
762
740
  enabled: true,
763
741
  config: {
764
- mode: 'proxy',
765
742
  backend,
766
743
  services: storedServices.length > 0 ? storedServices : ['anthropic', 'openai'],
767
- proxyPort: 8081
768
744
  }
769
745
  };
770
746
  fs.writeFileSync(openclawJsonPath, JSON.stringify(openclawConfig, null, 2), 'utf-8');
@@ -900,35 +876,77 @@ program
900
876
  config = loadConfig();
901
877
  }
902
878
  // 4. Proxy running
903
- const proxyPort = config.credentials.proxyPort;
879
+ const sockPath = path.join(getConfigDir(), 'proxy.sock');
904
880
  const pluginInstalled = fs.existsSync(path.join(openclawStateDir, 'extensions', 'aquaman-plugin'));
905
881
  const proxyFix = pluginInstalled
906
882
  ? 'Proxy starts automatically with OpenClaw. Run: openclaw'
907
883
  : 'Install plugin first: aquaman setup';
908
884
  try {
909
- const resp = await fetch(`http://127.0.0.1:${proxyPort}/_health`);
910
- if (resp.ok) {
911
- const health = await resp.json();
912
- const proxyVer = health.version || 'unknown';
913
- console.log(` \u2713 ${aqua('Proxy')} running on port ${proxyPort} (v${proxyVer})`);
914
- if (health.version && health.version !== VERSION) {
915
- console.log(` \u2717 ${aqua('Version mismatch:')} CLI v${VERSION} \u2260 proxy v${health.version}`);
916
- console.log(' \u2192 Update: npm install -g aquaman-proxy');
917
- issues++;
918
- }
919
- }
920
- else {
921
- console.log(` \u2717 ${aqua('Proxy')} not running on port ${proxyPort}`);
922
- console.log(` \u2192 ${proxyFix}`);
885
+ const healthData = await new Promise((resolve, reject) => {
886
+ const req = http.request({ socketPath: sockPath, path: '/_health', method: 'GET' }, (res) => {
887
+ let body = '';
888
+ res.on('data', (chunk) => { body += chunk.toString(); });
889
+ res.on('end', () => {
890
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
891
+ resolve(body);
892
+ }
893
+ else {
894
+ reject(new Error(`HTTP ${res.statusCode}`));
895
+ }
896
+ });
897
+ });
898
+ req.on('error', reject);
899
+ req.end();
900
+ });
901
+ const health = JSON.parse(healthData);
902
+ const proxyVer = health.version || 'unknown';
903
+ console.log(` \u2713 ${aqua('Proxy')} running on socket (v${proxyVer})`);
904
+ if (health.version && health.version !== VERSION) {
905
+ console.log(` \u2717 ${aqua('Version mismatch:')} CLI v${VERSION} \u2260 proxy v${health.version}`);
906
+ console.log(' \u2192 Update: npm install -g aquaman-proxy');
923
907
  issues++;
924
908
  }
925
909
  }
926
910
  catch {
927
- console.log(` \u2717 ${aqua('Proxy')} not running on port ${proxyPort}`);
911
+ console.log(` \u2717 ${aqua('Proxy')} not running on socket`);
928
912
  console.log(` \u2192 ${proxyFix}`);
929
913
  issues++;
930
914
  }
931
- // 5. OpenClaw detection
915
+ // 5. Audit logger
916
+ if (config) {
917
+ const auditDir = config.audit.logDir;
918
+ const auditLog = path.join(auditDir, 'current.jsonl');
919
+ if (!config.audit.enabled) {
920
+ console.log(` - ${aqua('Audit')} disabled in config`);
921
+ }
922
+ else if (!fs.existsSync(auditDir)) {
923
+ console.log(` \u2717 ${aqua('Audit')} directory missing (${auditDir})`);
924
+ console.log(' \u2192 Run: aquaman init');
925
+ issues++;
926
+ }
927
+ else {
928
+ // Check log file exists and is writable
929
+ try {
930
+ if (fs.existsSync(auditLog)) {
931
+ fs.accessSync(auditLog, fs.constants.W_OK);
932
+ const content = fs.readFileSync(auditLog, 'utf-8').trim();
933
+ const entryCount = content ? content.split('\n').length : 0;
934
+ console.log(` \u2713 ${aqua('Audit')} log writable (${entryCount} entries)`);
935
+ }
936
+ else {
937
+ // Dir exists but no log yet — that's fine, first request will create it
938
+ fs.accessSync(auditDir, fs.constants.W_OK);
939
+ console.log(` \u2713 ${aqua('Audit')} directory writable (no entries yet)`);
940
+ }
941
+ }
942
+ catch {
943
+ console.log(` \u2717 ${aqua('Audit')} log not writable (${auditLog})`);
944
+ console.log(' \u2192 Check file permissions on ~/.aquaman/audit/');
945
+ issues++;
946
+ }
947
+ }
948
+ }
949
+ // 6. OpenClaw detection
932
950
  let openclawDetected = false;
933
951
  let cliFound = false;
934
952
  try {
@@ -1832,8 +1850,7 @@ program
1832
1850
  console.log('Configuration:');
1833
1851
  console.log(` Config dir: ${getConfigDir()}`);
1834
1852
  console.log(` Credential backend: ${config.credentials.backend}`);
1835
- console.log(` Proxy port: ${config.credentials.proxyPort}`);
1836
- console.log(` TLS: ${config.credentials.tls?.enabled ? 'enabled' : 'disabled'}`);
1853
+ console.log(` Socket path: ${path.join(getConfigDir(), 'proxy.sock')}`);
1837
1854
  console.log(` Audit logging: ${config.audit.enabled ? 'enabled' : 'disabled'}`);
1838
1855
  console.log('\nProxied services:');
1839
1856
  for (const service of config.credentials.proxiedServices) {