@synap-core/eve 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +251 -0
  2. package/dist/add-R6RGUYER.js +22 -0
  3. package/dist/add-R6RGUYER.js.map +1 -0
  4. package/dist/auth-7FFZNARZ-4OIRGZ7R.js +31 -0
  5. package/dist/auth-7FFZNARZ-4OIRGZ7R.js.map +1 -0
  6. package/dist/chunk-22RIHU4J.js +975 -0
  7. package/dist/chunk-22RIHU4J.js.map +1 -0
  8. package/dist/chunk-23XQDB7K.js +1773 -0
  9. package/dist/chunk-23XQDB7K.js.map +1 -0
  10. package/dist/chunk-5TBV2VHZ.js +6067 -0
  11. package/dist/chunk-5TBV2VHZ.js.map +1 -0
  12. package/dist/chunk-D7P3IYYR.js +44 -0
  13. package/dist/chunk-D7P3IYYR.js.map +1 -0
  14. package/dist/chunk-EHPC7CKE.js +757 -0
  15. package/dist/chunk-EHPC7CKE.js.map +1 -0
  16. package/dist/chunk-FAE5UZFE.js +17 -0
  17. package/dist/chunk-FAE5UZFE.js.map +1 -0
  18. package/dist/chunk-HRF6TNXX.js +53 -0
  19. package/dist/chunk-HRF6TNXX.js.map +1 -0
  20. package/dist/chunk-HVJEW7TU.js +495 -0
  21. package/dist/chunk-HVJEW7TU.js.map +1 -0
  22. package/dist/chunk-JO5H5G6U.js +1529 -0
  23. package/dist/chunk-JO5H5G6U.js.map +1 -0
  24. package/dist/chunk-MUEQNBE6.js +1140 -0
  25. package/dist/chunk-MUEQNBE6.js.map +1 -0
  26. package/dist/chunk-O5WTCVMZ.js +3391 -0
  27. package/dist/chunk-O5WTCVMZ.js.map +1 -0
  28. package/dist/chunk-ROKIQIEX.js +65 -0
  29. package/dist/chunk-ROKIQIEX.js.map +1 -0
  30. package/dist/chunk-T7GCAJK5.js +4895 -0
  31. package/dist/chunk-T7GCAJK5.js.map +1 -0
  32. package/dist/chunk-UOQWJ3S4.js +138 -0
  33. package/dist/chunk-UOQWJ3S4.js.map +1 -0
  34. package/dist/chunk-YQWV5W4U.js +3479 -0
  35. package/dist/chunk-YQWV5W4U.js.map +1 -0
  36. package/dist/chunk-ZPDNZRVW.js +272 -0
  37. package/dist/chunk-ZPDNZRVW.js.map +1 -0
  38. package/dist/config-store-KTOWIKAS-XVZHNPKW.js +11 -0
  39. package/dist/config-store-KTOWIKAS-XVZHNPKW.js.map +1 -0
  40. package/dist/dist-2VRFSXMO.js +40 -0
  41. package/dist/dist-2VRFSXMO.js.map +1 -0
  42. package/dist/dist-C2QB4IKT.js +340 -0
  43. package/dist/dist-C2QB4IKT.js.map +1 -0
  44. package/dist/dist-DEIUVZ57.js +299 -0
  45. package/dist/dist-DEIUVZ57.js.map +1 -0
  46. package/dist/dist-DSKHGECB.js +36 -0
  47. package/dist/dist-DSKHGECB.js.map +1 -0
  48. package/dist/dist-GN2DN7CI.js +95 -0
  49. package/dist/dist-GN2DN7CI.js.map +1 -0
  50. package/dist/dist-TZL4XW2R.js +58 -0
  51. package/dist/dist-TZL4XW2R.js.map +1 -0
  52. package/dist/dist-ZP2APOYV.js +53 -0
  53. package/dist/dist-ZP2APOYV.js.map +1 -0
  54. package/dist/index.js +15083 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/operational-5RT6AZJI-ZEMPD32Q.js +12 -0
  57. package/dist/operational-5RT6AZJI-ZEMPD32Q.js.map +1 -0
  58. package/dist/reconcile-A4I3Z7VX-GQMEN4GC.js +12 -0
  59. package/dist/reconcile-A4I3Z7VX-GQMEN4GC.js.map +1 -0
  60. package/dist/rsshub-GOJBTNOD-UNNVKBFL.js +18 -0
  61. package/dist/rsshub-GOJBTNOD-UNNVKBFL.js.map +1 -0
  62. package/dist/synap-image-install-X36REYQ5-UGO4MAOP.js +17 -0
  63. package/dist/synap-image-install-X36REYQ5-UGO4MAOP.js.map +1 -0
  64. package/package.json +44 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/add.ts","../src/lib/ui.ts"],"sourcesContent":["/**\n * `eve add <component>` — add a component to an existing entity.\n *\n * Resolves the component from the shared registry, checks prerequisites,\n * runs the appropriate organ install, then updates state.json and setup-profile.json.\n */\n\nimport type { Command } from 'commander';\nimport { execa } from 'execa';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { select, text, isCancel, cancel } from '@clack/prompts';\nimport {\n entityStateManager,\n readEveSecrets,\n writeEveSecrets,\n ensureEveSkillsLayout,\n defaultSkillsDir,\n} from '@eve/dna';\n\nconst execFileAsync = promisify(execFile);\n\n/** True if a container with that name exists (any state). */\nasync function containerExists(name: string): Promise<boolean> {\n try {\n const { stdout } = await execFileAsync(\n 'docker', ['ps', '-a', '--filter', `name=^${name}$`, '--format', '{{.Names}}'],\n { timeout: 4000 },\n );\n return stdout.trim() === name;\n } catch { return false; }\n}\n\n/**\n * Find a running canonical Synap compose service by labels. Eve's\n * `eve-brain-*` values are Docker network aliases, never container names.\n */\nasync function findSynapComposeContainer(\n service: 'backend' | 'pod-admin',\n): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(\n 'docker',\n [\n 'ps',\n '--filter', 'label=com.docker.compose.project=synap-backend',\n '--filter', `label=com.docker.compose.service=${service}`,\n '--format', '{{.Names}}',\n ],\n { timeout: 4000 },\n );\n return stdout.trim().split('\\n')[0]?.trim() || null;\n } catch { return null; }\n}\n\nasync function findSynapBackendContainer(): Promise<string | null> {\n return findSynapComposeContainer('backend');\n}\n\nfunction hasCanonicalSynapDeployment(): boolean {\n const delegate = resolveSynapDelegate();\n return Boolean(delegate && existsSync(join(delegate.deployDir, '.env')));\n}\n\n/**\n * An existing canonical Pod is recovered by its own CLI, never by rerunning\n * installation. A missing Pod Admin service must not cause Eve to replace the\n * Pod's bootstrap path or ask the operator for installation details again.\n */\nasync function reportExistingSynapDeployment(): Promise<boolean> {\n const delegate = resolveSynapDelegate();\n if (!delegate || !hasCanonicalSynapDeployment()) return false;\n\n const [backend, podAdmin] = await Promise.all([\n findSynapComposeContainer('backend'),\n findSynapComposeContainer('pod-admin'),\n ]);\n\n printWarning(`Synap Data Pod is already installed at ${delegate.repoRoot}.`);\n if (backend && podAdmin) {\n await entityStateManager.updateComponentEntry('synap', { state: 'ready' });\n printInfo(` Backend (${backend}) and Pod Admin (${podAdmin}) are running.`);\n } else {\n await entityStateManager.updateComponentEntry('synap', { state: 'error' });\n const missing = [!backend && 'backend', !podAdmin && 'pod-admin']\n .filter(Boolean)\n .join(', ');\n printWarning(` Pod service${missing.includes(',') ? 's' : ''} not running: ${missing}.`);\n printInfo(' Eve will not reinstall the Pod or replace its identity.');\n printInfo(' Recover it with: eve update synap');\n }\n return true;\n}\n\nasync function findSynapPostgresContainer(): Promise<string | null> {\n try {\n // Match any compose postgres service regardless of project name\n const { stdout } = await execFileAsync(\n 'docker',\n [\n 'ps',\n '--filter', 'label=com.docker.compose.service=postgres',\n '--filter', 'ancestor=postgres',\n '--format', '{{.Names}}',\n ],\n { timeout: 4000 },\n );\n return stdout.trim().split('\\n')[0]?.trim() || null;\n } catch { return null; }\n}\n\n/**\n * Returns true if the brain (synap) is ready.\n * Checks state.json first; if state says error/missing but the synap backend\n * container is actually running, auto-reconciles state to 'ready' so\n * manually-deployed pods don't get blocked.\n */\nasync function isBrainReady(): Promise<boolean> {\n const state = await entityStateManager.getState();\n if (state.organs.brain.state === 'ready') return true;\n\n // State is stale — check if the synap backend container is actually running\n const container = await findSynapBackendContainer();\n if (!container) return false;\n\n // Container is up but state is wrong — reconcile\n printInfo(`Synap container (${container}) is running — reconciling state to ready.`);\n await entityStateManager.updateOrgan('brain', 'ready');\n return true;\n}\nimport { runBrainInit, runInferenceInit, resolveSynapDelegate } from '@eve/brain';\nimport { runLegsProxySetup, verifyComponent, installDashboardContainer } from '@eve/legs';\nimport { materializeTargets, normalizeBareDomain } from '@eve/lifecycle';\nimport {\n colors,\n emojis,\n printHeader,\n printSuccess,\n printError,\n printInfo,\n printWarning,\n createSpinner,\n} from '../lib/ui.js';\nimport {\n COMPONENTS,\n type ComponentInfo,\n resolveComponent,\n selectedIds,\n allComponentIds,\n} from '../lib/components.js';\n\n// Organ → install function mapping for add operations.\n// Each add operation is lighter than a fresh install — no full setup wizard.\n\ninterface AddFn {\n label: string;\n fn: () => Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Component-specific add implementations\n// ---------------------------------------------------------------------------\n\nasync function addTraefik(): Promise<void> {\n await runLegsProxySetup({ standalone: true });\n}\n\nasync function addSynap(): Promise<void> {\n // Resolution chain matches `eve install` (single funnel): explicit flag\n // → SYNAP_REPO_ROOT → resolveSynapDelegate (auto-detect /opt/synap-backend\n // and friends). The previous version checked only the env var and bailed\n // even when /opt/synap-backend was right there.\n const flags = process.argv.slice(2);\n const flagRepoIdx = flags.indexOf('--synap-repo');\n const flagRepo = flagRepoIdx >= 0 ? flags[flagRepoIdx + 1] : undefined;\n const envRepo = process.env.SYNAP_REPO_ROOT;\n const delegate = resolveSynapDelegate();\n const repoRoot = flagRepo || envRepo || delegate?.repoRoot;\n if (!repoRoot || !existsSync(repoRoot)) {\n printWarning(\n 'Synap installation requires a synap-backend checkout.\\n' +\n ` Pass --synap-repo <path>, set SYNAP_REPO_ROOT, or clone to /opt/synap-backend.\\n` +\n ' See: https://github.com/synap/synap-backend',\n );\n process.exit(1);\n }\n\n // Pull domain/email from secrets so an existing pod doesn't get reset to\n // localhost defaults. Mirrors what gatherInstallConfig does for `eve install`.\n // `eve` is commonly invoked from the Pod deploy directory during recovery.\n // Its own domain/contact settings live in EVE_HOME, not in that transient\n // current directory.\n const secrets = await readEveSecrets(process.env.EVE_HOME ?? process.cwd()).catch(() => null);\n const flagDomainIdx = flags.indexOf('--domain');\n const flagDomain = flagDomainIdx >= 0 ? flags[flagDomainIdx + 1] : undefined;\n const domain =\n normalizeBareDomain(flagDomain) ||\n normalizeBareDomain(secrets?.domain?.primary) ||\n 'localhost';\n const email =\n process.env.LETSENCRYPT_EMAIL?.trim() ||\n secrets?.domain?.email?.trim() ||\n (domain !== 'localhost' ? `noreply@${domain}` : undefined);\n\n await runBrainInit({\n synapRepo: repoRoot,\n domain,\n email,\n adminBootstrapMode: 'token',\n withAi: false,\n withOpenclaw: false,\n withRsshub: false,\n });\n}\n\nasync function addOllama(model?: string): Promise<void> {\n await runInferenceInit({ model, withGateway: true, internalOllamaOnly: true });\n}\n\nasync function addOpenclaw(): Promise<void> {\n if (!await isBrainReady()) {\n printError('Brain is not ready. Please install Synap first: `eve add synap`');\n process.exit(1);\n }\n\n // Check for synap delegate (bash script path)\n const synapScript = process.env.SYNAP_SETUP_SCRIPT;\n if (synapScript && existsSync(synapScript)) {\n await execa('bash', [synapScript, 'profiles', 'enable', 'openclaw'], {\n env: { ...process.env, SYNAP_DEPLOY_DIR: process.env.SYNAP_DEPLOY_DIR || '', SYNAP_ASSUME_YES: '1' },\n stdio: 'inherit',\n });\n await execa('bash', [synapScript, 'services', 'add', 'openclaw'], {\n env: { ...process.env, SYNAP_DEPLOY_DIR: process.env.SYNAP_DEPLOY_DIR || '', SYNAP_ASSUME_YES: '1' },\n stdio: 'inherit',\n });\n } else {\n printWarning('OpenClaw add via Synap delegate not available.');\n printInfo(' Set SYNAP_SETUP_SCRIPT to point to synap-backend/setup.sh for auto-provisioning.');\n printInfo(' Otherwise install OpenClaw manually: https://github.com/danielmiessler/openclaw');\n }\n}\n\n/**\n * Patch Nango's Connect UI index.html with a setImmediate polyfill, copy the\n * patched file to the host, then recreate the container with it volume-mounted\n * read-only so the fix survives restarts and image updates.\n */\nasync function applyNangoConnectUiPolyfill(originalDockerRunArgs: string[]): Promise<void> {\n const hostPath = '/opt/nango/connect-ui-index.html';\n const containerPath = '/app/nango/packages/connect-ui/dist/index.html';\n const containerName = 'eve-arms-nango';\n const image = 'nangohq/nango-server:hosted';\n\n printInfo('Applying setImmediate polyfill to Nango Connect UI...');\n\n // Extract the ORIGINAL index.html from a FRESH temp container (no volume\n // mount), NOT from the running container. The running container may have\n // a stale host file mounted with outdated asset hashes from a previous\n // Nango version.\n const extractAndPatch = `\n const fs = require('fs');\n const p = '${containerPath}';\n let h = fs.readFileSync(p, 'utf8');\n if (h.includes('window.setImmediate = window.setImmediate ||')) {\n console.log('already patched'); process.exit(0);\n }\n const poly = '<script>\\\\n(function() {\\\\n' +\n ' window.setImmediate = window.setImmediate || function(fn) {\\\\n' +\n ' var args = Array.prototype.slice.call(arguments, 1);\\\\n' +\n ' var id = setTimeout(function() { fn.apply(null, args); }, 0);\\\\n' +\n ' return { _id: id, type: \\\\'Immediate\\\\' };\\\\n' +\n ' };\\\\n' +\n ' window.clearImmediate = window.clearImmediate || function(h) { clearTimeout(h && h._id !== undefined ? h._id : h); };\\\\n' +\n '})();\\\\n' +\n '<\\\\/script>';\n // Insert as first element in <head> so it runs before any module scripts\n h = h.replace('<head>', '<head>\\\\n' + poly);\n fs.writeFileSync(p, h);\n console.log('patched ok');\n `.trim();\n\n const tmpContainer = 'eve-nango-polyfill-tmp';\n try {\n await execFileAsync('docker', ['rm', '-f', tmpContainer], { timeout: 10_000 }).catch(() => {});\n await execFileAsync('docker', ['create', '--name', tmpContainer, image], { timeout: 15_000 });\n await execFileAsync('docker', ['exec', tmpContainer, 'node', '-e', extractAndPatch], { timeout: 15_000 });\n await execFileAsync('sh', ['-c', `mkdir -p \"$(dirname ${hostPath})\"`], { timeout: 5_000 }).catch(() => {});\n await execFileAsync('docker', ['cp', `${tmpContainer}:${containerPath}`, hostPath], { timeout: 10_000 });\n await execFileAsync('docker', ['rm', '-f', tmpContainer], { timeout: 10_000 }).catch(() => {});\n } catch (err) {\n printWarning(` Could not patch via temp container: ${(err as Error).message}`);\n // Fallback: patch running container (works on first install before volume mount)\n try {\n await execFileAsync('docker', ['exec', containerName, 'node', '-e', extractAndPatch], { timeout: 15_000 });\n await execFileAsync('docker', ['cp', `${containerName}:${containerPath}`, hostPath], { timeout: 10_000 });\n } catch (err2) {\n printWarning(` Fallback also failed: ${(err2 as Error).message}`);\n return;\n }\n }\n\n // Recreate container with the patched file mounted read-only.\n printInfo(' Recreating container with polyfill volume mount...');\n await execFileAsync('docker', ['rm', '-f', containerName], { timeout: 10_000 }).catch(() => {});\n const newArgs = [\n ...originalDockerRunArgs,\n '-v', `${hostPath}:${containerPath}:ro`,\n ];\n await execFileAsync('docker', newArgs, { timeout: 30_000 });\n printInfo(' Container recreated — polyfill is now permanent.');\n}\n\n/** Wait for Nango to accept requests then create the initial admin account (idempotent). */\n/**\n * Create/verify the Nango admin account and return the environment's actual\n * secret key (the one stored in _nango_environments, NOT the UUID we generated).\n *\n * Nango's signup creates its own environment secret key — our generated UUID\n * is only used as NANGO_SECRET_KEY (server-level identifier) during container\n * startup, but API calls must use the environment key from the Nango DB.\n */\nasync function nangoAutoSignup(secretKey: string, ownerEmail?: string): Promise<string | null> {\n const email = ownerEmail ?? 'admin@eve.local';\n // Derived password satisfies Nango's complexity rules: uppercase + lowercase + number + special\n const pw = `Nango_${secretKey.slice(0, 12)}`;\n // Use 127.0.0.1 explicitly — inside the container `localhost` may resolve to IPv6 ::1\n // while Nango only binds on IPv4, causing ECONNREFUSED.\n const node = `\n const attempt = (n) => fetch('http://127.0.0.1:3003/api/v1/account/signup', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name: 'Admin', email: ${JSON.stringify(email)}, password: ${JSON.stringify(pw)} }),\n }).then(r => r.json()).then(d => {\n const code = d?.error?.code ?? d?.error;\n if (d?.data?.uuid || code === 'account_already_exists' || code === 'email_not_verified') process.exit(0);\n if (n > 0) setTimeout(() => attempt(n - 1), 2000); else process.exit(1);\n }).catch(() => { if (n > 0) setTimeout(() => attempt(n - 1), 2000); else process.exit(1); });\n attempt(15);\n `;\n await execFileAsync('docker', ['exec', 'eve-arms-nango', 'node', '-e', node], { timeout: 40_000 }).catch(() => {/* non-fatal */});\n\n // Auto-verify the email directly in the DB so login works without SMTP.\n const pgContainer = await findSynapPostgresContainer();\n if (pgContainer) {\n await execFileAsync('docker', [\n 'exec', pgContainer,\n 'psql', '-U', 'synap', '-d', 'nango',\n '-c', `UPDATE nango._nango_users SET email_verified = true WHERE email = '${email}';`,\n ], { timeout: 10_000 }).catch(() => {/* non-fatal — table may not exist yet */});\n }\n\n // Fetch the actual environment secret key from Nango via signin + /api/v1/environment.\n // This is the key that must be used as Bearer token for all subsequent API calls.\n const fetchEnvKey = `\n const signin = await fetch('http://127.0.0.1:3003/api/v1/account/signin', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email: ${JSON.stringify(email)}, password: ${JSON.stringify(pw)} }),\n }).then(r => r.json()).catch(() => null);\n const token = signin?.data?.token;\n if (!token) { process.stdout.write(''); process.exit(0); }\n const env = await fetch('http://127.0.0.1:3003/api/v1/environment', {\n headers: { Authorization: 'Bearer ' + token },\n }).then(r => r.json()).catch(() => null);\n const key = env?.data?.secret_key ?? env?.secret_key ?? '';\n process.stdout.write(key);\n `;\n try {\n const { stdout } = await execFileAsync('docker', ['exec', 'eve-arms-nango', 'node', '--input-type=module', '-e', fetchEnvKey], { timeout: 15_000 });\n const envKey = stdout.trim();\n if (envKey && envKey.length > 10) {\n printInfo(` Nango environment secret key retrieved: ${envKey.slice(0, 8)}...`);\n return envKey;\n }\n } catch { /* non-fatal — caller falls back to generated key */ }\n return null;\n}\n\nasync function addNango(): Promise<void> {\n if (!await isBrainReady()) {\n printError('Brain is not ready. Install Synap first: `eve add synap`');\n process.exit(1);\n }\n\n const { randomUUID } = await import('node:crypto');\n const { readFile, writeFile } = await import('node:fs/promises');\n const { existsSync } = await import('node:fs');\n const { join: pathJoin } = await import('node:path');\n\n // Generate a UUID v4 secret key — Nango validates the key must be UUID v4 format\n const secrets = await readEveSecrets(process.cwd()).catch(() => null);\n const existingKey = secrets?.connectors?.nango?.secretKey;\n const uuidV4Re = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n const secretKey = (existingKey && uuidV4Re.test(existingKey)) ? existingKey : randomUUID();\n\n // Resolve deploy/.env early so we can read PUBLIC_URL and postgres credentials\n // BEFORE they're needed (the nango DB below is created with pgUser).\n // Detection order:\n // 1. SYNAP_DEPLOY_DIR env var (explicit override)\n // 2. Well-known path /opt/synap-backend/deploy\n // 3. Auto-detect from running backend container's compose project.working_dir label\n const _autoDetectDeployDir = async (): Promise<string | null> => {\n const container = await findSynapBackendContainer();\n if (!container) return null;\n try {\n const { stdout } = await execFileAsync('docker', [\n 'inspect', container,\n '--format', '{{index .Config.Labels \"com.docker.compose.project.working_dir\"}}',\n ], { timeout: 4000 });\n const dir = stdout.trim();\n return dir || null;\n } catch { return null; }\n };\n const deployDir: string | null =\n process.env.SYNAP_DEPLOY_DIR ||\n (existsSync('/opt/synap-backend/deploy') ? '/opt/synap-backend/deploy' : null) ||\n await _autoDetectDeployDir();\n\n let podPublicUrl = '';\n let pgUser = 'synap';\n let pgPassword = 'synap';\n if (deployDir) {\n const { readFile: rf } = await import('node:fs/promises');\n const envPath = pathJoin(deployDir, '.env');\n try {\n const envContent = await rf(envPath, 'utf8');\n const matchUrl = envContent.match(/^PUBLIC_URL=(.+)$/m);\n if (matchUrl?.[1]) podPublicUrl = matchUrl[1].trim();\n const matchUser = envContent.match(/^POSTGRES_USER=(.+)$/m);\n if (matchUser?.[1]) pgUser = matchUser[1].trim();\n const matchPass = envContent.match(/^POSTGRES_PASSWORD=(.+)$/m);\n if (matchPass?.[1]) pgPassword = matchPass[1].trim();\n } catch { /* .env may not exist yet */ }\n }\n\n // Find the actual postgres container (name varies by compose project, e.g. synap-backend-postgres-1)\n const postgresContainer = await findSynapPostgresContainer();\n if (!postgresContainer) {\n printWarning(' Could not find synap-backend postgres container — skipping database creation.');\n } else {\n // Create the nango database in the shared postgres instance\n printInfo(`Creating Nango database in ${postgresContainer}...`);\n try {\n await execFileAsync('docker', [\n 'exec', postgresContainer,\n 'psql', '-U', pgUser, '-c',\n 'CREATE DATABASE nango;',\n ], { timeout: 10_000 });\n } catch {\n // Ignore \"already exists\" errors — idempotent\n }\n\n // Nango runs on eve-network but postgres is on synap-backend's compose network.\n // Connect postgres to eve-network with the alias `eve-brain-postgres` so Nango\n // can resolve it by that hostname.\n try {\n await execFileAsync('docker', [\n 'network', 'connect', '--alias', 'eve-brain-postgres',\n 'eve-network', postgresContainer,\n ], { timeout: 10_000 });\n printInfo(` Connected ${postgresContainer} to eve-network as eve-brain-postgres.`);\n } catch {\n // Already connected — fine\n }\n }\n\n // Pull image\n printInfo('Pulling nangohq/nango-server:hosted...');\n await execFileAsync('docker', ['pull', 'nangohq/nango-server:hosted'], { timeout: 120_000 });\n\n // Idempotent container start: remove stopped/crashed container, skip if already running\n const { stdout: runningOut } = await execFileAsync(\n 'docker', ['ps', '--filter', 'name=eve-arms-nango', '--format', '{{.Names}}'],\n { timeout: 4000 },\n ).catch(() => ({ stdout: '' }));\n const alreadyRunning = runningOut.trim().split('\\n').includes('eve-arms-nango');\n\n // Derive nangoHost early — needed both for NANGO_SERVER_URL in docker run\n // and for writing NANGO_HOST to deploy/.env. Uses secrets read at startup;\n // domain config won't change during this function.\n const _nangoDomain = secrets?.domain?.primary;\n const _nangoSsl = secrets?.domain?.ssl !== false;\n const nangoHost = _nangoDomain\n ? `${_nangoSsl ? 'https' : 'http'}://nango.${_nangoDomain}`\n : 'http://eve-arms-nango:3003';\n // Connect UI is served on port 3009 at a dedicated subdomain.\n // Falls back to empty string when no domain is configured — written to\n // deploy/.env only when a domain is known.\n const connectUrl = _nangoDomain\n ? `${_nangoSsl ? 'https' : 'http'}://connect.${_nangoDomain}`\n : '';\n\n if (!alreadyRunning) {\n // Remove stopped/exited container if it exists so docker run can reuse the name\n await execFileAsync('docker', ['rm', '-f', 'eve-arms-nango'], { timeout: 10_000 }).catch(() => {/* not found — fine */});\n\n // Derive a stable AES encryption key for the keystore (PBKDF2 for session tokens).\n // The keystore module always requires NANGO_ENCRYPTION_KEY — it throws at startup without it.\n const { createHash } = await import('node:crypto');\n const nangoEncryptionKey = createHash('sha256').update(secretKey).digest('base64');\n\n // Build docker run args — include webhook URL if pod public URL is known\n const dockerRunArgs = [\n 'run', '-d',\n '--name', 'eve-arms-nango',\n '--network', 'eve-network',\n '--restart', 'unless-stopped',\n '-e', `NANGO_SECRET_KEY=${secretKey}`,\n // Self-hosted Nango authenticates Bearer tokens via NANGO_SECRET_KEY_<envname> env vars,\n // NOT via the api_secrets DB table. Setting these makes our secretKey the API key for\n // both the prod and dev environments created during account signup.\n '-e', `NANGO_SECRET_KEY_PROD=${secretKey}`,\n '-e', `NANGO_SECRET_KEY_DEV=${secretKey}`,\n // Required by @nangohq/keystore for AES encryption of session tokens — throws without it.\n '-e', `NANGO_ENCRYPTION_KEY=${nangoEncryptionKey}`,\n '-e', 'SERVER_PORT=3003',\n '-e', `NANGO_DATABASE_URL=postgresql://${pgUser}:${pgPassword}@eve-brain-postgres:5432/nango`,\n '-e', 'NODE_ENV=production',\n '-e', 'NANGO_EMAIL_ACCOUNT_VERIFICATION_REQUIRED=false',\n '-e', 'FLAG_SERVE_CONNECT_UI=true',\n '-e', 'NANGO_CONNECT_UI_PORT=3009',\n ...(nangoHost ? ['-e', `NANGO_SERVER_URL=${nangoHost}`] : []),\n // NANGO_PUBLIC_CONNECT_URL: read by Nango server to populate env.js connectUrl field\n // NANGO_CONNECT_URL: read by our NangoConnector to build redirect URLs for the pod backend\n ...(connectUrl ? ['-e', `NANGO_PUBLIC_CONNECT_URL=${connectUrl}`, '-e', `NANGO_CONNECT_URL=${connectUrl}`] : []),\n ...(podPublicUrl ? ['-e', `NANGO_WEBHOOK_URL=${podPublicUrl}/api/connectors/nango-webhook`] : []),\n '-v', 'eve-arms-nango-data:/var/lib/nango',\n 'nangohq/nango-server:hosted',\n ];\n\n printInfo('Starting Nango container...');\n await execFileAsync('docker', dockerRunArgs, { timeout: 30_000 });\n\n // Patch Connect UI index.html with a setImmediate polyfill, then remount it\n // as a read-only volume so the fix survives container restarts.\n // The browser's native polyfill returns a number; Nango's bundle does\n // `'type' in handle` which throws TypeError on primitives → infinite spinner.\n await applyNangoConnectUiPolyfill(dockerRunArgs);\n } else {\n printInfo('Nango container already running.');\n // Show current admin info — no re-signup needed.\n // The admin account already exists (signup is idempotent but the email\n // prompt would be misleading on re-run). Use `eve connectors admin`\n // to view or update credentials.\n printInfo(' View admin credentials: eve connectors admin');\n printInfo(' Update admin email: eve connectors admin --set-email <email>');\n printInfo(' Change admin password: eve connectors admin --reset-password');\n // Still write env vars to deploy/.env (may not have been done on first run)\n }\n\n // Only attempt signup on fresh installs — on re-runs the account exists.\n let ownerEmail: string | undefined;\n if (!alreadyRunning) {\n ownerEmail = secrets?.synap?.userSession?.email ?? secrets?.builder?.openwebui?.adminEmail;\n if (!ownerEmail) {\n console.log();\n ownerEmail = await text({\n message: 'Nango admin email (used to sign in to the dashboard)',\n placeholder: 'you@example.com',\n validate: (v) => (v && v.includes('@') ? undefined : 'Enter a valid email address'),\n }) as string;\n if (isCancel(ownerEmail)) { cancel('Setup cancelled.'); process.exit(0); }\n }\n }\n // nangoAutoSignup returns the actual environment secret key from Nango's DB.\n // Nango generates its own key on first account creation — our generated UUID\n // is only used as NANGO_SECRET_KEY (container env identifier) but the API\n // Bearer token must match the environment key Nango stores internally.\n let effectiveSecretKey = secretKey;\n if (!alreadyRunning) {\n const nangoEnvKey = await nangoAutoSignup(secretKey, ownerEmail);\n if (nangoEnvKey) effectiveSecretKey = nangoEnvKey;\n if (nangoEnvKey && nangoEnvKey !== secretKey) {\n printInfo(` Using Nango environment key for backend API calls: ${nangoEnvKey.slice(0, 8)}...`);\n }\n }\n\n if (!podPublicUrl) {\n printWarning(' PUBLIC_URL not found in deploy/.env — NANGO_WEBHOOK_URL not set.');\n printWarning(' After setting PUBLIC_URL, re-run: eve add nango');\n }\n\n // Write to secrets.json\n await writeEveSecrets({\n ...(secrets ?? {}),\n connectors: {\n ...(secrets?.connectors ?? {}),\n nango: {\n secretKey: effectiveSecretKey,\n installedAt: new Date().toISOString(),\n oauthApps: secrets?.connectors?.nango?.oauthApps ?? {},\n },\n },\n }, process.cwd());\n\n // Write NANGO_HOST + NANGO_SECRET_KEY to pod deploy/.env\n if (deployDir) {\n const envPath = pathJoin(deployDir, '.env');\n let envContent = '';\n try { envContent = await readFile(envPath, 'utf8'); } catch { /* new file */ }\n\n const setEnvVar = (content: string, key: string, value: string): string => {\n const re = new RegExp(`^${key}=.*$`, 'm');\n const line = `${key}=${value}`;\n return re.test(content) ? content.replace(re, line) : `${content}\\n${line}`;\n };\n\n // Write NANGO_HOST as the internal Docker URL — the backend calls Nango's API\n // directly, not through the reverse proxy (which strips the Authorization header).\n // The public URLs (NANGO_SERVER_URL, NANGO_CONNECT_URL) are for browser redirects only.\n envContent = setEnvVar(envContent, 'NANGO_HOST', 'http://eve-arms-nango:3003');\n envContent = setEnvVar(envContent, 'NANGO_SECRET_KEY', effectiveSecretKey);\n if (connectUrl) envContent = setEnvVar(envContent, 'NANGO_CONNECT_URL', connectUrl);\n await writeFile(envPath, envContent.trimStart(), 'utf8');\n printInfo(` Wrote NANGO_HOST=${nangoHost} + NANGO_SECRET_KEY${connectUrl ? ` + NANGO_CONNECT_URL=${connectUrl}` : ''} to ${envPath}`);\n\n // Recreate synap-backend so it picks up the new env vars from .env.\n // `docker restart` keeps the original env — `compose up --force-recreate`\n // re-reads .env and creates a fresh container with updated vars.\n const backendContainer = await findSynapBackendContainer();\n if (backendContainer) {\n printInfo(` Recreating ${backendContainer} to apply NANGO_SECRET_KEY...`);\n // Derive the compose service name from the container label\n const { stdout: svcOut } = await execFileAsync('docker', [\n 'inspect', backendContainer,\n '--format', '{{index .Config.Labels \"com.docker.compose.service\"}}',\n ], { timeout: 4000 }).catch(() => ({ stdout: 'backend' }));\n const serviceName = svcOut.trim() || 'backend';\n await execFileAsync('docker', [\n 'compose', '--project-directory', deployDir,\n 'up', '-d', '--no-deps', '--force-recreate', serviceName,\n ], { timeout: 120_000 });\n printInfo(' Backend recreated with updated env.');\n } else {\n printWarning(' Could not find synap-backend container — run `docker compose up -d --force-recreate backend` in your deploy dir to apply NANGO_SECRET_KEY.');\n }\n } else {\n printWarning(' Could not locate deploy/.env — set SYNAP_DEPLOY_DIR and rerun to write env vars.');\n printInfo(` Add manually: NANGO_HOST=http://eve-arms-nango:3003 NANGO_SECRET_KEY=${secretKey}`);\n }\n\n // Wire nango.{domain} subdomain via Traefik (no-op if no domain configured yet)\n await materializeTargets(null, ['traefik-routes']);\n\n if (!alreadyRunning) {\n const adminPw = `Nango_${secretKey.slice(0, 12)}`;\n printSuccess('Nango installed.');\n printInfo(` Dashboard: ${nangoHost}`);\n printInfo(` Admin email: ${ownerEmail ?? 'admin@eve.local'}`);\n printInfo(` Admin password: ${adminPw}`);\n printInfo(' Email verification is bypassed — sign in directly, do not use the \"sign up\" link.');\n } else {\n printSuccess('Nango is running.');\n printInfo(` Dashboard: ${nangoHost}`);\n printInfo(' Manage your account: eve connectors admin');\n }\n console.log();\n printInfo(' Next: register an OAuth app so users can connect their accounts:');\n printInfo(' eve connectors setup google # or github, notion, slack, linear');\n printInfo(' Until a provider is set up, `synap connect <provider>` returns \"Integration does not exist\".');\n}\n\nasync function addRsshub(): Promise<void> {\n if (!await isBrainReady()) {\n printError('Brain is not ready. Please install Synap first: `eve add synap`');\n process.exit(1);\n }\n\n // Import the RSSHubService dynamically to avoid hard deps\n const { RSSHubService } = await import('@eve/eyes');\n const rsshub = new RSSHubService();\n if (await rsshub.isInstalled()) {\n printInfo('RSSHub is already installed. Use `eve eyes:start` to start it.');\n return;\n }\n await rsshub.install({ port: 1200 });\n await entityStateManager.updateOrgan('eyes', 'ready');\n printSuccess('RSSHub installed successfully!');\n printInfo(' URL: http://localhost:1200');\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport interface AddOptions {\n synapRepo?: string;\n model?: string;\n}\n\n/**\n * Add a component to the current entity.\n *\n * This is the shared implementation for both the `eve add` command and\n * programmatic use.\n */\nexport async function runAdd(\n componentId: string,\n opts: AddOptions = {},\n): Promise<void> {\n const comp = resolveComponent(componentId);\n\n // Synap owns its compose project, persistent volumes and identity. Its\n // `eve-brain-synap` registry value is a network alias, so the generic\n // exact-container drift check below is not valid for this component.\n if (componentId === 'synap' && await reportExistingSynapDeployment()) {\n return;\n }\n\n const existing = await entityStateManager.isComponentInstalled(componentId);\n if (existing) {\n printWarning(`${comp.label} is already installed.`);\n // `comp.organ` is optional in the registry; fall back to `eve status`\n // when missing so we never print \"eve undefined status\".\n const statusCmd = comp.organ ? `eve ${comp.organ} status` : 'eve status';\n printInfo(` Run \"${statusCmd}\" to check its state.`);\n\n // Drift detection: state.json says installed but the container is\n // gone (manually removed, host wiped, container never created\n // because a previous install failed mid-way). Auto-reinstall\n // instead of asking the user to manually recover.\n const containerName = comp.service?.containerName;\n if (containerName && !(await containerExists(containerName))) {\n printWarning(` …but the ${containerName} container is missing. Reinstalling...`);\n await entityStateManager.updateComponentEntry(componentId, { state: 'error' });\n // Fall through to reinstall below\n } else {\n printInfo(` Or \"eve update ${componentId}\" to pull the latest image.`);\n return;\n }\n }\n\n // Check prerequisites\n const currentComponents = await entityStateManager.getInstalledComponents();\n const missingDeps = (comp.requires ?? []).filter(dep => !currentComponents.includes(dep));\n if (missingDeps.length > 0) {\n const depNames = missingDeps.map(dep => {\n const info = COMPONENTS.find(c => c.id === dep);\n return info ? info.label : dep;\n });\n printError(`Missing prerequisites: ${depNames.join(', ')}`);\n printInfo(` Install them first: ${missingDeps.map(d => `eve add ${d}`).join(' / ')}`);\n process.exit(1);\n }\n\n // Resolve synap repo from env or option\n if (opts.synapRepo) {\n process.env.SYNAP_REPO_ROOT = opts.synapRepo;\n }\n\n printHeader(`Adding ${comp.label}`, comp.emoji);\n console.log();\n printInfo(comp.description.split('\\n')[0]);\n console.log();\n\n // Determine and run the add function\n let step: AddFn;\n try {\n step = buildAddStep(comp.id, opts);\n } catch (err) {\n printError(String(err));\n process.exit(1);\n }\n\n const spinner = createSpinner(step.label);\n spinner.start();\n try {\n await step.fn();\n spinner.succeed(step.label);\n } catch (err) {\n spinner.fail(step.label);\n printError(`Failed to add ${comp.label}: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n // Verify the component is actually serving (not just \"docker run returned 0\")\n const verifySpinner = createSpinner(`Verifying ${comp.label} is reachable...`);\n verifySpinner.start();\n const verification = await verifyComponent(comp.id);\n if (verification.ok) {\n verifySpinner.succeed(verification.summary);\n } else {\n verifySpinner.warn(verification.summary);\n for (const c of verification.checks) {\n if (!c.ok && c.detail) {\n printWarning(` • ${c.name}: ${c.detail}`);\n }\n }\n printInfo(` Component installed but not yet responding. Check logs: docker logs ${comp.id}`);\n }\n\n // Update state — mark as 'error' if verification failed so eve status / dashboard reflect reality\n await updateStateAfterAdd(comp.id, verification.ok ? 'ready' : 'error');\n\n // Auto-refresh Traefik routes so the new component is reachable via domain\n const [refresh] = await materializeTargets(null, ['traefik-routes']);\n if (refresh?.changed) {\n printInfo(refresh.summary);\n } else if (refresh && !refresh.ok) {\n printWarning(`Could not refresh Traefik routes: ${refresh.error ?? refresh.summary}`);\n }\n\n console.log();\n printSuccess(`${comp.label} added successfully!`);\n console.log();\n printInfo('Next steps:');\n printInfo(` - Run \"eve status\" to check entity state`);\n if (comp.organ) printInfo(` - Run \"eve ${comp.organ} status\" for ${comp.label} status`);\n if (refresh?.changed) printInfo(` - Run \"eve domain check\" to verify routing`);\n console.log();\n}\n\n// ---------------------------------------------------------------------------\n// Step builder\n// ---------------------------------------------------------------------------\n\nfunction buildAddStep(\n componentId: string,\n opts: AddOptions,\n): AddFn {\n const model = opts.model || 'llama3.1:8b';\n\n switch (componentId) {\n case 'traefik':\n return {\n label: 'Setting up Traefik routing...',\n fn: addTraefik,\n };\n case 'synap':\n return {\n label: 'Installing Synap Data Pod...',\n fn: addSynap,\n };\n case 'ollama':\n return {\n label: 'Setting up Ollama + AI gateway...',\n fn: () => addOllama(model),\n };\n case 'openclaw':\n return {\n label: 'Installing OpenClaw...',\n fn: addOpenclaw,\n };\n case 'nango':\n return {\n label: 'Installing Nango (self-hosted OAuth platform)...',\n fn: addNango,\n };\n case 'rsshub':\n return {\n label: 'Installing RSSHub...',\n fn: addRsshub,\n };\n case 'openwebui': {\n return {\n label: 'Installing Open WebUI...',\n async fn() {\n const { mkdirSync, writeFileSync, existsSync } = await import('node:fs');\n const { join: pathJoin } = await import('node:path');\n const { readAgentKeyOrLegacy, readEveSecrets } = await import('@eve/dna');\n const { randomBytes } = await import('node:crypto');\n const { execa } = await import('execa');\n\n const deployDir = '/opt/openwebui';\n mkdirSync(deployDir, { recursive: true });\n\n // Read secrets for IS wiring. OpenWebUI calls Synap IS using the\n // openwebui-pipelines agent identity (its canonical pod identity),\n // falling back to legacy for un-migrated installs.\n const secrets = await readEveSecrets(process.cwd());\n const synapApiKey =\n (await readAgentKeyOrLegacy('openwebui-pipelines', process.cwd())) ||\n process.env.SYNAP_API_KEY ||\n '';\n const isUrl = process.env.SYNAP_IS_URL ?? 'http://intelligence-hub:3001';\n\n // Write a clean, self-contained compose file. We declare eve-network\n // as `external: true` so this container joins the same network as\n // Traefik (required for chat.<domain> routing to work).\n const composeYaml = `# Open WebUI — generated by Eve CLI\n# Self-contained compose. Joins eve-network so Traefik can route chat.<domain>\n# to this container. Uses SQLite by default (no external DB).\n\nservices:\n openwebui:\n image: ghcr.io/open-webui/open-webui:main\n container_name: hestia-openwebui\n restart: unless-stopped\n environment:\n - ENV=production\n - WEBUI_SECRET_KEY=\\${WEBUI_SECRET_KEY:-change-me}\n - SCARF_NO_ANALYTICS=true\n - DO_NOT_TRACK=true\n # Synap IS as the OpenAI-compat backend\n - ENABLE_OPENAI_API=true\n - OPENAI_API_BASE_URLS=\\${OPENAI_API_BASE_URLS:-http://eve-brain-synap:4000/v1}\n - OPENAI_API_KEYS=\\${OPENAI_API_KEYS:-}\n # Local Ollama as fallback\n - OLLAMA_BASE_URL=\\${OLLAMA_BASE_URL:-http://eve-brain-ollama:11434}\n # Features\n - ENABLE_RAG=true\n - ENABLE_WEB_SEARCH=true\n - WEB_SEARCH_ENGINE=duckduckgo\n - ENABLE_SIGNUP=\\${ENABLE_SIGNUP:-true}\n - DEFAULT_USER_ROLE=\\${DEFAULT_USER_ROLE:-user}\n ports:\n - \"3011:8080\"\n volumes:\n - openwebui-data:/app/backend/data\n networks:\n - eve-network\n\nnetworks:\n eve-network:\n external: true\n\nvolumes:\n openwebui-data:\n`;\n writeFileSync(pathJoin(deployDir, 'docker-compose.yml'), composeYaml);\n\n // Write .env (referenced by compose)\n const envPath = pathJoin(deployDir, '.env');\n if (!existsSync(envPath)) {\n writeFileSync(envPath, [\n '# Open WebUI — generated by Eve CLI',\n `SYNAP_API_KEY=${synapApiKey}`,\n `SYNAP_IS_URL=${isUrl}`,\n `WEBUI_SECRET_KEY=${randomBytes(32).toString('hex')}`,\n `OLLAMA_BASE_URL=http://eve-brain-ollama:11434`,\n `ENABLE_SIGNUP=true`,\n `DEFAULT_USER_ROLE=user`,\n ].join('\\n'), { mode: 0o600 });\n }\n\n // Ensure eve-network exists (Traefik needs it; we declared it as external)\n try {\n await execa('docker', ['network', 'inspect', 'eve-network'], { stdio: 'ignore' });\n } catch {\n await execa('docker', ['network', 'create', 'eve-network'], { stdio: 'inherit' });\n }\n\n // Pull + start\n console.log(` Config: ${deployDir}/docker-compose.yml`);\n await execa('docker', ['compose', 'up', '-d'], {\n cwd: deployDir,\n stdio: 'inherit',\n });\n },\n };\n }\n case 'openwebui-pipelines':\n return {\n label: 'Installing Open WebUI Pipelines sidecar...',\n async fn() {\n // Delegate to @eve/lifecycle — single source of truth for both\n // the CLI and the dashboard install path.\n const { runActionToCompletion } = await import('@eve/lifecycle');\n const result = await runActionToCompletion('openwebui-pipelines', 'install');\n if (!result.ok) {\n throw new Error(result.error ?? 'Pipelines install failed');\n }\n // Lifecycle yields logs as it goes — we already printed via spinner;\n // dump the structured logs now for the user.\n for (const line of result.logs) console.log(' ' + line);\n },\n };\n case 'eve-dashboard':\n return {\n label: 'Installing Eve Dashboard...',\n async fn() {\n const { randomBytes } = await import('node:crypto');\n\n // Generate a dashboard secret if one doesn't already exist.\n let secrets = await readEveSecrets(process.cwd());\n let secret = secrets?.dashboard?.secret;\n if (!secret) {\n secret = randomBytes(32).toString('hex');\n await writeEveSecrets({ dashboard: { secret, port: 7979 } });\n console.log();\n console.log(colors.primary.bold('Dashboard key generated — save this somewhere safe:'));\n console.log(colors.muted('─'.repeat(66)));\n console.log(colors.primary.bold(secret));\n console.log(colors.muted('─'.repeat(66)));\n } else {\n console.log();\n console.log(colors.muted('Reusing existing dashboard key.'));\n }\n\n installDashboardContainer({\n workspaceRoot: process.cwd(),\n secret,\n });\n },\n };\n // Thin delegate to the ONE install recipe in @eve/lifecycle — deliberately\n // NOT a second inline compose string here. `openwebui` has exactly that\n // (a different YAML in this file from the one lifecycle writes), and the\n // two have drifted; adding a third copy is how that becomes permanent.\n case 'freellmapi':\n return {\n label: 'Installing FreeLLMAPI gateway…',\n async fn() {\n const { runActionToCompletion } = await import('@eve/lifecycle');\n const result = await runActionToCompletion('freellmapi', 'install');\n if (!result.ok) throw new Error(result.error ?? 'FreeLLMAPI install failed');\n for (const line of result.logs) console.log(' ' + line);\n },\n };\n case 'hermes':\n return {\n label: 'Installing Hermes AI agent…',\n async fn() {\n const { runActionToCompletion } = await import('@eve/lifecycle');\n const result = await runActionToCompletion('hermes', 'install');\n if (!result.ok) throw new Error(result.error ?? 'Hermes install failed');\n for (const line of result.logs) console.log(' ' + line);\n },\n };\n case 'dokploy':\n case 'opencode':\n case 'openclaude':\n // Builders install via the lifecycle recipe (docker run / config write).\n // The CLI handles them here so interactive edge-cases (missing deps, drift)\n // surface the right recovery message.\n return {\n label: `Installing ${COMPONENTS.find(c => c.id === componentId)?.label ?? componentId}…`,\n async fn() {\n const { runActionToCompletion } = await import('@eve/lifecycle');\n const result = await runActionToCompletion(componentId, 'install');\n if (!result.ok) throw new Error(result.error ?? 'Install failed');\n for (const line of result.logs) console.log(' ' + line);\n },\n };\n case 't3code':\n // T3 Code: prompt for AI provider + key, then lifecycle deploys the\n // container (node:22-slim + npx t3) and wires backend .env.\n return {\n label: 'Installing T3 Code server…',\n async fn() {\n const { select: clackSelect, text: clackInput, password } = await import('@clack/prompts');\n const secrets = await readEveSecrets(process.cwd()).catch(() => null);\n const existing = secrets?.builder?.t3code ?? {};\n\n // Provider selection — default to whatever is already configured.\n // Prefer pod IS if already set up (no external key needed).\n const currentBaseUrl = existing.openaiBaseUrl ?? '';\n const podApiUrl = secrets?.synap?.apiUrl ? `${secrets.synap.apiUrl}/v1` : '';\n const isPodIs = currentBaseUrl && podApiUrl && currentBaseUrl === podApiUrl;\n const currentProvider = isPodIs ? 'pod'\n : currentBaseUrl.includes('openrouter') ? 'openrouter'\n : currentBaseUrl ? 'custom'\n : podApiUrl ? 'pod'\n : 'openai';\n\n const provider = await clackSelect({\n message: 'AI provider for Codex (T3 Code uses the OpenAI-compatible API)',\n options: [\n ...(podApiUrl ? [{ value: 'pod', label: 'Pod IS', hint: `${podApiUrl} — already configured` }] : []),\n { value: 'openai', label: 'OpenAI', hint: 'api.openai.com — official' },\n { value: 'openrouter', label: 'OpenRouter', hint: 'openrouter.ai — 200+ models, unified key' },\n { value: 'custom', label: 'Custom', hint: 'Any OpenAI-compatible base URL' },\n ],\n initialValue: currentProvider,\n });\n if (typeof provider !== 'string') throw new Error('Cancelled');\n\n let openaiBaseUrl = '';\n if (provider === 'pod') {\n openaiBaseUrl = podApiUrl;\n } else if (provider === 'openrouter') {\n openaiBaseUrl = 'https://openrouter.ai/api/v1';\n } else if (provider === 'custom') {\n const url = await clackInput({\n message: 'Base URL (e.g. https://my-proxy.example.com/v1)',\n initialValue: currentBaseUrl,\n validate: (v: string) => v.trim() ? undefined : 'URL is required',\n });\n if (typeof url !== 'string') throw new Error('Cancelled');\n openaiBaseUrl = url.trim();\n }\n\n // Pod IS uses the agent API key — no separate key needed.\n const podKey = secrets?.synap?.agentApiKey ?? '';\n const existingKey = existing.openaiApiKey ?? process.env.OPENAI_API_KEY ?? '';\n let openaiApiKey = provider === 'pod' ? podKey : existingKey;\n if (!openaiApiKey) {\n const keyLabel = provider === 'openrouter' ? 'OpenRouter API key' : 'API key';\n const val = await password({ message: keyLabel });\n if (typeof val !== 'string' || !val.trim()) throw new Error('API key is required');\n openaiApiKey = val.trim();\n }\n\n await writeEveSecrets({\n builder: { t3code: { ...existing, openaiApiKey, openaiBaseUrl: openaiBaseUrl || undefined } },\n });\n\n const { runActionToCompletion } = await import('@eve/lifecycle');\n const result = await runActionToCompletion('t3code', 'install');\n if (!result.ok) throw new Error(result.error ?? 'T3 Code install failed');\n for (const line of result.logs) console.log(' ' + line);\n },\n };\n default:\n throw new Error(`No add handler for component: ${componentId}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// State update\n// ---------------------------------------------------------------------------\n\nasync function updateStateAfterAdd(componentId: string, finalState: 'ready' | 'error' = 'ready'): Promise<void> {\n const organMap: Record<string, 'brain' | 'arms' | 'builder' | 'eyes' | 'legs'> = {\n synap: 'brain',\n ollama: 'brain',\n openclaw: 'arms',\n hermes: 'arms', // Hermes is the primary agent, same organ as OpenClaw\n rsshub: 'eyes',\n traefik: 'legs',\n openwebui: 'eyes',\n 'openwebui-pipelines': 'eyes',\n dokploy: 'builder',\n opencode: 'builder',\n openclaude: 'builder',\n t3code: 'builder',\n 'eve-dashboard': 'legs',\n };\n\n const organ = organMap[componentId];\n if (organ) {\n await entityStateManager.updateOrgan(organ, finalState, { version: '0.1.0' });\n }\n\n await entityStateManager.updateComponentEntry(componentId, {\n state: finalState,\n version: '0.1.0',\n managedBy: 'eve',\n });\n\n // Update setup profile v2 components list (always — even errored components are\n // tracked so future installs see them and the user can `eve doctor` them)\n const current = await entityStateManager.getInstalledComponents();\n if (!current.includes(componentId)) {\n await entityStateManager.updateSetupProfile({ components: [...current, componentId] });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Builder picker\n// ---------------------------------------------------------------------------\n\n/** The builders users can pick from. Order matters — shown top-to-bottom. */\nconst BUILDER_OPTIONS = [\n {\n id: 'opencode',\n label: 'OpenCode',\n hint: 'AI-powered code editor running on your server',\n },\n {\n id: 'openclaude',\n label: 'OpenClaude',\n hint: 'Claude Code as a service — delegate hard coding tasks to Claude',\n },\n {\n id: 'dokploy',\n label: 'Dokploy',\n hint: 'Visual PaaS for deploying apps (like a self-hosted Railway)',\n },\n {\n id: 't3code',\n label: 'T3 Code',\n hint: 'External code execution backend — store connection details for DevPlane pipeline',\n },\n] as const;\n\n/**\n * Show an interactive picker for builder components and return the selected\n * component ID, or null if the user cancelled.\n */\nasync function pickBuilder(): Promise<string | null> {\n console.log();\n const choice = await select({\n message: 'Which builder would you like to install?',\n options: BUILDER_OPTIONS.map(b => ({\n value: b.id,\n label: b.label,\n hint: b.hint,\n })),\n });\n\n if (isCancel(choice)) {\n printInfo('Cancelled.');\n return null;\n }\n return choice as string;\n}\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\nexport function addCommand(program: Command): void {\n program\n .command('add')\n .description('Add a component to an existing entity')\n .argument('[components...]', 'One component ID or category to add (hermes, synap, ollama, openclaw, rsshub, openwebui, builder, opencode, openclaude, dokploy, …)')\n .option('--synap-repo <path>', 'Path to synap-backend checkout (for synap component)')\n .option('--model <model>', 'Ollama model (for ollama component)', 'llama3.1:8b')\n .action(async (components: string[] | undefined, opts: { synapRepo?: string; model?: string }) => {\n const requested = components ?? [];\n if (requested.length > 1) {\n if (requested.includes('synap') && requested.includes('pod-admin')) {\n printInfo('Pod Admin ships with the Synap Data Pod; it is not a separately added component.');\n printInfo('Use `eve add synap` only for a new Pod, or `eve update synap` to recover an existing one.');\n } else {\n printWarning('`eve add` installs one component at a time.');\n printInfo(`Received: ${requested.join(', ')}`);\n }\n process.exitCode = 1;\n return;\n }\n\n let component = requested[0];\n // \"eve add builder\" — show picker for which builder to install\n if (component === 'builder') {\n const picked = await pickBuilder();\n if (!picked) process.exit(0);\n component = picked;\n }\n\n if (!component) {\n console.log();\n printHeader('Eve — Add Component', emojis.entity);\n console.log();\n printInfo('Usage: eve add <component>');\n console.log();\n\n // Group components for readability\n const groups: Array<{ heading: string; ids: string[] }> = [\n { heading: 'AI agents', ids: ['hermes', 'openclaw'] },\n { heading: 'Data & inference', ids: ['synap', 'ollama', 'openwebui', 'openwebui-pipelines', 'rsshub'] },\n { heading: 'Builders', ids: ['opencode', 'openclaude', 'dokploy', 't3code'] },\n { heading: 'Infrastructure', ids: ['traefik', 'eve-dashboard'] },\n ];\n\n for (const group of groups) {\n console.log(colors.muted.bold(`\\n ${group.heading}`));\n for (const id of group.ids) {\n const comp = COMPONENTS.find(c => c.id === id);\n if (!comp) continue;\n const installed = await entityStateManager.isComponentInstalled(id);\n const tag = installed\n ? colors.success(' [installed]')\n : comp.deprecated\n ? colors.muted(' [deprecated]')\n : '';\n console.log(` ${comp.emoji} ${colors.primary.bold(comp.label)}${tag}`);\n console.log(` ${colors.muted(comp.description.split('\\n')[0])}`);\n }\n }\n\n console.log();\n printInfo('Tip: `eve add builder` shows a picker for OpenCode / OpenClaude / Dokploy');\n printInfo('Examples:');\n printInfo(' eve add hermes # AI agent with sovereign memory');\n printInfo(' eve add ollama # Local AI inference');\n printInfo(' eve add builder # Pick a code-execution builder');\n console.log();\n return;\n }\n\n await runAdd(component, opts);\n });\n}\n","import chalk from 'chalk';\nimport boxen from 'boxen';\n\n// Simple color palette using chalk only\nexport const colors = {\n primary: chalk.hex('#6366f1'),\n success: chalk.green,\n warning: chalk.yellow,\n error: chalk.red,\n info: chalk.blue,\n muted: chalk.gray,\n brain: chalk.hex('#f59e0b'),\n arms: chalk.green,\n builder: chalk.blue,\n eyes: chalk.magenta,\n legs: chalk.cyan,\n};\n\n// Emojis\nexport const emojis = {\n brain: '🧠',\n arms: '🦾',\n builder: '🏗️',\n eyes: '👁️',\n legs: '🦿',\n entity: '🌿',\n success: '✅',\n error: '❌',\n warning: '⚠️',\n info: 'ℹ️',\n sparkles: '✨',\n check: '✓',\n cross: '✗',\n bullet: '•',\n};\n\n// Simple spinner using stdout. \\x1b[2K clears the entire line BEFORE writing\n// new content so shorter \"succeed\" text doesn't leave a tail of the longer\n// spinner text behind.\nconst CLEAR_LINE = '\\r\\x1b[2K';\n\nexport function createSpinner(text: string) {\n let interval: NodeJS.Timeout;\n const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n let i = 0;\n\n return {\n start() {\n process.stdout.write(`${CLEAR_LINE}${colors.info(`${frames[0]} ${text}`)}`);\n interval = setInterval(() => {\n process.stdout.write(`${CLEAR_LINE}${colors.info(`${frames[i]} ${text}`)}`);\n i = (i + 1) % frames.length;\n }, 80);\n },\n succeed(msg?: string) {\n clearInterval(interval);\n console.log(`${CLEAR_LINE}${colors.success(`${emojis.check} ${msg || text}`)}`);\n },\n fail(msg?: string) {\n clearInterval(interval);\n console.log(`${CLEAR_LINE}${colors.error(`${emojis.cross} ${msg || text}`)}`);\n },\n warn(msg?: string) {\n clearInterval(interval);\n console.log(`${CLEAR_LINE}${colors.warning(`${emojis.warning} ${msg || text}`)}`);\n },\n };\n}\n\n// Print helpers\nexport function printHeader(title: string, emoji?: string): void {\n console.log();\n console.log(colors.primary.bold(`${emoji ? emoji + ' ' : ''}${title}`));\n console.log(colors.primary('─'.repeat(title.length + (emoji ? 2 : 0))));\n}\n\nexport function printSuccess(message: string): void {\n console.log(colors.success(`${emojis.success} ${message}`));\n}\n\nexport function printError(message: string): void {\n console.log(colors.error(`${emojis.error} ${message}`));\n}\n\nexport function printWarning(message: string): void {\n console.log(colors.warning(`${emojis.warning} ${message}`));\n}\n\nexport function printInfo(message: string): void {\n console.log(colors.info(`${emojis.info} ${message}`));\n}\n\nexport function printBullet(message: string, indent = 0): void {\n const indentStr = ' '.repeat(indent);\n console.log(`${indentStr}${colors.muted(emojis.bullet)} ${message}`);\n}\n\nexport function printKeyValue(key: string, value: string, keyWidth = 20): void {\n const paddedKey = key.padEnd(keyWidth);\n console.log(`${colors.muted(paddedKey)} ${value}`);\n}\n\nexport function formatOrgan(organ: string): string {\n const organColors: Record<string, (text: string) => string> = {\n brain: colors.brain,\n arms: colors.arms,\n builder: colors.builder,\n eyes: colors.eyes,\n legs: colors.legs,\n };\n const color = organColors[organ] || colors.info;\n const emoji = emojis[organ as keyof typeof emojis] || emojis.bullet;\n return color(`${emoji} ${organ.charAt(0).toUpperCase() + organ.slice(1)}`);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/** Framed summary block (uses boxen + theme primary border) */\nexport function printBox(title: string, lines: string[]): void {\n const body = lines.join('\\n');\n console.log(\n boxen(`${colors.primary.bold(title)}\\n\\n${body}`, {\n padding: 1,\n margin: { top: 0, bottom: 1, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: '#6366f1',\n })\n );\n}\n\n"],"mappings":"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","names":["text","existsSync","readEveSecrets","execa"]}