@camstack/agent 0.1.1
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/dist/chunk-6333DU2U.mjs +851 -0
- package/dist/chunk-6333DU2U.mjs.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +962 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +126 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +861 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +16 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent-config.ts","../src/agent-service.ts","../src/agent-http.ts","../src/agent-bootstrap.ts"],"sourcesContent":["import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as crypto from 'node:crypto'\nimport * as os from 'node:os'\n\ninterface AgentConfig {\n readonly nodeId: string\n readonly name: string\n readonly hubAddress?: string\n readonly dataDir: string\n readonly addonsDir: string\n readonly logLevel: string\n readonly secret?: string\n /** Resolved path to the config file (for persisting renames). */\n readonly configPath: string\n /** HTTP port for the agent status API + optional UI (default: 4444). */\n readonly statusPort: number\n}\n\n/**\n * Generate a stable nodeId and persist it to the config file.\n *\n * Resolution order (first match wins, persisted on first boot):\n * 1. Existing `nodeId` in the config file — survives env var changes\n * and host renames once seeded.\n * 2. `CAMSTACK_NODE_ID` env var on first boot — lets dev workflows\n * pin a stable, human-readable nodeId (e.g. `dev-agent-0`)\n * without clobbering already-persisted random ids.\n * 3. A fresh random hex (`agent-a1b2c3`) — production fallback when\n * no env var is set.\n *\n * Seeded values get written to the config file so subsequent boots\n * round-trip exactly the same identity (Moleculer nodeID, capability\n * routing, persisted agentSettings — all keyed by this string).\n */\nfunction ensurePersistedNodeId(configPath: string, dataDir: string): string {\n const resolvedPath = path.resolve(dataDir, configPath)\n let raw: Record<string, unknown> = {}\n if (fs.existsSync(resolvedPath)) {\n try { raw = JSON.parse(fs.readFileSync(resolvedPath, 'utf-8')) as Record<string, unknown> } catch { /* corrupt file */ }\n }\n if (typeof raw.nodeId === 'string' && raw.nodeId.length > 0) {\n return raw.nodeId\n }\n const envSeed = process.env.CAMSTACK_NODE_ID\n const id = envSeed && envSeed.length > 0\n ? envSeed\n : `agent-${crypto.randomBytes(4).toString('hex')}`\n raw.nodeId = id\n try {\n fs.mkdirSync(path.dirname(resolvedPath), { recursive: true })\n fs.writeFileSync(resolvedPath, JSON.stringify(raw, null, 2), 'utf-8')\n } catch { /* best-effort */ }\n return id\n}\n\nfunction loadAgentConfig(configPath?: string, dataDirOverride?: string): AgentConfig {\n const filePath = configPath ?? process.env.CAMSTACK_AGENT_CONFIG ?? 'agent.json'\n const dataDir = dataDirOverride ?? process.env.CAMSTACK_DATA_DIR ?? './camstack-data'\n const resolvedDataDir = path.resolve(dataDir)\n\n // Name: config file takes priority over env (allows UI rename to stick).\n // Env is the initial seed, config file is the persisted override.\n const envName = process.env.CAMSTACK_NODE_ID\n ?? process.env.CAMSTACK_AGENT_NAME\n ?? `${os.hostname()}-${os.arch()}`\n\n // Environment variables for hub connection (optional — agent starts without)\n const envHubAddress = process.env.CAMSTACK_HUB_ADDRESS || undefined\n const envSecret = process.env.CAMSTACK_CLUSTER_SECRET || undefined\n const configFullPath = path.resolve(resolvedDataDir, filePath)\n const nodeId = ensurePersistedNodeId(filePath, resolvedDataDir)\n\n // Read persisted config — these override env vars\n let fileHubAddress: string | undefined\n let fileName: string | undefined\n let fileSecret: string | undefined\n if (fs.existsSync(configFullPath)) {\n try {\n const raw = JSON.parse(fs.readFileSync(configFullPath, 'utf-8')) as Record<string, unknown>\n fileHubAddress = typeof raw.hubAddress === 'string' ? raw.hubAddress : undefined\n fileName = typeof raw.name === 'string' ? raw.name : undefined\n fileSecret = typeof raw.secret === 'string' ? raw.secret : undefined\n } catch { /* corrupt config */ }\n }\n\n // Config file wins over env for all user-editable fields\n const effectiveName = fileName ?? envName\n const effectiveHub = fileHubAddress ?? envHubAddress\n const effectiveSecret = fileSecret ?? envSecret\n\n return {\n nodeId,\n name: effectiveName,\n hubAddress: effectiveHub,\n dataDir: resolvedDataDir,\n addonsDir: path.resolve(resolvedDataDir, 'addons'),\n logLevel: process.env.CAMSTACK_LOG_LEVEL ?? 'info',\n secret: effectiveSecret,\n configPath: configFullPath,\n statusPort: Number(process.env.CAMSTACK_STATUS_PORT) || 4444,\n }\n}\n\nexport { loadAgentConfig }\nexport type { AgentConfig }\n","import * as os from 'node:os'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { ServiceSchema, Context } from 'moleculer'\nimport type { AgentHealth, IMetricsProvider } from '@camstack/types'\n\nfunction getLocalIps(): string[] {\n const interfaces = os.networkInterfaces()\n const ips: string[] = []\n for (const ifaces of Object.values(interfaces)) {\n if (!ifaces) continue\n for (const iface of ifaces) {\n if (iface.internal) continue\n ips.push(iface.address)\n }\n }\n return ips\n}\n\ninterface LoadedAddonEntry {\n readonly id: string\n readonly status: string\n readonly version?: string\n readonly packageName?: string\n readonly addon?: {\n shutdown?(): Promise<void>\n onHubReachable?(): Promise<void> | void\n }\n}\n\ninterface AgentServiceDeps {\n readonly addonsDir: string\n readonly dataDir: string\n /** Human-readable agent name from env/config (e.g. \"dev-agent-0\"). */\n agentName: string\n /** Path to the agent config file (for persisting renames). */\n readonly configPath: string\n readonly loadedAddons: Map<string, LoadedAddonEntry>\n /**\n * Resolver for the current metrics-provider cap. Looked up lazily so the\n * service still answers `$agent.status` even before the metrics addon has\n * finished initializing.\n */\n readonly getMetricsProvider?: () => IMetricsProvider | null\n /** Package version of the agent runtime (informational, surfaced via `$agent.health`). */\n readonly agentVersion?: string\n}\n\ninterface AgentConfigFileShape {\n readonly hubAddress?: string\n}\n\nfunction readHubAddressFromConfig(configPath: string): string | null {\n if (!configPath) return null\n try {\n if (!fs.existsSync(configPath)) return null\n const raw = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as AgentConfigFileShape\n return typeof raw.hubAddress === 'string' && raw.hubAddress.length > 0 ? raw.hubAddress : null\n } catch { return null }\n}\n\nfunction isHubConnected(broker: Context['broker']): boolean {\n try {\n const registry = (broker as unknown as Record<string, unknown>).registry as\n | { getNodeList?: (opts: { onlyAvailable: boolean }) => readonly { id: string }[] }\n | undefined\n const nodes = registry?.getNodeList?.({ onlyAvailable: true }) ?? []\n return nodes.some((n) => n.id === 'hub')\n } catch { return false }\n}\n\nfunction createAgentService(deps: AgentServiceDeps): ServiceSchema {\n return {\n name: '$agent',\n actions: {\n status: {\n handler: async (ctx: Context) => {\n const cpus = os.cpus()\n let cpuPercent = 0\n let memoryPercent = 0\n const metrics = deps.getMetricsProvider?.()\n if (metrics) {\n const snapshot = await metrics.getCached()\n if (snapshot) {\n cpuPercent = snapshot.cpu.total\n memoryPercent = snapshot.memory.percent\n }\n }\n return {\n nodeId: ctx.broker.nodeID,\n name: deps.agentName,\n platform: os.platform(),\n arch: os.arch(),\n hostname: os.hostname(),\n cpuCores: cpus.length,\n cpuModel: cpus[0]?.model,\n totalMemoryMB: Math.round(os.totalmem() / 1024 / 1024),\n freeMemoryMB: Math.round(os.freemem() / 1024 / 1024),\n cpuPercent,\n memoryPercent,\n uptime: os.uptime(),\n localIps: getLocalIps(),\n addons: [...deps.loadedAddons.values()].map((a) => ({\n id: a.id,\n status: a.status,\n version: a.version,\n packageName: a.packageName,\n })),\n }\n },\n },\n\n health: {\n handler: async (ctx: Context): Promise<AgentHealth> => {\n let cpuPercent = 0\n let memoryPercent = 0\n const metrics = deps.getMetricsProvider?.()\n if (metrics) {\n try {\n const snapshot = await metrics.getCached()\n if (snapshot) {\n cpuPercent = snapshot.cpu.total\n memoryPercent = snapshot.memory.percent\n }\n } catch { /* metrics may be transiently unavailable */ }\n }\n let total = 0\n let running = 0\n let errored = 0\n for (const a of deps.loadedAddons.values()) {\n total++\n if (a.status === 'running') running++\n else if (a.status === 'error') errored++\n }\n const hubAddress = readHubAddressFromConfig(deps.configPath)\n return {\n ok: errored === 0,\n nodeId: ctx.broker.nodeID,\n name: deps.agentName,\n version: deps.agentVersion ?? 'unknown',\n uptimeSeconds: Math.round(process.uptime()),\n pid: process.pid,\n hubConnected: isHubConnected(ctx.broker),\n hubAddress,\n addons: { total, running, error: errored },\n cpuPercent,\n memoryPercent,\n checkedAt: new Date().toISOString(),\n }\n },\n },\n\n shutdown: {\n handler() {\n // Graceful shutdown — schedule so the Moleculer response goes out first\n setTimeout(() => process.exit(0), 500)\n return { success: true }\n },\n },\n\n rename: {\n handler(ctx: Context<{ name: string }>) {\n const newName = ctx.params.name\n if (!newName || typeof newName !== 'string') {\n throw new Error('$agent.rename: name is required')\n }\n const oldName = deps.agentName\n // Update in-memory name (affects subsequent $agent.status responses)\n deps.agentName = newName.trim()\n ctx.broker.logger.info(`Agent renamed: \"${oldName}\" → \"${deps.agentName}\"`)\n // Persist to config file\n try {\n const configFile = path.resolve(deps.configPath)\n let raw: Record<string, unknown> = {}\n if (fs.existsSync(configFile)) {\n try { raw = JSON.parse(fs.readFileSync(configFile, 'utf-8')) as Record<string, unknown> } catch { /* corrupt */ }\n }\n raw.name = deps.agentName\n fs.mkdirSync(path.dirname(configFile), { recursive: true })\n fs.writeFileSync(configFile, JSON.stringify(raw, null, 2), 'utf-8')\n ctx.broker.logger.info(`Agent name persisted to ${configFile}`)\n } catch (err) {\n ctx.broker.logger.warn('Agent rename: config file write failed (in-memory rename still active)', { error: String(err) })\n }\n return { success: true, name: deps.agentName }\n },\n },\n\n listAddons: {\n handler() {\n return [...deps.loadedAddons.keys()]\n },\n },\n\n deploy: {\n handler: async (\n ctx: Context<{\n addonId: string\n bundle: Buffer | string\n config?: Record<string, unknown>\n }>,\n ) => {\n const { addonId, bundle } = ctx.params\n const addonDir = path.join(deps.addonsDir, addonId)\n\n fs.mkdirSync(deps.addonsDir, { recursive: true })\n\n const bundlePath = path.join(deps.addonsDir, `${addonId}.tgz`)\n const bufferData = typeof bundle === 'string' ? Buffer.from(bundle, 'base64') : bundle\n fs.writeFileSync(bundlePath, bufferData)\n\n const { execSync } = await import('node:child_process')\n fs.mkdirSync(addonDir, { recursive: true })\n execSync(`tar -xzf \"${bundlePath}\" -C \"${addonDir}\" --strip-components=1`, {\n timeout: 30000,\n })\n\n fs.unlinkSync(bundlePath)\n\n return { success: true, addonId, path: addonDir }\n },\n },\n\n undeploy: {\n handler: async (ctx: Context<{ addonId: string }>) => {\n const { addonId } = ctx.params\n const addonDir = path.join(deps.addonsDir, addonId)\n\n deps.loadedAddons.delete(addonId)\n\n if (fs.existsSync(addonDir)) {\n fs.rmSync(addonDir, { recursive: true, force: true })\n }\n\n return { success: true, addonId }\n },\n },\n\n restart: {\n handler: async (ctx: Context<{ addonId: string }>) => {\n const { addonId } = ctx.params\n return { success: true, addonId, action: 'restart-queued' }\n },\n },\n },\n }\n}\n\nexport { createAgentService }\nexport type { AgentServiceDeps, LoadedAddonEntry }\n","/**\n * Agent HTTP server -- lightweight Fastify instance for agent status,\n * process management, config editing, and static UI serving.\n */\nimport Fastify from 'fastify'\nimport type { FastifyInstance } from 'fastify'\nimport type { ServiceBroker } from 'moleculer'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\n\n// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\nexport interface AgentHttpConfig {\n readonly port: number\n readonly nodeId: string\n readonly dataDir: string\n readonly configPath: string\n /** Called when the UI requests a reconnect (hub/secret changed). */\n readonly onReconnect?: () => Promise<void>\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction resolveUiDistDir(dataDir: string): string | null {\n const candidates = [\n path.resolve(__dirname, '../../addon-agent-ui/dist'),\n path.join(dataDir, 'addons', '@camstack', 'addon-agent-ui', 'dist'),\n path.join(dataDir, 'agent-ui'),\n ]\n for (const dir of candidates) {\n if (fs.existsSync(path.join(dir, 'index.html'))) return dir\n }\n return null\n}\n\nfunction readConfigFile(configPath: string): Record<string, unknown> {\n if (!fs.existsSync(configPath)) return {}\n try {\n return JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Record<string, unknown>\n } catch { return {} }\n}\n\nfunction writeConfigFile(configPath: string, data: Record<string, unknown>): void {\n fs.mkdirSync(path.dirname(configPath), { recursive: true })\n fs.writeFileSync(configPath, JSON.stringify(data, null, 2), 'utf-8')\n}\n\nfunction getRegistryNodes(broker: ServiceBroker): readonly { id: string }[] {\n try {\n const registry = (broker as unknown as Record<string, unknown>).registry as\n | { getNodeList?: (opts: { onlyAvailable: boolean }) => readonly { id: string }[] }\n | undefined\n return registry?.getNodeList?.({ onlyAvailable: true }) ?? []\n } catch { return [] }\n}\n\n/**\n * Read the current effective config from the persisted file.\n * This is the single source of truth -- always reflects what the UI wrote.\n */\nfunction getEffectiveConfig(configPath: string, nodeId: string): {\n name: string\n hubAddress: string | null\n hasSecret: boolean\n} {\n const raw = readConfigFile(configPath)\n return {\n name: typeof raw.name === 'string' ? raw.name : nodeId,\n hubAddress: typeof raw.hubAddress === 'string' ? raw.hubAddress : null,\n hasSecret: typeof raw.secret === 'string' && raw.secret.length > 0,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport async function createAgentHttpServer(\n getBroker: () => ServiceBroker,\n config: AgentHttpConfig,\n): Promise<FastifyInstance> {\n const app = Fastify({ logger: false })\n\n const cors = await import('@fastify/cors')\n await app.register(cors.default)\n\n // -- Health ---------------------------------------------------------\n // Detailed shape lives on `$agent.health` (Moleculer action) so the\n // hub can call the same surface via `broker.call('$agent.health', {},\n // { nodeID })`. The HTTP route delegates so external monitors see the\n // identical payload.\n app.get('/health', async (_req, reply) => {\n try {\n const result = await getBroker().call('$agent.health')\n return result\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return reply.status(503).send({\n ok: false,\n nodeId: config.nodeId,\n error: message,\n })\n }\n })\n\n // -- Agent status (enriched with connection state) ------------------\n\n app.get('/api/agent/status', async () => {\n const broker = getBroker()\n const eff = getEffectiveConfig(config.configPath, config.nodeId)\n const nodes = getRegistryNodes(broker)\n const hubConnected = nodes.some(n => n.id === 'hub')\n const discoveryMode = !eff.hubAddress\n\n try {\n const status = await broker.call('$agent.status') as Record<string, unknown>\n return {\n ...status,\n name: eff.name,\n hubAddress: eff.hubAddress,\n hubConnected,\n discoveryMode,\n hasSecret: eff.hasSecret,\n discoveredNodes: nodes\n .filter(n => n.id !== broker.nodeID)\n .map(n => n.id),\n }\n } catch {\n return {\n nodeId: config.nodeId,\n name: eff.name,\n hubAddress: eff.hubAddress,\n hubConnected,\n discoveryMode,\n hasSecret: eff.hasSecret,\n discoveredNodes: [],\n addons: [],\n localIps: [],\n }\n }\n })\n\n // -- Processes ------------------------------------------------------\n\n app.get('/api/agent/processes', async () => {\n try { return await getBroker().call('$process.list') }\n catch { return [] }\n })\n\n // -- Addon restart --------------------------------------------------\n\n app.post<{ Body: { addonId: string } }>('/api/agent/addon/restart', async (req, reply) => {\n const addonId = req.body?.addonId\n if (!addonId) return reply.status(400).send({ error: 'addonId required' })\n return getBroker().call('$agent.restart', { addonId })\n })\n\n // -- Process restart ------------------------------------------------\n\n app.post<{ Body: { name: string } }>('/api/agent/process/restart', async (req, reply) => {\n const name = req.body?.name\n if (!name) return reply.status(400).send({ error: 'name required' })\n return getBroker().call('$process.restart', { name })\n })\n\n // -- Config read (always from file -- single source of truth) -------\n\n app.get('/api/agent/config', async () => {\n const persisted = readConfigFile(config.configPath)\n const eff = getEffectiveConfig(config.configPath, config.nodeId)\n return {\n nodeId: config.nodeId,\n name: eff.name,\n hubAddress: eff.hubAddress,\n hasSecret: eff.hasSecret,\n configPath: config.configPath,\n dataDir: config.dataDir,\n // Include all persisted fields except raw secret\n ...Object.fromEntries(\n Object.entries(persisted).filter(([k]) => k !== 'secret'),\n ),\n }\n })\n\n // -- Config write (merge-patch + persist) ---------------------------\n\n app.post<{ Body: Record<string, unknown> }>('/api/agent/config', async (req) => {\n const patch = req.body ?? {}\n const existing = readConfigFile(config.configPath)\n const merged = { ...existing, ...patch }\n writeConfigFile(config.configPath, merged)\n\n // Apply name change immediately (no reconnect needed)\n if (typeof patch.name === 'string' && patch.name.trim()) {\n try {\n await getBroker().call('$agent.rename', { name: patch.name.trim() })\n console.log(`[Agent] Name changed to \"${patch.name.trim()}\"`)\n } catch { /* best-effort */ }\n }\n\n const needsReconnect = Boolean(\n patch.hubAddress !== undefined ||\n patch.secret !== undefined\n )\n\n return {\n success: true,\n restartRequired: needsReconnect,\n }\n })\n\n // -- Agent reconnect (applies new hub/secret config) ----------------\n\n app.post('/api/agent/restart', async () => {\n if (!config.onReconnect) {\n return { success: false, message: 'Reconnect not available' }\n }\n console.log('[Agent] Reconnect requested from UI')\n void config.onReconnect().catch((err: unknown) => {\n console.error('[Agent] Reconnect failed:', err)\n })\n return { success: true, message: 'Agent reconnecting...' }\n })\n\n // -- Discovered nodes -----------------------------------------------\n\n app.get('/api/agent/discovered-nodes', async () => {\n const b = getBroker()\n const nodes = getRegistryNodes(b)\n return nodes\n .filter(n => n.id !== b.nodeID)\n .map(n => ({ id: n.id, isHub: n.id === 'hub' }))\n })\n\n // -- Static file serving (agent-ui) ---------------------------------\n\n const uiDir = resolveUiDistDir(config.dataDir)\n if (uiDir) {\n const fastifyStatic = await import('@fastify/static')\n await app.register(fastifyStatic.default, {\n root: uiDir,\n prefix: '/',\n wildcard: false,\n decorateReply: false,\n })\n\n app.setNotFoundHandler(async (req, reply) => {\n if (req.url.startsWith('/api/') || req.url.startsWith('/health')) {\n return reply.status(404).send({ error: 'Not found' })\n }\n return reply.type('text/html').sendFile('index.html')\n })\n\n console.log(`[Agent] UI served from: ${uiDir}`)\n }\n\n return app\n}\n\n// ---------------------------------------------------------------------------\n// Start helper\n// ---------------------------------------------------------------------------\n\nexport async function startAgentHttpServer(\n getBroker: () => ServiceBroker,\n config: AgentHttpConfig,\n): Promise<void> {\n try {\n const app = await createAgentHttpServer(getBroker, config)\n await app.listen({ port: config.port, host: '0.0.0.0' })\n console.log(`[Agent] HTTP server: http://localhost:${config.port}`)\n } catch (err) {\n console.warn(`[Agent] HTTP server failed to start on port ${config.port}:`, err)\n }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { startAgentHttpServer } from './agent-http.js'\nimport {\n createBroker,\n createAddonService,\n createAddonContext,\n createProcessService,\n AddonLoader,\n AddonInstaller,\n detectWorkspacePackagesDir,\n CapabilityRegistry,\n INFRA_CAPABILITIES,\n registerClusterEventsService,\n createHwAccelService,\n createKernelHwAccel,\n} from '@camstack/kernel'\nimport type { AddonContextOptions } from '@camstack/kernel'\nimport type { IStorageProvider, IScopedLogger, ILogDestination, IMetricsProvider } from '@camstack/types'\nimport {\n normalizeAddonInitResult,\n isDeployableToAgent,\n resolveAddonGroup,\n resolveAddonPlacement,\n} from '@camstack/types'\n// Capability definitions — must be declared before addon registerProvider() calls\nimport {\n storageCapability, settingsStoreCapability, logDestinationCapability, metricsProviderCapability,\n decoderCapability, motionDetectionCapability, pipelineExecutorCapability,\n pipelineRunnerCapability,\n audioAnalyzerCapability,\n platformProbeCapability,\n errMsg,\n} from '@camstack/types'\nimport { loadAgentConfig } from './agent-config.js'\nimport { createAgentService } from './agent-service.js'\nimport type { LoadedAddonEntry } from './agent-service.js'\n\n// ---------------------------------------------------------------------------\n// Agent LogManager — shared log pipeline for all addon loggers.\n// The hub-forwarder addon registers as a destination, so all log\n// entries flow through it (console output + hub forwarding).\n// ---------------------------------------------------------------------------\nimport { LogManager } from '@camstack/core'\n\nconst agentLogManager = new LogManager(5000)\n\n// ---------------------------------------------------------------------------\n// Main\n// ---------------------------------------------------------------------------\n\n\nasync function startAgent(configPath?: string): Promise<void> {\n const config = loadAgentConfig(configPath)\n\n if (config.hubAddress) {\n console.log(`[Agent] Starting node \"${config.nodeId}\" (name=\"${config.name}\") connecting to ${config.hubAddress}`)\n } else {\n console.log(`[Agent] Starting node \"${config.nodeId}\" (name=\"${config.name}\") in discovery mode`)\n }\n console.log(`[Agent] Config: ${config.configPath}`)\n console.log(`[Agent] Data dir: ${config.dataDir}`)\n\n // Ensure required addon packages are installed in the agent's addonsDir\n // Uses same AddonInstaller as the hub — symlinks in dev, npm install in prod.\n const explicitSource = process.env['CAMSTACK_INSTALL_SOURCE'] as 'npm' | 'symlink' | 'local' | undefined\n const workspaceDir = explicitSource === 'npm' ? null : detectWorkspacePackagesDir(config.dataDir)\n const installer = new AddonInstaller({\n addonsDir: config.addonsDir,\n workspacePackagesDir: workspaceDir ?? undefined,\n installSource: explicitSource,\n })\n await installer.ensureRequiredPackages(AddonInstaller.AGENT_PACKAGES)\n console.log(`[Agent] Addon packages ready in ${config.addonsDir}`)\n\n let broker = createBroker({\n nodeID: config.nodeId,\n mode: 'agent',\n hubAddress: config.hubAddress,\n logLevel: config.logLevel,\n secret: config.secret,\n })\n\n /**\n * Reconnect: stop the current broker, reload config from file,\n * create a new broker with the updated hub/secret, and restart.\n * The HTTP server stays alive throughout.\n */\n const reconnect = async (): Promise<void> => {\n console.log('[Agent] Reconnecting with updated config...')\n try {\n await broker.stop()\n } catch { /* already stopped */ }\n\n // Reload config from file (UI may have written new hubAddress/secret)\n const fresh = loadAgentConfig(undefined, config.dataDir)\n console.log(`[Agent] New config: hub=${fresh.hubAddress ?? 'discovery'}, secret=${fresh.secret ? 'yes' : 'none'}`)\n\n broker = createBroker({\n nodeID: config.nodeId,\n mode: 'agent',\n hubAddress: fresh.hubAddress,\n logLevel: fresh.logLevel,\n secret: fresh.secret,\n })\n await broker.start()\n console.log('[Agent] Reconnected successfully')\n }\n\n const loadedAddons = new Map<string, LoadedAddonEntry>()\n const consoleLogger: IScopedLogger = {\n info: (msg) => console.log(`[Agent] ${msg}`),\n warn: (msg) => console.warn(`[Agent] ${msg}`),\n error: (msg) => console.error(`[Agent] ${msg}`),\n debug: (msg) => console.debug(`[Agent] ${msg}`),\n child: () => consoleLogger,\n withTags: () => consoleLogger,\n }\n const capabilityRegistry = new CapabilityRegistry(consoleLogger)\n\n // Declare all capabilities the agent uses — required before registerProvider()\n const agentCapabilities = [\n storageCapability, settingsStoreCapability, logDestinationCapability, metricsProviderCapability,\n decoderCapability, motionDetectionCapability, pipelineExecutorCapability,\n pipelineRunnerCapability,\n audioAnalyzerCapability,\n platformProbeCapability,\n ]\n for (const cap of agentCapabilities) {\n capabilityRegistry.declareCapability(cap)\n }\n\n // Logger factory — creates scoped loggers from the shared LogManager.\n // All entries flow through registered ILogDestination providers (hub-forwarder).\n // No scope — the brand bracket `[agent/addonId]` already identifies the addon.\n // `addonId` tag is required for the brand bracket resolver.\n const loggerFactory = (addonId: string) => agentLogManager.createLogger().withTags({ addonId })\n\n const agentService = createAgentService({\n addonsDir: config.addonsDir,\n dataDir: config.dataDir,\n agentName: config.name,\n configPath: config.configPath,\n loadedAddons,\n // Resolve the current metrics-provider cap lazily from the registry.\n // The cap is registered during bootCoreAddons but may not exist in test\n // scenarios — `null` is a documented fallback for both.\n getMetricsProvider: () => capabilityRegistry.getSingleton<IMetricsProvider>('metrics-provider'),\n agentVersion: readAgentVersion(),\n })\n broker.createService(agentService)\n\n // $process service — manages forked child processes (same as hub)\n const processService = createProcessService(broker.nodeID, config.dataDir)\n broker.createService(processService)\n\n // $addonHost — REMOVED (Sprint 6). Three-level settings are now\n // exposed per-addon via `settings.*` actions in createAddonService.\n\n // Register $cluster-events BEFORE start so the service subscription\n // is announced during discovery. See addon-context-factory.ts for\n // the rationale — post-start registration propagates via heartbeat\n // and is unreliable for the first ~10s.\n registerClusterEventsService(broker)\n\n // Per-node `$hwaccel` — exposes this agent's local hwaccel probe to\n // the rest of the cluster. Hub UI calls\n // `broker.call('$hwaccel.resolve', {}, { nodeID: '<agent>' })` to\n // render the pipeline-page \"hardware acceleration\" column.\n broker.createService(createHwAccelService(createKernelHwAccel()))\n\n // Start broker BEFORE bootCoreAddons. Core infra addons (storage,\n // sqlite-settings, ...) run their own BaseAddon.initialize() which\n // calls `ctx.settings.readAddonStore()` on every addon; that call\n // routes through `brokerTransportLink` and would deadline-free poll\n // for the hub's `settings-store.get` service if the broker weren't\n // connected to the mesh yet. Starting the broker first lets service\n // discovery resolve (or time out cleanly via the read-blob fallback)\n // so agent boot completes instead of hanging on the first infra addon.\n await broker.start()\n\n // ── HTTP server (Fastify) — status API + process management + UI ──\n // Started early (before addon boot) so the status page is reachable\n // even while addons are still loading.\n void startAgentHttpServer(() => broker, {\n port: config.statusPort ?? 4444,\n nodeId: config.nodeId,\n dataDir: config.dataDir,\n configPath: config.configPath,\n onReconnect: reconnect,\n })\n\n // ── Phase 1: Load core infrastructure addons (in-process) ──\n // storage + settings + metrics + hub-forwarder (log destination)\n await bootCoreAddons(broker, config, capabilityRegistry, loadedAddons, loggerFactory)\n\n // Plug every registered `log-destination` provider into the shared\n // LogManager. The LogManager replays its ring buffer to each destination\n // on registration, so boot-time log entries still reach destinations that\n // came up mid-boot (e.g. hub-forwarder arriving after the first logs).\n for (const dest of capabilityRegistry.getCollection<ILogDestination>('log-destination')) {\n agentLogManager.addDestination(dest)\n }\n\n // Everything downstream reads the resolved infra providers from the\n // capability registry — no hand-curated side-channel.\n const storageProvider = capabilityRegistry.getSingleton<IStorageProvider>('storage') ?? undefined\n\n // `ctx.api` for every addon is built inside `createAddonContext` from\n // `[localProviderLink, brokerTransportLink(broker)]`. Unresolved calls\n // route via Moleculer to the hub (or any other node hosting the cap).\n // No separate hub WSS client, no `CAMSTACK_HUB_API_URL` — all cross-node\n // traffic rides the broker mesh.\n\n // ── Phase 1.5: Load cluster-capable addon packages (forkable → child process) ──\n await loadClusterCapableAddons(broker, config, capabilityRegistry, loadedAddons)\n\n // ── Phase 2: Load deployed addons (from hub $agent.deploy) ──\n await loadDeployedAddons(broker, config.addonsDir, config.dataDir, loadedAddons, storageProvider, loggerFactory, capabilityRegistry)\n\n // Fire `onHubReachable()` on every in-process addon as soon as the hub\n // node connects to our broker — this is the safe point for ctx.api.* calls\n // into hub-provided capabilities. Forked children get the same hook via\n // `process-runner.ts`.\n let hubReachableFired = false\n broker.localBus.on('$node.connected', ({ node }: { node: { id: string } }) => {\n if (node.id !== 'hub') return\n if (hubReachableFired) return\n hubReachableFired = true\n for (const [, entry] of loadedAddons) {\n if (!entry.addon || typeof entry.addon.onHubReachable !== 'function') continue\n Promise.resolve(entry.addon.onHubReachable()).catch((err: unknown) => {\n console.error(`[Agent] ${entry.id} onHubReachable() threw:`, err)\n })\n }\n })\n\n console.log(`[Agent] Node \"${config.nodeId}\" (name=\"${config.name}\") ready — ${loadedAddons.size} addon(s) loaded`)\n\n // Graceful shutdown\n const shutdown = async () => {\n console.log('[Agent] Shutting down...')\n for (const [, entry] of loadedAddons) {\n if (entry.addon?.shutdown) {\n try { await entry.addon.shutdown() } catch { /* */ }\n }\n }\n await broker.stop()\n process.exit(0)\n }\n process.on('SIGTERM', shutdown)\n process.on('SIGINT', shutdown)\n}\n\n// ---------------------------------------------------------------------------\n// Phase 1: Boot core addons (storage, settings, metrics — NO winston)\n// ---------------------------------------------------------------------------\n\n// Core infra addons to load on agent — all infra including log-destination (hub-forwarder)\nconst AGENT_INFRA = INFRA_CAPABILITIES\n\nasync function bootCoreAddons(\n broker: ReturnType<typeof createBroker>,\n config: { dataDir: string; addonsDir: string },\n registry: CapabilityRegistry,\n loadedAddons: Map<string, LoadedAddonEntry>,\n loggerFactory: (addonId: string) => IScopedLogger,\n): Promise<void> {\n // Scan every installed addon package — infra providers may live outside\n // `@camstack/core` (e.g. `@camstack/addon-platform-probe-native`).\n const packageDirs = resolveAddonPackageDirs(config.addonsDir)\n if (packageDirs.length === 0) {\n console.warn('[Agent] No addon packages found — running without infrastructure addons')\n return\n }\n\n console.log(`[Agent] Scanning ${packageDirs.length} addon package(s) for infra providers`)\n const loader = new AddonLoader()\n for (const dir of packageDirs) {\n try { await loader.loadFromAddonDir(dir) } catch (err) {\n console.warn(`[Agent] Failed to scan ${dir}: ${errMsg(err)}`)\n }\n }\n\n for (const infra of AGENT_INFRA) {\n const candidates = loader.listAddons().filter((a) =>\n a.declaration.capabilities?.some((c) => {\n const capName = typeof c === 'string' ? c : c.name\n return capName === infra.name\n }),\n )\n // For log-destination, prefer hub-forwarder over winston-logging\n const addon = infra.name === 'log-destination'\n ? candidates.find((a) => a.declaration.id === 'hub-forwarder') ?? candidates[0]\n : candidates[0]\n if (!addon) {\n if (infra.required) {\n console.error(`[Agent] Required infrastructure addon for \"${infra.name}\" not found`)\n }\n continue\n }\n\n const addonId = addon.declaration.id\n try {\n const instance = new addon.addonClass()\n // Seed ctx.kernel.storage from whatever storage provider is already\n // in the registry (the storage addon declares itself before the\n // addons that depend on it per AGENT_INFRA order).\n const storageProvider = registry.getSingleton<IStorageProvider>('storage') ?? undefined\n const context = createAddonContext(broker, addon.declaration, config.dataDir, {\n storageProvider,\n addonConfig: { rootPath: config.dataDir },\n createLogger: loggerFactory,\n capabilityRegistry: registry,\n })\n\n const initResult = normalizeAddonInitResult(await instance.initialize(context))\n\n for (const reg of initResult?.providers ?? []) {\n const capName = reg.capability.name\n registry.registerProvider(capName, addonId, reg.provider)\n // Also register in the per-broker context registry\n context.registerProvider(capName, reg.provider)\n }\n\n loadedAddons.set(addonId, {\n id: addonId,\n status: 'running',\n version: addon.declaration.version,\n packageName: addon.packageName,\n addon: instance,\n })\n\n console.log(`[Agent] Core addon \"${addonId}\" initialized`)\n } catch (err) {\n const msg = errMsg(err)\n console.error(`[Agent] Failed to initialize core addon \"${addonId}\": ${msg}`)\n if (infra.required) {\n throw new Error(`Required infrastructure addon \"${addonId}\" failed: ${msg}`, { cause: err })\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Phase 1.5: Load cluster-capable addon packages\n// ---------------------------------------------------------------------------\n\nasync function loadClusterCapableAddons(\n broker: ReturnType<typeof createBroker>,\n config: { dataDir: string; addonsDir: string },\n capabilityRegistry: CapabilityRegistry,\n loadedAddons: Map<string, LoadedAddonEntry>,\n): Promise<void> {\n const addonPackageDirs = resolveAddonPackageDirs(config.addonsDir)\n if (addonPackageDirs.length === 0) return\n\n // ── Phase 0 (cross-package): collect every group-eligible addon\n // across ALL package dirs FIRST so we issue exactly one\n // `$process.spawnGroup` per group. Doing this inside the per-dir\n // loop spawned the same group multiple times — Moleculer rejected\n // subsequent attempts with \"already running\" and the surviving\n // subprocess only had the first dir's subset of addons.\n type GroupCandidate = {\n readonly groupId: string\n readonly addonId: string\n readonly addonDir: string\n readonly version: string\n readonly packageName: string\n readonly capabilities: ReadonlyArray<string | { readonly name: string }>\n }\n const allGroupCandidates: GroupCandidate[] = []\n // Loaders are reused below for the per-addon legacy path; cache them\n // so each dir is parsed once.\n const dirToLoader = new Map<string, AddonLoader>()\n\n for (const dir of addonPackageDirs) {\n const loader = new AddonLoader()\n try {\n await loader.loadFromAddonDir(dir)\n } catch (err) {\n console.warn(`[Agent] Skipping ${dir}: ${errMsg(err)}`)\n continue\n }\n dirToLoader.set(dir, loader)\n\n for (const registered of loader.listAddons()) {\n if (loadedAddons.has(registered.declaration.id)) continue\n if (registered.declaration.execution === undefined) continue\n const placement = resolveAddonPlacement(registered.declaration)\n if (placement === 'hub-only') continue\n allGroupCandidates.push({\n groupId: resolveAddonGroup(registered.declaration),\n addonId: registered.declaration.id,\n addonDir: dir,\n version: registered.declaration.version ?? '0.0.0',\n packageName: registered.packageName,\n capabilities: registered.declaration.capabilities ?? [],\n })\n }\n }\n\n if (allGroupCandidates.length > 0) {\n const grouped = new Map<string, GroupCandidate[]>()\n for (const c of allGroupCandidates) {\n const arr = grouped.get(c.groupId) ?? []\n arr.push(c)\n grouped.set(c.groupId, arr)\n }\n for (const [groupId, addons] of grouped) {\n try {\n await broker.call('$process.spawnGroup', {\n groupId,\n addons: addons.map((a) => ({ addonId: a.addonId, addonDir: a.addonDir })),\n })\n for (const a of addons) {\n for (const cap of a.capabilities) {\n const capName = typeof cap === 'string' ? cap : cap.name\n const proxy = new Proxy<Record<string, unknown>>({}, {\n get(_target, prop: string) {\n if (prop === 'then' || typeof prop === 'symbol') return undefined\n return (params: unknown) => broker.call(`${a.addonId}.${capName}.${prop}`, params)\n },\n })\n capabilityRegistry.registerProvider(capName, a.addonId, proxy)\n }\n loadedAddons.set(a.addonId, {\n id: a.addonId,\n status: 'running',\n version: a.version,\n packageName: a.packageName,\n })\n }\n console.log(`[Agent] Group \"${groupId}\" spawned with ${addons.length} addon(s): ${addons.map((a) => a.addonId).join(', ')}`)\n } catch (err) {\n const msg = err instanceof Error ? err.stack ?? err.message : String(err)\n console.error(`[Agent] Failed to spawn group \"${groupId}\": ${msg}`)\n for (const a of addons) {\n loadedAddons.set(a.addonId, { id: a.addonId, status: 'error' })\n }\n }\n }\n }\n\n // Diagnostic — list addons that exist in the agent's package dir but\n // were filtered out by Phase 0 (placement=hub-only or no execution).\n for (const dir of addonPackageDirs) {\n const loader = dirToLoader.get(dir)\n if (!loader) continue\n for (const registered of loader.listAddons()) {\n const addonId = registered.declaration.id\n if (loadedAddons.has(addonId)) continue\n if (!isDeployableToAgent(registered.declaration)) continue\n console.warn(\n `[Agent] Addon \"${addonId}\" is deployable but missing from any spawned group — verify package.json execution field`,\n )\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Phase 2: Load deployed addons (pushed from hub via $agent.deploy)\n// ---------------------------------------------------------------------------\n\nasync function loadDeployedAddons(\n broker: ReturnType<typeof createBroker>,\n addonsDir: string,\n dataDir: string,\n loadedAddons: Map<string, LoadedAddonEntry>,\n storageProvider: IStorageProvider | undefined,\n loggerFactory: (addonId: string) => IScopedLogger,\n capabilityRegistry?: CapabilityRegistry,\n): Promise<void> {\n if (!fs.existsSync(addonsDir)) return\n\n const loader = new AddonLoader()\n await loader.loadFromDirectory(addonsDir)\n\n const contextOptions: AddonContextOptions = {\n storageProvider,\n addonConfig: storageProvider\n ? { modelsDir: storageProvider.resolve({ location: 'models', relativePath: '' }) }\n : {},\n createLogger: loggerFactory,\n capabilityRegistry,\n }\n\n for (const registered of loader.listAddons()) {\n const addonId = registered.declaration.id\n if (loadedAddons.has(addonId)) continue\n if (!isDeployableToAgent(registered.declaration)) continue\n\n try {\n const instance = new registered.addonClass()\n const context = createAddonContext(broker, registered.declaration, dataDir, contextOptions)\n await instance.initialize(context)\n\n const service = createAddonService(instance, registered.declaration)\n broker.createService(service)\n\n loadedAddons.set(addonId, {\n id: addonId,\n status: 'running',\n version: registered.declaration.version,\n packageName: registered.packageName,\n addon: instance,\n })\n\n console.log(`[Agent] Deployed addon \"${addonId}\" loaded`)\n } catch (err) {\n const msg = errMsg(err)\n console.error(`[Agent] Failed to load deployed addon \"${addonId}\": ${msg}`)\n loadedAddons.set(addonId, { id: addonId, status: 'error' })\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Read the agent's own package.json version (best-effort). */\nfunction readAgentVersion(): string {\n // package.json sits two dirs up from `dist/`. Walk up until we hit it.\n const candidates = [\n path.resolve(__dirname, '..', 'package.json'),\n path.resolve(__dirname, '..', '..', 'package.json'),\n ]\n for (const candidate of candidates) {\n try {\n if (!fs.existsSync(candidate)) continue\n const raw = JSON.parse(fs.readFileSync(candidate, 'utf-8')) as { name?: string; version?: string }\n if (raw.name === '@camstack/agent' && typeof raw.version === 'string') return raw.version\n } catch { /* keep searching */ }\n }\n return 'unknown'\n}\n\n/** Check if path is a directory (follows symlinks) */\nfunction isDir(p: string): boolean {\n try { return fs.statSync(p).isDirectory() } catch { return false }\n}\n\n/** Scan addonsDir for addon packages (scoped and unscoped, follows symlinks) */\nfunction resolveAddonPackageDirs(addonsDir: string): string[] {\n const dirs: string[] = []\n if (!fs.existsSync(addonsDir)) return dirs\n\n for (const name of fs.readdirSync(addonsDir)) {\n const full = path.join(addonsDir, name)\n if (name.startsWith('@') && isDir(full)) {\n // Scoped packages: @camstack/addon-xyz\n for (const sub of fs.readdirSync(full)) {\n const subFull = path.join(full, sub)\n if (isDir(subFull) && fs.existsSync(path.join(subFull, 'package.json'))) {\n dirs.push(subFull)\n }\n }\n } else if (isDir(full) && fs.existsSync(path.join(full, 'package.json'))) {\n dirs.push(full)\n }\n }\n\n return dirs\n}\n\n// Run if executed directly\nconst scriptName = process.argv[1] ?? ''\nif (scriptName.endsWith('agent-bootstrap.js') || scriptName.endsWith('agent-bootstrap.ts')) {\n startAgent().catch((err: unknown) => {\n console.error('[Agent] Fatal error:', err)\n process.exit(1)\n })\n}\n\nexport { startAgent }\n"],"mappings":"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","names":["os","fs","path","cpus","fs","path","fs","path"]}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|