@rookdaemon/agora 0.8.0 → 0.8.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/LICENSE +21 -21
- package/README.md +210 -210
- package/dist/{chunk-NHTC6OZW.js → chunk-C4IFVZTN.js} +19 -6
- package/dist/chunk-C4IFVZTN.js.map +1 -0
- package/dist/{chunk-MJGCRX6B.js → chunk-EFX36SN3.js} +10 -18
- package/dist/chunk-EFX36SN3.js.map +1 -0
- package/dist/{chunk-OVDMZHTX.js → chunk-RG3ZM57F.js} +5 -11
- package/dist/chunk-RG3ZM57F.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +13 -9
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/relay/relay-server.js +2 -2
- package/dist/relay/relay-server.js.map +1 -1
- package/package.json +54 -54
- package/dist/chunk-MJGCRX6B.js.map +0 -1
- package/dist/chunk-NHTC6OZW.js.map +0 -1
- package/dist/chunk-OVDMZHTX.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/relay/message-buffer.ts","../src/relay/jwt-auth.ts","../src/relay/rest-api.ts","../src/relay/run-relay.ts"],"sourcesContent":["/**\n * message-buffer.ts — In-memory bounded message queue per agent.\n *\n * When messages are delivered to an agent via the relay, they are also\n * stored here so that HTTP polling clients can retrieve them via GET /v1/messages.\n */\n\nexport interface BufferedMessage {\n id: string;\n from: string;\n type: string;\n payload: unknown;\n timestamp: number;\n inReplyTo?: string;\n}\n\ninterface StoredMessage {\n message: BufferedMessage;\n receivedAt: number;\n}\n\nconst MAX_MESSAGES_PER_AGENT = 100;\n\n/**\n * MessageBuffer stores inbound messages per agent public key.\n * FIFO eviction when the buffer is full (max 100 messages).\n * Messages older than ttlMs (measured from when they were received) are pruned on access.\n */\nexport class MessageBuffer {\n private buffers: Map<string, StoredMessage[]> = new Map();\n private ttlMs: number;\n\n constructor(options?: { ttlMs?: number }) {\n this.ttlMs = options?.ttlMs ?? 86400000; // default 24h\n }\n\n /**\n * Add a message to an agent's buffer.\n * Evicts the oldest message if the buffer is full.\n */\n add(publicKey: string, message: BufferedMessage): void {\n let queue = this.buffers.get(publicKey);\n if (!queue) {\n queue = [];\n this.buffers.set(publicKey, queue);\n }\n queue.push({ message, receivedAt: Date.now() });\n if (queue.length > MAX_MESSAGES_PER_AGENT) {\n queue.shift(); // FIFO eviction\n }\n }\n\n /**\n * Retrieve messages for an agent, optionally filtering by `since` timestamp.\n * Returns messages with timestamp > since (exclusive). Prunes expired messages.\n */\n get(publicKey: string, since?: number): BufferedMessage[] {\n const now = Date.now();\n let queue = this.buffers.get(publicKey) ?? [];\n // Prune messages older than ttlMs (based on wall-clock receive time)\n queue = queue.filter((s) => now - s.receivedAt < this.ttlMs);\n this.buffers.set(publicKey, queue);\n const messages = queue.map((s) => s.message);\n if (since === undefined) {\n return [...messages];\n }\n return messages.filter((m) => m.timestamp > since);\n }\n\n /**\n * Clear all messages for an agent (after polling without `since`).\n */\n clear(publicKey: string): void {\n this.buffers.set(publicKey, []);\n }\n\n /**\n * Remove all state for a disconnected agent.\n */\n delete(publicKey: string): void {\n this.buffers.delete(publicKey);\n }\n}\n","/**\n * jwt-auth.ts — JWT token creation and validation middleware.\n *\n * Tokens are signed with AGORA_RELAY_JWT_SECRET (required env var).\n * Expiry defaults to 3600 seconds (1 hour), configurable via AGORA_JWT_EXPIRY_SECONDS.\n *\n * Token payload: { publicKey, name }\n */\n\nimport jwt from 'jsonwebtoken';\nimport { randomBytes } from 'node:crypto';\nimport type { Request, Response, NextFunction } from 'express';\n\nexport interface JwtPayload {\n publicKey: string;\n name?: string;\n}\n\n/**\n * Augment Express Request to carry decoded JWT payload.\n */\nexport interface AuthenticatedRequest extends Request {\n agent?: JwtPayload;\n}\n\n/**\n * Revocation set for invalidated tokens (populated by DELETE /v1/disconnect).\n * Stored as a Map of JWT `jti` → expiry timestamp (ms).\n * Entries are automatically removed once their JWT would have expired anyway,\n * preventing unbounded memory growth.\n */\nconst revokedJtis: Map<string, number> = new Map();\n\n/**\n * Remove revoked JTI entries whose token expiry has already passed.\n * These tokens can no longer be used regardless, so no need to keep them.\n */\nfunction pruneExpiredRevocations(): void {\n const now = Date.now();\n for (const [jti, expiry] of revokedJtis) {\n if (expiry <= now) {\n revokedJtis.delete(jti);\n }\n }\n}\n\nfunction getJwtSecret(): string {\n const secret = process.env.AGORA_RELAY_JWT_SECRET;\n if (!secret) {\n throw new Error(\n 'AGORA_RELAY_JWT_SECRET environment variable is required but not set'\n );\n }\n return secret;\n}\n\nfunction getExpirySeconds(): number {\n const raw = process.env.AGORA_JWT_EXPIRY_SECONDS;\n if (raw) {\n const parsed = parseInt(raw, 10);\n if (!isNaN(parsed) && parsed > 0) {\n return parsed;\n }\n }\n return 3600; // 1 hour default\n}\n\n/**\n * Create a signed JWT for a registered agent.\n * Returns the token string and its expiry timestamp (ms since epoch).\n */\nexport function createToken(payload: JwtPayload): {\n token: string;\n expiresAt: number;\n} {\n const secret = getJwtSecret();\n const expirySeconds = getExpirySeconds();\n const jti = `${Date.now()}-${randomBytes(16).toString('hex')}`;\n\n const token = jwt.sign(\n { publicKey: payload.publicKey, name: payload.name, jti },\n secret,\n { expiresIn: expirySeconds }\n );\n\n const expiresAt = Date.now() + expirySeconds * 1000;\n return { token, expiresAt };\n}\n\n/**\n * Revoke a token by its jti claim so it cannot be used again.\n * The revocation entry is stored with the token's expiry so it can be\n * pruned automatically once the token would no longer be valid anyway.\n */\nexport function revokeToken(token: string): void {\n try {\n const secret = getJwtSecret();\n const decoded = jwt.verify(token, secret) as jwt.JwtPayload & {\n jti?: string;\n exp?: number;\n };\n if (decoded.jti) {\n const expiry = decoded.exp ? decoded.exp * 1000 : Date.now();\n revokedJtis.set(decoded.jti, expiry);\n pruneExpiredRevocations();\n }\n } catch {\n // Token already invalid — nothing to revoke\n }\n}\n\n/**\n * Express middleware that validates the Authorization: Bearer <token> header.\n * Attaches decoded payload to `req.agent` on success.\n * Responds with 401 if missing/invalid/expired/revoked.\n */\nexport function requireAuth(\n req: AuthenticatedRequest,\n res: Response,\n next: NextFunction\n): void {\n const authHeader = req.headers.authorization;\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n res.status(401).json({ error: 'Missing or malformed Authorization header' });\n return;\n }\n\n const token = authHeader.slice(7);\n try {\n const secret = getJwtSecret();\n const decoded = jwt.verify(token, secret) as jwt.JwtPayload & {\n publicKey: string;\n name?: string;\n jti?: string;\n };\n\n if (decoded.jti && revokedJtis.has(decoded.jti)) {\n res.status(401).json({ error: 'Token has been revoked' });\n return;\n }\n\n req.agent = { publicKey: decoded.publicKey, name: decoded.name };\n next();\n } catch (err) {\n if (err instanceof jwt.TokenExpiredError) {\n res.status(401).json({ error: 'Token expired' });\n } else {\n res.status(401).json({ error: 'Invalid token' });\n }\n }\n}\n","/**\n * rest-api.ts — Express router implementing the Agora relay REST API.\n *\n * Endpoints:\n * POST /v1/register — Register agent, obtain JWT session token\n * POST /v1/send — Send message to a peer (requires auth)\n * GET /v1/peers — List online peers (requires auth)\n * GET /v1/messages — Poll for new inbound messages (requires auth)\n * DELETE /v1/disconnect — Invalidate token and disconnect (requires auth)\n */\n\nimport { Router } from 'express';\nimport type { Request, Response } from 'express';\nimport { rateLimit } from 'express-rate-limit';\nimport {\n createToken,\n revokeToken,\n requireAuth,\n type AuthenticatedRequest,\n} from './jwt-auth';\nimport { MessageBuffer, type BufferedMessage } from './message-buffer';\n\nconst apiRateLimit = (rpm: number): ReturnType<typeof rateLimit> => rateLimit({\n windowMs: 60_000,\n limit: rpm,\n standardHeaders: 'draft-7',\n legacyHeaders: false,\n message: { error: 'Too many requests — try again later' },\n});\n\n/**\n * A session for a REST-connected agent.\n * privateKey is held only in memory and never logged or persisted.\n */\nexport interface RestSession {\n publicKey: string;\n privateKey: string;\n metadata?: { version?: string; capabilities?: string[] };\n registeredAt: number;\n expiresAt: number;\n token: string;\n}\n\nfunction pruneExpiredSessions(\n sessions: Map<string, RestSession>,\n buffer: MessageBuffer\n): void {\n const now = Date.now();\n for (const [publicKey, session] of sessions) {\n if (session.expiresAt <= now) {\n sessions.delete(publicKey);\n buffer.delete(publicKey);\n }\n }\n}\n\n/**\n * Minimal interface for the relay server that the REST API depends on.\n */\nexport interface RelayInterface {\n getAgents(): Map<\n string,\n {\n publicKey: string;\n lastSeen: number;\n metadata?: { version?: string; capabilities?: string[] };\n socket: unknown;\n }\n >;\n on(\n event: 'message-relayed',\n handler: (from: string, to: string, envelope: unknown) => void\n ): void;\n}\n\n/**\n * Envelope creation function interface (matches createEnvelope from message/envelope).\n */\nexport type CreateEnvelopeFn = (\n type: string,\n from: string,\n to: string[],\n privateKey: string,\n payload: unknown,\n timestamp?: number,\n inReplyTo?: string\n) => {\n id: string;\n type: string;\n from: string;\n to: string[];\n timestamp: number;\n payload: unknown;\n signature: string;\n inReplyTo?: string;\n};\n\n/**\n * Envelope verification function interface.\n */\nexport type VerifyEnvelopeFn = (envelope: unknown) => {\n valid: boolean;\n reason?: string;\n};\n\n/**\n * Create the REST API router.\n */\nexport function createRestRouter(\n relay: RelayInterface,\n buffer: MessageBuffer,\n sessions: Map<string, RestSession>,\n createEnv: CreateEnvelopeFn,\n verifyEnv: VerifyEnvelopeFn,\n rateLimitRpm = 60\n): Router {\n const router = Router();\n router.use(apiRateLimit(rateLimitRpm));\n\n relay.on('message-relayed', (from, to, envelope) => {\n if (!sessions.has(to)) return;\n const env = envelope as {\n id: string;\n type: string;\n payload: unknown;\n timestamp: number;\n inReplyTo?: string;\n };\n const msg: BufferedMessage = {\n id: env.id,\n from,\n type: env.type,\n payload: env.payload,\n timestamp: env.timestamp,\n inReplyTo: env.inReplyTo,\n };\n buffer.add(to, msg);\n });\n\n router.post('/v1/register', async (req: Request, res: Response) => {\n const { publicKey, privateKey, metadata } = req.body as {\n publicKey?: string;\n privateKey?: string;\n metadata?: { version?: string; capabilities?: string[] };\n };\n\n if (!publicKey || typeof publicKey !== 'string') {\n res.status(400).json({ error: 'publicKey is required' });\n return;\n }\n if (!privateKey || typeof privateKey !== 'string') {\n res.status(400).json({ error: 'privateKey is required' });\n return;\n }\n\n const testEnvelope = createEnv(\n 'announce',\n publicKey,\n [publicKey],\n privateKey,\n { challenge: 'register' },\n Date.now()\n );\n const verification = verifyEnv(testEnvelope);\n if (!verification.valid) {\n res\n .status(400)\n .json({ error: 'Key pair verification failed: ' + verification.reason });\n return;\n }\n\n const { token, expiresAt } = createToken({ publicKey });\n pruneExpiredSessions(sessions, buffer);\n\n const session: RestSession = {\n publicKey,\n privateKey,\n metadata,\n registeredAt: Date.now(),\n expiresAt,\n token,\n };\n sessions.set(publicKey, session);\n\n const wsAgents = relay.getAgents();\n const peers: Array<{ publicKey: string; lastSeen: number }> = [];\n for (const agent of wsAgents.values()) {\n if (agent.publicKey !== publicKey) {\n peers.push({\n publicKey: agent.publicKey,\n lastSeen: agent.lastSeen,\n });\n }\n }\n for (const s of sessions.values()) {\n if (s.publicKey !== publicKey && !wsAgents.has(s.publicKey)) {\n peers.push({\n publicKey: s.publicKey,\n lastSeen: s.registeredAt,\n });\n }\n }\n\n res.json({ token, expiresAt, peers });\n });\n\n router.post(\n '/v1/send',\n requireAuth,\n async (req: AuthenticatedRequest, res: Response) => {\n const { to, type, payload, inReplyTo } = req.body as {\n to?: string;\n type?: string;\n payload?: unknown;\n inReplyTo?: string;\n };\n\n if (!to || typeof to !== 'string') {\n res.status(400).json({ error: 'to is required' });\n return;\n }\n if (!type || typeof type !== 'string') {\n res.status(400).json({ error: 'type is required' });\n return;\n }\n if (payload === undefined) {\n res.status(400).json({ error: 'payload is required' });\n return;\n }\n\n const senderPublicKey = req.agent!.publicKey;\n const session = sessions.get(senderPublicKey);\n if (!session) {\n res.status(401).json({ error: 'Session not found — please re-register' });\n return;\n }\n\n const envelope = createEnv(\n type,\n senderPublicKey,\n [to],\n session.privateKey,\n payload,\n Date.now(),\n inReplyTo\n );\n\n const wsAgents = relay.getAgents();\n const wsRecipient = wsAgents.get(to);\n if (wsRecipient && wsRecipient.socket) {\n const ws = wsRecipient.socket as { readyState: number; send(data: string): void };\n const OPEN = 1;\n if (ws.readyState !== OPEN) {\n res.status(503).json({ error: 'Recipient connection is not open' });\n return;\n }\n try {\n const relayMsg = JSON.stringify({\n type: 'message',\n from: senderPublicKey,\n envelope,\n });\n ws.send(relayMsg);\n res.json({ ok: true, envelopeId: envelope.id });\n return;\n } catch (err) {\n res.status(500).json({\n error:\n 'Failed to deliver message: ' +\n (err instanceof Error ? err.message : String(err)),\n });\n return;\n }\n }\n\n const restRecipient = sessions.get(to);\n if (restRecipient) {\n const msg: BufferedMessage = {\n id: envelope.id,\n from: senderPublicKey,\n type: envelope.type,\n payload: envelope.payload,\n timestamp: envelope.timestamp,\n inReplyTo: envelope.inReplyTo,\n };\n buffer.add(to, msg);\n res.json({ ok: true, envelopeId: envelope.id });\n return;\n }\n\n res.status(404).json({ error: `Recipient not connected: ${to}` });\n }\n );\n\n router.get(\n '/v1/peers',\n requireAuth,\n (req: AuthenticatedRequest, res: Response) => {\n const callerPublicKey = req.agent!.publicKey;\n const wsAgents = relay.getAgents();\n const peerList: Array<{\n publicKey: string;\n lastSeen: number;\n metadata?: { version?: string; capabilities?: string[] };\n }> = [];\n\n for (const agent of wsAgents.values()) {\n if (agent.publicKey !== callerPublicKey) {\n peerList.push({\n publicKey: agent.publicKey,\n lastSeen: agent.lastSeen,\n metadata: agent.metadata,\n });\n }\n }\n\n for (const s of sessions.values()) {\n if (s.publicKey !== callerPublicKey && !wsAgents.has(s.publicKey)) {\n peerList.push({\n publicKey: s.publicKey,\n lastSeen: s.registeredAt,\n metadata: s.metadata,\n });\n }\n }\n\n res.json({ peers: peerList });\n }\n );\n\n router.get(\n '/v1/messages',\n requireAuth,\n (req: AuthenticatedRequest, res: Response) => {\n const publicKey = req.agent!.publicKey;\n const sinceRaw = req.query.since as string | undefined;\n const limitRaw = req.query.limit as string | undefined;\n\n const since = sinceRaw ? parseInt(sinceRaw, 10) : undefined;\n const limit = Math.min(limitRaw ? parseInt(limitRaw, 10) : 50, 100);\n\n let messages = buffer.get(publicKey, since);\n const hasMore = messages.length > limit;\n if (hasMore) {\n messages = messages.slice(0, limit);\n }\n\n if (since === undefined) {\n buffer.clear(publicKey);\n }\n\n res.json({ messages, hasMore });\n }\n );\n\n router.delete(\n '/v1/disconnect',\n requireAuth,\n (req: AuthenticatedRequest, res: Response) => {\n const publicKey = req.agent!.publicKey;\n const authHeader = req.headers.authorization!;\n const token = authHeader.slice(7);\n\n revokeToken(token);\n sessions.delete(publicKey);\n buffer.delete(publicKey);\n\n res.json({ ok: true });\n }\n );\n\n return router;\n}\n","/**\n * run-relay.ts — Start Agora relay: WebSocket server and optional REST API.\n *\n * When REST is enabled, starts:\n * 1. WebSocket relay (RelayServer) on wsPort\n * 2. REST API server (Express) on restPort\n *\n * Environment variables:\n * RELAY_PORT — WebSocket relay port (default: 3002); alias: PORT\n * REST_PORT — REST API port (default: 3001)\n * JWT_SECRET — Secret for JWT session tokens (alias: AGORA_RELAY_JWT_SECRET)\n * AGORA_JWT_EXPIRY_SECONDS — JWT expiry in seconds (default: 3600)\n * MAX_PEERS — Maximum concurrent registered peers (default: 100)\n * MESSAGE_TTL_MS — Message buffer TTL in ms (default: 86400000 = 24h)\n * RATE_LIMIT_RPM — REST API requests per minute per IP (default: 60)\n * ALLOWED_ORIGINS — CORS origins, comma-separated or * (default: *)\n */\n\nimport http from 'node:http';\nimport express from 'express';\nimport cors from 'cors';\nimport { RelayServer, type RelayServerOptions } from './server';\nimport {\n createEnvelope,\n verifyEnvelope,\n type Envelope,\n type MessageType,\n} from '../message/envelope';\nimport { createRestRouter, type CreateEnvelopeFn } from './rest-api';\nimport { MessageBuffer } from './message-buffer';\nimport type { RestSession } from './rest-api';\n\n/** Wrapper so REST API can pass string type; createEnvelope expects MessageType */\nconst createEnvelopeForRest: CreateEnvelopeFn = (\n type,\n from,\n to,\n privateKey,\n payload,\n timestamp,\n inReplyTo\n) =>\n createEnvelope(\n type as MessageType,\n from,\n privateKey,\n payload,\n timestamp ?? Date.now(),\n inReplyTo,\n to\n );\n\nexport interface RunRelayOptions {\n /** WebSocket port (default from RELAY_PORT or PORT env, or 3002) */\n wsPort?: number;\n /** REST API port (default from REST_PORT env, or 3001). Ignored if enableRest is false. */\n restPort?: number;\n /** Enable REST API (requires JWT_SECRET or AGORA_RELAY_JWT_SECRET). Default: true if secret is set. */\n enableRest?: boolean;\n /** Relay server options (identity, storagePeers, storageDir) */\n relayOptions?: RelayServerOptions;\n}\n\n/**\n * Start WebSocket relay and optionally REST API.\n * Returns { relay, httpServer } where httpServer is set only when REST is enabled.\n */\nexport async function runRelay(options: RunRelayOptions = {}): Promise<{\n relay: RelayServer;\n httpServer?: http.Server;\n}> {\n const wsPort = options.wsPort ?? parseInt(\n process.env.RELAY_PORT ?? process.env.PORT ?? '3002', 10\n );\n const jwtSecret = process.env.JWT_SECRET ?? process.env.AGORA_RELAY_JWT_SECRET;\n const enableRest =\n options.enableRest ??\n (typeof jwtSecret === 'string' && jwtSecret.length > 0);\n\n const maxPeers = parseInt(process.env.MAX_PEERS ?? '100', 10);\n const relayOptions: RelayServerOptions = { ...options.relayOptions, maxPeers };\n\n const relay = new RelayServer(relayOptions);\n await relay.start(wsPort);\n\n if (!enableRest) {\n return { relay };\n }\n\n if (!jwtSecret) {\n await relay.stop();\n throw new Error(\n 'JWT_SECRET (or AGORA_RELAY_JWT_SECRET) environment variable is required when REST API is enabled'\n );\n }\n\n // Expose jwtSecret via env so jwt-auth.ts can read it (it reads AGORA_RELAY_JWT_SECRET)\n if (!process.env.AGORA_RELAY_JWT_SECRET) {\n process.env.AGORA_RELAY_JWT_SECRET = jwtSecret;\n }\n\n const restPort = options.restPort ?? parseInt(process.env.REST_PORT ?? '3001', 10);\n const messageTtlMs = parseInt(process.env.MESSAGE_TTL_MS ?? '86400000', 10);\n const messageBuffer = new MessageBuffer({ ttlMs: messageTtlMs });\n const restSessions = new Map<string, RestSession>();\n\n const allowedOrigins = process.env.ALLOWED_ORIGINS ?? '*';\n const corsOrigins = allowedOrigins === '*'\n ? '*'\n : allowedOrigins.split(',').map((o) => o.trim()).filter((o) => o.length > 0);\n\n const app = express();\n app.use(cors({\n origin: corsOrigins,\n methods: ['GET', 'POST', 'DELETE'],\n allowedHeaders: ['Content-Type', 'Authorization'],\n }));\n app.use(express.json());\n\n const verifyForRest = (envelope: unknown): { valid: boolean; reason?: string } =>\n verifyEnvelope(envelope as Envelope);\n\n const rateLimitRpm = parseInt(process.env.RATE_LIMIT_RPM ?? '60', 10);\n const router = createRestRouter(\n relay as Parameters<typeof createRestRouter>[0],\n messageBuffer,\n restSessions,\n createEnvelopeForRest,\n verifyForRest,\n rateLimitRpm\n );\n app.use(router);\n\n app.use((_req, res) => {\n res.status(404).json({ error: 'Not found' });\n });\n\n const httpServer = http.createServer(app);\n await new Promise<void>((resolve, reject) => {\n httpServer.listen(restPort, () => resolve());\n httpServer.on('error', reject);\n });\n\n return { relay, httpServer };\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -25,12 +25,12 @@ import {
|
|
|
25
25
|
sendToPeer,
|
|
26
26
|
sendViaRelay,
|
|
27
27
|
verifyReveal
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-C4IFVZTN.js";
|
|
29
29
|
import {
|
|
30
30
|
RelayServer,
|
|
31
31
|
createEnvelope,
|
|
32
32
|
verifyEnvelope
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-EFX36SN3.js";
|
|
34
34
|
|
|
35
35
|
// src/cli.ts
|
|
36
36
|
import { parseArgs } from "util";
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/peer/server.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { parseArgs } from 'node:util';\r\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\r\nimport { dirname, resolve } from 'node:path';\r\nimport { homedir } from 'node:os';\r\nimport { loadPeerConfig, savePeerConfig, initPeerConfig } from './transport/peer-config';\r\nimport { sendToPeer, decodeInboundEnvelope, type PeerConfig } from './transport/http';\r\nimport { sendViaRelay } from './transport/relay';\r\nimport type { MessageType } from './message/envelope';\r\nimport type { AnnouncePayload } from './registry/messages';\r\nimport {\r\n getProfileConfigPath,\r\n listProfiles,\r\n loadAgoraConfig,\r\n exportConfig,\r\n importConfig,\r\n saveAgoraConfig,\r\n type ExportedConfig,\r\n} from './config';\r\nimport { PeerServer } from './peer/server';\r\nimport { RelayServer } from './relay/server';\r\nimport { RelayClient } from './relay/client';\r\nimport { PeerDiscoveryService } from './discovery/peer-discovery';\r\nimport { getDefaultBootstrapRelay } from './discovery/bootstrap';\r\nimport { compactInlineReferences, expand, expandInlineReferences, resolveBroadcastName } from './utils';\r\nimport { ReputationStore } from './reputation/store';\r\nimport { createVerification } from './reputation/verification';\r\nimport { createCommit, createReveal, verifyReveal } from './reputation/commit-reveal';\r\nimport { computeTrustScore } from './reputation/scoring';\r\n\r\ninterface CliOptions {\r\n config?: string;\r\n profile?: string;\r\n pretty?: boolean;\r\n}\r\n\r\ntype ConfigPeer = ReturnType<typeof loadPeerConfig>['peers'][string];\r\n\r\nfunction resolvePeerEntry(peers: Record<string, ConfigPeer>, identifier: string): { key: string; peer: ConfigPeer } | undefined {\r\n const expanded = expand(identifier, peers);\r\n if (expanded && peers[expanded]) {\r\n return { key: expanded, peer: peers[expanded] };\r\n }\r\n\r\n const direct = peers[identifier];\r\n if (direct) {\r\n return { key: identifier, peer: direct };\r\n }\r\n\r\n for (const [key, peer] of Object.entries(peers)) {\r\n if (peer.publicKey === identifier || peer.name === identifier) {\r\n return { key, peer };\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nfunction compactPayloadTextReferences(payload: unknown, peers: Record<string, ConfigPeer>): unknown {\r\n if (!payload || typeof payload !== 'object') {\r\n return payload;\r\n }\r\n if ('text' in payload && typeof (payload as Record<string, unknown>).text === 'string') {\r\n return {\r\n ...(payload as Record<string, unknown>),\r\n text: compactInlineReferences((payload as { text: string }).text, peers),\r\n };\r\n }\r\n return payload;\r\n}\r\n\r\n/**\r\n * Suggest the closest known flag for a typo (Levenshtein distance ≤ 3).\r\n */\r\nfunction didYouMean(input: string, known: Set<string>): string | undefined {\r\n let best: string | undefined;\r\n let bestDist = 4; // threshold\r\n for (const candidate of known) {\r\n const d = levenshtein(input, candidate);\r\n if (d < bestDist) {\r\n bestDist = d;\r\n best = candidate;\r\n }\r\n }\r\n return best;\r\n}\r\n\r\nfunction levenshtein(a: string, b: string): number {\r\n const m = a.length, n = b.length;\r\n const dp: number[] = Array.from({ length: n + 1 }, (_, i) => i);\r\n for (let i = 1; i <= m; i++) {\r\n let prev = dp[0];\r\n dp[0] = i;\r\n for (let j = 1; j <= n; j++) {\r\n const tmp = dp[j];\r\n dp[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, dp[j], dp[j - 1]);\r\n prev = tmp;\r\n }\r\n }\r\n return dp[n];\r\n}\r\n\r\n/**\r\n * Get the config file path from CLI options, environment, or default.\r\n */\r\nfunction getConfigPath(options: CliOptions): string {\r\n if (options.config) {\r\n return resolve(options.config);\r\n }\r\n return getProfileConfigPath(options.profile);\r\n}\r\n\r\n/**\r\n * Ensure the config directory exists.\r\n */\r\nfunction ensureConfigDir(configPath: string): void {\r\n const dir = dirname(configPath);\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n}\r\n\r\n/**\r\n * Output data as JSON or pretty format.\r\n */\r\nfunction output(data: unknown, pretty: boolean): void {\r\n if (pretty) {\r\n // Pretty output for humans\r\n if (typeof data === 'object' && data !== null) {\r\n for (const [key, value] of Object.entries(data)) {\r\n if (Array.isArray(value)) {\r\n console.log(`${key}:`);\r\n for (const item of value) {\r\n if (typeof item === 'object' && item !== null) {\r\n const entries = Object.entries(item);\r\n console.log(` - ${entries.map(([k, v]) => `${k}: ${v}`).join(', ')}`);\r\n } else {\r\n console.log(` - ${item}`);\r\n }\r\n }\r\n } else if (typeof value === 'object' && value !== null) {\r\n console.log(`${key}:`);\r\n for (const [k, v] of Object.entries(value)) {\r\n console.log(` ${k}: ${v}`);\r\n }\r\n } else {\r\n console.log(`${key}: ${value}`);\r\n }\r\n }\r\n } else {\r\n console.log(data);\r\n }\r\n } else {\r\n // JSON output for programmatic use\r\n console.log(JSON.stringify(data, null, 2));\r\n }\r\n}\r\n\r\n/**\r\n * Handle the `agora init` command.\r\n */\r\nfunction handleInit(options: CliOptions): void {\r\n const configPath = getConfigPath(options);\r\n ensureConfigDir(configPath);\r\n\r\n if (existsSync(configPath)) {\r\n const config = loadPeerConfig(configPath);\r\n output({ \r\n status: 'already_initialized',\r\n publicKey: config.identity.publicKey,\r\n configPath \r\n }, options.pretty || false);\r\n process.exit(0);\r\n }\r\n\r\n const config = initPeerConfig(configPath);\r\n output({ \r\n status: 'initialized',\r\n publicKey: config.identity.publicKey,\r\n configPath \r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora whoami` command.\r\n */\r\nfunction handleWhoami(options: CliOptions): void {\r\n const configPath = getConfigPath(options);\r\n \r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n output({ \r\n publicKey: config.identity.publicKey,\r\n configPath \r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora peers add` command.\r\n */\r\nfunction handlePeersAdd(args: string[], options: CliOptions & { url?: string; token?: string; pubkey?: string }): void {\r\n if (args.length < 1) {\r\n console.error('Error: Missing peer name. Usage: agora peers add <name> --pubkey <pubkey> [--url <url> --token <token>]');\r\n process.exit(1);\r\n }\r\n\r\n const name = args[0];\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const url = options.url;\r\n const token = options.token;\r\n const pubkey = options.pubkey;\r\n\r\n if (!pubkey) {\r\n console.error('Error: Missing required --pubkey option.');\r\n process.exit(1);\r\n }\r\n\r\n // Validate that if one of url/token is provided, both must be\r\n if ((url && !token) || (!url && token)) {\r\n console.error('Error: Both --url and --token must be provided together.');\r\n process.exit(1);\r\n }\r\n\r\n // Check if we have HTTP transport or relay\r\n const config = loadPeerConfig(configPath);\r\n const hasHttpConfig = url && token;\r\n const hasRelay = config.relay;\r\n\r\n if (!hasHttpConfig && !hasRelay) {\r\n console.error('Error: Either (--url and --token) must be provided, or relay must be configured in config file.');\r\n process.exit(1);\r\n }\r\n\r\n // Add/update the peer (canonical key is full public key)\r\n const existingByPubKey = Object.entries(config.peers).find(([, peer]) => peer.publicKey === pubkey);\r\n if (existingByPubKey && existingByPubKey[0] !== pubkey) {\r\n delete config.peers[existingByPubKey[0]];\r\n }\r\n\r\n config.peers[pubkey] = {\r\n publicKey: pubkey,\r\n name,\r\n };\r\n\r\n if (url && token) {\r\n config.peers[pubkey].url = url;\r\n config.peers[pubkey].token = token;\r\n }\r\n\r\n savePeerConfig(configPath, config);\r\n \r\n const outputData: Record<string, unknown> = { \r\n status: 'added',\r\n name,\r\n publicKey: pubkey\r\n };\r\n \r\n if (url) {\r\n outputData.url = url;\r\n }\r\n \r\n output(outputData, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora peers list` command.\r\n */\r\nfunction handlePeersList(options: CliOptions): void {\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n const peers = Object.entries(config.peers).map(([key, peer]) => ({\r\n name: peer.name || key,\r\n url: peer.url,\r\n publicKey: peer.publicKey,\r\n }));\r\n\r\n output({ peers }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora peers remove` command.\r\n */\r\nfunction handlePeersRemove(args: string[], options: CliOptions): void {\r\n if (args.length < 1) {\r\n console.error('Error: Missing peer name. Usage: agora peers remove <name>');\r\n process.exit(1);\r\n }\r\n\r\n const peerRef = args[0];\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n\r\n const resolved = resolvePeerEntry(config.peers, peerRef);\r\n if (!resolved) {\r\n console.error(`Error: Peer '${peerRef}' not found.`);\r\n process.exit(1);\r\n }\r\n\r\n delete config.peers[resolved.key];\r\n savePeerConfig(configPath, config);\r\n output({ \r\n status: 'removed',\r\n name: peerRef \r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora peers discover` command.\r\n */\r\nasync function handlePeersDiscover(\r\n options: CliOptions & { \r\n relay?: string; \r\n 'relay-pubkey'?: string;\r\n limit?: string;\r\n 'active-within'?: string;\r\n save?: boolean;\r\n }\r\n): Promise<void> {\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n\r\n // Determine relay configuration\r\n let relayUrl: string;\r\n let relayPublicKey: string | undefined;\r\n\r\n if (options.relay) {\r\n // Use custom relay from command line\r\n relayUrl = options.relay;\r\n relayPublicKey = options['relay-pubkey'];\r\n } else if (config.relay) {\r\n // Use relay from config\r\n relayUrl = typeof config.relay === 'string' ? config.relay : config.relay.url;\r\n // TODO: Add relayPublicKey to config schema in future\r\n relayPublicKey = undefined;\r\n } else {\r\n // Use default bootstrap relay\r\n const bootstrap = getDefaultBootstrapRelay();\r\n relayUrl = bootstrap.relayUrl;\r\n relayPublicKey = bootstrap.relayPublicKey;\r\n }\r\n\r\n // Parse filters\r\n const filters: { activeWithin?: number; limit?: number } = {};\r\n if (options['active-within']) {\r\n const ms = parseInt(options['active-within'], 10);\r\n if (isNaN(ms) || ms <= 0) {\r\n console.error('Error: --active-within must be a positive number (milliseconds)');\r\n process.exit(1);\r\n }\r\n filters.activeWithin = ms;\r\n }\r\n if (options.limit) {\r\n const limit = parseInt(options.limit, 10);\r\n if (isNaN(limit) || limit <= 0) {\r\n console.error('Error: --limit must be a positive number');\r\n process.exit(1);\r\n }\r\n filters.limit = limit;\r\n }\r\n\r\n // Resolve broadcast name\r\n const broadcastName = resolveBroadcastName(config, undefined);\r\n\r\n // Connect to relay\r\n const relayClient = new RelayClient({\r\n relayUrl,\r\n publicKey: config.identity.publicKey,\r\n privateKey: config.identity.privateKey,\r\n name: broadcastName,\r\n });\r\n\r\n try {\r\n // Connect\r\n await relayClient.connect();\r\n\r\n // Create discovery service\r\n const discoveryService = new PeerDiscoveryService({\r\n publicKey: config.identity.publicKey,\r\n privateKey: config.identity.privateKey,\r\n relayClient,\r\n relayPublicKey,\r\n });\r\n\r\n // Discover peers\r\n const peerList = await discoveryService.discoverViaRelay(Object.keys(filters).length > 0 ? filters : undefined);\r\n\r\n if (!peerList) {\r\n output({\r\n status: 'no_response',\r\n message: 'No response from relay',\r\n }, options.pretty || false);\r\n process.exit(1);\r\n }\r\n\r\n // Save to config if requested\r\n if (options.save) {\r\n let savedCount = 0;\r\n for (const peer of peerList.peers) {\r\n // Only save if not already in config\r\n const existing = Object.values(config.peers).find(p => p.publicKey === peer.publicKey);\r\n if (!existing) {\r\n config.peers[peer.publicKey] = {\r\n publicKey: peer.publicKey,\r\n name: peer.metadata?.name,\r\n };\r\n savedCount++;\r\n }\r\n }\r\n if (savedCount > 0) {\r\n savePeerConfig(configPath, config);\r\n }\r\n\r\n output({\r\n status: 'discovered',\r\n totalPeers: peerList.totalPeers,\r\n peersReturned: peerList.peers.length,\r\n peersSaved: savedCount,\r\n relayPublicKey: peerList.relayPublicKey,\r\n peers: peerList.peers.map(p => ({\r\n publicKey: p.publicKey,\r\n name: p.metadata?.name,\r\n version: p.metadata?.version,\r\n lastSeen: p.lastSeen,\r\n })),\r\n }, options.pretty || false);\r\n } else {\r\n output({\r\n status: 'discovered',\r\n totalPeers: peerList.totalPeers,\r\n peersReturned: peerList.peers.length,\r\n relayPublicKey: peerList.relayPublicKey,\r\n peers: peerList.peers.map(p => ({\r\n publicKey: p.publicKey,\r\n name: p.metadata?.name,\r\n version: p.metadata?.version,\r\n lastSeen: p.lastSeen,\r\n })),\r\n }, options.pretty || false);\r\n }\r\n } catch (e) {\r\n console.error('Error discovering peers:', e instanceof Error ? e.message : String(e));\r\n process.exit(1);\r\n } finally {\r\n relayClient.disconnect();\r\n }\r\n}\r\n\r\n/**\r\n * Handle the `agora send` command.\r\n */\r\nasync function handleSend(args: string[], options: CliOptions & { type?: string; payload?: string; direct?: boolean; 'relay-only'?: boolean }): Promise<void> {\r\n if (args.length < 1) {\r\n console.error('Error: Missing peer name. Usage: agora send <name> <message> OR agora send <name> --type <type> --payload <json>');\r\n process.exit(1);\r\n }\r\n\r\n const peerRef = args[0];\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n\r\n const resolved = resolvePeerEntry(config.peers, peerRef);\r\n if (!resolved) {\r\n console.error(`Error: Peer '${peerRef}' not found.`);\r\n process.exit(1);\r\n }\r\n\r\n const peer = resolved.peer;\r\n\r\n let messageType: MessageType;\r\n let messagePayload: unknown;\r\n\r\n if (options.type && options.payload) {\r\n // Typed message - validate it's a valid MessageType\r\n const validTypes: MessageType[] = ['announce', 'discover', 'request', 'response', 'publish', 'subscribe', 'verify', 'ack', 'error'];\r\n if (!validTypes.includes(options.type as MessageType)) {\r\n console.error(`Error: Invalid message type '${options.type}'. Valid types: ${validTypes.join(', ')}`);\r\n process.exit(1);\r\n }\r\n messageType = options.type as MessageType;\r\n try {\r\n messagePayload = JSON.parse(options.payload);\r\n } catch {\r\n console.error('Error: Invalid JSON payload.');\r\n process.exit(1);\r\n }\r\n } else {\r\n // Text message - use 'publish' type with text payload\r\n if (args.length < 2) {\r\n console.error('Error: Missing message text. Usage: agora send <name> <message>');\r\n process.exit(1);\r\n }\r\n messageType = 'publish';\r\n messagePayload = { text: expandInlineReferences(args.slice(1).join(' '), config.peers) };\r\n }\r\n\r\n const isDirect = options.direct === true;\r\n const isRelayOnly = options['relay-only'] === true;\r\n\r\n // Validate flag combination\r\n if (isDirect && isRelayOnly) {\r\n console.error('Error: --direct and --relay-only are mutually exclusive.');\r\n process.exit(1);\r\n }\r\n\r\n // --direct requires the peer to have a URL\r\n if (isDirect && !peer.url) {\r\n console.error(`Error: --direct requested but peer '${peerRef}' has no URL configured.`);\r\n process.exit(1);\r\n }\r\n\r\n // Whether to attempt HTTP transport for this send\r\n const shouldTryHttp = peer.url && !isRelayOnly;\r\n const hasRelay = config.relay;\r\n\r\n // Send the message\r\n try {\r\n if (shouldTryHttp) {\r\n // Use HTTP transport\r\n const transportConfig = {\r\n identity: config.identity,\r\n peers: new Map<string, PeerConfig>([[peer.publicKey, {\r\n url: peer.url!,\r\n token: peer.token,\r\n publicKey: peer.publicKey,\r\n }]]),\r\n };\r\n\r\n const result = await sendToPeer(\r\n transportConfig,\r\n peer.publicKey,\r\n messageType,\r\n messagePayload\r\n );\r\n\r\n if (result.ok) {\r\n output({ \r\n status: 'sent',\r\n peer: peerRef,\r\n type: messageType,\r\n transport: 'http',\r\n httpStatus: result.status\r\n }, options.pretty || false);\r\n return;\r\n }\r\n\r\n // HTTP failed\r\n if (isDirect) {\r\n // --direct: do not fall back to relay\r\n output({ \r\n status: 'failed',\r\n peer: peerRef,\r\n type: messageType,\r\n transport: 'http',\r\n httpStatus: result.status,\r\n error: result.error\r\n }, options.pretty || false);\r\n process.exit(1);\r\n }\r\n\r\n // Fall through to relay if available\r\n if (!hasRelay || !config.relay) {\r\n output({ \r\n status: 'failed',\r\n peer: peerRef,\r\n type: messageType,\r\n transport: 'http',\r\n httpStatus: result.status,\r\n error: result.error\r\n }, options.pretty || false);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n // Use relay transport (relay-only mode, or HTTP failed with relay available, or no URL)\r\n if (hasRelay && config.relay) {\r\n // Extract URL from relay (string or object)\r\n const relayUrl = typeof config.relay === 'string' ? config.relay : config.relay.url;\r\n const relayConfig = {\r\n identity: config.identity,\r\n relayUrl,\r\n };\r\n\r\n const result = await sendViaRelay(\r\n relayConfig,\r\n peer.publicKey,\r\n messageType,\r\n messagePayload\r\n );\r\n\r\n if (result.ok) {\r\n output({ \r\n status: 'sent',\r\n peer: peerRef,\r\n type: messageType,\r\n transport: 'relay'\r\n }, options.pretty || false);\r\n } else {\r\n output({ \r\n status: 'failed',\r\n peer: peerRef,\r\n type: messageType,\r\n transport: 'relay',\r\n error: result.error\r\n }, options.pretty || false);\r\n process.exit(1);\r\n }\r\n } else if (!shouldTryHttp) {\r\n // Neither HTTP nor relay available\r\n console.error(`Error: Peer '${peerRef}' unreachable. No HTTP endpoint and no relay configured.`);\r\n process.exit(1);\r\n }\r\n } catch (e) {\r\n console.error('Error sending message:', e instanceof Error ? e.message : String(e));\r\n process.exit(1);\r\n }\r\n}\r\n\r\n/**\r\n * Handle the `agora decode` command.\r\n */\r\nfunction handleDecode(args: string[], options: CliOptions): void {\r\n if (args.length < 1) {\r\n console.error('Error: Missing message. Usage: agora decode <message>');\r\n process.exit(1);\r\n }\r\n\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n const peers = new Map<string, PeerConfig>();\r\n for (const [, val] of Object.entries(config.peers)) {\r\n // Only add peers with HTTP config to the map for decoding\r\n if (val.url && val.token) {\r\n peers.set(val.publicKey, {\r\n url: val.url,\r\n token: val.token,\r\n publicKey: val.publicKey,\r\n });\r\n }\r\n }\r\n\r\n const message = args.join(' ');\r\n const result = decodeInboundEnvelope(message, peers);\r\n\r\n if (result.ok) {\r\n output({\r\n status: 'verified',\r\n from: result.envelope.from,\r\n to: result.envelope.to,\r\n type: result.envelope.type,\r\n payload: compactPayloadTextReferences(result.envelope.payload, config.peers),\r\n id: result.envelope.id,\r\n timestamp: result.envelope.timestamp,\r\n inReplyTo: result.envelope.inReplyTo || null,\r\n }, options.pretty || false);\r\n } else {\r\n output({\r\n status: 'failed',\r\n reason: result.reason,\r\n }, options.pretty || false);\r\n process.exit(1);\r\n }\r\n}\r\n\r\n/**\r\n * Handle the `agora status` command.\r\n */\r\nfunction handleStatus(options: CliOptions): void {\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n const peerCount = Object.keys(config.peers).length;\r\n\r\n output({\r\n identity: config.identity.publicKey,\r\n configPath,\r\n relay: config.relay || 'not configured',\r\n peerCount,\r\n peers: Object.keys(config.peers),\r\n }, options.pretty || false);\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Profile & config transfer commands\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Handle the `agora config profiles` command.\r\n */\r\nfunction handleConfigProfiles(options: CliOptions): void {\r\n const profiles = listProfiles();\r\n if (profiles.length === 0) {\r\n output({ profiles: [], message: 'No profiles found. Run `agora init` first.' }, options.pretty || false);\r\n return;\r\n }\r\n output({ profiles }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora config export` command.\r\n */\r\nfunction handleConfigExport(options: CliOptions & { 'include-identity'?: boolean; output?: string }): void {\r\n const configPath = getConfigPath(options);\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadAgoraConfig(configPath);\r\n const exported = exportConfig(config, { includeIdentity: options['include-identity'] });\r\n\r\n if (options.output) {\r\n const outPath = resolve(options.output);\r\n const dir = dirname(outPath);\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true });\r\n }\r\n writeFileSync(outPath, JSON.stringify(exported, null, 2) + '\\n', 'utf-8');\r\n output({ status: 'exported', path: outPath, peerCount: Object.keys(exported.peers).length, includesIdentity: !!exported.identity }, options.pretty || false);\r\n } else {\r\n // Write to stdout for piping\r\n console.log(JSON.stringify(exported, null, 2));\r\n }\r\n}\r\n\r\n/**\r\n * Handle the `agora config import` command.\r\n */\r\nfunction handleConfigImport(\r\n args: string[],\r\n options: CliOptions & { 'overwrite-identity'?: boolean; 'overwrite-relay'?: boolean; 'dry-run'?: boolean },\r\n): void {\r\n if (args.length < 1) {\r\n console.error('Error: Missing import file. Usage: agora config import <file> [--overwrite-identity] [--overwrite-relay] [--dry-run]');\r\n process.exit(1);\r\n }\r\n\r\n const importPath = resolve(args[0]);\r\n if (!existsSync(importPath)) {\r\n console.error(`Error: Import file not found: ${importPath}`);\r\n process.exit(1);\r\n }\r\n\r\n let incoming: ExportedConfig;\r\n try {\r\n incoming = JSON.parse(readFileSync(importPath, 'utf-8')) as ExportedConfig;\r\n } catch {\r\n console.error(`Error: Invalid JSON in import file: ${importPath}`);\r\n process.exit(1);\r\n }\r\n\r\n if (incoming.version !== 1) {\r\n console.error(`Error: Unsupported export version: ${(incoming as unknown as Record<string, unknown>).version}. Expected version 1 (from 'agora config export').`);\r\n process.exit(1);\r\n }\r\n\r\n const configPath = getConfigPath(options);\r\n\r\n // When target doesn't exist, auto-apply identity/relay from the export file\r\n // (--overwrite-identity is only needed when the target already has an identity you want to replace)\r\n const isNewProfile = !existsSync(configPath);\r\n if (isNewProfile) {\r\n ensureConfigDir(configPath);\r\n initPeerConfig(configPath);\r\n }\r\n\r\n const config = loadAgoraConfig(configPath);\r\n const result = importConfig(config, incoming, {\r\n overwriteIdentity: options['overwrite-identity'] || isNewProfile,\r\n overwriteRelay: options['overwrite-relay'] || isNewProfile,\r\n });\r\n\r\n if (!options['dry-run']) {\r\n saveAgoraConfig(configPath, config);\r\n }\r\n\r\n output({\r\n status: options['dry-run'] ? 'dry-run' : 'imported',\r\n configPath,\r\n peersAdded: result.peersAdded.length,\r\n peersSkipped: result.peersSkipped.length,\r\n identityImported: result.identityImported,\r\n relayImported: result.relayImported,\r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora peers copy` command.\r\n * Copy a peer from one profile to another.\r\n */\r\nfunction handlePeersCopy(\r\n args: string[],\r\n options: CliOptions & { from?: string; to?: string },\r\n): void {\r\n if (args.length < 1) {\r\n console.error('Error: Missing peer name. Usage: agora peers copy <name> --from <profile> --to <profile>');\r\n console.error(' Profile names: \"default\" or a named profile. Omit for the current --profile / default.');\r\n process.exit(1);\r\n }\r\n\r\n const peerRef = args[0];\r\n const fromProfile = options.from;\r\n const toProfile = options.to;\r\n\r\n // Resolve source config\r\n const fromPath = fromProfile !== undefined\r\n ? getProfileConfigPath(fromProfile)\r\n : getConfigPath(options);\r\n\r\n if (!existsSync(fromPath)) {\r\n console.error(`Error: Source config not found: ${fromPath}`);\r\n process.exit(1);\r\n }\r\n\r\n // Resolve target config\r\n const toPath = toProfile !== undefined\r\n ? getProfileConfigPath(toProfile)\r\n : getConfigPath(options);\r\n\r\n if (fromPath === toPath) {\r\n console.error('Error: Source and target profiles are the same.');\r\n process.exit(1);\r\n }\r\n\r\n // Load source and resolve peer\r\n const sourceConfig = loadPeerConfig(fromPath);\r\n const resolved = resolvePeerEntry(sourceConfig.peers, peerRef);\r\n if (!resolved) {\r\n console.error(`Error: Peer '${peerRef}' not found in source config (${fromPath}).`);\r\n process.exit(1);\r\n }\r\n\r\n // Ensure target exists\r\n if (!existsSync(toPath)) {\r\n ensureConfigDir(toPath);\r\n initPeerConfig(toPath);\r\n }\r\n\r\n const targetConfig = loadPeerConfig(toPath);\r\n\r\n // Copy peer (overwrite if already present)\r\n targetConfig.peers[resolved.key] = { ...resolved.peer };\r\n savePeerConfig(toPath, targetConfig);\r\n\r\n output({\r\n status: 'copied',\r\n peer: resolved.peer.name || resolved.key,\r\n publicKey: resolved.peer.publicKey,\r\n from: fromPath,\r\n to: toPath,\r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora announce` command.\r\n * Disabled to enforce strict peer-to-peer semantics.\r\n */\r\nasync function handleAnnounce(options: CliOptions & { name?: string; version?: string }): Promise<void> {\r\n void options;\r\n console.error('Error: `agora announce` is disabled. Agora now supports strict peer-to-peer only (no all/broadcast).');\r\n console.error('Use: agora send <peer> --type announce --payload <json>');\r\n process.exit(1);\r\n}\r\n\r\n/**\r\n * Handle the `agora diagnose` command.\r\n * Run diagnostic checks on a peer (ping, workspace, tools).\r\n */\r\nasync function handleDiagnose(args: string[], options: CliOptions & { checks?: string }): Promise<void> {\r\n if (args.length < 1) {\r\n console.error('Error: Missing peer name. Usage: agora diagnose <name> [--checks <comma-separated-list>]');\r\n process.exit(1);\r\n }\r\n\r\n const peerRef = args[0];\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n\r\n const resolved = resolvePeerEntry(config.peers, peerRef);\r\n if (!resolved) {\r\n console.error(`Error: Peer '${peerRef}' not found.`);\r\n process.exit(1);\r\n }\r\n\r\n const peer = resolved.peer;\r\n\r\n if (!peer.url) {\r\n console.error(`Error: Peer '${peerRef}' has no URL configured. Cannot diagnose.`);\r\n process.exit(1);\r\n }\r\n\r\n // Parse checks parameter\r\n const checksParam = options.checks || 'ping';\r\n const requestedChecks = checksParam.split(',').map(c => c.trim());\r\n \r\n // Validate check types\r\n const validChecks = ['ping', 'workspace', 'tools'];\r\n for (const check of requestedChecks) {\r\n if (!validChecks.includes(check)) {\r\n console.error(`Error: Invalid check type '${check}'. Valid checks: ${validChecks.join(', ')}`);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n // Result structure\r\n interface CheckResult {\r\n ok: boolean;\r\n latency_ms?: number;\r\n error?: string;\r\n implemented?: boolean;\r\n [key: string]: unknown;\r\n }\r\n \r\n const result: {\r\n peer: string;\r\n status: string;\r\n checks: Record<string, CheckResult>;\r\n timestamp: string;\r\n } = {\r\n peer: peerRef,\r\n status: 'unknown',\r\n checks: {},\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n // Run ping check\r\n if (requestedChecks.includes('ping')) {\r\n const startTime = Date.now();\r\n try {\r\n // Add timeout to prevent hanging on unreachable peers\r\n const controller = new AbortController();\r\n const timeout = setTimeout(() => controller.abort(), 10000);\r\n \r\n const response = await fetch(peer.url, {\r\n method: 'GET',\r\n headers: peer.token ? { 'Authorization': `Bearer ${peer.token}` } : {},\r\n signal: controller.signal,\r\n });\r\n \r\n clearTimeout(timeout);\r\n const latency = Date.now() - startTime;\r\n \r\n if (response.ok || response.status === 404 || response.status === 405) {\r\n // 404 or 405 means the endpoint exists but GET isn't supported - that's OK for a ping\r\n result.checks.ping = { ok: true, latency_ms: latency };\r\n } else {\r\n result.checks.ping = { ok: false, latency_ms: latency, error: `HTTP ${response.status}` };\r\n }\r\n } catch (err) {\r\n const latency = Date.now() - startTime;\r\n result.checks.ping = { \r\n ok: false, \r\n latency_ms: latency,\r\n error: err instanceof Error ? err.message : String(err) \r\n };\r\n }\r\n }\r\n\r\n // Run workspace check\r\n if (requestedChecks.includes('workspace')) {\r\n // This is a placeholder - actual implementation would depend on peer's diagnostic protocol\r\n result.checks.workspace = { \r\n ok: false,\r\n implemented: false,\r\n error: 'Workspace check requires peer diagnostic protocol support' \r\n };\r\n }\r\n\r\n // Run tools check\r\n if (requestedChecks.includes('tools')) {\r\n // This is a placeholder - actual implementation would depend on peer's diagnostic protocol\r\n result.checks.tools = { \r\n ok: false,\r\n implemented: false,\r\n error: 'Tools check requires peer diagnostic protocol support' \r\n };\r\n }\r\n\r\n // Determine overall status - only consider implemented checks\r\n const implementedChecks = Object.values(result.checks).filter(\r\n check => check.implemented !== false\r\n );\r\n \r\n if (implementedChecks.length === 0) {\r\n result.status = 'unknown';\r\n } else {\r\n const allOk = implementedChecks.every(check => check.ok);\r\n const anyOk = implementedChecks.some(check => check.ok);\r\n result.status = allOk ? 'healthy' : anyOk ? 'degraded' : 'unhealthy';\r\n }\r\n\r\n output(result, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora serve` command.\r\n * Starts a persistent WebSocket server for incoming peer connections.\r\n */\r\nasync function handleServe(options: CliOptions & { port?: string; name?: string }): Promise<void> {\r\n const configPath = getConfigPath(options);\r\n\r\n if (!existsSync(configPath)) {\r\n console.error('Error: Config file not found. Run `agora init` first.');\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n const port = parseInt(options.port || '9473', 10);\r\n \r\n // Validate port\r\n if (isNaN(port) || port < 1 || port > 65535) {\r\n console.error(`Error: Invalid port number '${options.port}'. Port must be between 1 and 65535.`);\r\n process.exit(1);\r\n }\r\n \r\n // Resolve server name using priority: CLI --name, config.relay.name, config.identity.name, default\r\n const serverName = resolveBroadcastName(config, options.name) || 'agora-server';\r\n\r\n // Create announce payload\r\n const announcePayload: AnnouncePayload = {\r\n capabilities: [],\r\n metadata: {\r\n name: serverName,\r\n version: '0.1.0',\r\n },\r\n };\r\n\r\n // Create and configure PeerServer\r\n const server = new PeerServer(config.identity, announcePayload);\r\n\r\n // Setup event listeners\r\n server.on('peer-connected', (publicKey, peer) => {\r\n const peerName = peer.metadata?.name || publicKey.substring(0, 16);\r\n console.log(`[${new Date().toISOString()}] Peer connected: ${peerName} (${publicKey})`);\r\n });\r\n\r\n server.on('peer-disconnected', (publicKey) => {\r\n console.log(`[${new Date().toISOString()}] Peer disconnected: ${publicKey}`);\r\n });\r\n\r\n server.on('message-received', (envelope, fromPublicKey) => {\r\n console.log(`[${new Date().toISOString()}] Message from ${fromPublicKey}:`);\r\n console.log(JSON.stringify({\r\n id: envelope.id,\r\n type: envelope.type,\r\n from: envelope.from,\r\n to: envelope.to,\r\n timestamp: envelope.timestamp,\r\n payload: envelope.payload,\r\n }, null, 2));\r\n });\r\n\r\n server.on('error', (error) => {\r\n console.error(`[${new Date().toISOString()}] Error:`, error.message);\r\n });\r\n\r\n // Start the server\r\n try {\r\n await server.start(port);\r\n console.log(`[${new Date().toISOString()}] Agora server started`);\r\n console.log(` Name: ${serverName}`);\r\n console.log(` Public Key: ${config.identity.publicKey}`);\r\n console.log(` WebSocket Port: ${port}`);\r\n console.log(` Listening for peer connections...`);\r\n console.log('');\r\n console.log('Press Ctrl+C to stop the server');\r\n\r\n // Keep the process alive\r\n process.on('SIGINT', async () => {\r\n console.log(`\\n[${new Date().toISOString()}] Shutting down server...`);\r\n await server.stop();\r\n console.log('Server stopped');\r\n process.exit(0);\r\n });\r\n\r\n process.on('SIGTERM', async () => {\r\n console.log(`\\n[${new Date().toISOString()}] Shutting down server...`);\r\n await server.stop();\r\n console.log('Server stopped');\r\n process.exit(0);\r\n });\r\n } catch (error) {\r\n console.error('Failed to start server:', error instanceof Error ? error.message : String(error));\r\n process.exit(1);\r\n }\r\n}\r\n\r\n/**\r\n * Handle the `agora relay` command.\r\n * Starts a WebSocket relay server for routing messages between agents.\r\n */\r\nasync function handleRelay(options: CliOptions & { port?: string }): Promise<void> {\r\n const port = parseInt(options.port || '9474', 10);\r\n \r\n // Validate port\r\n if (isNaN(port) || port < 1 || port > 65535) {\r\n console.error(`Error: Invalid port number '${options.port}'. Port must be between 1 and 65535.`);\r\n process.exit(1);\r\n }\r\n\r\n // Create and configure RelayServer\r\n const server = new RelayServer();\r\n\r\n // Setup event listeners\r\n server.on('agent-registered', (publicKey) => {\r\n console.log(`[${new Date().toISOString()}] Agent registered: ${publicKey}`);\r\n });\r\n\r\n server.on('agent-disconnected', (publicKey) => {\r\n console.log(`[${new Date().toISOString()}] Agent disconnected: ${publicKey}`);\r\n });\r\n\r\n server.on('message-relayed', (from, to, envelope) => {\r\n console.log(`[${new Date().toISOString()}] Message relayed: ${from.substring(0, 16)}... → ${to.substring(0, 16)}... (type: ${envelope.type})`);\r\n });\r\n\r\n server.on('error', (error) => {\r\n console.error(`[${new Date().toISOString()}] Error:`, error.message);\r\n });\r\n\r\n // Start the server\r\n try {\r\n await server.start(port);\r\n console.log(`[${new Date().toISOString()}] Agora relay server started`);\r\n console.log(` WebSocket Port: ${port}`);\r\n console.log(` Connected agents: 0`);\r\n console.log(` Listening for agent connections...`);\r\n console.log('');\r\n console.log('Press Ctrl+C to stop the relay');\r\n\r\n // Shared shutdown handler\r\n const shutdown = async (): Promise<void> => {\r\n console.log(`\\n[${new Date().toISOString()}] Shutting down relay...`);\r\n await server.stop();\r\n console.log('Relay stopped');\r\n process.exit(0);\r\n };\r\n\r\n // Keep the process alive\r\n process.on('SIGINT', shutdown);\r\n process.on('SIGTERM', shutdown);\r\n } catch (error) {\r\n console.error('Failed to start relay:', error instanceof Error ? error.message : String(error));\r\n process.exit(1);\r\n }\r\n}\r\n\r\n/**\r\n * Get the reputation store file path.\r\n */\r\nfunction getReputationStorePath(): string {\r\n return resolve(homedir(), '.local', 'share', 'agora', 'reputation.jsonl');\r\n}\r\n\r\n/**\r\n * Handle the `agora reputation verify` command.\r\n * Creates a verification record for another agent's output.\r\n */\r\nasync function handleReputationVerify(\r\n args: string[],\r\n options: CliOptions & {\r\n target?: string;\r\n domain?: string;\r\n verdict?: string;\r\n confidence?: string;\r\n evidence?: string;\r\n }\r\n): Promise<void> {\r\n if (!options.target || !options.domain || !options.verdict) {\r\n console.error('Error: Missing required options');\r\n console.error('Usage: agora reputation verify --target <id> --domain <domain> --verdict <correct|incorrect|disputed> --confidence <0-1> [--evidence <url>]');\r\n process.exit(1);\r\n }\r\n\r\n // Validate verdict\r\n if (!['correct', 'incorrect', 'disputed'].includes(options.verdict)) {\r\n console.error('Error: verdict must be one of: correct, incorrect, disputed');\r\n process.exit(1);\r\n }\r\n\r\n // Parse confidence\r\n const confidence = options.confidence ? parseFloat(options.confidence) : 1.0;\r\n if (isNaN(confidence) || confidence < 0 || confidence > 1) {\r\n console.error('Error: confidence must be a number between 0 and 1');\r\n process.exit(1);\r\n }\r\n\r\n // Load config\r\n const configPath = getConfigPath(options);\r\n if (!existsSync(configPath)) {\r\n console.error(`Error: Config file not found at ${configPath}. Run 'agora init' first.`);\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n\r\n // Create verification\r\n const verification = createVerification(\r\n config.identity.publicKey,\r\n config.identity.privateKey,\r\n options.target,\r\n options.domain,\r\n options.verdict as 'correct' | 'incorrect' | 'disputed',\r\n confidence,\r\n Date.now(),\r\n options.evidence\r\n );\r\n\r\n // Save to reputation store\r\n const storePath = getReputationStorePath();\r\n const store = new ReputationStore(storePath);\r\n await store.addVerification(verification);\r\n\r\n output({\r\n status: 'verification_created',\r\n id: verification.id,\r\n verifier: verification.verifier,\r\n target: verification.target,\r\n domain: verification.domain,\r\n verdict: verification.verdict,\r\n confidence: verification.confidence,\r\n timestamp: verification.timestamp,\r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora reputation commit` command.\r\n * Creates a commitment to a prediction before outcome is known.\r\n */\r\nasync function handleReputationCommit(\r\n args: string[],\r\n options: CliOptions & {\r\n domain?: string;\r\n prediction?: string;\r\n expiry?: string;\r\n }\r\n): Promise<void> {\r\n if (!options.domain || !options.prediction) {\r\n console.error('Error: Missing required options');\r\n console.error('Usage: agora reputation commit --domain <domain> --prediction <text> [--expiry <milliseconds>]');\r\n console.error('Example: agora reputation commit --domain weather_forecast --prediction \"It will rain tomorrow\" --expiry 86400000');\r\n process.exit(1);\r\n }\r\n\r\n // Parse expiry (default 24 hours)\r\n const expiryMs = options.expiry ? parseInt(options.expiry, 10) : 86400000;\r\n if (isNaN(expiryMs) || expiryMs <= 0) {\r\n console.error('Error: expiry must be a positive number (milliseconds)');\r\n process.exit(1);\r\n }\r\n\r\n // Load config\r\n const configPath = getConfigPath(options);\r\n if (!existsSync(configPath)) {\r\n console.error(`Error: Config file not found at ${configPath}. Run 'agora init' first.`);\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n\r\n // Create commit\r\n const commit = createCommit(\r\n config.identity.publicKey,\r\n config.identity.privateKey,\r\n options.domain,\r\n options.prediction,\r\n Date.now(),\r\n expiryMs\r\n );\r\n\r\n // Save to reputation store\r\n const storePath = getReputationStorePath();\r\n const store = new ReputationStore(storePath);\r\n await store.addCommit(commit);\r\n\r\n output({\r\n status: 'commitment_created',\r\n id: commit.id,\r\n agent: commit.agent,\r\n domain: commit.domain,\r\n commitment: commit.commitment,\r\n timestamp: commit.timestamp,\r\n expiry: commit.expiry,\r\n note: 'Store this ID to reveal the prediction after expiry',\r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora reputation reveal` command.\r\n * Reveals a prediction and outcome after commitment expiry.\r\n */\r\nasync function handleReputationReveal(\r\n args: string[],\r\n options: CliOptions & {\r\n 'commit-id'?: string;\r\n prediction?: string;\r\n outcome?: string;\r\n evidence?: string;\r\n }\r\n): Promise<void> {\r\n if (!options['commit-id'] || !options.prediction || !options.outcome) {\r\n console.error('Error: Missing required options');\r\n console.error('Usage: agora reputation reveal --commit-id <id> --prediction <text> --outcome <text> [--evidence <url>]');\r\n process.exit(1);\r\n }\r\n\r\n // Load config\r\n const configPath = getConfigPath(options);\r\n if (!existsSync(configPath)) {\r\n console.error(`Error: Config file not found at ${configPath}. Run 'agora init' first.`);\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n\r\n // Load commit from store\r\n const storePath = getReputationStorePath();\r\n const store = new ReputationStore(storePath);\r\n const commit = await store.getCommit(options['commit-id']);\r\n\r\n if (!commit) {\r\n console.error(`Error: Commitment ${options['commit-id']} not found in local store`);\r\n process.exit(1);\r\n }\r\n\r\n // Create reveal\r\n const reveal = createReveal(\r\n config.identity.publicKey,\r\n config.identity.privateKey,\r\n options['commit-id'],\r\n options.prediction,\r\n options.outcome,\r\n Date.now(),\r\n options.evidence\r\n );\r\n \r\n // Verify the reveal against the commit\r\n const verification = verifyReveal(commit, reveal);\r\n if (!verification.valid) {\r\n console.error(`Error: Reveal verification failed: ${verification.reason}`);\r\n process.exit(1);\r\n }\r\n\r\n // Save to reputation store\r\n await store.addReveal(reveal);\r\n\r\n output({\r\n status: 'prediction_revealed',\r\n id: reveal.id,\r\n agent: reveal.agent,\r\n commitmentId: reveal.commitmentId,\r\n prediction: reveal.prediction,\r\n outcome: reveal.outcome,\r\n timestamp: reveal.timestamp,\r\n verified: true,\r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Handle the `agora reputation query` command.\r\n * Queries reputation score for an agent in a domain.\r\n */\r\nasync function handleReputationQuery(\r\n args: string[],\r\n options: CliOptions & {\r\n agent?: string;\r\n domain?: string;\r\n }\r\n): Promise<void> {\r\n if (!options.domain) {\r\n console.error('Error: Missing required option: --domain');\r\n console.error('Usage: agora reputation query --domain <domain> [--agent <pubkey>]');\r\n console.error('If --agent is omitted, shows reputation for current agent');\r\n process.exit(1);\r\n }\r\n\r\n // Load config\r\n const configPath = getConfigPath(options);\r\n if (!existsSync(configPath)) {\r\n console.error(`Error: Config file not found at ${configPath}. Run 'agora init' first.`);\r\n process.exit(1);\r\n }\r\n\r\n const config = loadPeerConfig(configPath);\r\n const agent = options.agent || config.identity.publicKey;\r\n\r\n // Load reputation store\r\n const storePath = getReputationStorePath();\r\n const store = new ReputationStore(storePath);\r\n const verifications = await store.getVerificationsByDomain(options.domain);\r\n\r\n // Filter verifications for this agent\r\n const agentVerifications = verifications.filter(v => v.target === agent);\r\n\r\n // Compute trust score\r\n const score = computeTrustScore(agent, options.domain, agentVerifications, Date.now());\r\n\r\n output({\r\n agent: score.agent,\r\n domain: score.domain,\r\n score: score.score,\r\n verificationCount: score.verificationCount,\r\n lastVerified: score.lastVerified,\r\n lastVerifiedDate: score.lastVerified > 0 ? new Date(score.lastVerified).toISOString() : 'never',\r\n topVerifiers: score.topVerifiers,\r\n }, options.pretty || false);\r\n}\r\n\r\n/**\r\n * Parse CLI arguments and route to appropriate handler.\r\n */\r\nasync function main(): Promise<void> {\r\n const args = process.argv.slice(2);\r\n\r\n if (args.length === 0) {\r\n console.error('Usage: agora <command> [options]');\r\n console.error('Commands: init, whoami, status, peers, config, send, decode, serve, diagnose, relay, reputation');\r\n console.error('Global: --profile <name> (or --as <name>) to select a named profile');\r\n console.error(' peers subcommands: add, list, remove, discover, copy');\r\n console.error(' config subcommands: profiles, export, import');\r\n console.error(' reputation subcommands: verify, commit, reveal, query');\r\n process.exit(1);\r\n }\r\n\r\n // Parse global options\r\n const parsed = parseArgs({\r\n args,\r\n options: {\r\n config: { type: 'string' },\r\n profile: { type: 'string' },\r\n as: { type: 'string' },\r\n pretty: { type: 'boolean' },\r\n // Config transfer options\r\n 'include-identity': { type: 'boolean' },\r\n 'overwrite-identity': { type: 'boolean' },\r\n 'overwrite-relay': { type: 'boolean' },\r\n 'dry-run': { type: 'boolean' },\r\n output: { type: 'string' },\r\n from: { type: 'string' },\r\n to: { type: 'string' },\r\n url: { type: 'string' },\r\n token: { type: 'string' },\r\n pubkey: { type: 'string' },\r\n type: { type: 'string' },\r\n payload: { type: 'string' },\r\n name: { type: 'string' },\r\n version: { type: 'string' },\r\n port: { type: 'string' },\r\n checks: { type: 'string' },\r\n relay: { type: 'string' },\r\n 'relay-pubkey': { type: 'string' },\r\n limit: { type: 'string' },\r\n 'active-within': { type: 'string' },\r\n save: { type: 'boolean' },\r\n // Reputation options\r\n target: { type: 'string' },\r\n domain: { type: 'string' },\r\n verdict: { type: 'string' },\r\n confidence: { type: 'string' },\r\n evidence: { type: 'string' },\r\n prediction: { type: 'string' },\r\n expiry: { type: 'string' },\r\n 'commit-id': { type: 'string' },\r\n outcome: { type: 'string' },\r\n agent: { type: 'string' },\r\n direct: { type: 'boolean' },\r\n 'relay-only': { type: 'boolean' },\r\n },\r\n strict: false,\r\n allowPositionals: true,\r\n });\r\n\r\n // Warn about unrecognised flags (catches typos like --owerwrite-identity)\r\n const knownFlags = new Set([\r\n 'config', 'profile', 'as', 'pretty',\r\n 'include-identity', 'overwrite-identity', 'overwrite-relay', 'dry-run',\r\n 'output', 'from', 'to',\r\n 'url', 'token', 'pubkey', 'type', 'payload', 'name', 'version',\r\n 'port', 'checks', 'relay', 'relay-pubkey', 'limit', 'active-within', 'save',\r\n 'target', 'domain', 'verdict', 'confidence', 'evidence', 'prediction',\r\n 'expiry', 'commit-id', 'outcome', 'agent', 'direct', 'relay-only',\r\n ]);\r\n for (const key of Object.keys(parsed.values)) {\r\n if (!knownFlags.has(key)) {\r\n const suggestion = didYouMean(key, knownFlags);\r\n const msg = suggestion\r\n ? `Warning: Unknown flag --${key}. Did you mean --${suggestion}?`\r\n : `Warning: Unknown flag --${key} (ignored).`;\r\n console.error(msg);\r\n }\r\n }\r\n\r\n const command = parsed.positionals[0];\r\n const subcommand = parsed.positionals[1];\r\n const remainingArgs = parsed.positionals.slice(2);\r\n\r\n // --as is an alias for --profile\r\n const profileValue = typeof parsed.values.profile === 'string'\r\n ? parsed.values.profile\r\n : typeof parsed.values.as === 'string'\r\n ? parsed.values.as\r\n : undefined;\r\n\r\n const options: CliOptions & { \r\n type?: string; \r\n payload?: string; \r\n url?: string; \r\n token?: string; \r\n pubkey?: string; \r\n name?: string; \r\n version?: string; \r\n port?: string; \r\n checks?: string;\r\n relay?: string;\r\n 'relay-pubkey'?: string;\r\n limit?: string;\r\n 'active-within'?: string;\r\n save?: boolean;\r\n // Config transfer options\r\n 'include-identity'?: boolean;\r\n 'overwrite-identity'?: boolean;\r\n 'overwrite-relay'?: boolean;\r\n 'dry-run'?: boolean;\r\n output?: string;\r\n from?: string;\r\n to?: string;\r\n // Reputation options\r\n target?: string;\r\n domain?: string;\r\n verdict?: string;\r\n confidence?: string;\r\n evidence?: string;\r\n prediction?: string;\r\n outcome?: string;\r\n expiry?: string;\r\n 'commit-id'?: string;\r\n agent?: string;\r\n direct?: boolean;\r\n 'relay-only'?: boolean;\r\n } = {\r\n config: typeof parsed.values.config === 'string' ? parsed.values.config : undefined,\r\n profile: profileValue,\r\n pretty: typeof parsed.values.pretty === 'boolean' ? parsed.values.pretty : undefined,\r\n type: typeof parsed.values.type === 'string' ? parsed.values.type : undefined,\r\n payload: typeof parsed.values.payload === 'string' ? parsed.values.payload : undefined,\r\n url: typeof parsed.values.url === 'string' ? parsed.values.url : undefined,\r\n token: typeof parsed.values.token === 'string' ? parsed.values.token : undefined,\r\n pubkey: typeof parsed.values.pubkey === 'string' ? parsed.values.pubkey : undefined,\r\n name: typeof parsed.values.name === 'string' ? parsed.values.name : undefined,\r\n version: typeof parsed.values.version === 'string' ? parsed.values.version : undefined,\r\n port: typeof parsed.values.port === 'string' ? parsed.values.port : undefined,\r\n checks: typeof parsed.values.checks === 'string' ? parsed.values.checks : undefined,\r\n relay: typeof parsed.values.relay === 'string' ? parsed.values.relay : undefined,\r\n 'relay-pubkey': typeof parsed.values['relay-pubkey'] === 'string' ? parsed.values['relay-pubkey'] : undefined,\r\n limit: typeof parsed.values.limit === 'string' ? parsed.values.limit : undefined,\r\n 'active-within': typeof parsed.values['active-within'] === 'string' ? parsed.values['active-within'] : undefined,\r\n save: typeof parsed.values.save === 'boolean' ? parsed.values.save : undefined,\r\n // Reputation options\r\n target: typeof parsed.values.target === 'string' ? parsed.values.target : undefined,\r\n domain: typeof parsed.values.domain === 'string' ? parsed.values.domain : undefined,\r\n verdict: typeof parsed.values.verdict === 'string' ? parsed.values.verdict : undefined,\r\n confidence: typeof parsed.values.confidence === 'string' ? parsed.values.confidence : undefined,\r\n evidence: typeof parsed.values.evidence === 'string' ? parsed.values.evidence : undefined,\r\n prediction: typeof parsed.values.prediction === 'string' ? parsed.values.prediction : undefined,\r\n expiry: typeof parsed.values.expiry === 'string' ? parsed.values.expiry : undefined,\r\n 'commit-id': typeof parsed.values['commit-id'] === 'string' ? parsed.values['commit-id'] : undefined,\r\n outcome: typeof parsed.values.outcome === 'string' ? parsed.values.outcome : undefined,\r\n agent: typeof parsed.values.agent === 'string' ? parsed.values.agent : undefined,\r\n direct: typeof parsed.values.direct === 'boolean' ? parsed.values.direct : undefined,\r\n 'relay-only': typeof parsed.values['relay-only'] === 'boolean' ? parsed.values['relay-only'] : undefined,\r\n 'include-identity': typeof parsed.values['include-identity'] === 'boolean' ? parsed.values['include-identity'] : undefined,\r\n 'overwrite-identity': typeof parsed.values['overwrite-identity'] === 'boolean' ? parsed.values['overwrite-identity'] : undefined,\r\n 'overwrite-relay': typeof parsed.values['overwrite-relay'] === 'boolean' ? parsed.values['overwrite-relay'] : undefined,\r\n 'dry-run': typeof parsed.values['dry-run'] === 'boolean' ? parsed.values['dry-run'] : undefined,\r\n output: typeof parsed.values.output === 'string' ? parsed.values.output : undefined,\r\n from: typeof parsed.values.from === 'string' ? parsed.values.from : undefined,\r\n to: typeof parsed.values.to === 'string' ? parsed.values.to : undefined,\r\n };\r\n\r\n try {\r\n switch (command) {\r\n case 'init':\r\n handleInit(options);\r\n break;\r\n case 'whoami':\r\n handleWhoami(options);\r\n break;\r\n case 'status':\r\n handleStatus(options);\r\n break;\r\n case 'announce':\r\n await handleAnnounce(options);\r\n break;\r\n case 'diagnose':\r\n await handleDiagnose([subcommand, ...remainingArgs].filter(Boolean), options);\r\n break;\r\n case 'peers':\r\n switch (subcommand) {\r\n case 'add':\r\n handlePeersAdd(remainingArgs, options);\r\n break;\r\n case 'list':\r\n case undefined:\r\n // Allow 'agora peers' to work like 'agora peers list'\r\n handlePeersList(options);\r\n break;\r\n case 'remove':\r\n handlePeersRemove(remainingArgs, options);\r\n break;\r\n case 'discover':\r\n await handlePeersDiscover(options);\r\n break;\r\n case 'copy':\r\n handlePeersCopy(remainingArgs, options);\r\n break;\r\n default:\r\n console.error('Error: Unknown peers subcommand. Use: add, list, remove, discover, copy');\r\n process.exit(1);\r\n }\r\n break;\r\n case 'send':\r\n await handleSend([subcommand, ...remainingArgs], options);\r\n break;\r\n case 'decode':\r\n handleDecode([subcommand, ...remainingArgs].filter(Boolean), options);\r\n break;\r\n case 'serve':\r\n await handleServe(options);\r\n break;\r\n case 'relay':\r\n await handleRelay(options);\r\n break;\r\n case 'config':\r\n switch (subcommand) {\r\n case 'profiles':\r\n handleConfigProfiles(options);\r\n break;\r\n case 'export':\r\n handleConfigExport(options);\r\n break;\r\n case 'import':\r\n handleConfigImport(remainingArgs, options);\r\n break;\r\n default:\r\n console.error('Error: Unknown config subcommand. Use: profiles, export, import');\r\n process.exit(1);\r\n }\r\n break;\r\n case 'reputation':\r\n switch (subcommand) {\r\n case 'verify':\r\n await handleReputationVerify(remainingArgs, options);\r\n break;\r\n case 'commit':\r\n await handleReputationCommit(remainingArgs, options);\r\n break;\r\n case 'reveal':\r\n await handleReputationReveal(remainingArgs, options);\r\n break;\r\n case 'query':\r\n await handleReputationQuery(remainingArgs, options);\r\n break;\r\n default:\r\n console.error('Error: Unknown reputation subcommand. Use: verify, commit, reveal, query');\r\n process.exit(1);\r\n }\r\n break;\r\n default:\r\n console.error(`Error: Unknown command '${command}'. Use: init, whoami, status, peers, config, send, decode, serve, diagnose, relay, reputation`);\r\n process.exit(1);\r\n }\r\n } catch (e) {\r\n console.error('Error:', e instanceof Error ? e.message : String(e));\r\n process.exit(1);\r\n }\r\n}\r\n\r\nmain().catch((e) => {\r\n console.error('Fatal error:', e instanceof Error ? e.message : String(e));\r\n process.exit(1);\r\n});\r\n","import { EventEmitter } from 'node:events';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport type { KeyPair } from '../identity/keypair';\nimport type { Envelope } from '../message/envelope';\nimport { createEnvelope, verifyEnvelope } from '../message/envelope';\nimport type { AnnouncePayload } from '../registry/messages';\n\n/**\n * Represents a connected peer\n */\nexport interface ConnectedPeer {\n /** Peer's public key */\n publicKey: string;\n /** WebSocket connection */\n socket: WebSocket;\n /** Whether the peer has been announced */\n announced: boolean;\n /** Peer metadata from announce message */\n metadata?: {\n name?: string;\n version?: string;\n };\n}\n\n/**\n * Events emitted by PeerServer\n */\nexport interface PeerServerEvents {\n 'peer-connected': (publicKey: string, peer: ConnectedPeer) => void;\n 'peer-disconnected': (publicKey: string) => void;\n 'message-received': (envelope: Envelope, fromPublicKey: string) => void;\n 'error': (error: Error) => void;\n}\n\n/**\n * WebSocket server for accepting peer connections\n */\nexport class PeerServer extends EventEmitter {\n private wss: WebSocketServer | null = null;\n private peers = new Map<string, ConnectedPeer>();\n private identity: KeyPair;\n private announcePayload: AnnouncePayload;\n\n constructor(identity: KeyPair, announcePayload: AnnouncePayload) {\n super();\n this.identity = identity;\n this.announcePayload = announcePayload;\n }\n\n /**\n * Start the WebSocket server\n */\n start(port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.wss = new WebSocketServer({ port });\n\n this.wss.on('error', (error) => {\n this.emit('error', error);\n reject(error);\n });\n\n this.wss.on('listening', () => {\n resolve();\n });\n\n this.wss.on('connection', (socket: WebSocket) => {\n this.handleConnection(socket);\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Stop the WebSocket server\n */\n async stop(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.wss) {\n resolve();\n return;\n }\n\n // Close all peer connections\n for (const peer of this.peers.values()) {\n peer.socket.close();\n }\n this.peers.clear();\n\n this.wss.close((err) => {\n if (err) {\n reject(err);\n } else {\n this.wss = null;\n resolve();\n }\n });\n });\n }\n\n /**\n * Get all connected peers\n */\n getPeers(): Map<string, ConnectedPeer> {\n return new Map(this.peers);\n }\n\n /**\n * Send a message to a specific peer\n */\n send(publicKey: string, envelope: Envelope): boolean {\n const peer = this.peers.get(publicKey);\n if (!peer || peer.socket.readyState !== WebSocket.OPEN) {\n return false;\n }\n\n try {\n peer.socket.send(JSON.stringify(envelope));\n return true;\n } catch (error) {\n this.emit('error', error as Error);\n return false;\n }\n }\n\n /**\n * Handle incoming connection\n */\n private handleConnection(socket: WebSocket): void {\n let peerPublicKey: string | null = null;\n\n // Send announce message immediately\n const announceEnvelope = createEnvelope(\n 'announce',\n this.identity.publicKey,\n this.identity.privateKey,\n this.announcePayload,\n Date.now(),\n undefined,\n [this.identity.publicKey]\n );\n socket.send(JSON.stringify(announceEnvelope));\n\n socket.on('message', (data: Buffer) => {\n try {\n const envelope = JSON.parse(data.toString()) as Envelope;\n\n // Verify envelope signature\n const verification = verifyEnvelope(envelope);\n if (!verification.valid) {\n // Drop invalid messages\n return;\n }\n\n // First message should be an announce\n if (!peerPublicKey) {\n if (envelope.type === 'announce') {\n peerPublicKey = envelope.from;\n const payload = envelope.payload as AnnouncePayload;\n \n const peer: ConnectedPeer = {\n publicKey: peerPublicKey,\n socket,\n announced: true,\n metadata: payload.metadata,\n };\n\n this.peers.set(peerPublicKey, peer);\n this.emit('peer-connected', peerPublicKey, peer);\n }\n return;\n }\n\n // Verify the message is from the announced peer\n if (envelope.from !== peerPublicKey) {\n // Drop messages from wrong sender\n return;\n }\n\n // Emit message-received event\n this.emit('message-received', envelope, peerPublicKey);\n } catch {\n // Invalid JSON or other parsing errors - drop the message\n }\n });\n\n socket.on('close', () => {\n if (peerPublicKey) {\n this.peers.delete(peerPublicKey);\n this.emit('peer-disconnected', peerPublicKey);\n }\n });\n\n socket.on('error', (error) => {\n this.emit('error', error);\n });\n }\n}\n"],"mappings":"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","names":["resolve","config"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/peer/server.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { parseArgs } from 'node:util';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { loadPeerConfig, savePeerConfig, initPeerConfig } from './transport/peer-config';\nimport { sendToPeer, decodeInboundEnvelope, type PeerConfig } from './transport/http';\nimport { sendViaRelay } from './transport/relay';\nimport type { MessageType } from './message/envelope';\nimport type { AnnouncePayload } from './registry/messages';\nimport {\n getProfileConfigPath,\n listProfiles,\n loadAgoraConfig,\n exportConfig,\n importConfig,\n saveAgoraConfig,\n type ExportedConfig,\n} from './config';\nimport { PeerServer } from './peer/server';\nimport { RelayServer } from './relay/server';\nimport { RelayClient } from './relay/client';\nimport { PeerDiscoveryService } from './discovery/peer-discovery';\nimport { getDefaultBootstrapRelay } from './discovery/bootstrap';\nimport { compactInlineReferences, expand, expandInlineReferences, resolveBroadcastName } from './utils';\nimport { ReputationStore } from './reputation/store';\nimport { createVerification } from './reputation/verification';\nimport { createCommit, createReveal, verifyReveal } from './reputation/commit-reveal';\nimport { computeTrustScore } from './reputation/scoring';\n\ninterface CliOptions {\n config?: string;\n profile?: string;\n pretty?: boolean;\n}\n\ntype ConfigPeer = ReturnType<typeof loadPeerConfig>['peers'][string];\n\nfunction resolvePeerEntry(peers: Record<string, ConfigPeer>, identifier: string): { key: string; peer: ConfigPeer } | undefined {\n const expanded = expand(identifier, peers);\n if (expanded && peers[expanded]) {\n return { key: expanded, peer: peers[expanded] };\n }\n\n const direct = peers[identifier];\n if (direct) {\n return { key: identifier, peer: direct };\n }\n\n for (const [key, peer] of Object.entries(peers)) {\n if (peer.publicKey === identifier || peer.name === identifier) {\n return { key, peer };\n }\n }\n\n return undefined;\n}\n\nfunction compactPayloadTextReferences(payload: unknown, peers: Record<string, ConfigPeer>): unknown {\n if (!payload || typeof payload !== 'object') {\n return payload;\n }\n if ('text' in payload && typeof (payload as Record<string, unknown>).text === 'string') {\n return {\n ...(payload as Record<string, unknown>),\n text: compactInlineReferences((payload as { text: string }).text, peers),\n };\n }\n return payload;\n}\n\n/**\n * Suggest the closest known flag for a typo (Levenshtein distance ≤ 3).\n */\nfunction didYouMean(input: string, known: Set<string>): string | undefined {\n let best: string | undefined;\n let bestDist = 4; // threshold\n for (const candidate of known) {\n const d = levenshtein(input, candidate);\n if (d < bestDist) {\n bestDist = d;\n best = candidate;\n }\n }\n return best;\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length, n = b.length;\n const dp: number[] = Array.from({ length: n + 1 }, (_, i) => i);\n for (let i = 1; i <= m; i++) {\n let prev = dp[0];\n dp[0] = i;\n for (let j = 1; j <= n; j++) {\n const tmp = dp[j];\n dp[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, dp[j], dp[j - 1]);\n prev = tmp;\n }\n }\n return dp[n];\n}\n\n/**\n * Get the config file path from CLI options, environment, or default.\n */\nfunction getConfigPath(options: CliOptions): string {\n if (options.config) {\n return resolve(options.config);\n }\n return getProfileConfigPath(options.profile);\n}\n\n/**\n * Ensure the config directory exists.\n */\nfunction ensureConfigDir(configPath: string): void {\n const dir = dirname(configPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\n/**\n * Output data as JSON or pretty format.\n */\nfunction output(data: unknown, pretty: boolean): void {\n if (pretty) {\n // Pretty output for humans\n if (typeof data === 'object' && data !== null) {\n for (const [key, value] of Object.entries(data)) {\n if (Array.isArray(value)) {\n console.log(`${key}:`);\n for (const item of value) {\n if (typeof item === 'object' && item !== null) {\n const entries = Object.entries(item);\n console.log(` - ${entries.map(([k, v]) => `${k}: ${v}`).join(', ')}`);\n } else {\n console.log(` - ${item}`);\n }\n }\n } else if (typeof value === 'object' && value !== null) {\n console.log(`${key}:`);\n for (const [k, v] of Object.entries(value)) {\n console.log(` ${k}: ${v}`);\n }\n } else {\n console.log(`${key}: ${value}`);\n }\n }\n } else {\n console.log(data);\n }\n } else {\n // JSON output for programmatic use\n console.log(JSON.stringify(data, null, 2));\n }\n}\n\n/**\n * Handle the `agora init` command.\n */\nfunction handleInit(options: CliOptions): void {\n const configPath = getConfigPath(options);\n ensureConfigDir(configPath);\n\n if (existsSync(configPath)) {\n const config = loadPeerConfig(configPath);\n output({ \n status: 'already_initialized',\n publicKey: config.identity.publicKey,\n configPath \n }, options.pretty || false);\n process.exit(0);\n }\n\n const config = initPeerConfig(configPath);\n output({ \n status: 'initialized',\n publicKey: config.identity.publicKey,\n configPath \n }, options.pretty || false);\n}\n\n/**\n * Handle the `agora whoami` command.\n */\nfunction handleWhoami(options: CliOptions): void {\n const configPath = getConfigPath(options);\n \n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n output({ \n publicKey: config.identity.publicKey,\n configPath \n }, options.pretty || false);\n}\n\n/**\n * Handle the `agora peers add` command.\n */\nfunction handlePeersAdd(args: string[], options: CliOptions & { url?: string; token?: string; pubkey?: string }): void {\n if (args.length < 1) {\n console.error('Error: Missing peer name. Usage: agora peers add <name> --pubkey <pubkey> [--url <url> --token <token>]');\n process.exit(1);\n }\n\n const name = args[0];\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const url = options.url;\n const token = options.token;\n const pubkey = options.pubkey;\n\n if (!pubkey) {\n console.error('Error: Missing required --pubkey option.');\n process.exit(1);\n }\n\n // Validate that if one of url/token is provided, both must be\n if ((url && !token) || (!url && token)) {\n console.error('Error: Both --url and --token must be provided together.');\n process.exit(1);\n }\n\n // Check if we have HTTP transport or relay\n const config = loadPeerConfig(configPath);\n const hasHttpConfig = url && token;\n const hasRelay = config.relay;\n\n if (!hasHttpConfig && !hasRelay) {\n console.error('Error: Either (--url and --token) must be provided, or relay must be configured in config file.');\n process.exit(1);\n }\n\n // Add/update the peer (canonical key is full public key)\n const existingByPubKey = Object.entries(config.peers).find(([, peer]) => peer.publicKey === pubkey);\n if (existingByPubKey && existingByPubKey[0] !== pubkey) {\n delete config.peers[existingByPubKey[0]];\n }\n\n config.peers[pubkey] = {\n publicKey: pubkey,\n name,\n };\n\n if (url && token) {\n config.peers[pubkey].url = url;\n config.peers[pubkey].token = token;\n }\n\n savePeerConfig(configPath, config);\n \n const outputData: Record<string, unknown> = { \n status: 'added',\n name,\n publicKey: pubkey\n };\n \n if (url) {\n outputData.url = url;\n }\n \n output(outputData, options.pretty || false);\n}\n\n/**\n * Handle the `agora peers list` command.\n */\nfunction handlePeersList(options: CliOptions): void {\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n const peers = Object.entries(config.peers).map(([key, peer]) => ({\n name: peer.name || key,\n url: peer.url,\n publicKey: peer.publicKey,\n }));\n\n output({ peers }, options.pretty || false);\n}\n\n/**\n * Handle the `agora peers remove` command.\n */\nfunction handlePeersRemove(args: string[], options: CliOptions): void {\n if (args.length < 1) {\n console.error('Error: Missing peer name. Usage: agora peers remove <name>');\n process.exit(1);\n }\n\n const peerRef = args[0];\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n\n const resolved = resolvePeerEntry(config.peers, peerRef);\n if (!resolved) {\n console.error(`Error: Peer '${peerRef}' not found.`);\n process.exit(1);\n }\n\n delete config.peers[resolved.key];\n savePeerConfig(configPath, config);\n output({ \n status: 'removed',\n name: peerRef \n }, options.pretty || false);\n}\n\n/**\n * Handle the `agora peers discover` command.\n */\nasync function handlePeersDiscover(\n options: CliOptions & { \n relay?: string; \n 'relay-pubkey'?: string;\n limit?: string;\n 'active-within'?: string;\n save?: boolean;\n }\n): Promise<void> {\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n\n // Determine relay configuration\n let relayUrl: string;\n let relayPublicKey: string | undefined;\n\n if (options.relay) {\n // Use custom relay from command line\n relayUrl = options.relay;\n relayPublicKey = options['relay-pubkey'];\n } else if (config.relay) {\n // Use relay from config\n relayUrl = typeof config.relay === 'string' ? config.relay : config.relay.url;\n // TODO: Add relayPublicKey to config schema in future\n relayPublicKey = undefined;\n } else {\n // Use default bootstrap relay\n const bootstrap = getDefaultBootstrapRelay();\n relayUrl = bootstrap.relayUrl;\n relayPublicKey = bootstrap.relayPublicKey;\n }\n\n // Parse filters\n const filters: { activeWithin?: number; limit?: number } = {};\n if (options['active-within']) {\n const ms = parseInt(options['active-within'], 10);\n if (isNaN(ms) || ms <= 0) {\n console.error('Error: --active-within must be a positive number (milliseconds)');\n process.exit(1);\n }\n filters.activeWithin = ms;\n }\n if (options.limit) {\n const limit = parseInt(options.limit, 10);\n if (isNaN(limit) || limit <= 0) {\n console.error('Error: --limit must be a positive number');\n process.exit(1);\n }\n filters.limit = limit;\n }\n\n // Resolve broadcast name\n const broadcastName = resolveBroadcastName(config, undefined);\n\n // Connect to relay\n const relayClient = new RelayClient({\n relayUrl,\n publicKey: config.identity.publicKey,\n privateKey: config.identity.privateKey,\n name: broadcastName,\n });\n\n try {\n // Connect\n await relayClient.connect();\n\n // Create discovery service\n const discoveryService = new PeerDiscoveryService({\n publicKey: config.identity.publicKey,\n privateKey: config.identity.privateKey,\n relayClient,\n relayPublicKey,\n });\n\n // Discover peers\n const peerList = await discoveryService.discoverViaRelay(Object.keys(filters).length > 0 ? filters : undefined);\n\n if (!peerList) {\n output({\n status: 'no_response',\n message: 'No response from relay',\n }, options.pretty || false);\n process.exit(1);\n }\n\n // Save to config if requested\n if (options.save) {\n let savedCount = 0;\n for (const peer of peerList.peers) {\n // Only save if not already in config\n const existing = Object.values(config.peers).find(p => p.publicKey === peer.publicKey);\n if (!existing) {\n config.peers[peer.publicKey] = {\n publicKey: peer.publicKey,\n name: peer.metadata?.name,\n };\n savedCount++;\n }\n }\n if (savedCount > 0) {\n savePeerConfig(configPath, config);\n }\n\n output({\n status: 'discovered',\n totalPeers: peerList.totalPeers,\n peersReturned: peerList.peers.length,\n peersSaved: savedCount,\n relayPublicKey: peerList.relayPublicKey,\n peers: peerList.peers.map(p => ({\n publicKey: p.publicKey,\n name: p.metadata?.name,\n version: p.metadata?.version,\n lastSeen: p.lastSeen,\n })),\n }, options.pretty || false);\n } else {\n output({\n status: 'discovered',\n totalPeers: peerList.totalPeers,\n peersReturned: peerList.peers.length,\n relayPublicKey: peerList.relayPublicKey,\n peers: peerList.peers.map(p => ({\n publicKey: p.publicKey,\n name: p.metadata?.name,\n version: p.metadata?.version,\n lastSeen: p.lastSeen,\n })),\n }, options.pretty || false);\n }\n } catch (e) {\n console.error('Error discovering peers:', e instanceof Error ? e.message : String(e));\n process.exit(1);\n } finally {\n relayClient.disconnect();\n }\n}\n\n/**\n * Handle the `agora send` command.\n */\nasync function handleSend(args: string[], options: CliOptions & { type?: string; payload?: string; direct?: boolean; 'relay-only'?: boolean }): Promise<void> {\n if (args.length < 1) {\n console.error('Error: Missing peer name. Usage: agora send <name> <message> OR agora send <name> --type <type> --payload <json>');\n process.exit(1);\n }\n\n const peerRef = args[0];\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n\n const resolved = resolvePeerEntry(config.peers, peerRef);\n if (!resolved) {\n console.error(`Error: Peer '${peerRef}' not found.`);\n process.exit(1);\n }\n\n const peer = resolved.peer;\n\n let messageType: MessageType;\n let messagePayload: unknown;\n\n if (options.type && options.payload) {\n // Typed message - validate it's a valid MessageType\n const validTypes: MessageType[] = ['announce', 'discover', 'request', 'response', 'publish', 'subscribe', 'verify', 'ack', 'error'];\n if (!validTypes.includes(options.type as MessageType)) {\n console.error(`Error: Invalid message type '${options.type}'. Valid types: ${validTypes.join(', ')}`);\n process.exit(1);\n }\n messageType = options.type as MessageType;\n try {\n messagePayload = JSON.parse(options.payload);\n } catch {\n console.error('Error: Invalid JSON payload.');\n process.exit(1);\n }\n } else {\n // Text message - use 'publish' type with text payload\n if (args.length < 2) {\n console.error('Error: Missing message text. Usage: agora send <name> <message>');\n process.exit(1);\n }\n messageType = 'publish';\n messagePayload = { text: expandInlineReferences(args.slice(1).join(' '), config.peers) };\n }\n\n const isDirect = options.direct === true;\n const isRelayOnly = options['relay-only'] === true;\n\n // Validate flag combination\n if (isDirect && isRelayOnly) {\n console.error('Error: --direct and --relay-only are mutually exclusive.');\n process.exit(1);\n }\n\n // --direct requires the peer to have a URL\n if (isDirect && !peer.url) {\n console.error(`Error: --direct requested but peer '${peerRef}' has no URL configured.`);\n process.exit(1);\n }\n\n // Whether to attempt HTTP transport for this send\n const shouldTryHttp = peer.url && !isRelayOnly;\n const hasRelay = config.relay;\n\n // Send the message\n try {\n if (shouldTryHttp) {\n // Use HTTP transport\n const transportConfig = {\n identity: config.identity,\n peers: new Map<string, PeerConfig>([[peer.publicKey, {\n url: peer.url!,\n token: peer.token,\n publicKey: peer.publicKey,\n }]]),\n };\n\n const result = await sendToPeer(\n transportConfig,\n peer.publicKey,\n messageType,\n messagePayload\n );\n\n if (result.ok) {\n output({ \n status: 'sent',\n peer: peerRef,\n type: messageType,\n transport: 'http',\n httpStatus: result.status\n }, options.pretty || false);\n return;\n }\n\n // HTTP failed\n if (isDirect) {\n // --direct: do not fall back to relay\n output({ \n status: 'failed',\n peer: peerRef,\n type: messageType,\n transport: 'http',\n httpStatus: result.status,\n error: result.error\n }, options.pretty || false);\n process.exit(1);\n }\n\n // Fall through to relay if available\n if (!hasRelay || !config.relay) {\n output({ \n status: 'failed',\n peer: peerRef,\n type: messageType,\n transport: 'http',\n httpStatus: result.status,\n error: result.error\n }, options.pretty || false);\n process.exit(1);\n }\n }\n\n // Use relay transport (relay-only mode, or HTTP failed with relay available, or no URL)\n if (hasRelay && config.relay) {\n // Extract URL from relay (string or object)\n const relayUrl = typeof config.relay === 'string' ? config.relay : config.relay.url;\n const relayConfig = {\n identity: config.identity,\n relayUrl,\n };\n\n const result = await sendViaRelay(\n relayConfig,\n peer.publicKey,\n messageType,\n messagePayload\n );\n\n if (result.ok) {\n output({ \n status: 'sent',\n peer: peerRef,\n type: messageType,\n transport: 'relay'\n }, options.pretty || false);\n } else {\n output({ \n status: 'failed',\n peer: peerRef,\n type: messageType,\n transport: 'relay',\n error: result.error\n }, options.pretty || false);\n process.exit(1);\n }\n } else if (!shouldTryHttp) {\n // Neither HTTP nor relay available\n console.error(`Error: Peer '${peerRef}' unreachable. No HTTP endpoint and no relay configured.`);\n process.exit(1);\n }\n } catch (e) {\n console.error('Error sending message:', e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n}\n\n/**\n * Handle the `agora decode` command.\n */\nfunction handleDecode(args: string[], options: CliOptions): void {\n if (args.length < 1) {\n console.error('Error: Missing message. Usage: agora decode <message>');\n process.exit(1);\n }\n\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n const peers = new Map<string, PeerConfig>();\n for (const [, val] of Object.entries(config.peers)) {\n // Only add peers with HTTP config to the map for decoding\n if (val.url && val.token) {\n peers.set(val.publicKey, {\n url: val.url,\n token: val.token,\n publicKey: val.publicKey,\n });\n }\n }\n\n const message = args.join(' ');\n const result = decodeInboundEnvelope(message, peers);\n\n if (result.ok) {\n output({\n status: 'verified',\n from: result.envelope.from,\n to: result.envelope.to,\n type: result.envelope.type,\n payload: compactPayloadTextReferences(result.envelope.payload, config.peers),\n id: result.envelope.id,\n timestamp: result.envelope.timestamp,\n inReplyTo: result.envelope.inReplyTo || null,\n }, options.pretty || false);\n } else {\n output({\n status: 'failed',\n reason: result.reason,\n }, options.pretty || false);\n process.exit(1);\n }\n}\n\n/**\n * Handle the `agora status` command.\n */\nfunction handleStatus(options: CliOptions): void {\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n const peerCount = Object.keys(config.peers).length;\n\n output({\n identity: config.identity.publicKey,\n configPath,\n relay: config.relay || 'not configured',\n peerCount,\n peers: Object.keys(config.peers),\n }, options.pretty || false);\n}\n\n// ---------------------------------------------------------------------------\n// Profile & config transfer commands\n// ---------------------------------------------------------------------------\n\n/**\n * Handle the `agora config profiles` command.\n */\nfunction handleConfigProfiles(options: CliOptions): void {\n const profiles = listProfiles();\n if (profiles.length === 0) {\n output({ profiles: [], message: 'No profiles found. Run `agora init` first.' }, options.pretty || false);\n return;\n }\n output({ profiles }, options.pretty || false);\n}\n\n/**\n * Handle the `agora config export` command.\n */\nfunction handleConfigExport(options: CliOptions & { 'include-identity'?: boolean; output?: string }): void {\n const configPath = getConfigPath(options);\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadAgoraConfig(configPath);\n const exported = exportConfig(config, { includeIdentity: options['include-identity'] });\n\n if (options.output) {\n const outPath = resolve(options.output);\n const dir = dirname(outPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(outPath, JSON.stringify(exported, null, 2) + '\\n', 'utf-8');\n output({ status: 'exported', path: outPath, peerCount: Object.keys(exported.peers).length, includesIdentity: !!exported.identity }, options.pretty || false);\n } else {\n // Write to stdout for piping\n console.log(JSON.stringify(exported, null, 2));\n }\n}\n\n/**\n * Handle the `agora config import` command.\n */\nfunction handleConfigImport(\n args: string[],\n options: CliOptions & { 'overwrite-identity'?: boolean; 'overwrite-relay'?: boolean; 'dry-run'?: boolean },\n): void {\n if (args.length < 1) {\n console.error('Error: Missing import file. Usage: agora config import <file> [--overwrite-identity] [--overwrite-relay] [--dry-run]');\n process.exit(1);\n }\n\n const importPath = resolve(args[0]);\n if (!existsSync(importPath)) {\n console.error(`Error: Import file not found: ${importPath}`);\n process.exit(1);\n }\n\n let incoming: ExportedConfig;\n try {\n incoming = JSON.parse(readFileSync(importPath, 'utf-8')) as ExportedConfig;\n } catch {\n console.error(`Error: Invalid JSON in import file: ${importPath}`);\n process.exit(1);\n }\n\n if (incoming.version !== 1) {\n console.error(`Error: Unsupported export version: ${(incoming as unknown as Record<string, unknown>).version}. Expected version 1 (from 'agora config export').`);\n process.exit(1);\n }\n\n const configPath = getConfigPath(options);\n\n // When target doesn't exist, auto-apply identity/relay from the export file\n // (--overwrite-identity is only needed when the target already has an identity you want to replace)\n const isNewProfile = !existsSync(configPath);\n if (isNewProfile) {\n ensureConfigDir(configPath);\n initPeerConfig(configPath);\n }\n\n const config = loadAgoraConfig(configPath);\n const result = importConfig(config, incoming, {\n overwriteIdentity: options['overwrite-identity'] || isNewProfile,\n overwriteRelay: options['overwrite-relay'] || isNewProfile,\n });\n\n if (!options['dry-run']) {\n saveAgoraConfig(configPath, config);\n }\n\n output({\n status: options['dry-run'] ? 'dry-run' : 'imported',\n configPath,\n peersAdded: result.peersAdded.length,\n peersSkipped: result.peersSkipped.length,\n identityImported: result.identityImported,\n relayImported: result.relayImported,\n }, options.pretty || false);\n}\n\n/**\n * Handle the `agora peers copy` command.\n * Copy a peer from one profile to another.\n */\nfunction handlePeersCopy(\n args: string[],\n options: CliOptions & { from?: string; to?: string },\n): void {\n if (args.length < 1) {\n console.error('Error: Missing peer name. Usage: agora peers copy <name> --from <profile> --to <profile>');\n console.error(' Profile names: \"default\" or a named profile. Omit for the current --profile / default.');\n process.exit(1);\n }\n\n const peerRef = args[0];\n const fromProfile = options.from;\n const toProfile = options.to;\n\n // Resolve source config\n const fromPath = fromProfile !== undefined\n ? getProfileConfigPath(fromProfile)\n : getConfigPath(options);\n\n if (!existsSync(fromPath)) {\n console.error(`Error: Source config not found: ${fromPath}`);\n process.exit(1);\n }\n\n // Resolve target config\n const toPath = toProfile !== undefined\n ? getProfileConfigPath(toProfile)\n : getConfigPath(options);\n\n if (fromPath === toPath) {\n console.error('Error: Source and target profiles are the same.');\n process.exit(1);\n }\n\n // Load source and resolve peer\n const sourceConfig = loadPeerConfig(fromPath);\n const resolved = resolvePeerEntry(sourceConfig.peers, peerRef);\n if (!resolved) {\n console.error(`Error: Peer '${peerRef}' not found in source config (${fromPath}).`);\n process.exit(1);\n }\n\n // Ensure target exists\n if (!existsSync(toPath)) {\n ensureConfigDir(toPath);\n initPeerConfig(toPath);\n }\n\n const targetConfig = loadPeerConfig(toPath);\n\n // Copy peer (overwrite if already present)\n targetConfig.peers[resolved.key] = { ...resolved.peer };\n savePeerConfig(toPath, targetConfig);\n\n output({\n status: 'copied',\n peer: resolved.peer.name || resolved.key,\n publicKey: resolved.peer.publicKey,\n from: fromPath,\n to: toPath,\n }, options.pretty || false);\n}\n\n/**\n * Handle the `agora announce` command.\n * Disabled to enforce strict peer-to-peer semantics.\n */\nasync function handleAnnounce(options: CliOptions & { name?: string; version?: string }): Promise<void> {\n void options;\n console.error('Error: `agora announce` is disabled. Agora now supports strict peer-to-peer only (no all/broadcast).');\n console.error('Use: agora send <peer> --type announce --payload <json>');\n process.exit(1);\n}\n\n/**\n * Handle the `agora diagnose` command.\n * Run diagnostic checks on a peer (ping, workspace, tools).\n */\nasync function handleDiagnose(args: string[], options: CliOptions & { checks?: string }): Promise<void> {\n if (args.length < 1) {\n console.error('Error: Missing peer name. Usage: agora diagnose <name> [--checks <comma-separated-list>]');\n process.exit(1);\n }\n\n const peerRef = args[0];\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n\n const resolved = resolvePeerEntry(config.peers, peerRef);\n if (!resolved) {\n console.error(`Error: Peer '${peerRef}' not found.`);\n process.exit(1);\n }\n\n const peer = resolved.peer;\n\n if (!peer.url) {\n console.error(`Error: Peer '${peerRef}' has no URL configured. Cannot diagnose.`);\n process.exit(1);\n }\n\n // Parse checks parameter\n const checksParam = options.checks || 'ping';\n const requestedChecks = checksParam.split(',').map(c => c.trim());\n \n // Validate check types\n const validChecks = ['ping', 'workspace', 'tools'];\n for (const check of requestedChecks) {\n if (!validChecks.includes(check)) {\n console.error(`Error: Invalid check type '${check}'. Valid checks: ${validChecks.join(', ')}`);\n process.exit(1);\n }\n }\n\n // Result structure\n interface CheckResult {\n ok: boolean;\n latency_ms?: number;\n error?: string;\n implemented?: boolean;\n [key: string]: unknown;\n }\n \n const result: {\n peer: string;\n status: string;\n checks: Record<string, CheckResult>;\n timestamp: string;\n } = {\n peer: peerRef,\n status: 'unknown',\n checks: {},\n timestamp: new Date().toISOString(),\n };\n\n // Run ping check\n if (requestedChecks.includes('ping')) {\n const startTime = Date.now();\n try {\n // Add timeout to prevent hanging on unreachable peers\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 10000);\n \n const response = await fetch(peer.url, {\n method: 'GET',\n headers: peer.token ? { 'Authorization': `Bearer ${peer.token}` } : {},\n signal: controller.signal,\n });\n \n clearTimeout(timeout);\n const latency = Date.now() - startTime;\n \n if (response.ok || response.status === 404 || response.status === 405) {\n // 404 or 405 means the endpoint exists but GET isn't supported - that's OK for a ping\n result.checks.ping = { ok: true, latency_ms: latency };\n } else {\n result.checks.ping = { ok: false, latency_ms: latency, error: `HTTP ${response.status}` };\n }\n } catch (err) {\n const latency = Date.now() - startTime;\n result.checks.ping = { \n ok: false, \n latency_ms: latency,\n error: err instanceof Error ? err.message : String(err) \n };\n }\n }\n\n // Run workspace check\n if (requestedChecks.includes('workspace')) {\n // This is a placeholder - actual implementation would depend on peer's diagnostic protocol\n result.checks.workspace = { \n ok: false,\n implemented: false,\n error: 'Workspace check requires peer diagnostic protocol support' \n };\n }\n\n // Run tools check\n if (requestedChecks.includes('tools')) {\n // This is a placeholder - actual implementation would depend on peer's diagnostic protocol\n result.checks.tools = { \n ok: false,\n implemented: false,\n error: 'Tools check requires peer diagnostic protocol support' \n };\n }\n\n // Determine overall status - only consider implemented checks\n const implementedChecks = Object.values(result.checks).filter(\n check => check.implemented !== false\n );\n \n if (implementedChecks.length === 0) {\n result.status = 'unknown';\n } else {\n const allOk = implementedChecks.every(check => check.ok);\n const anyOk = implementedChecks.some(check => check.ok);\n result.status = allOk ? 'healthy' : anyOk ? 'degraded' : 'unhealthy';\n }\n\n output(result, options.pretty || false);\n}\n\n/**\n * Handle the `agora serve` command.\n * Starts a persistent WebSocket server for incoming peer connections.\n */\nasync function handleServe(options: CliOptions & { port?: string; name?: string }): Promise<void> {\n const configPath = getConfigPath(options);\n\n if (!existsSync(configPath)) {\n console.error('Error: Config file not found. Run `agora init` first.');\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n const port = parseInt(options.port || '9473', 10);\n \n // Validate port\n if (isNaN(port) || port < 1 || port > 65535) {\n console.error(`Error: Invalid port number '${options.port}'. Port must be between 1 and 65535.`);\n process.exit(1);\n }\n \n // Resolve server name using priority: CLI --name, config.relay.name, config.identity.name, default\n const serverName = resolveBroadcastName(config, options.name) || 'agora-server';\n\n // Create announce payload\n const announcePayload: AnnouncePayload = {\n capabilities: [],\n metadata: {\n name: serverName,\n version: '0.1.0',\n },\n };\n\n // Create and configure PeerServer\n const server = new PeerServer(config.identity, announcePayload);\n\n // Setup event listeners\n server.on('peer-connected', (publicKey, peer) => {\n const peerName = peer.metadata?.name || publicKey.substring(0, 16);\n console.log(`[${new Date().toISOString()}] Peer connected: ${peerName} (${publicKey})`);\n });\n\n server.on('peer-disconnected', (publicKey) => {\n console.log(`[${new Date().toISOString()}] Peer disconnected: ${publicKey}`);\n });\n\n server.on('message-received', (envelope, fromPublicKey) => {\n console.log(`[${new Date().toISOString()}] Message from ${fromPublicKey}:`);\n console.log(JSON.stringify({\n id: envelope.id,\n type: envelope.type,\n from: envelope.from,\n to: envelope.to,\n timestamp: envelope.timestamp,\n payload: envelope.payload,\n }, null, 2));\n });\n\n server.on('error', (error) => {\n console.error(`[${new Date().toISOString()}] Error:`, error.message);\n });\n\n // Start the server\n try {\n await server.start(port);\n console.log(`[${new Date().toISOString()}] Agora server started`);\n console.log(` Name: ${serverName}`);\n console.log(` Public Key: ${config.identity.publicKey}`);\n console.log(` WebSocket Port: ${port}`);\n console.log(` Listening for peer connections...`);\n console.log('');\n console.log('Press Ctrl+C to stop the server');\n\n // Keep the process alive\n process.on('SIGINT', async () => {\n console.log(`\\n[${new Date().toISOString()}] Shutting down server...`);\n await server.stop();\n console.log('Server stopped');\n process.exit(0);\n });\n\n process.on('SIGTERM', async () => {\n console.log(`\\n[${new Date().toISOString()}] Shutting down server...`);\n await server.stop();\n console.log('Server stopped');\n process.exit(0);\n });\n } catch (error) {\n console.error('Failed to start server:', error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n}\n\n/**\n * Handle the `agora relay` command.\n * Starts a WebSocket relay server for routing messages between agents.\n */\nasync function handleRelay(options: CliOptions & { port?: string }): Promise<void> {\n const port = parseInt(options.port || '9474', 10);\n \n // Validate port\n if (isNaN(port) || port < 1 || port > 65535) {\n console.error(`Error: Invalid port number '${options.port}'. Port must be between 1 and 65535.`);\n process.exit(1);\n }\n\n // Create and configure RelayServer\n const server = new RelayServer();\n\n // Setup event listeners\n server.on('agent-registered', (publicKey) => {\n console.log(`[${new Date().toISOString()}] Agent registered: ${publicKey}`);\n });\n\n server.on('agent-disconnected', (publicKey) => {\n console.log(`[${new Date().toISOString()}] Agent disconnected: ${publicKey}`);\n });\n\n server.on('message-relayed', (from, to, envelope) => {\n console.log(`[${new Date().toISOString()}] Message relayed: ${from.substring(0, 16)}... → ${to.substring(0, 16)}... (type: ${envelope.type})`);\n });\n\n server.on('error', (error) => {\n console.error(`[${new Date().toISOString()}] Error:`, error.message);\n });\n\n // Start the server\n try {\n await server.start(port);\n console.log(`[${new Date().toISOString()}] Agora relay server started`);\n console.log(` WebSocket Port: ${port}`);\n console.log(` Connected agents: 0`);\n console.log(` Listening for agent connections...`);\n console.log('');\n console.log('Press Ctrl+C to stop the relay');\n\n // Shared shutdown handler\n const shutdown = async (): Promise<void> => {\n console.log(`\\n[${new Date().toISOString()}] Shutting down relay...`);\n await server.stop();\n console.log('Relay stopped');\n process.exit(0);\n };\n\n // Keep the process alive\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n } catch (error) {\n console.error('Failed to start relay:', error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n}\n\n/**\n * Get the reputation store file path.\n */\nfunction getReputationStorePath(): string {\n return resolve(homedir(), '.local', 'share', 'agora', 'reputation.jsonl');\n}\n\n/**\n * Handle the `agora reputation verify` command.\n * Creates a verification record for another agent's output.\n */\nasync function handleReputationVerify(\n args: string[],\n options: CliOptions & {\n target?: string;\n domain?: string;\n verdict?: string;\n confidence?: string;\n evidence?: string;\n }\n): Promise<void> {\n if (!options.target || !options.domain || !options.verdict) {\n console.error('Error: Missing required options');\n console.error('Usage: agora reputation verify --target <id> --domain <domain> --verdict <correct|incorrect|disputed> --confidence <0-1> [--evidence <url>]');\n process.exit(1);\n }\n\n // Validate verdict\n if (!['correct', 'incorrect', 'disputed'].includes(options.verdict)) {\n console.error('Error: verdict must be one of: correct, incorrect, disputed');\n process.exit(1);\n }\n\n // Parse confidence\n const confidence = options.confidence ? parseFloat(options.confidence) : 1.0;\n if (isNaN(confidence) || confidence < 0 || confidence > 1) {\n console.error('Error: confidence must be a number between 0 and 1');\n process.exit(1);\n }\n\n // Load config\n const configPath = getConfigPath(options);\n if (!existsSync(configPath)) {\n console.error(`Error: Config file not found at ${configPath}. Run 'agora init' first.`);\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n\n // Create verification\n const verification = createVerification(\n config.identity.publicKey,\n config.identity.privateKey,\n options.target,\n options.domain,\n options.verdict as 'correct' | 'incorrect' | 'disputed',\n confidence,\n Date.now(),\n options.evidence\n );\n\n // Save to reputation store\n const storePath = getReputationStorePath();\n const store = new ReputationStore(storePath);\n await store.addVerification(verification);\n\n output({\n status: 'verification_created',\n id: verification.id,\n verifier: verification.verifier,\n target: verification.target,\n domain: verification.domain,\n verdict: verification.verdict,\n confidence: verification.confidence,\n timestamp: verification.timestamp,\n }, options.pretty || false);\n}\n\n/**\n * Handle the `agora reputation commit` command.\n * Creates a commitment to a prediction before outcome is known.\n */\nasync function handleReputationCommit(\n args: string[],\n options: CliOptions & {\n domain?: string;\n prediction?: string;\n expiry?: string;\n }\n): Promise<void> {\n if (!options.domain || !options.prediction) {\n console.error('Error: Missing required options');\n console.error('Usage: agora reputation commit --domain <domain> --prediction <text> [--expiry <milliseconds>]');\n console.error('Example: agora reputation commit --domain weather_forecast --prediction \"It will rain tomorrow\" --expiry 86400000');\n process.exit(1);\n }\n\n // Parse expiry (default 24 hours)\n const expiryMs = options.expiry ? parseInt(options.expiry, 10) : 86400000;\n if (isNaN(expiryMs) || expiryMs <= 0) {\n console.error('Error: expiry must be a positive number (milliseconds)');\n process.exit(1);\n }\n\n // Load config\n const configPath = getConfigPath(options);\n if (!existsSync(configPath)) {\n console.error(`Error: Config file not found at ${configPath}. Run 'agora init' first.`);\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n\n // Create commit\n const commit = createCommit(\n config.identity.publicKey,\n config.identity.privateKey,\n options.domain,\n options.prediction,\n Date.now(),\n expiryMs\n );\n\n // Save to reputation store\n const storePath = getReputationStorePath();\n const store = new ReputationStore(storePath);\n await store.addCommit(commit);\n\n output({\n status: 'commitment_created',\n id: commit.id,\n agent: commit.agent,\n domain: commit.domain,\n commitment: commit.commitment,\n timestamp: commit.timestamp,\n expiry: commit.expiry,\n note: 'Store this ID to reveal the prediction after expiry',\n }, options.pretty || false);\n}\n\n/**\n * Handle the `agora reputation reveal` command.\n * Reveals a prediction and outcome after commitment expiry.\n */\nasync function handleReputationReveal(\n args: string[],\n options: CliOptions & {\n 'commit-id'?: string;\n prediction?: string;\n outcome?: string;\n evidence?: string;\n }\n): Promise<void> {\n if (!options['commit-id'] || !options.prediction || !options.outcome) {\n console.error('Error: Missing required options');\n console.error('Usage: agora reputation reveal --commit-id <id> --prediction <text> --outcome <text> [--evidence <url>]');\n process.exit(1);\n }\n\n // Load config\n const configPath = getConfigPath(options);\n if (!existsSync(configPath)) {\n console.error(`Error: Config file not found at ${configPath}. Run 'agora init' first.`);\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n\n // Load commit from store\n const storePath = getReputationStorePath();\n const store = new ReputationStore(storePath);\n const commit = await store.getCommit(options['commit-id']);\n\n if (!commit) {\n console.error(`Error: Commitment ${options['commit-id']} not found in local store`);\n process.exit(1);\n }\n\n // Create reveal\n const reveal = createReveal(\n config.identity.publicKey,\n config.identity.privateKey,\n options['commit-id'],\n options.prediction,\n options.outcome,\n Date.now(),\n options.evidence\n );\n \n // Verify the reveal against the commit\n const verification = verifyReveal(commit, reveal);\n if (!verification.valid) {\n console.error(`Error: Reveal verification failed: ${verification.reason}`);\n process.exit(1);\n }\n\n // Save to reputation store\n await store.addReveal(reveal);\n\n output({\n status: 'prediction_revealed',\n id: reveal.id,\n agent: reveal.agent,\n commitmentId: reveal.commitmentId,\n prediction: reveal.prediction,\n outcome: reveal.outcome,\n timestamp: reveal.timestamp,\n verified: true,\n }, options.pretty || false);\n}\n\n/**\n * Handle the `agora reputation query` command.\n * Queries reputation score for an agent in a domain.\n */\nasync function handleReputationQuery(\n args: string[],\n options: CliOptions & {\n agent?: string;\n domain?: string;\n }\n): Promise<void> {\n if (!options.domain) {\n console.error('Error: Missing required option: --domain');\n console.error('Usage: agora reputation query --domain <domain> [--agent <pubkey>]');\n console.error('If --agent is omitted, shows reputation for current agent');\n process.exit(1);\n }\n\n // Load config\n const configPath = getConfigPath(options);\n if (!existsSync(configPath)) {\n console.error(`Error: Config file not found at ${configPath}. Run 'agora init' first.`);\n process.exit(1);\n }\n\n const config = loadPeerConfig(configPath);\n const agent = options.agent || config.identity.publicKey;\n\n // Load reputation store\n const storePath = getReputationStorePath();\n const store = new ReputationStore(storePath);\n const verifications = await store.getVerificationsByDomain(options.domain);\n\n // Filter verifications for this agent\n const agentVerifications = verifications.filter(v => v.target === agent);\n\n // Compute trust score\n const score = computeTrustScore(agent, options.domain, agentVerifications, Date.now());\n\n output({\n agent: score.agent,\n domain: score.domain,\n score: score.score,\n verificationCount: score.verificationCount,\n lastVerified: score.lastVerified,\n lastVerifiedDate: score.lastVerified > 0 ? new Date(score.lastVerified).toISOString() : 'never',\n topVerifiers: score.topVerifiers,\n }, options.pretty || false);\n}\n\n/**\n * Parse CLI arguments and route to appropriate handler.\n */\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length === 0) {\n console.error('Usage: agora <command> [options]');\n console.error('Commands: init, whoami, status, peers, config, send, decode, serve, diagnose, relay, reputation');\n console.error('Global: --profile <name> (or --as <name>) to select a named profile');\n console.error(' peers subcommands: add, list, remove, discover, copy');\n console.error(' config subcommands: profiles, export, import');\n console.error(' reputation subcommands: verify, commit, reveal, query');\n process.exit(1);\n }\n\n // Parse global options\n const parsed = parseArgs({\n args,\n options: {\n config: { type: 'string' },\n profile: { type: 'string' },\n as: { type: 'string' },\n pretty: { type: 'boolean' },\n // Config transfer options\n 'include-identity': { type: 'boolean' },\n 'overwrite-identity': { type: 'boolean' },\n 'overwrite-relay': { type: 'boolean' },\n 'dry-run': { type: 'boolean' },\n output: { type: 'string' },\n from: { type: 'string' },\n to: { type: 'string' },\n url: { type: 'string' },\n token: { type: 'string' },\n pubkey: { type: 'string' },\n type: { type: 'string' },\n payload: { type: 'string' },\n name: { type: 'string' },\n version: { type: 'string' },\n port: { type: 'string' },\n checks: { type: 'string' },\n relay: { type: 'string' },\n 'relay-pubkey': { type: 'string' },\n limit: { type: 'string' },\n 'active-within': { type: 'string' },\n save: { type: 'boolean' },\n // Reputation options\n target: { type: 'string' },\n domain: { type: 'string' },\n verdict: { type: 'string' },\n confidence: { type: 'string' },\n evidence: { type: 'string' },\n prediction: { type: 'string' },\n expiry: { type: 'string' },\n 'commit-id': { type: 'string' },\n outcome: { type: 'string' },\n agent: { type: 'string' },\n direct: { type: 'boolean' },\n 'relay-only': { type: 'boolean' },\n },\n strict: false,\n allowPositionals: true,\n });\n\n // Warn about unrecognised flags (catches typos like --owerwrite-identity)\n const knownFlags = new Set([\n 'config', 'profile', 'as', 'pretty',\n 'include-identity', 'overwrite-identity', 'overwrite-relay', 'dry-run',\n 'output', 'from', 'to',\n 'url', 'token', 'pubkey', 'type', 'payload', 'name', 'version',\n 'port', 'checks', 'relay', 'relay-pubkey', 'limit', 'active-within', 'save',\n 'target', 'domain', 'verdict', 'confidence', 'evidence', 'prediction',\n 'expiry', 'commit-id', 'outcome', 'agent', 'direct', 'relay-only',\n ]);\n for (const key of Object.keys(parsed.values)) {\n if (!knownFlags.has(key)) {\n const suggestion = didYouMean(key, knownFlags);\n const msg = suggestion\n ? `Warning: Unknown flag --${key}. Did you mean --${suggestion}?`\n : `Warning: Unknown flag --${key} (ignored).`;\n console.error(msg);\n }\n }\n\n const command = parsed.positionals[0];\n const subcommand = parsed.positionals[1];\n const remainingArgs = parsed.positionals.slice(2);\n\n // --as is an alias for --profile\n const profileValue = typeof parsed.values.profile === 'string'\n ? parsed.values.profile\n : typeof parsed.values.as === 'string'\n ? parsed.values.as\n : undefined;\n\n const options: CliOptions & { \n type?: string; \n payload?: string; \n url?: string; \n token?: string; \n pubkey?: string; \n name?: string; \n version?: string; \n port?: string; \n checks?: string;\n relay?: string;\n 'relay-pubkey'?: string;\n limit?: string;\n 'active-within'?: string;\n save?: boolean;\n // Config transfer options\n 'include-identity'?: boolean;\n 'overwrite-identity'?: boolean;\n 'overwrite-relay'?: boolean;\n 'dry-run'?: boolean;\n output?: string;\n from?: string;\n to?: string;\n // Reputation options\n target?: string;\n domain?: string;\n verdict?: string;\n confidence?: string;\n evidence?: string;\n prediction?: string;\n outcome?: string;\n expiry?: string;\n 'commit-id'?: string;\n agent?: string;\n direct?: boolean;\n 'relay-only'?: boolean;\n } = {\n config: typeof parsed.values.config === 'string' ? parsed.values.config : undefined,\n profile: profileValue,\n pretty: typeof parsed.values.pretty === 'boolean' ? parsed.values.pretty : undefined,\n type: typeof parsed.values.type === 'string' ? parsed.values.type : undefined,\n payload: typeof parsed.values.payload === 'string' ? parsed.values.payload : undefined,\n url: typeof parsed.values.url === 'string' ? parsed.values.url : undefined,\n token: typeof parsed.values.token === 'string' ? parsed.values.token : undefined,\n pubkey: typeof parsed.values.pubkey === 'string' ? parsed.values.pubkey : undefined,\n name: typeof parsed.values.name === 'string' ? parsed.values.name : undefined,\n version: typeof parsed.values.version === 'string' ? parsed.values.version : undefined,\n port: typeof parsed.values.port === 'string' ? parsed.values.port : undefined,\n checks: typeof parsed.values.checks === 'string' ? parsed.values.checks : undefined,\n relay: typeof parsed.values.relay === 'string' ? parsed.values.relay : undefined,\n 'relay-pubkey': typeof parsed.values['relay-pubkey'] === 'string' ? parsed.values['relay-pubkey'] : undefined,\n limit: typeof parsed.values.limit === 'string' ? parsed.values.limit : undefined,\n 'active-within': typeof parsed.values['active-within'] === 'string' ? parsed.values['active-within'] : undefined,\n save: typeof parsed.values.save === 'boolean' ? parsed.values.save : undefined,\n // Reputation options\n target: typeof parsed.values.target === 'string' ? parsed.values.target : undefined,\n domain: typeof parsed.values.domain === 'string' ? parsed.values.domain : undefined,\n verdict: typeof parsed.values.verdict === 'string' ? parsed.values.verdict : undefined,\n confidence: typeof parsed.values.confidence === 'string' ? parsed.values.confidence : undefined,\n evidence: typeof parsed.values.evidence === 'string' ? parsed.values.evidence : undefined,\n prediction: typeof parsed.values.prediction === 'string' ? parsed.values.prediction : undefined,\n expiry: typeof parsed.values.expiry === 'string' ? parsed.values.expiry : undefined,\n 'commit-id': typeof parsed.values['commit-id'] === 'string' ? parsed.values['commit-id'] : undefined,\n outcome: typeof parsed.values.outcome === 'string' ? parsed.values.outcome : undefined,\n agent: typeof parsed.values.agent === 'string' ? parsed.values.agent : undefined,\n direct: typeof parsed.values.direct === 'boolean' ? parsed.values.direct : undefined,\n 'relay-only': typeof parsed.values['relay-only'] === 'boolean' ? parsed.values['relay-only'] : undefined,\n 'include-identity': typeof parsed.values['include-identity'] === 'boolean' ? parsed.values['include-identity'] : undefined,\n 'overwrite-identity': typeof parsed.values['overwrite-identity'] === 'boolean' ? parsed.values['overwrite-identity'] : undefined,\n 'overwrite-relay': typeof parsed.values['overwrite-relay'] === 'boolean' ? parsed.values['overwrite-relay'] : undefined,\n 'dry-run': typeof parsed.values['dry-run'] === 'boolean' ? parsed.values['dry-run'] : undefined,\n output: typeof parsed.values.output === 'string' ? parsed.values.output : undefined,\n from: typeof parsed.values.from === 'string' ? parsed.values.from : undefined,\n to: typeof parsed.values.to === 'string' ? parsed.values.to : undefined,\n };\n\n try {\n switch (command) {\n case 'init':\n handleInit(options);\n break;\n case 'whoami':\n handleWhoami(options);\n break;\n case 'status':\n handleStatus(options);\n break;\n case 'announce':\n await handleAnnounce(options);\n break;\n case 'diagnose':\n await handleDiagnose([subcommand, ...remainingArgs].filter(Boolean), options);\n break;\n case 'peers':\n switch (subcommand) {\n case 'add':\n handlePeersAdd(remainingArgs, options);\n break;\n case 'list':\n case undefined:\n // Allow 'agora peers' to work like 'agora peers list'\n handlePeersList(options);\n break;\n case 'remove':\n handlePeersRemove(remainingArgs, options);\n break;\n case 'discover':\n await handlePeersDiscover(options);\n break;\n case 'copy':\n handlePeersCopy(remainingArgs, options);\n break;\n default:\n console.error('Error: Unknown peers subcommand. Use: add, list, remove, discover, copy');\n process.exit(1);\n }\n break;\n case 'send':\n await handleSend([subcommand, ...remainingArgs], options);\n break;\n case 'decode':\n handleDecode([subcommand, ...remainingArgs].filter(Boolean), options);\n break;\n case 'serve':\n await handleServe(options);\n break;\n case 'relay':\n await handleRelay(options);\n break;\n case 'config':\n switch (subcommand) {\n case 'profiles':\n handleConfigProfiles(options);\n break;\n case 'export':\n handleConfigExport(options);\n break;\n case 'import':\n handleConfigImport(remainingArgs, options);\n break;\n default:\n console.error('Error: Unknown config subcommand. Use: profiles, export, import');\n process.exit(1);\n }\n break;\n case 'reputation':\n switch (subcommand) {\n case 'verify':\n await handleReputationVerify(remainingArgs, options);\n break;\n case 'commit':\n await handleReputationCommit(remainingArgs, options);\n break;\n case 'reveal':\n await handleReputationReveal(remainingArgs, options);\n break;\n case 'query':\n await handleReputationQuery(remainingArgs, options);\n break;\n default:\n console.error('Error: Unknown reputation subcommand. Use: verify, commit, reveal, query');\n process.exit(1);\n }\n break;\n default:\n console.error(`Error: Unknown command '${command}'. Use: init, whoami, status, peers, config, send, decode, serve, diagnose, relay, reputation`);\n process.exit(1);\n }\n } catch (e) {\n console.error('Error:', e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n}\n\nmain().catch((e) => {\n console.error('Fatal error:', e instanceof Error ? e.message : String(e));\n process.exit(1);\n});\n","import { EventEmitter } from 'node:events';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport type { KeyPair } from '../identity/keypair';\nimport type { Envelope } from '../message/envelope';\nimport { createEnvelope, verifyEnvelope } from '../message/envelope';\nimport type { AnnouncePayload } from '../registry/messages';\n\n/**\n * Represents a connected peer\n */\nexport interface ConnectedPeer {\n /** Peer's public key */\n publicKey: string;\n /** WebSocket connection */\n socket: WebSocket;\n /** Whether the peer has been announced */\n announced: boolean;\n /** Peer metadata from announce message */\n metadata?: {\n name?: string;\n version?: string;\n };\n}\n\n/**\n * Events emitted by PeerServer\n */\nexport interface PeerServerEvents {\n 'peer-connected': (publicKey: string, peer: ConnectedPeer) => void;\n 'peer-disconnected': (publicKey: string) => void;\n 'message-received': (envelope: Envelope, fromPublicKey: string) => void;\n 'error': (error: Error) => void;\n}\n\n/**\n * WebSocket server for accepting peer connections\n */\nexport class PeerServer extends EventEmitter {\n private wss: WebSocketServer | null = null;\n private peers = new Map<string, ConnectedPeer>();\n private identity: KeyPair;\n private announcePayload: AnnouncePayload;\n\n constructor(identity: KeyPair, announcePayload: AnnouncePayload) {\n super();\n this.identity = identity;\n this.announcePayload = announcePayload;\n }\n\n /**\n * Start the WebSocket server\n */\n start(port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.wss = new WebSocketServer({ port });\n\n this.wss.on('error', (error) => {\n this.emit('error', error);\n reject(error);\n });\n\n this.wss.on('listening', () => {\n resolve();\n });\n\n this.wss.on('connection', (socket: WebSocket) => {\n this.handleConnection(socket);\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Stop the WebSocket server\n */\n async stop(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (!this.wss) {\n resolve();\n return;\n }\n\n // Close all peer connections\n for (const peer of this.peers.values()) {\n peer.socket.close();\n }\n this.peers.clear();\n\n this.wss.close((err) => {\n if (err) {\n reject(err);\n } else {\n this.wss = null;\n resolve();\n }\n });\n });\n }\n\n /**\n * Get all connected peers\n */\n getPeers(): Map<string, ConnectedPeer> {\n return new Map(this.peers);\n }\n\n /**\n * Send a message to a specific peer\n */\n send(publicKey: string, envelope: Envelope): boolean {\n const peer = this.peers.get(publicKey);\n if (!peer || peer.socket.readyState !== WebSocket.OPEN) {\n return false;\n }\n\n try {\n peer.socket.send(JSON.stringify(envelope));\n return true;\n } catch (error) {\n this.emit('error', error as Error);\n return false;\n }\n }\n\n /**\n * Handle incoming connection\n */\n private handleConnection(socket: WebSocket): void {\n let peerPublicKey: string | null = null;\n\n // Send announce message immediately\n const announceEnvelope = createEnvelope(\n 'announce',\n this.identity.publicKey,\n this.identity.privateKey,\n this.announcePayload,\n Date.now(),\n undefined,\n [this.identity.publicKey]\n );\n socket.send(JSON.stringify(announceEnvelope));\n\n socket.on('message', (data: Buffer) => {\n try {\n const envelope = JSON.parse(data.toString()) as Envelope;\n\n // Verify envelope signature\n const verification = verifyEnvelope(envelope);\n if (!verification.valid) {\n // Drop invalid messages\n return;\n }\n\n // First message should be an announce\n if (!peerPublicKey) {\n if (envelope.type === 'announce') {\n peerPublicKey = envelope.from;\n const payload = envelope.payload as AnnouncePayload;\n \n const peer: ConnectedPeer = {\n publicKey: peerPublicKey,\n socket,\n announced: true,\n metadata: payload.metadata,\n };\n\n this.peers.set(peerPublicKey, peer);\n this.emit('peer-connected', peerPublicKey, peer);\n }\n return;\n }\n\n // Verify the message is from the announced peer\n if (envelope.from !== peerPublicKey) {\n // Drop messages from wrong sender\n return;\n }\n\n // Emit message-received event\n this.emit('message-received', envelope, peerPublicKey);\n } catch {\n // Invalid JSON or other parsing errors - drop the message\n }\n });\n\n socket.on('close', () => {\n if (peerPublicKey) {\n this.peers.delete(peerPublicKey);\n this.emit('peer-disconnected', peerPublicKey);\n }\n });\n\n socket.on('error', (error) => {\n this.emit('error', error);\n });\n }\n}\n"],"mappings":"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","names":["resolve","config"]}
|