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.
- package/README.md +10 -9
- package/dist/cli/index.js +104 -87
- package/dist/cli/index.js.map +1 -1
- package/dist/core/audit/index.d.ts +5 -0
- package/dist/core/audit/index.d.ts.map +1 -0
- package/dist/core/audit/index.js +5 -0
- package/dist/core/audit/index.js.map +1 -0
- package/dist/core/audit/logger.d.ts +53 -0
- package/dist/core/audit/logger.d.ts.map +1 -0
- package/dist/core/audit/logger.js +262 -0
- package/dist/core/audit/logger.js.map +1 -0
- package/dist/core/credentials/backends/keepassxc.d.ts +45 -0
- package/dist/core/credentials/backends/keepassxc.d.ts.map +1 -0
- package/dist/core/credentials/backends/keepassxc.js +229 -0
- package/dist/core/credentials/backends/keepassxc.js.map +1 -0
- package/dist/core/credentials/backends/onepassword.d.ts +38 -0
- package/dist/core/credentials/backends/onepassword.d.ts.map +1 -0
- package/dist/core/credentials/backends/onepassword.js +218 -0
- package/dist/core/credentials/backends/onepassword.js.map +1 -0
- package/dist/core/credentials/backends/vault.d.ts +56 -0
- package/dist/core/credentials/backends/vault.d.ts.map +1 -0
- package/dist/core/credentials/backends/vault.js +206 -0
- package/dist/core/credentials/backends/vault.js.map +1 -0
- package/dist/core/credentials/index.d.ts +8 -0
- package/dist/core/credentials/index.d.ts.map +1 -0
- package/dist/core/credentials/index.js +8 -0
- package/dist/core/credentials/index.js.map +1 -0
- package/dist/core/credentials/store.d.ts +102 -0
- package/dist/core/credentials/store.d.ts.map +1 -0
- package/dist/core/credentials/store.js +289 -0
- package/dist/core/credentials/store.js.map +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +18 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/types.d.ts +81 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +11 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/utils/config.d.ts +19 -0
- package/dist/core/utils/config.d.ts.map +1 -0
- package/dist/core/utils/config.js +136 -0
- package/dist/core/utils/config.js.map +1 -0
- package/dist/core/utils/hash.d.ts +27 -0
- package/dist/core/utils/hash.d.ts.map +1 -0
- package/dist/core/utils/hash.js +348 -0
- package/dist/core/utils/hash.js.map +1 -0
- package/dist/core/utils/index.d.ts +6 -0
- package/dist/core/utils/index.d.ts.map +1 -0
- package/dist/core/utils/index.js +6 -0
- package/dist/core/utils/index.js.map +1 -0
- package/dist/daemon.d.ts +4 -19
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +24 -101
- package/dist/daemon.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/migration/openclaw-migrator.d.ts +1 -1
- package/dist/migration/openclaw-migrator.d.ts.map +1 -1
- package/dist/oauth-token-cache.d.ts +1 -1
- package/dist/oauth-token-cache.d.ts.map +1 -1
- package/dist/openclaw/env-writer.d.ts +7 -7
- package/dist/openclaw/env-writer.d.ts.map +1 -1
- package/dist/openclaw/env-writer.js +8 -13
- package/dist/openclaw/env-writer.js.map +1 -1
- package/dist/openclaw/integration.d.ts +5 -3
- package/dist/openclaw/integration.d.ts.map +1 -1
- package/dist/openclaw/integration.js +7 -14
- package/dist/openclaw/integration.js.map +1 -1
- 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
|
|
12
|
-
│ =
|
|
13
|
-
│
|
|
14
|
-
│ fetch() interceptor
|
|
15
|
-
│ redirects channel │
|
|
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
|
-
│
|
|
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
|
|
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
|
|
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(`
|
|
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
|
|
129
|
+
const socketPath = path.join(getConfigDir(), 'proxy.sock');
|
|
131
130
|
const credentialProxy = createCredentialProxy({
|
|
132
|
-
|
|
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
|
-
|
|
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
|
-
.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
361
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
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
|
|
911
|
+
console.log(` \u2717 ${aqua('Proxy')} not running on socket`);
|
|
928
912
|
console.log(` \u2192 ${proxyFix}`);
|
|
929
913
|
issues++;
|
|
930
914
|
}
|
|
931
|
-
// 5.
|
|
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(`
|
|
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) {
|