UNPKG

@essentialai/cogent-bridge

Version:

Cogent Bridge — cross-agent comms for Claude Code, OpenAI Codex and Slack. Codex users: install with `curl -fsSL https://cogent.tools/install.sh | sh`, then start with `cogent-codex` for real-time peer wake.

94 lines (82 loc) • 3.91 kB
#!/usr/bin/env node /** * All-in-one installer for `npm install -g @essentialai/cogent-bridge`. * * Goal (operator spec): the INSTALLER installs EVERYTHING, so the user's only step * is running `cogent-codex`. This runs on a GLOBAL install and provisions: * 1. codex's managed build (the app-server daemon needs it — additive, lives * at ~/.codex/packages/standalone, coexists with any * existing Homebrew/npm codex); * 2. the `cogent@cogent` codex plugin (the cogent tools inside codex); * (the `cogent-codex` command itself is the package's own bin → already on PATH after * the global install; the daemon starts at run time.) * * HARD RULES: * - Runs ONLY on a global install (`npm install -g`) and never on a dependency/npx * install — guarded by npm_config_global. Skips CI and Windows (unix-socket rail). * - NEVER throws / never non-zero: a setup hiccup must not fail `npm install`. Every * step is best-effort with a clear log line; the run-time `cogent-codex` wrapper is * the safety net for anything that didn't complete here. */ import { spawnSync } from "node:child_process"; import { existsSync } from "node:fs"; import os from "node:os"; import path from "node:path"; const log = (m) => process.stdout.write(`[cogent-install] ${m}\n`); function shouldRun() { if (process.env.COGENT_SKIP_SETUP === "1") return false; if (process.env.COGENT_FORCE_SETUP === "1") return true; // for testing if (process.env.CI) return false; if (process.platform === "win32") return false; // app-server rail is unix-socket only // npm sets npm_config_global="true" during `npm install -g`. Only then. return String(process.env.npm_config_global).toLowerCase() === "true"; } /** Run a command, inheriting the terminal; return true on exit 0. Never throws. */ function run(cmd, args, opts = {}) { try { const res = spawnSync(cmd, args, { stdio: "inherit", timeout: 300000, ...opts }); return res.status === 0; } catch { return false; } } /** True if the command exists (via `command -v`, best-effort). */ function has(cmd) { try { return spawnSync("sh", ["-c", `command -v ${cmd}`], { stdio: "ignore" }).status === 0; } catch { return false; } } function managedCodexPresent() { return existsSync(path.join(os.homedir(), ".codex", "packages", "standalone", "current", "codex")); } function main() { if (!shouldRun()) return; // dependency/npx/CI/Windows → silently do nothing log("setting up Cogent for Codex — installing all components (one-time)…"); // 1) codex's managed build (needed for real-time wake's app-server daemon). if (managedCodexPresent()) { log("✓ codex managed build already present"); } else { log("installing codex's managed build…"); const ok = run("sh", ["-c", "curl -fsSL https://chatgpt.com/codex/install.sh | sh"]); log(ok && managedCodexPresent() ? "✓ codex managed build installed" : "… managed build not completed (cogent-codex will offer it on first run)"); } // 2) the cogent@cogent codex plugin (the cogent tools inside codex). Idempotent. if (has("codex")) { log("installing the cogent@cogent codex plugin…"); run("codex", ["plugin", "marketplace", "add", "https://github.com/eaisdevelopment/cogent.git"]); const ok = run("codex", ["plugin", "add", "cogent@cogent"]); log(ok ? "✓ cogent@cogent plugin installed" : "… plugin add not completed (re-run `codex plugin add cogent@cogent` if needed)"); } else { log("… `codex` not on PATH yet — open a new terminal, then run `cogent-codex` (it finishes setup)."); } log("done. Start codex with: cogent-codex"); } try { main(); } catch (e) { // Absolutely never fail the npm install. log(`setup skipped (${e?.message ?? e}); run \`cogent-codex\` to finish.`); } process.exit(0);