negotium 0.2.19 → 0.2.21
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/agent-helpers.js +573 -593
- package/dist/agent-helpers.js.map +17 -17
- package/dist/background-bash.js +3 -2
- package/dist/background-bash.js.map +3 -3
- package/dist/browser-runtime.js +76 -36
- package/dist/browser-runtime.js.map +6 -6
- package/dist/canonical-mcp-bridge.js +1 -1
- package/dist/{chunk-fc58cqry.js → chunk-rhp26p2c.js} +171 -26
- package/dist/{chunk-fc58cqry.js.map → chunk-rhp26p2c.js.map} +6 -5
- package/dist/{chunk-r0xs3t81.js → chunk-s2gez3wg.js} +18 -3
- package/dist/{chunk-r0xs3t81.js.map → chunk-s2gez3wg.js.map} +2 -2
- package/dist/hosted-agent.js +185 -54
- package/dist/hosted-agent.js.map +7 -6
- package/dist/main.js +1209 -1114
- package/dist/main.js.map +25 -25
- package/dist/mcp-catalog.js.map +1 -1
- package/dist/mcp-factories.js +526 -540
- package/dist/mcp-factories.js.map +17 -17
- package/dist/outbox.js.map +1 -1
- package/dist/platform-runtime.js.map +1 -1
- package/dist/prompts.js +3 -2
- package/dist/prompts.js.map +3 -3
- package/dist/query-runtime.js +63 -26
- package/dist/query-runtime.js.map +4 -4
- package/dist/registry.js +4 -3
- package/dist/registry.js.map +3 -3
- package/dist/rollout.js +1 -1
- package/dist/runtime/src/agents/archiver.ts +3 -2
- package/dist/runtime/src/application/switch-topic-access-mode.ts +81 -8
- package/dist/runtime/src/bus.ts +19 -2
- package/dist/runtime/src/mcp/session-comm/runtime.ts +16 -0
- package/dist/runtime/src/platform/config.ts +13 -1
- package/dist/runtime/src/runtime/ask-callbacks.ts +19 -11
- package/dist/runtime/src/runtime/background-sessions.ts +9 -7
- package/dist/runtime/src/runtime/visual-store.ts +31 -23
- package/dist/runtime/src/storage/api-topics.ts +26 -0
- package/dist/runtime/src/storage/browser-profiles.ts +16 -8
- package/dist/runtime/src/storage/runtime-events.ts +30 -20
- package/dist/runtime/src/storage/runtime-gateway-submissions.ts +24 -16
- package/dist/runtime/src/storage/runtime-turn-requests.ts +9 -1
- package/dist/runtime/src/storage/self-schedules.ts +32 -24
- package/dist/runtime/src/storage/storage-host.ts +105 -43
- package/dist/runtime/src/storage/vault.ts +12 -3
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js +63 -26
- package/dist/runtime-helpers.js.map +4 -4
- package/dist/sqlite.js +17 -1
- package/dist/sqlite.js.map +2 -2
- package/dist/storage.js +92 -46
- package/dist/storage.js.map +4 -4
- package/dist/types/packages/core/src/storage/api-topics.d.ts +15 -0
- package/dist/types/packages/core/src/storage/storage-host.d.ts +10 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js +156 -10
- package/dist/vault.js.map +6 -5
- package/package.json +1 -1
package/dist/background-bash.js
CHANGED
|
@@ -123,11 +123,12 @@ function versionAtLeast(actualVersion, minimumVersion) {
|
|
|
123
123
|
}
|
|
124
124
|
return true;
|
|
125
125
|
}
|
|
126
|
+
var BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000;
|
|
126
127
|
function browserRsMeetsMinimumVersion(candidate) {
|
|
127
128
|
try {
|
|
128
129
|
const output = execFileSync(candidate, ["--version"], {
|
|
129
130
|
encoding: "utf8",
|
|
130
|
-
timeout:
|
|
131
|
+
timeout: BROWSER_RS_VERSION_PROBE_TIMEOUT_MS,
|
|
131
132
|
stdio: ["ignore", "pipe", "ignore"]
|
|
132
133
|
}).trim();
|
|
133
134
|
const match = output.match(/^browser-rs (\d+)\.(\d+)\.(\d+)$/);
|
|
@@ -500,4 +501,4 @@ export {
|
|
|
500
501
|
bgBashContextCapability
|
|
501
502
|
};
|
|
502
503
|
|
|
503
|
-
//# debugId=
|
|
504
|
+
//# debugId=C69F97401A0FD56B64756E2164756E21
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"sources": ["../../../packages/core/src/platform/background-bash/manager.ts", "../../../packages/core/src/platform/config.ts", "../../../packages/core/src/platform/config-helpers.ts", "../../../packages/core/src/platform/logger.ts", "../../../packages/core/src/types.ts", "../../../packages/core/src/platform/delay.ts", "../../../packages/core/src/platform/background-bash/context.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { type ChildProcess, execFileSync, spawn } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n BASH_RS_BIN,\n BASH_RS_VERSION,\n BASHRS_SPILL_ROOT,\n BG_BASH_BASE_PORT,\n BG_BASH_MAX_PORT,\n} from \"#platform/config\";\nimport { delay } from \"#platform/delay\";\nimport { logger } from \"#platform/logger\";\nimport { deriveBgBashContextCapability } from \"./context\";\n\nexport function makeBgBashKey(_userId: string, _topic: string): string {\n return \"runtime\";\n}\n\ninterface BgBashInstance {\n process: ChildProcess;\n port: number;\n startedAt: number;\n lastUsedAt: number;\n}\n\nexport interface BackgroundBashManager {\n contextCapability(userId: string, topic: string): string;\n ensure(userId: string, topic: string): Promise<number>;\n clear(userId: string, topic: string): void;\n clearUser(userId: string): void;\n killAll(): Promise<void>;\n}\n\nexport interface BackgroundBashManagerOptions {\n /**\n * bash-rs executable. Defaults to the installed binary; injectable so a test\n * can drive the manager's bookkeeping with a fake `spawn` on a host that has\n * no binary at all.\n */\n bashRsBin?: string;\n basePort?: number;\n maxPort?: number;\n capability?: string;\n serverId?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: typeof globalThis.fetch;\n now?: () => number;\n delay?: (milliseconds: number) => Promise<void>;\n portPids?: (port: number) => readonly number[];\n spawn?: (\n command: string,\n args: readonly string[],\n options: Parameters<typeof spawn>[2],\n ) => ChildProcess;\n}\n\nfunction defaultPortPids(port: number): number[] {\n try {\n return execFileSync(\"lsof\", [\"-i\", `:${port}`, \"-t\"], { stdio: \"pipe\" })\n .toString()\n .trim()\n .split(\"\\n\")\n .map((pid) => Number.parseInt(pid, 10))\n .filter((pid) => !Number.isNaN(pid));\n } catch {\n return [];\n }\n}\n\n/** Create a fully isolated manager. All mutable process/port/context state belongs to the caller. */\nexport function createBackgroundBashManager(\n options: BackgroundBashManagerOptions = {},\n): BackgroundBashManager {\n const instances = new Map<string, BgBashInstance>();\n const usedPorts = new Set<number>();\n const spawning = new Map<string, Promise<number>>();\n const knownContexts = new Map<string, { userId: string; topic: string }>();\n const runtimeCapability = options.capability ?? randomBytes(32).toString(\"hex\");\n const runtimeServerId = options.serverId ?? randomBytes(16).toString(\"hex\");\n const bashRsBin = options.bashRsBin ?? BASH_RS_BIN;\n const basePort = options.basePort ?? BG_BASH_BASE_PORT;\n const maxPort = options.maxPort ?? BG_BASH_MAX_PORT;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const now = options.now ?? Date.now;\n const wait = options.delay ?? delay;\n const portPids = options.portPids ?? defaultPortPids;\n const spawnImpl =\n options.spawn ?? ((command, args, spawnOptions) => spawn(command, [...args], spawnOptions));\n\n function contextKey(userId: string, topic: string): string {\n return `${userId}\\0${topic}`;\n }\n\n function contextCapability(userId: string, topic: string): string {\n return deriveBgBashContextCapability(runtimeCapability, userId, topic);\n }\n\n async function allocatePort(excludedPorts: ReadonlySet<number> = new Set()): Promise<number> {\n for (let port = basePort; port <= maxPort; port++) {\n if (usedPorts.has(port) || excludedPorts.has(port)) continue;\n usedPorts.add(port);\n if (portPids(port).length > 0) {\n usedPorts.delete(port);\n continue;\n }\n return port;\n }\n throw new Error(\n `No available ports for background-bash (range ${basePort}-${maxPort}, ${instances.size} active)`,\n );\n }\n\n async function isHealthy(port: number): Promise<boolean> {\n try {\n const response = await fetchImpl(`http://127.0.0.1:${port}/health`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!response.ok) return false;\n // Confirm this port answers for *our* spawned process rather than a\n // stale one left behind by a previous manager instance.\n const body = await response.text();\n try {\n const parsed = JSON.parse(body);\n return (\n Boolean(parsed) && typeof parsed === \"object\" && parsed.instance_id === runtimeServerId\n );\n } catch {\n return false;\n }\n } catch {\n return false;\n }\n }\n\n function killRuntime(): void {\n const key = \"runtime\";\n const instance = instances.get(key);\n if (!instance) return;\n try {\n instance.process.kill(\"SIGTERM\");\n } catch {}\n usedPorts.delete(instance.port);\n instances.delete(key);\n logger.info({ key, port: instance.port }, \"background-bash server killed\");\n }\n\n async function spawnServer(\n key: string,\n reservedPort?: number,\n excludedPorts: ReadonlySet<number> = new Set(),\n ): Promise<number> {\n // bash-rs is the only implementation. A TS server used to stand in when the\n // binary was absent, but the two agreed on the HTTP protocol while exposing\n // different MCP tool names (bash_run vs background_bash_run), so which one\n // spawned silently changed the tool surface an agent saw. Failing loudly\n // beats serving a different API than the caller was told to expect.\n //\n // Checked before allocating: the caller retries once per turn, and a port\n // reserved by a throw is never released, so allocating first leaked one\n // port per attempt until the range was exhausted and the real cause was\n // buried under \"No available ports\".\n if (!bashRsBin) {\n throw new Error(\n `background-bash requires the bash-rs ${BASH_RS_VERSION} binary; run install-bash-rs.mjs (or set NEGOTIUM_BASH_RS_BIN)`,\n );\n }\n const port = reservedPort ?? (await allocatePort(excludedPorts));\n const process = spawnImpl(bashRsBin, [String(port)], {\n stdio: \"ignore\",\n detached: false,\n env: {\n ...(options.env ?? globalThis.process.env),\n NEGOTIUM_BG_BASH_CAPABILITY: runtimeCapability,\n NEGOTIUM_BG_BASH_SERVER_ID: runtimeServerId,\n BASHRS_HTTP_CAPABILITY: runtimeCapability,\n BASHRS_INSTANCE_ID: runtimeServerId,\n BASHRS_SPILL_ROOT,\n },\n });\n\n process.once(\"error\", (error) => {\n logger.error({ err: error, key }, \"background-bash server error\");\n if (instances.get(key)?.process === process) {\n usedPorts.delete(port);\n instances.delete(key);\n }\n });\n process.once(\"exit\", (code) => {\n logger.info({ key, code }, \"background-bash server exited\");\n if (instances.get(key)?.process === process) {\n usedPorts.delete(port);\n instances.delete(key);\n }\n });\n\n const timestamp = now();\n instances.set(key, { process, port, startedAt: timestamp, lastUsedAt: timestamp });\n const started = now();\n while (now() - started < 8_000) {\n if (process.exitCode !== null) {\n const nextExcluded = new Set(excludedPorts);\n nextExcluded.add(port);\n return spawnServer(key, undefined, nextExcluded);\n }\n if (await isHealthy(port)) return port;\n await wait(200);\n }\n killRuntime();\n throw new Error(`background-bash server failed health check after spawn on port ${port}`);\n }\n\n async function ensure(userId: string, topic: string): Promise<number> {\n const key = makeBgBashKey(userId, topic);\n knownContexts.set(contextKey(userId, topic), { userId, topic });\n const inProgress = spawning.get(key);\n if (inProgress) return inProgress;\n\n const promise = (async () => {\n const existing = instances.get(key);\n if (existing && !existing.process.killed && existing.process.exitCode === null) {\n if (await isHealthy(existing.port)) {\n existing.lastUsedAt = now();\n return existing.port;\n }\n killRuntime();\n } else if (existing) {\n usedPorts.delete(existing.port);\n instances.delete(key);\n }\n return spawnServer(key);\n })().finally(() => spawning.delete(key));\n spawning.set(key, promise);\n return promise;\n }\n\n function clear(userId: string, topic: string): void {\n knownContexts.delete(contextKey(userId, topic));\n const instance = instances.get(\"runtime\");\n if (!instance) return;\n const query = new URLSearchParams({\n user: userId,\n topic,\n capability: contextCapability(userId, topic),\n });\n void fetchImpl(`http://127.0.0.1:${instance.port}/contexts?${query}`, {\n method: \"DELETE\",\n }).catch(() => {});\n }\n\n function clearUser(userId: string): void {\n for (const context of [...knownContexts.values()]) {\n if (context.userId === userId) clear(context.userId, context.topic);\n }\n }\n\n async function killAll(): Promise<void> {\n const entries = [...instances.values()];\n for (const instance of entries) {\n try {\n instance.process.kill(\"SIGTERM\");\n } catch {}\n }\n instances.clear();\n usedPorts.clear();\n knownContexts.clear();\n const deadline = now() + 3000;\n await Promise.all(\n entries.map(\n (instance) =>\n new Promise<void>((resolve) => {\n if (instance.process.exitCode !== null || instance.process.killed) return resolve();\n instance.process.once(\"exit\", resolve);\n instance.process.once(\"error\", resolve);\n const timer = setTimeout(resolve, Math.max(0, deadline - now()));\n timer.unref?.();\n }),\n ),\n );\n }\n\n return { contextCapability, ensure, clear, clearUser, killAll };\n}\n\nconst defaultManager = createBackgroundBashManager();\n\nexport const bgBashContextCapability = defaultManager.contextCapability;\nexport const ensureBgBash = defaultManager.ensure;\nexport const killBgBash = defaultManager.clear;\nexport const killBgBashForUser = defaultManager.clearUser;\nexport const killAllBgBash = defaultManager.killAll;\n",
|
|
6
|
-
"import { execFileSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n accessSync,\n chmodSync,\n constants,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseRuntimePort, readEnvText, safeRuntimePathSegment } from \"#platform/config-helpers\";\nimport { logger } from \"#platform/logger\";\nimport { type AgentKind, isAgentKind } from \"#types\";\n\nexport function envText(envKey: string): string | undefined {\n return readEnvText(process.env, envKey);\n}\n\nfunction resolveAgentEnv(envKey: string, fallback: AgentKind, legacyEnvKey?: string): AgentKind {\n const value = envText(envKey) ?? (legacyEnvKey ? envText(legacyEnvKey) : undefined);\n return isAgentKind(value) ? value : fallback;\n}\n\nconst HOME = homedir();\n\n// new URL(\"../..\", import.meta.url) causes webpack to treat \"../..\" as a module import.\n// Split into fileURLToPath → dirname → resolve to avoid that.\nfunction resolveProjectRoot(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const packagedRuntime = resolve(moduleDir, \"runtime\");\n if (existsSync(resolve(packagedRuntime, \"src\"))) return packagedRuntime;\n return resolve(moduleDir, \"../..\");\n}\n\nexport const PROJECT_ROOT = resolveProjectRoot();\n\n/** Resolve a dependency executable from either a package-local or hoisted install. */\nfunction resolveDependencyBin(name: string): string {\n let dir = PROJECT_ROOT;\n while (true) {\n const candidate = resolve(dir, \"node_modules\", \".bin\", name);\n if (existsSync(candidate)) return candidate;\n const parent = dirname(dir);\n if (parent === dir) return candidate;\n dir = parent;\n }\n}\n\n// Each machine is one negotium node; all node state lives in one dotdir.\n// NEGOTIUM_STATE_DIR overrides (useful for tests and multi-node-on-one-box).\nconst STATE_DIR_ENV = envText(\"NEGOTIUM_STATE_DIR\");\nexport const STATE_DIR = STATE_DIR_ENV ? resolve(STATE_DIR_ENV) : resolve(HOME, \".negotium\");\n\nfunction resolveLocalStateDir(envKey: string, stateName: string): string {\n const envValue = envText(envKey);\n if (envValue) return resolve(envValue);\n return resolve(STATE_DIR, stateName);\n}\n\nfunction parsePortEnv(envValue: string | undefined, fallback: number): number {\n return parseRuntimePort(envValue, fallback);\n}\n\nexport const WORKSPACE_DIR = resolveLocalStateDir(\"NEGOTIUM_WORKSPACE_DIR\", \"workspace\");\nexport const TOPIC_WORKSPACE_DIR = resolve(WORKSPACE_DIR, \"topics\");\nexport const SHARED_WIKI_DIR = resolve(WORKSPACE_DIR, \"wiki\");\nexport const CRON_WORKSPACE_DIR = resolve(WORKSPACE_DIR, \"cron\");\nexport const BROWSER_DIR = resolveLocalStateDir(\"NEGOTIUM_BROWSER_DIR\", \"browser\");\nexport const BROWSER_PROFILES_DIR = resolve(BROWSER_DIR, \"profiles\");\nexport const BINARIES_DIR = resolve(STATE_DIR, \"binaries\");\nexport const SECRETS_DIR = resolve(STATE_DIR, \"secrets\");\n// Legacy names remain public, but their durable contents now live under data.\nexport const DM_WORKSPACE_DIR = resolve(STATE_DIR, \"data\", \"dm\");\nexport const SESSION_WORKSPACE_DIR = resolve(STATE_DIR, \"data\", \"sessions\");\n// The Claude Agent SDK ships a platform-matched Claude Code binary. Keep that\n// SDK/CLI pair together by default; only use an external executable when an\n// operator explicitly opts in. This avoids silently pairing an older SDK with\n// a newer globally installed Claude Code release.\nconst CLAUDE_EXECUTABLE_ENV = envText(\"NEGOTIUM_CLAUDE_EXECUTABLE\");\nexport const CLAUDE_EXECUTABLE = CLAUDE_EXECUTABLE_ENV ? resolve(CLAUDE_EXECUTABLE_ENV) : undefined;\n\n// Fallback output language for model-generated prose (topic/channel/manager\n// replies and the archiver's summaries, briefs, articles, completion reply).\n// Defaults to English; set `NEGOTIUM_LANG` to the user's mother tongue (e.g.\n// `Korean`, `ko`). The assistant still mirrors whatever language the user\n// writes in; `NEGOTIUM_MEMORY_LANG` can narrow just the archiver. Fixed system\n// chrome / degraded-path strings emitted by code stay English (can't translate\n// an arbitrary value at runtime).\nexport const DEFAULT_OUTPUT_LANGUAGE = \"English\";\n\nexport function resolveOutputLanguage(): string {\n const raw = envText(\"NEGOTIUM_LANG\")?.trim();\n return raw && raw.length > 0 ? raw : DEFAULT_OUTPUT_LANGUAGE;\n}\n\n/** Browser.rs release tested with this Negotium version. */\nexport const BROWSER_RS_VERSION = \"v0.1.19\";\n/** Require the authenticated listener and the current Browser.rs tool contract. */\nexport const BROWSER_RS_MIN_SECURE_VERSION = \"0.1.15\";\n\nfunction versionAtLeast(actualVersion: string, minimumVersion: string): boolean {\n const actual = actualVersion.split(\".\").map(Number);\n const minimum = minimumVersion.split(\".\").map(Number);\n if (actual.some(Number.isNaN) || minimum.some(Number.isNaN)) return false;\n for (let index = 0; index < minimum.length; index += 1) {\n if ((actual[index] ?? 0) > (minimum[index] ?? 0)) return true;\n if ((actual[index] ?? 0) < (minimum[index] ?? 0)) return false;\n }\n return true;\n}\n\nfunction browserRsMeetsMinimumVersion(candidate: string): boolean {\n try {\n const output = execFileSync(candidate, [\"--version\"], {\n encoding: \"utf8\",\n timeout: 2_000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n const match = output.match(/^browser-rs (\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) return false;\n return versionAtLeast(match.slice(1).join(\".\"), BROWSER_RS_MIN_SECURE_VERSION);\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the preferred Browser.rs engine without consulting PATH. The\n * versioned private location keeps different Negotium releases reproducible\n * and avoids changing a user's global browser-rs installation.\n */\nexport function resolveBrowserRsBin(envValue?: string): string | undefined {\n const override = envValue?.trim();\n if (\n !override &&\n !versionAtLeast(BROWSER_RS_VERSION.replace(/^v/, \"\"), BROWSER_RS_MIN_SECURE_VERSION)\n ) {\n return undefined;\n }\n const candidate = override\n ? resolve(override)\n : resolve(BINARIES_DIR, \"browser-rs\", BROWSER_RS_VERSION, \"browser-rs\");\n try {\n accessSync(candidate, constants.X_OK);\n return browserRsMeetsMinimumVersion(candidate) ? candidate : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Backend that stores documents published by `publish_html` and serves them\n * at `<base>/snippets/<id>`. Unset means the deployment has nowhere to\n * publish, and the publish tools are omitted from the catalog rather than\n * offering a link that cannot be minted.\n */\nexport const SNIPPETS_API_URL = (\n envText(\"NEGOTIUM_SNIPPETS_API_URL\") ??\n envText(\"SNIPPETS_API_URL\") ??\n \"\"\n).replace(/\\/+$/, \"\");\n\nexport const BROWSER_RS_BIN = resolveBrowserRsBin(envText(\"NEGOTIUM_BROWSER_RS_BIN\"));\n\n/** bash-rs release tested with this Negotium version — see apps/negotium/install-bash-rs.mjs. */\nexport const BASH_RS_VERSION = \"v0.1.5\";\n\n/**\n * Resolve the bash-rs binary the same way `resolveBrowserRsBin` resolves\n * Browser.rs: a versioned private location, no PATH lookup, `undefined`\n * (rather than throwing) when it's missing. There is no substitute: the manager\n * throws when a turn tries to prepare background-bash without a binary (see\n * `background-bash/manager.ts`), the turn runner catches that and continues\n * with a reminder that the tools are gone, so background-bash is simply\n * unavailable on a platform without a prebuilt binary.\n */\nexport function resolveBashRsBin(envValue?: string): string | undefined {\n const override = envValue?.trim();\n const candidate = override\n ? resolve(override)\n : resolve(BINARIES_DIR, \"bash-rs\", BASH_RS_VERSION, \"bash-rs\");\n try {\n accessSync(candidate, constants.X_OK);\n return candidate;\n } catch {\n return undefined;\n }\n}\n\nexport const BASH_RS_BIN = resolveBashRsBin(envText(\"NEGOTIUM_BASH_RS_BIN\"));\n\n// Managed Browser.rs terminates MCP transports and security policy itself.\nexport function resolveBrowserMcpBin(envValue?: string): string {\n const override = envValue?.trim();\n if (override) return resolve(override);\n return BROWSER_RS_BIN ?? resolve(BINARIES_DIR, \"browser-rs\", BROWSER_RS_VERSION, \"browser-rs\");\n}\n\nexport const PLAYWRIGHT_MCP_BIN = resolveBrowserMcpBin(envText(\"NEGOTIUM_BROWSER_MCP_BIN\"));\n\n// --- Browser egress proxy ---\n//\n// On a datacenter host (AWS) the browser's egress IP is a known cloud range,\n// so anti-bot services (Cloudflare, DataDome, reCAPTCHA) challenge or block it\n// far more than a residential IP would. Routing the automation browser through\n// a residential/ISP proxy moves the egress IP out of the datacenter range.\n//\n// Operators set BROWSER_PROXY_URL, e.g. http://user:pass@proxy.host:8080 or\n// socks5://proxy.host:1080. Credentials in the URL are split out because\n// Playwright takes them as separate fields. BROWSER_PROXY_BYPASS is an optional\n// comma-separated no-proxy list (e.g. \"localhost,127.0.0.1,*.internal\").\n//\n// NOTE: Chromium does not support authentication for SOCKS proxies — put\n// credentials only on http/https proxy URLs.\nexport type BrowserProxyConfig = {\n server: string;\n username?: string;\n password?: string;\n bypass?: string;\n};\n\nexport function resolveBrowserProxy(): BrowserProxyConfig | null {\n const raw = envText(\"BROWSER_PROXY_URL\");\n if (!raw) return null;\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n logger.warn({ raw }, \"Ignoring malformed BROWSER_PROXY_URL\");\n return null;\n }\n // Playwright wants the server without embedded credentials.\n const server = `${url.protocol}//${url.host}`;\n const proxy: BrowserProxyConfig = { server };\n if (url.username) proxy.username = decodeURIComponent(url.username);\n if (url.password) proxy.password = decodeURIComponent(url.password);\n const bypass = envText(\"BROWSER_PROXY_BYPASS\");\n if (bypass) proxy.bypass = bypass;\n return proxy;\n}\n\n// --- Node/tsx runtime for the `codex` agent's MCP servers ---\n//\n// codex 0.135's rmcp stdio MCP client cannot reliably complete the initialize\n// handshake with servers spawned via `bun` (the JSON-RPC initialize is\n// dropped/raced and no tools ever reach the model). Pure-node servers connect\n// reliably, so codex turns launch the SAME .ts servers via node + tsx instead\n// of `bun run`. claude/maestro keep using `bun run` (fast, native, unaffected).\n//\n// tsx transpiles .ts on the fly and resolves the `@/*` tsconfig path aliases,\n// but only when it can find the tsconfig — and MCP servers run with cwd set to\n// the user's workspace dir, not PROJECT_ROOT — so we pass TSX_TSCONFIG_PATH\n// explicitly via env. Requires package.json `\"type\": \"module\"` so the servers'\n// top-level `await` loads as ESM under node.\nexport const TSX_BIN = resolveDependencyBin(\"tsx\");\n/** In-process tsx loader used by Node MCP entrypoints (avoids the tsx CLI child process). */\nexport const TSX_LOADER = createRequire(import.meta.url).resolve(\"tsx\");\nexport const TSCONFIG_PATH = resolve(PROJECT_ROOT, \"tsconfig.json\");\n\nexport const SESSION_COMM_SERVER = resolve(PROJECT_ROOT, \"src/mcp/session-comm/server.ts\");\n\nexport const TASK_SERVER = resolve(PROJECT_ROOT, \"src/mcp/task-server.ts\");\nexport const BROWSER_MCP_SSE_PROXY_SERVER = resolve(\n PROJECT_ROOT,\n \"src/mcp/browser-sse-proxy-server.ts\",\n);\nexport const CANONICAL_MCP_PROXY_SERVER = resolve(\n PROJECT_ROOT,\n \"src/mcp/canonical-proxy-server.ts\",\n);\n\nexport const WIKI_SERVER = resolve(PROJECT_ROOT, \"src/mcp/wiki-server.ts\");\n\nexport const TOKEN_STATS_SERVER = resolve(PROJECT_ROOT, \"src/mcp/token-stats-server.ts\");\n\nexport const COMPACTION_LOG_SERVER = resolve(PROJECT_ROOT, \"src/mcp/compaction-log-server.ts\");\n\nexport const SYSTEM_HEALTH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/system-health-server.ts\");\n\nexport const AGENT_HEALTH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/agent-health-server.ts\");\n\nexport const VAULT_SERVER = resolve(PROJECT_ROOT, \"src/mcp/vault-server.ts\");\n\nexport const BG_BASH_BASE_PORT = parsePortEnv(process.env.BG_BASH_BASE_PORT, 9700);\nexport const BG_BASH_MAX_PORT = parsePortEnv(process.env.BG_BASH_MAX_PORT, 9799);\n\nfunction safeWorkspaceSegment(value: string, fallback: string): string {\n return safeRuntimePathSegment(value, fallback);\n}\n\n/** Resolve the shared filesystem workspace for an API topic. */\nexport function resolveTopicWorkspaceDir(topicId: string): string {\n return join(TOPIC_WORKSPACE_DIR, safeWorkspaceSegment(topicId, \"topic\"));\n}\n\nexport function isProductionEnv(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\n\nfunction loadOrCreateLocalSecret(\n envKey: string,\n filename: string,\n options: { persistEnvValue?: boolean } = {},\n): string {\n const envValue = envText(envKey);\n const secretFile = resolve(SECRETS_DIR, filename);\n mkdirSync(dirname(secretFile), { recursive: true });\n if (envValue) {\n if (options.persistEnvValue) {\n writeFileSync(secretFile, `${envValue}\\n`, { mode: 0o600 });\n chmodSync(secretFile, 0o600);\n }\n return envValue;\n }\n\n if (existsSync(secretFile)) {\n const stored = readFileSync(secretFile, \"utf-8\").trim();\n if (stored) {\n chmodSync(secretFile, 0o600);\n return stored;\n }\n }\n\n const secret = randomBytes(32).toString(\"base64url\");\n try {\n writeFileSync(secretFile, `${secret}\\n`, { mode: 0o600, flag: \"wx\" });\n return secret;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const stored = readFileSync(secretFile, \"utf-8\").trim();\n if (!stored) throw new Error(`Secret file exists but is empty: ${secretFile}`);\n chmodSync(secretFile, 0o600);\n return stored;\n }\n}\n\nexport const RUNTIME_MCP_SECRET = loadOrCreateLocalSecret(\n \"RUNTIME_MCP_SECRET\",\n \"runtime-mcp-secret\",\n);\n/** Local bearer token for the loopback node-control API. */\nexport const NODE_CONTROL_TOKEN = loadOrCreateLocalSecret(\n \"NEGOTIUM_CONTROL_TOKEN\",\n \"node-control-token\",\n);\nexport const VAULT_MASTER_KEY = loadOrCreateLocalSecret(\n \"NEGOTIUM_VAULT_MASTER_KEY\",\n \"vault-master-key\",\n { persistEnvValue: true },\n);\n// Agent/tool subprocesses inherit process.env. Keep the loaded key in this\n// process only so `env`/`ps` inside an agent workspace cannot reveal it.\ndelete process.env.NEGOTIUM_VAULT_MASTER_KEY;\n\n/** The node's single open port: runtime MCP endpoint + node API. */\nexport const NEGOTIUM_PORT = parseInt(process.env.NEGOTIUM_PORT || \"7777\", 10);\nexport const hostname = process.env.HOSTNAME || \"127.0.0.1\";\n\n// Persistent state (survives restarts, long-lived)\nexport const DATA_DIR = resolveLocalStateDir(\"NEGOTIUM_DATA_DIR\", \"data\");\nexport const LOG_DIR = resolveLocalStateDir(\"NEGOTIUM_LOG_DIR\", \"logs\");\nexport const UPLOADS_DIR = resolve(DATA_DIR, \"uploads\");\nexport const VAULT_DIR = resolve(DATA_DIR, \"vault\");\n// SESSIONS_DB_PATH env override lets tests point the DB singleton at a temp file.\nexport const SESSIONS_DB = process.env.SESSIONS_DB_PATH\n ? resolve(process.env.SESSIONS_DB_PATH)\n : resolve(DATA_DIR, \"sessions.db\");\nexport const DEBUG_FILE = resolve(DATA_DIR, \"debug-users.json\");\nexport const USERS_LOG_DIR = resolve(DATA_DIR, \"users\");\n\n// Runtime IPC queues (transient, safe to clear on restart)\n/** @deprecated Use the runtime layout name; NEGOTIUM_RUN_DIR remains a compatibility override. */\nexport const RUN_DIR = resolveLocalStateDir(\"NEGOTIUM_RUN_DIR\", \"runtime\");\nexport const RUNTIME_DIR = RUN_DIR;\nexport const PROGRESS_DIR = resolve(RUN_DIR, \"progress\");\nexport const DM_CMD_DIR = resolve(RUN_DIR, \"dm-commands\");\nexport const DM_RESP_DIR = resolve(RUN_DIR, \"dm-responses\");\nexport const SESSION_INBOX_DIR = resolve(RUN_DIR, \"session-inbox\");\nexport const SESSION_ASKS_DIR = resolve(RUN_DIR, \"session-asks\");\n/**\n * Passed to `bash-rs` as `BASHRS_SPILL_ROOT`. Each job gets a subdirectory\n * here (`{bash_id}/meta.json`, `result.json`, `stdout.log`, `stderr.log`) —\n * see bash-rs-mcp's `journal.rs`. `runtime/bashrs-completions.ts` watches\n * this directory and turns `result.json` into a session-inbox `tell`. The\n * retired TypeScript server used to write one directly instead.\n */\nexport const BASHRS_SPILL_ROOT = resolve(RUN_DIR, \"bashrs\");\nexport const PLAYWRIGHT_BASE_PORT = parsePortEnv(process.env.PLAYWRIGHT_BASE_PORT, 9100);\nexport const PLAYWRIGHT_MAX_PORT = parsePortEnv(process.env.PLAYWRIGHT_MAX_PORT, 9499);\nexport const PLAYWRIGHT_PORTS_DIR = resolve(RUN_DIR, \"playwright-ports\");\nmkdirSync(STATE_DIR, { recursive: true });\nmkdirSync(DATA_DIR, { recursive: true });\nmkdirSync(UPLOADS_DIR, { recursive: true });\nmkdirSync(VAULT_DIR, { recursive: true, mode: 0o700 });\nmkdirSync(LOG_DIR, { recursive: true });\nmkdirSync(PROGRESS_DIR, { recursive: true });\nmkdirSync(DM_CMD_DIR, { recursive: true });\nmkdirSync(DM_RESP_DIR, { recursive: true });\nmkdirSync(SESSION_INBOX_DIR, { recursive: true });\nmkdirSync(SESSION_ASKS_DIR, { recursive: true });\nmkdirSync(PLAYWRIGHT_PORTS_DIR, { recursive: true });\nmkdirSync(WORKSPACE_DIR, { recursive: true });\nmkdirSync(TOPIC_WORKSPACE_DIR, { recursive: true });\nmkdirSync(SHARED_WIKI_DIR, { recursive: true });\nmkdirSync(CRON_WORKSPACE_DIR, { recursive: true });\nmkdirSync(DM_WORKSPACE_DIR, { recursive: true });\nmkdirSync(SESSION_WORKSPACE_DIR, { recursive: true });\nmkdirSync(BROWSER_DIR, { recursive: true });\nmkdirSync(BROWSER_PROFILES_DIR, { recursive: true });\nmkdirSync(BINARIES_DIR, { recursive: true });\nmkdirSync(SECRETS_DIR, { recursive: true, mode: 0o700 });\n\n/** Stale threshold for active-query state files (crash recovery) */\nexport const ACTIVE_QUERY_STALE_MS = 10 * 60 * 1000; // 10 minutes\n\nexport const AGENTS_PROMPTS_DIR = resolve(PROJECT_ROOT, \"src/prompts/agents\");\nexport const RESOURCES_DIR = resolve(PROJECT_ROOT, \"src/resources\");\n\n/** Returns process.env without CLAUDECODE, to prevent nested claude-code detection in subprocesses. */\nexport function getCleanEnv(): NodeJS.ProcessEnv {\n const env = { ...process.env };\n delete env.CLAUDECODE;\n return env;\n}\n\nexport const FILE_EXTENSIONS_REGEX =\n /(?:\\/[^\\s\"'<>|*?[\\]]+\\.(?:png|jpg|jpeg|gif|webp|svg|pdf|csv|xlsx|xls|json|txt|md|html|zip|py|js|ts|tsx|jsx|css|xml|yaml|yml|docx|pptx))/gi;\n\nexport const FILE_TAG_REGEX = /\\[FILE:(\\/[^\\]]+)\\]/gi;\n\n// Canonical Claude model IDs — update here when Anthropic releases new versions\nexport const MODEL_SONNET = \"claude-sonnet-5\";\nexport const MODEL_OPUS = \"claude-opus-5\";\nexport const MODEL_HAIKU = \"claude-haiku-4-5-20251001\";\nexport const MODEL_FABLE = \"claude-fable-5\"; // Mythos-class, announced 2026-06-09\n\n// DeepSeek V4 (released 2026-04-24). API is OpenAI-compatible at\n// https://api.deepseek.com/v1/chat/completions; thinking mode is enabled via\n// `extra_body.thinking.type` + `reasoning_effort`. Legacy `deepseek-chat` /\n// `deepseek-reasoner` are deprecated 2026-07-24.\nexport const MODEL_DEEPSEEK_V4_PRO = \"deepseek-v4-pro\";\nexport const MODEL_DEEPSEEK_V4_FLASH = \"deepseek-v4-flash\";\n\n// Agent + model defaults split by session role. FALLBACK_* is the shared base;\n// SESSION_* overrides topic + ephemeral; GATEWAY_* overrides dm + manager.\n// DEFAULT_* is accepted as a legacy alias during the env migration window.\nexport const FALLBACK_AGENT: AgentKind = resolveAgentEnv(\n \"FALLBACK_AGENT\",\n \"maestro\",\n \"DEFAULT_AGENT\",\n);\nexport const SESSION_AGENT: AgentKind = resolveAgentEnv(\"SESSION_AGENT\", FALLBACK_AGENT);\nexport const GATEWAY_AGENT: AgentKind = resolveAgentEnv(\"GATEWAY_AGENT\", FALLBACK_AGENT);\n\nexport const FALLBACK_MODEL = envText(\"FALLBACK_MODEL\") ?? envText(\"DEFAULT_MODEL\");\n\nfunction resolveModelEnv(envKey: string, agentConst: AgentKind): string | undefined {\n return envText(envKey) ?? (agentConst === FALLBACK_AGENT ? FALLBACK_MODEL : undefined);\n}\n\nexport const SESSION_MODEL = resolveModelEnv(\"SESSION_MODEL\", SESSION_AGENT);\nexport const GATEWAY_MODEL = resolveModelEnv(\"GATEWAY_MODEL\", GATEWAY_AGENT);\n\n/** Resolve the effective display/default model for a topic (session context).\n * Applies the session model override only when that role owns the agent;\n * otherwise each registry's native default stays authoritative. */\nexport function resolveDefaultModel(agent: string, registryDefaultModel: string): string {\n return agent === SESSION_AGENT && SESSION_MODEL ? SESSION_MODEL : registryDefaultModel;\n}\n\n// ── External tool binaries + media pipeline env ───────────────────\n// (src/media/* 에서 사용. 미설정 시 fallback 의미는 기존 그대로:\n// FFMPEG_BIN은 text-extractor에서 필수(undefined면 spawn 시점 실패),\n// video.ts에서는 PATH의 ffmpeg/ffprobe로 fallback.)\nexport const FFMPEG_BIN = envText(\"FFMPEG_BIN\");\nexport const FFPROBE_BIN = envText(\"FFPROBE_BIN\");\nexport const PYTHON_BIN = envText(\"PYTHON_BIN\") ?? \"python3\";\nexport const FASTER_WHISPER_WRAPPER =\n envText(\"FASTER_WHISPER_WRAPPER\") ?? resolve(PROJECT_ROOT, \"scripts/faster-whisper-wrapper.py\");\nexport const WHISPER_MODEL = envText(\"WHISPER_MODEL_FILE\") ?? \"turbo\";\nexport const TESSERACT_BIN = envText(\"TESSERACT_BIN\") ?? \"tesseract\";\nexport const PDFTOTEXT_BIN = envText(\"PDFTOTEXT_BIN\") ?? \"pdftotext\";\n\n// Max tell_session relay depth from origin user. ask_session forks reset to\n// depth=0, so this only caps tell_session chains. Override via MAX_TELL_DEPTH\n// (positive int); defaults to 20 when unset or invalid.\nconst _envMaxTellDepth = Number.parseInt(process.env.MAX_TELL_DEPTH ?? \"\", 10);\nexport const MAX_TELL_DEPTH =\n Number.isInteger(_envMaxTellDepth) && _envMaxTellDepth > 0 ? _envMaxTellDepth : 20;\n\n/** Codex CLI auth file. 호출 시점에 env를 읽는다 — 테스트가 런타임에\n * NEGOTIUM_CODEX_AUTH_FILE을 바꾸므로 모듈 로드 상수로 만들면 안 된다. */\nexport function codexAuthFilePath(): string {\n return (\n process.env.NEGOTIUM_CODEX_AUTH_FILE ||\n join(process.env.CODEX_HOME || join(homedir(), \".codex\"), \"auth.json\")\n );\n}\n\n// System defaults moved to per-agent registries\n// (`src/agents/{claude,codex}-registry.ts`). Read via\n// `getRegistry(agent).defaultModel` / `.defaultEffort`.\n\n// MCP server builders -> src/platform/mcp-config.ts\n",
|
|
6
|
+
"import { execFileSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n accessSync,\n chmodSync,\n constants,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseRuntimePort, readEnvText, safeRuntimePathSegment } from \"#platform/config-helpers\";\nimport { logger } from \"#platform/logger\";\nimport { type AgentKind, isAgentKind } from \"#types\";\n\nexport function envText(envKey: string): string | undefined {\n return readEnvText(process.env, envKey);\n}\n\nfunction resolveAgentEnv(envKey: string, fallback: AgentKind, legacyEnvKey?: string): AgentKind {\n const value = envText(envKey) ?? (legacyEnvKey ? envText(legacyEnvKey) : undefined);\n return isAgentKind(value) ? value : fallback;\n}\n\nconst HOME = homedir();\n\n// new URL(\"../..\", import.meta.url) causes webpack to treat \"../..\" as a module import.\n// Split into fileURLToPath → dirname → resolve to avoid that.\nfunction resolveProjectRoot(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const packagedRuntime = resolve(moduleDir, \"runtime\");\n if (existsSync(resolve(packagedRuntime, \"src\"))) return packagedRuntime;\n return resolve(moduleDir, \"../..\");\n}\n\nexport const PROJECT_ROOT = resolveProjectRoot();\n\n/** Resolve a dependency executable from either a package-local or hoisted install. */\nfunction resolveDependencyBin(name: string): string {\n let dir = PROJECT_ROOT;\n while (true) {\n const candidate = resolve(dir, \"node_modules\", \".bin\", name);\n if (existsSync(candidate)) return candidate;\n const parent = dirname(dir);\n if (parent === dir) return candidate;\n dir = parent;\n }\n}\n\n// Each machine is one negotium node; all node state lives in one dotdir.\n// NEGOTIUM_STATE_DIR overrides (useful for tests and multi-node-on-one-box).\nconst STATE_DIR_ENV = envText(\"NEGOTIUM_STATE_DIR\");\nexport const STATE_DIR = STATE_DIR_ENV ? resolve(STATE_DIR_ENV) : resolve(HOME, \".negotium\");\n\nfunction resolveLocalStateDir(envKey: string, stateName: string): string {\n const envValue = envText(envKey);\n if (envValue) return resolve(envValue);\n return resolve(STATE_DIR, stateName);\n}\n\nfunction parsePortEnv(envValue: string | undefined, fallback: number): number {\n return parseRuntimePort(envValue, fallback);\n}\n\nexport const WORKSPACE_DIR = resolveLocalStateDir(\"NEGOTIUM_WORKSPACE_DIR\", \"workspace\");\nexport const TOPIC_WORKSPACE_DIR = resolve(WORKSPACE_DIR, \"topics\");\nexport const SHARED_WIKI_DIR = resolve(WORKSPACE_DIR, \"wiki\");\nexport const CRON_WORKSPACE_DIR = resolve(WORKSPACE_DIR, \"cron\");\nexport const BROWSER_DIR = resolveLocalStateDir(\"NEGOTIUM_BROWSER_DIR\", \"browser\");\nexport const BROWSER_PROFILES_DIR = resolve(BROWSER_DIR, \"profiles\");\nexport const BINARIES_DIR = resolve(STATE_DIR, \"binaries\");\nexport const SECRETS_DIR = resolve(STATE_DIR, \"secrets\");\n// Legacy names remain public, but their durable contents now live under data.\nexport const DM_WORKSPACE_DIR = resolve(STATE_DIR, \"data\", \"dm\");\nexport const SESSION_WORKSPACE_DIR = resolve(STATE_DIR, \"data\", \"sessions\");\n// The Claude Agent SDK ships a platform-matched Claude Code binary. Keep that\n// SDK/CLI pair together by default; only use an external executable when an\n// operator explicitly opts in. This avoids silently pairing an older SDK with\n// a newer globally installed Claude Code release.\nconst CLAUDE_EXECUTABLE_ENV = envText(\"NEGOTIUM_CLAUDE_EXECUTABLE\");\nexport const CLAUDE_EXECUTABLE = CLAUDE_EXECUTABLE_ENV ? resolve(CLAUDE_EXECUTABLE_ENV) : undefined;\n\n// Fallback output language for model-generated prose (topic/channel/manager\n// replies and the archiver's summaries, briefs, articles, completion reply).\n// Defaults to English; set `NEGOTIUM_LANG` to the user's mother tongue (e.g.\n// `Korean`, `ko`). The assistant still mirrors whatever language the user\n// writes in; `NEGOTIUM_MEMORY_LANG` can narrow just the archiver. Fixed system\n// chrome / degraded-path strings emitted by code stay English (can't translate\n// an arbitrary value at runtime).\nexport const DEFAULT_OUTPUT_LANGUAGE = \"English\";\n\nexport function resolveOutputLanguage(): string {\n const raw = envText(\"NEGOTIUM_LANG\")?.trim();\n return raw && raw.length > 0 ? raw : DEFAULT_OUTPUT_LANGUAGE;\n}\n\n/** Browser.rs release tested with this Negotium version. */\nexport const BROWSER_RS_VERSION = \"v0.1.19\";\n/** Require the authenticated listener and the current Browser.rs tool contract. */\nexport const BROWSER_RS_MIN_SECURE_VERSION = \"0.1.15\";\n\nfunction versionAtLeast(actualVersion: string, minimumVersion: string): boolean {\n const actual = actualVersion.split(\".\").map(Number);\n const minimum = minimumVersion.split(\".\").map(Number);\n if (actual.some(Number.isNaN) || minimum.some(Number.isNaN)) return false;\n for (let index = 0; index < minimum.length; index += 1) {\n if ((actual[index] ?? 0) > (minimum[index] ?? 0)) return true;\n if ((actual[index] ?? 0) < (minimum[index] ?? 0)) return false;\n }\n return true;\n}\n\n/**\n * Ceiling for the `--version` probe, not a latency expectation.\n *\n * The probe exists so a wedged binary cannot hang startup; a healthy one\n * answers in milliseconds. At 2s it also failed whenever the machine was merely\n * busy — process startup under a loaded test suite regularly exceeds that —\n * which turned a correctness check into a load measurement and made\n * `resolveBrowserRsBin` intermittently report a perfectly good binary as\n * unusable. Generous enough that only a genuinely stuck process trips it.\n */\nconst BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15_000;\n\nfunction browserRsMeetsMinimumVersion(candidate: string): boolean {\n try {\n const output = execFileSync(candidate, [\"--version\"], {\n encoding: \"utf8\",\n timeout: BROWSER_RS_VERSION_PROBE_TIMEOUT_MS,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n const match = output.match(/^browser-rs (\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) return false;\n return versionAtLeast(match.slice(1).join(\".\"), BROWSER_RS_MIN_SECURE_VERSION);\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the preferred Browser.rs engine without consulting PATH. The\n * versioned private location keeps different Negotium releases reproducible\n * and avoids changing a user's global browser-rs installation.\n */\nexport function resolveBrowserRsBin(envValue?: string): string | undefined {\n const override = envValue?.trim();\n if (\n !override &&\n !versionAtLeast(BROWSER_RS_VERSION.replace(/^v/, \"\"), BROWSER_RS_MIN_SECURE_VERSION)\n ) {\n return undefined;\n }\n const candidate = override\n ? resolve(override)\n : resolve(BINARIES_DIR, \"browser-rs\", BROWSER_RS_VERSION, \"browser-rs\");\n try {\n accessSync(candidate, constants.X_OK);\n return browserRsMeetsMinimumVersion(candidate) ? candidate : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Backend that stores documents published by `publish_html` and serves them\n * at `<base>/snippets/<id>`. Unset means the deployment has nowhere to\n * publish, and the publish tools are omitted from the catalog rather than\n * offering a link that cannot be minted.\n */\nexport const SNIPPETS_API_URL = (\n envText(\"NEGOTIUM_SNIPPETS_API_URL\") ??\n envText(\"SNIPPETS_API_URL\") ??\n \"\"\n).replace(/\\/+$/, \"\");\n\nexport const BROWSER_RS_BIN = resolveBrowserRsBin(envText(\"NEGOTIUM_BROWSER_RS_BIN\"));\n\n/** bash-rs release tested with this Negotium version — see apps/negotium/install-bash-rs.mjs. */\nexport const BASH_RS_VERSION = \"v0.1.5\";\n\n/**\n * Resolve the bash-rs binary the same way `resolveBrowserRsBin` resolves\n * Browser.rs: a versioned private location, no PATH lookup, `undefined`\n * (rather than throwing) when it's missing. There is no substitute: the manager\n * throws when a turn tries to prepare background-bash without a binary (see\n * `background-bash/manager.ts`), the turn runner catches that and continues\n * with a reminder that the tools are gone, so background-bash is simply\n * unavailable on a platform without a prebuilt binary.\n */\nexport function resolveBashRsBin(envValue?: string): string | undefined {\n const override = envValue?.trim();\n const candidate = override\n ? resolve(override)\n : resolve(BINARIES_DIR, \"bash-rs\", BASH_RS_VERSION, \"bash-rs\");\n try {\n accessSync(candidate, constants.X_OK);\n return candidate;\n } catch {\n return undefined;\n }\n}\n\nexport const BASH_RS_BIN = resolveBashRsBin(envText(\"NEGOTIUM_BASH_RS_BIN\"));\n\n// Managed Browser.rs terminates MCP transports and security policy itself.\nexport function resolveBrowserMcpBin(envValue?: string): string {\n const override = envValue?.trim();\n if (override) return resolve(override);\n return BROWSER_RS_BIN ?? resolve(BINARIES_DIR, \"browser-rs\", BROWSER_RS_VERSION, \"browser-rs\");\n}\n\nexport const PLAYWRIGHT_MCP_BIN = resolveBrowserMcpBin(envText(\"NEGOTIUM_BROWSER_MCP_BIN\"));\n\n// --- Browser egress proxy ---\n//\n// On a datacenter host (AWS) the browser's egress IP is a known cloud range,\n// so anti-bot services (Cloudflare, DataDome, reCAPTCHA) challenge or block it\n// far more than a residential IP would. Routing the automation browser through\n// a residential/ISP proxy moves the egress IP out of the datacenter range.\n//\n// Operators set BROWSER_PROXY_URL, e.g. http://user:pass@proxy.host:8080 or\n// socks5://proxy.host:1080. Credentials in the URL are split out because\n// Playwright takes them as separate fields. BROWSER_PROXY_BYPASS is an optional\n// comma-separated no-proxy list (e.g. \"localhost,127.0.0.1,*.internal\").\n//\n// NOTE: Chromium does not support authentication for SOCKS proxies — put\n// credentials only on http/https proxy URLs.\nexport type BrowserProxyConfig = {\n server: string;\n username?: string;\n password?: string;\n bypass?: string;\n};\n\nexport function resolveBrowserProxy(): BrowserProxyConfig | null {\n const raw = envText(\"BROWSER_PROXY_URL\");\n if (!raw) return null;\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n logger.warn({ raw }, \"Ignoring malformed BROWSER_PROXY_URL\");\n return null;\n }\n // Playwright wants the server without embedded credentials.\n const server = `${url.protocol}//${url.host}`;\n const proxy: BrowserProxyConfig = { server };\n if (url.username) proxy.username = decodeURIComponent(url.username);\n if (url.password) proxy.password = decodeURIComponent(url.password);\n const bypass = envText(\"BROWSER_PROXY_BYPASS\");\n if (bypass) proxy.bypass = bypass;\n return proxy;\n}\n\n// --- Node/tsx runtime for the `codex` agent's MCP servers ---\n//\n// codex 0.135's rmcp stdio MCP client cannot reliably complete the initialize\n// handshake with servers spawned via `bun` (the JSON-RPC initialize is\n// dropped/raced and no tools ever reach the model). Pure-node servers connect\n// reliably, so codex turns launch the SAME .ts servers via node + tsx instead\n// of `bun run`. claude/maestro keep using `bun run` (fast, native, unaffected).\n//\n// tsx transpiles .ts on the fly and resolves the `@/*` tsconfig path aliases,\n// but only when it can find the tsconfig — and MCP servers run with cwd set to\n// the user's workspace dir, not PROJECT_ROOT — so we pass TSX_TSCONFIG_PATH\n// explicitly via env. Requires package.json `\"type\": \"module\"` so the servers'\n// top-level `await` loads as ESM under node.\nexport const TSX_BIN = resolveDependencyBin(\"tsx\");\n/** In-process tsx loader used by Node MCP entrypoints (avoids the tsx CLI child process). */\nexport const TSX_LOADER = createRequire(import.meta.url).resolve(\"tsx\");\nexport const TSCONFIG_PATH = resolve(PROJECT_ROOT, \"tsconfig.json\");\n\nexport const SESSION_COMM_SERVER = resolve(PROJECT_ROOT, \"src/mcp/session-comm/server.ts\");\n\nexport const TASK_SERVER = resolve(PROJECT_ROOT, \"src/mcp/task-server.ts\");\nexport const BROWSER_MCP_SSE_PROXY_SERVER = resolve(\n PROJECT_ROOT,\n \"src/mcp/browser-sse-proxy-server.ts\",\n);\nexport const CANONICAL_MCP_PROXY_SERVER = resolve(\n PROJECT_ROOT,\n \"src/mcp/canonical-proxy-server.ts\",\n);\n\nexport const WIKI_SERVER = resolve(PROJECT_ROOT, \"src/mcp/wiki-server.ts\");\n\nexport const TOKEN_STATS_SERVER = resolve(PROJECT_ROOT, \"src/mcp/token-stats-server.ts\");\n\nexport const COMPACTION_LOG_SERVER = resolve(PROJECT_ROOT, \"src/mcp/compaction-log-server.ts\");\n\nexport const SYSTEM_HEALTH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/system-health-server.ts\");\n\nexport const AGENT_HEALTH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/agent-health-server.ts\");\n\nexport const VAULT_SERVER = resolve(PROJECT_ROOT, \"src/mcp/vault-server.ts\");\n\nexport const BG_BASH_BASE_PORT = parsePortEnv(process.env.BG_BASH_BASE_PORT, 9700);\nexport const BG_BASH_MAX_PORT = parsePortEnv(process.env.BG_BASH_MAX_PORT, 9799);\n\nfunction safeWorkspaceSegment(value: string, fallback: string): string {\n return safeRuntimePathSegment(value, fallback);\n}\n\n/** Resolve the shared filesystem workspace for an API topic. */\nexport function resolveTopicWorkspaceDir(topicId: string): string {\n return join(TOPIC_WORKSPACE_DIR, safeWorkspaceSegment(topicId, \"topic\"));\n}\n\nexport function isProductionEnv(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\n\nfunction loadOrCreateLocalSecret(\n envKey: string,\n filename: string,\n options: { persistEnvValue?: boolean } = {},\n): string {\n const envValue = envText(envKey);\n const secretFile = resolve(SECRETS_DIR, filename);\n mkdirSync(dirname(secretFile), { recursive: true });\n if (envValue) {\n if (options.persistEnvValue) {\n writeFileSync(secretFile, `${envValue}\\n`, { mode: 0o600 });\n chmodSync(secretFile, 0o600);\n }\n return envValue;\n }\n\n if (existsSync(secretFile)) {\n const stored = readFileSync(secretFile, \"utf-8\").trim();\n if (stored) {\n chmodSync(secretFile, 0o600);\n return stored;\n }\n }\n\n const secret = randomBytes(32).toString(\"base64url\");\n try {\n writeFileSync(secretFile, `${secret}\\n`, { mode: 0o600, flag: \"wx\" });\n return secret;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const stored = readFileSync(secretFile, \"utf-8\").trim();\n if (!stored) throw new Error(`Secret file exists but is empty: ${secretFile}`);\n chmodSync(secretFile, 0o600);\n return stored;\n }\n}\n\nexport const RUNTIME_MCP_SECRET = loadOrCreateLocalSecret(\n \"RUNTIME_MCP_SECRET\",\n \"runtime-mcp-secret\",\n);\n/** Local bearer token for the loopback node-control API. */\nexport const NODE_CONTROL_TOKEN = loadOrCreateLocalSecret(\n \"NEGOTIUM_CONTROL_TOKEN\",\n \"node-control-token\",\n);\nexport const VAULT_MASTER_KEY = loadOrCreateLocalSecret(\n \"NEGOTIUM_VAULT_MASTER_KEY\",\n \"vault-master-key\",\n { persistEnvValue: true },\n);\n// Agent/tool subprocesses inherit process.env. Keep the loaded key in this\n// process only so `env`/`ps` inside an agent workspace cannot reveal it.\ndelete process.env.NEGOTIUM_VAULT_MASTER_KEY;\n\n/** The node's single open port: runtime MCP endpoint + node API. */\nexport const NEGOTIUM_PORT = parseInt(process.env.NEGOTIUM_PORT || \"7777\", 10);\nexport const hostname = process.env.HOSTNAME || \"127.0.0.1\";\n\n// Persistent state (survives restarts, long-lived)\nexport const DATA_DIR = resolveLocalStateDir(\"NEGOTIUM_DATA_DIR\", \"data\");\nexport const LOG_DIR = resolveLocalStateDir(\"NEGOTIUM_LOG_DIR\", \"logs\");\nexport const UPLOADS_DIR = resolve(DATA_DIR, \"uploads\");\nexport const VAULT_DIR = resolve(DATA_DIR, \"vault\");\n// SESSIONS_DB_PATH env override lets tests point the DB singleton at a temp file.\nexport const SESSIONS_DB = process.env.SESSIONS_DB_PATH\n ? resolve(process.env.SESSIONS_DB_PATH)\n : resolve(DATA_DIR, \"sessions.db\");\nexport const DEBUG_FILE = resolve(DATA_DIR, \"debug-users.json\");\nexport const USERS_LOG_DIR = resolve(DATA_DIR, \"users\");\n\n// Runtime IPC queues (transient, safe to clear on restart)\n/** @deprecated Use the runtime layout name; NEGOTIUM_RUN_DIR remains a compatibility override. */\nexport const RUN_DIR = resolveLocalStateDir(\"NEGOTIUM_RUN_DIR\", \"runtime\");\nexport const RUNTIME_DIR = RUN_DIR;\nexport const PROGRESS_DIR = resolve(RUN_DIR, \"progress\");\nexport const DM_CMD_DIR = resolve(RUN_DIR, \"dm-commands\");\nexport const DM_RESP_DIR = resolve(RUN_DIR, \"dm-responses\");\nexport const SESSION_INBOX_DIR = resolve(RUN_DIR, \"session-inbox\");\nexport const SESSION_ASKS_DIR = resolve(RUN_DIR, \"session-asks\");\n/**\n * Passed to `bash-rs` as `BASHRS_SPILL_ROOT`. Each job gets a subdirectory\n * here (`{bash_id}/meta.json`, `result.json`, `stdout.log`, `stderr.log`) —\n * see bash-rs-mcp's `journal.rs`. `runtime/bashrs-completions.ts` watches\n * this directory and turns `result.json` into a session-inbox `tell`. The\n * retired TypeScript server used to write one directly instead.\n */\nexport const BASHRS_SPILL_ROOT = resolve(RUN_DIR, \"bashrs\");\nexport const PLAYWRIGHT_BASE_PORT = parsePortEnv(process.env.PLAYWRIGHT_BASE_PORT, 9100);\nexport const PLAYWRIGHT_MAX_PORT = parsePortEnv(process.env.PLAYWRIGHT_MAX_PORT, 9499);\nexport const PLAYWRIGHT_PORTS_DIR = resolve(RUN_DIR, \"playwright-ports\");\nmkdirSync(STATE_DIR, { recursive: true });\nmkdirSync(DATA_DIR, { recursive: true });\nmkdirSync(UPLOADS_DIR, { recursive: true });\nmkdirSync(VAULT_DIR, { recursive: true, mode: 0o700 });\nmkdirSync(LOG_DIR, { recursive: true });\nmkdirSync(PROGRESS_DIR, { recursive: true });\nmkdirSync(DM_CMD_DIR, { recursive: true });\nmkdirSync(DM_RESP_DIR, { recursive: true });\nmkdirSync(SESSION_INBOX_DIR, { recursive: true });\nmkdirSync(SESSION_ASKS_DIR, { recursive: true });\nmkdirSync(PLAYWRIGHT_PORTS_DIR, { recursive: true });\nmkdirSync(WORKSPACE_DIR, { recursive: true });\nmkdirSync(TOPIC_WORKSPACE_DIR, { recursive: true });\nmkdirSync(SHARED_WIKI_DIR, { recursive: true });\nmkdirSync(CRON_WORKSPACE_DIR, { recursive: true });\nmkdirSync(DM_WORKSPACE_DIR, { recursive: true });\nmkdirSync(SESSION_WORKSPACE_DIR, { recursive: true });\nmkdirSync(BROWSER_DIR, { recursive: true });\nmkdirSync(BROWSER_PROFILES_DIR, { recursive: true });\nmkdirSync(BINARIES_DIR, { recursive: true });\nmkdirSync(SECRETS_DIR, { recursive: true, mode: 0o700 });\n\n/** Stale threshold for active-query state files (crash recovery) */\nexport const ACTIVE_QUERY_STALE_MS = 10 * 60 * 1000; // 10 minutes\n\nexport const AGENTS_PROMPTS_DIR = resolve(PROJECT_ROOT, \"src/prompts/agents\");\nexport const RESOURCES_DIR = resolve(PROJECT_ROOT, \"src/resources\");\n\n/** Returns process.env without CLAUDECODE, to prevent nested claude-code detection in subprocesses. */\nexport function getCleanEnv(): NodeJS.ProcessEnv {\n const env = { ...process.env };\n delete env.CLAUDECODE;\n return env;\n}\n\nexport const FILE_EXTENSIONS_REGEX =\n /(?:\\/[^\\s\"'<>|*?[\\]]+\\.(?:png|jpg|jpeg|gif|webp|svg|pdf|csv|xlsx|xls|json|txt|md|html|zip|py|js|ts|tsx|jsx|css|xml|yaml|yml|docx|pptx))/gi;\n\nexport const FILE_TAG_REGEX = /\\[FILE:(\\/[^\\]]+)\\]/gi;\n\n// Canonical Claude model IDs — update here when Anthropic releases new versions\nexport const MODEL_SONNET = \"claude-sonnet-5\";\nexport const MODEL_OPUS = \"claude-opus-5\";\nexport const MODEL_HAIKU = \"claude-haiku-4-5-20251001\";\nexport const MODEL_FABLE = \"claude-fable-5\"; // Mythos-class, announced 2026-06-09\n\n// DeepSeek V4 (released 2026-04-24). API is OpenAI-compatible at\n// https://api.deepseek.com/v1/chat/completions; thinking mode is enabled via\n// `extra_body.thinking.type` + `reasoning_effort`. Legacy `deepseek-chat` /\n// `deepseek-reasoner` are deprecated 2026-07-24.\nexport const MODEL_DEEPSEEK_V4_PRO = \"deepseek-v4-pro\";\nexport const MODEL_DEEPSEEK_V4_FLASH = \"deepseek-v4-flash\";\n\n// Agent + model defaults split by session role. FALLBACK_* is the shared base;\n// SESSION_* overrides topic + ephemeral; GATEWAY_* overrides dm + manager.\n// DEFAULT_* is accepted as a legacy alias during the env migration window.\nexport const FALLBACK_AGENT: AgentKind = resolveAgentEnv(\n \"FALLBACK_AGENT\",\n \"maestro\",\n \"DEFAULT_AGENT\",\n);\nexport const SESSION_AGENT: AgentKind = resolveAgentEnv(\"SESSION_AGENT\", FALLBACK_AGENT);\nexport const GATEWAY_AGENT: AgentKind = resolveAgentEnv(\"GATEWAY_AGENT\", FALLBACK_AGENT);\n\nexport const FALLBACK_MODEL = envText(\"FALLBACK_MODEL\") ?? envText(\"DEFAULT_MODEL\");\n\nfunction resolveModelEnv(envKey: string, agentConst: AgentKind): string | undefined {\n return envText(envKey) ?? (agentConst === FALLBACK_AGENT ? FALLBACK_MODEL : undefined);\n}\n\nexport const SESSION_MODEL = resolveModelEnv(\"SESSION_MODEL\", SESSION_AGENT);\nexport const GATEWAY_MODEL = resolveModelEnv(\"GATEWAY_MODEL\", GATEWAY_AGENT);\n\n/** Resolve the effective display/default model for a topic (session context).\n * Applies the session model override only when that role owns the agent;\n * otherwise each registry's native default stays authoritative. */\nexport function resolveDefaultModel(agent: string, registryDefaultModel: string): string {\n return agent === SESSION_AGENT && SESSION_MODEL ? SESSION_MODEL : registryDefaultModel;\n}\n\n// ── External tool binaries + media pipeline env ───────────────────\n// (src/media/* 에서 사용. 미설정 시 fallback 의미는 기존 그대로:\n// FFMPEG_BIN은 text-extractor에서 필수(undefined면 spawn 시점 실패),\n// video.ts에서는 PATH의 ffmpeg/ffprobe로 fallback.)\nexport const FFMPEG_BIN = envText(\"FFMPEG_BIN\");\nexport const FFPROBE_BIN = envText(\"FFPROBE_BIN\");\nexport const PYTHON_BIN = envText(\"PYTHON_BIN\") ?? \"python3\";\nexport const FASTER_WHISPER_WRAPPER =\n envText(\"FASTER_WHISPER_WRAPPER\") ?? resolve(PROJECT_ROOT, \"scripts/faster-whisper-wrapper.py\");\nexport const WHISPER_MODEL = envText(\"WHISPER_MODEL_FILE\") ?? \"turbo\";\nexport const TESSERACT_BIN = envText(\"TESSERACT_BIN\") ?? \"tesseract\";\nexport const PDFTOTEXT_BIN = envText(\"PDFTOTEXT_BIN\") ?? \"pdftotext\";\n\n// Max tell_session relay depth from origin user. ask_session forks reset to\n// depth=0, so this only caps tell_session chains. Override via MAX_TELL_DEPTH\n// (positive int); defaults to 20 when unset or invalid.\nconst _envMaxTellDepth = Number.parseInt(process.env.MAX_TELL_DEPTH ?? \"\", 10);\nexport const MAX_TELL_DEPTH =\n Number.isInteger(_envMaxTellDepth) && _envMaxTellDepth > 0 ? _envMaxTellDepth : 20;\n\n/** Codex CLI auth file. 호출 시점에 env를 읽는다 — 테스트가 런타임에\n * NEGOTIUM_CODEX_AUTH_FILE을 바꾸므로 모듈 로드 상수로 만들면 안 된다. */\nexport function codexAuthFilePath(): string {\n return (\n process.env.NEGOTIUM_CODEX_AUTH_FILE ||\n join(process.env.CODEX_HOME || join(homedir(), \".codex\"), \"auth.json\")\n );\n}\n\n// System defaults moved to per-agent registries\n// (`src/agents/{claude,codex}-registry.ts`). Read via\n// `getRegistry(agent).defaultModel` / `.defaultEffort`.\n\n// MCP server builders -> src/platform/mcp-config.ts\n",
|
|
7
7
|
"import { resolve } from \"node:path\";\n\nexport type RuntimeEnvironment = Readonly<Record<string, string | undefined>>;\n\nexport function readEnvText(env: RuntimeEnvironment, key: string): string | undefined {\n const value = env[key]?.trim();\n return value || undefined;\n}\n\nexport function parseRuntimePort(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const port = Number.parseInt(value, 10);\n return Number.isInteger(port) && port > 0 && port <= 65_535 ? port : fallback;\n}\n\nexport function resolveRuntimeStateDir(options: {\n env: RuntimeEnvironment;\n envKey: string;\n fallbackRoot: string;\n fallbackName: string;\n}): string {\n const configured = readEnvText(options.env, options.envKey);\n return configured ? resolve(configured) : resolve(options.fallbackRoot, options.fallbackName);\n}\n\nexport function safeRuntimePathSegment(value: string, fallback: string, maxLength = 160): string {\n const cleaned = value\n .trim()\n .replace(/[^A-Za-z0-9._-]/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, maxLength);\n return cleaned || fallback;\n}\n",
|
|
8
8
|
"import pino from \"pino\";\n\nexport interface StdioLoggerOptions {\n level?: string;\n development?: boolean;\n}\n\n/**\n * Always write logs to stderr (fd 2), never stdout.\n *\n * MCP servers under `src/mcp/**` run as stdio subprocesses where stdout is the\n * JSON-RPC transport channel. A single log line on stdout corrupts the next\n * message and the MCP client closes the transport (\"Transport closed\"). The\n * main bot process is also fine with stderr — pm2 captures both streams.\n *\n * In dev mode pino spawns a `pino-pretty` worker that owns its own sink, so we\n * pass `destination: 2` through transport.options. In prod (no transport) the\n * second arg to `pino()` sets the destination directly.\n */\nexport function createStdioLogger(options: StdioLoggerOptions = {}) {\n const development = options.development ?? process.env.NODE_ENV === \"development\";\n return pino(\n {\n level: options.level ?? process.env.LOG_LEVEL ?? \"info\",\n transport: development\n ? {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n translateTime: \"SYS:yyyy-mm-dd HH:MM:ss\",\n destination: 2,\n },\n }\n : undefined,\n },\n pino.destination(2),\n );\n}\n\nexport type StdioLogger = ReturnType<typeof createStdioLogger>;\n\nexport const logger = createStdioLogger();\n",
|
|
9
9
|
"/**\n * Common context carried through the attachment/prompt-build pipeline.\n * Used by buildPromptFromMessage and related helpers.\n */\nexport interface SessionContext {\n userId: number;\n topicName?: string;\n userDir?: string;\n sessionType?: \"dm\" | \"forum\" | \"ephemeral\" | \"manager\" | \"cron\";\n}\n\nexport interface TokenUsage {\n /** Aggregate billable input across every model call made during this turn. */\n inputTokens: number;\n outputTokens: number;\n cacheCreationInputTokens?: number;\n cacheReadInputTokens?: number;\n /** Provider-reported query cost when available. */\n costUsd?: number;\n /** Tokens occupied by the latest model call, not aggregate turn spend. */\n contextTokens?: number;\n /** Provider-reported context window for the latest model call. */\n contextWindow?: number;\n}\n\n/** Agent identifier — one of the supported AI provider backends. */\nexport type AgentKind = \"maestro\" | \"claude\" | \"codex\";\n\nexport const SUPPORTED_AGENTS: readonly AgentKind[] = [\"maestro\", \"claude\", \"codex\"] as const;\n\nexport function isAgentKind(value: unknown): value is AgentKind {\n return typeof value === \"string\" && (SUPPORTED_AGENTS as readonly string[]).includes(value);\n}\n\n/**\n * Per-agent supported reasoning efforts. Single source of truth for both the\n * `EffortLevel` type and each registry's `validEfforts` runtime list — the\n * registries import these directly so adding a value in one place\n * propagates to validation, footer rendering, and zod enums.\n *\n * Claude SDK rejects 'minimal'; Codex SDK rejects 'max'. The two sets\n * intersect on low/medium/high/xhigh. Maestro (TS port) currently piggybacks\n * on the Anthropic provider, so its efforts mirror the Claude set; this can\n * narrow per-provider once Phase 5 lands.\n *\n * 'minimal' removed from codex: Codex API rejects it when default tools\n * (image_gen, web_search) are active, making agent sessions unusable.\n */\nexport const CLAUDE_EFFORT_VALUES = [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\nexport const CODEX_EFFORT_VALUES = [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\nexport const MAESTRO_EFFORT_VALUES = [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\n\nexport type EffortLevel =\n | (typeof CLAUDE_EFFORT_VALUES)[number]\n | (typeof CODEX_EFFORT_VALUES)[number]\n | (typeof MAESTRO_EFFORT_VALUES)[number];\n\n/**\n * Runtime iteration list (used by zod enums and any callers that need to\n * loop over every accepted value). Manually ordered for readability; the\n * `satisfies` check fails the build if an entry here isn't covered by the\n * per-agent unions above.\n */\nexport const EFFORT_VALUES = [\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n] as const satisfies readonly EffortLevel[];\n\n/**\n * Normalized events yielded by any agent provider (claudeProvider, codexProvider).\n * The handler/event-processor consumes these without caring which backend produced them.\n *\n * `user_message` is the lone \"into-the-log\" variant — no provider yields it.\n * The query handler writes it directly to the conversation log right before\n * `runAgent()` starts, so cross-agent rollout reconstruction can pair every\n * assistant turn with the user prompt that triggered it. Consumers that only\n * react to provider output (e.g. processAgentEvent) can safely ignore it.\n */\n/**\n * Wire-safe projection of one task, carried by the `tasks` UnifiedEvent.\n *\n * This is also the on-disk shape of Otium's shared task store, so claude,\n * codex, and maestro render the same live panel from the same source of truth.\n */\nexport interface TaskSnapshot {\n id: string;\n subject: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n /** Task ids this one is blocked by; omitted when empty. */\n blockedBy?: string[];\n /** Present-continuous label for spinners, when set. */\n activeForm?: string;\n /** Owner / agent name for multi-agent runs, when set. */\n owner?: string;\n}\n\nexport type UnifiedEvent =\n | {\n type: \"user_message\";\n content: string;\n synthetic?: \"compaction\";\n /** Total ordered user submissions represented by one preempting provider turn. */\n consecutiveBatchSize?: number;\n /** Zero-based position within the ordered preemption batch. */\n consecutiveBatchIndex?: number;\n }\n | { type: \"session\"; sessionId: string }\n | {\n type: \"tool_use\";\n name: string;\n input: Record<string, unknown>;\n /** Provider-assigned id so the client can match tool_use→tool_result pairs. */\n toolUseId?: string;\n }\n | { type: \"tool_progress\"; toolName: string; elapsed: number }\n | { type: \"tool_use_summary\"; summary: string }\n // Provider reasoning/thinking summary text (Codex `reasoning` items; Claude\n // extended-thinking). Surfaced so background runs (cron/archiver) show the\n // agent's thought process, not just tool calls.\n | { type: \"reasoning\"; content: string }\n // Full task-list snapshot (replace, not delta) from Otium's shared task\n // store. Provider-native task/todo stores are not authoritative.\n | { type: \"tasks\"; tasks: TaskSnapshot[] }\n | {\n type: \"tool_result\";\n toolUseId: string;\n content: string;\n /** True when the tool call failed; absent/false means success. */\n isError?: boolean;\n metadata?: {\n truncatedForModel: boolean;\n originalBytes: number;\n returnedBytes: number;\n omittedBytes?: number;\n outputPath?: string;\n };\n }\n | { type: \"text_delta\"; content: string }\n | { type: \"text\"; content: string }\n | { type: \"result\"; content: string; stopReason: string; usage?: TokenUsage }\n | { type: \"file\"; path: string; source: string; origin: \"tag\" | \"extension\" }\n | {\n type: \"error\";\n content: string;\n usage?: TokenUsage;\n code?: \"budget_exceeded\";\n }\n | { type: \"status\"; content: string };\n\nexport interface AgentInputAttachment {\n id: string;\n type: \"image\" | \"file\" | \"audio\";\n filename: string;\n mimeType: string;\n sizeBytes: number;\n path: string;\n}\n\n/** Worker-side runtime tools proxy user-facing state back to the canonical\n * hub topic identified here. */\nexport interface PeerRuntimeBridgeContext {\n hubCellId: string;\n hostTopicId: string;\n hostQueryId: string;\n canSpawnSubagents: boolean;\n}\n\nexport interface AgentQueryOptions {\n agent: AgentKind;\n prompt: string;\n attachments?: AgentInputAttachment[];\n sessionId?: string | null;\n cwd: string;\n systemPrompt: string;\n /**\n * Trusted system-level instructions for this Maestro invocation only.\n * Maestro projects them onto the invocation-start user message without\n * persisting them in session history or compaction. Omitted for Claude/Codex.\n */\n ephemeralSystemPrompt?: string;\n userId?: string;\n /** Credential namespace when it differs from the execution principal. */\n vaultUserId?: string;\n session?: string;\n playwrightPort?: number;\n playwrightCapability?: string;\n bgBashPort?: number;\n sessionType?: \"dm\" | \"forum\" | \"ephemeral\" | \"manager\" | \"cron\";\n /** API topic id (REST/WS world). Carries per-query topic context for MCP servers. */\n topicId?: string;\n /** Direct parent topic id when this query runs inside a subagent room. */\n subagentParentTopicId?: string;\n /** API query id for the currently running turn. Used by runtime MCP tools. */\n queryId?: string;\n /** Optional wiki-memory topic id. Derived topics use their root origin here\n * while other per-topic MCP servers keep `topicId` bound to the live room. */\n wikiTopicId?: string;\n /** Whether self-config MCP may enqueue an automatic continue turn after set_* changes. */\n autoContinue?: boolean;\n /** Expose Otium-only visual panel tools for this turn. Default-deny. */\n visualTools?: boolean;\n /** Expose adapter-backed file-delivery tools for this turn. Default-deny. */\n fileDeliveryTools?: boolean;\n abortController?: AbortController;\n model?: string;\n /** Provider-side hard budget when the selected SDK supports one. */\n maxBudgetUsd?: number;\n depth?: number;\n agents?: Record<\n string,\n {\n description: string;\n prompt: string;\n model?: string;\n tools?: string[];\n maxTurns?: number;\n effort?: EffortLevel | number;\n }\n >;\n effort?: EffortLevel;\n /**\n * Per-API-call `max_tokens` ceiling on the assistant's output. Wired\n * through to the underlying provider request body for every agent\n * (claude/codex/maestro). Omit to inherit each provider SDK's per-model\n * default — for maestro that's the v0.1.21+ `getNativeMaxOutputTokens`\n * catalog (deepseek-pro=64K, kimi-k3=64K, kimi-k2.7-code=32K).\n *\n * Pass an explicit number when a specific topic / surface needs a tighter\n * latency cap or a higher ceiling for long-form generation (legal\n * report writing, multi-K Write/Edit file bodies). Pre-0.1.21 maestro\n * builds silently clamped at 4096 and truncated outputs mid-string;\n * setting this field is now the supported way to lift that ceiling.\n */\n maxTokens?: number;\n /**\n * v0.1.22+: Claude-Code-style deferred tool catalog + `ToolSearch` built-in.\n *\n * Wired straight through to `maestro-agent-sdk`'s\n * `AgentQueryOptions.enableToolSearch`. When `true`, the maestro provider\n * registers every MCP tool as deferred — schemas stay off the wire until\n * the model promotes them via `ToolSearch(\"select:Name1,Name2\")` or\n * `ToolSearch(\"keyword\")`. Active set persists across resume.\n *\n * Otium's maestro provider supplies `true` when the caller leaves this\n * option unset, because most forum turns carry enough MCP surface for the\n * reminder-token savings to outweigh the first-use `ToolSearch` round-trip.\n * Callers can still pass `false` per call when a narrow surface or\n * latency-sensitive workflow is better served by eager MCP schemas.\n *\n * No-op for claude / codex agents — they have their own deferred-tool\n * machinery owned by their respective SDKs.\n */\n enableToolSearch?: boolean;\n /**\n * Bounded tool results with the full output kept on disk.\n *\n * Wired to `maestro-agent-sdk`'s `AgentQueryOptions.toolResultTruncation`.\n * The SDK caps a string tool result, writes the untruncated bytes to a file,\n * and splices an opaque `maestro://tool-output/<id>` reference into the text\n * that the `ReadToolOutput` tool can page back through.\n *\n * The maestro provider enables it by default. Left unset, every tool result\n * — a whole-file `Read`, a wide `Grep`, a `WebFetch` of a large page —\n * entered the context at full size, and the `\"ReadToolOutput\"` entry in the\n * provider's builtin list was dead, because the SDK only registers that tool\n * when truncation is on with `saveFullOutput`.\n *\n * Pass an explicit object to tune the budget, or `{ enabled: false }` for a\n * call whose tool results must arrive whole.\n *\n * No-op for claude / codex agents — their SDKs do their own truncation.\n */\n toolResultTruncation?: {\n enabled?: boolean;\n maxBytes?: number;\n headBytes?: number;\n tailBytes?: number;\n saveFullOutput?: boolean;\n outputDir?: string;\n retentionDays?: number;\n ignoreTools?: string[];\n };\n /**\n * Claude-Code-compatible exact tool denylist. Maestro v0.1.42+ hides these\n * tools from provider schemas / ToolSearch and blocks dispatch if a stale\n * call still arrives. Claude maps this to its SDK option. Codex does not\n * support this name-based list; its provider-native multi-agent tool family\n * is disabled separately through the Codex feature config.\n */\n disallowedTools?: readonly string[];\n /**\n * Hard provider tool policy for auxiliary model calls.\n *\n * `\"none\"` removes MCP and provider-native tools before the request is\n * dispatched. `\"compaction-log\"` keeps provider-native tools disabled and\n * exposes only the host-scoped immutable log reader. Use these for untrusted\n * transcript transforms; reacting to tool events after dispatch is not a\n * security boundary.\n */\n toolPolicy?: \"none\" | \"compaction-log\";\n mcpEnabled?: string[] | null;\n peerBridge?: PeerRuntimeBridgeContext;\n mcpExtra?: Record<string, unknown>;\n /**\n * true for silent fork runs generating ask_session replies — restricts session-comm\n * outbound tools (ask/tell/abort) so the forked session can only produce text\n */\n silent?: boolean;\n}\n\n/** State file written to data/users/{userId}/active-queries/{topicId}.json while a query is running. */\nexport interface QueryState {\n topicId?: string;\n topicName?: string;\n task?: string; // first 100 chars of prompt, newlines normalized\n since: string; // ISO timestamp\n}\n",
|
|
10
10
|
"export const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n",
|
|
11
11
|
"import { createHmac } from \"node:crypto\";\n\nexport function deriveBgBashContextCapability(\n runtimeCapability: string,\n userId: string,\n topic: string,\n): string {\n return createHmac(\"sha256\", runtimeCapability).update(`${userId}\\0${topic}`).digest(\"hex\");\n}\n"
|
|
12
12
|
],
|
|
13
|
-
"mappings": "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",
|
|
14
|
-
"debugId": "
|
|
13
|
+
"mappings": "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",
|
|
14
|
+
"debugId": "C69F97401A0FD56B64756E2164756E21",
|
|
15
15
|
"names": []
|
|
16
16
|
}
|
package/dist/browser-runtime.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
2
18
|
var __require = import.meta.require;
|
|
3
19
|
|
|
4
20
|
// ../../packages/core/src/platform/playwright/browser-processes.ts
|
|
@@ -127,11 +143,12 @@ function versionAtLeast(actualVersion, minimumVersion) {
|
|
|
127
143
|
}
|
|
128
144
|
return true;
|
|
129
145
|
}
|
|
146
|
+
var BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000;
|
|
130
147
|
function browserRsMeetsMinimumVersion(candidate) {
|
|
131
148
|
try {
|
|
132
149
|
const output = execFileSync(candidate, ["--version"], {
|
|
133
150
|
encoding: "utf8",
|
|
134
|
-
timeout:
|
|
151
|
+
timeout: BROWSER_RS_VERSION_PROBE_TIMEOUT_MS,
|
|
135
152
|
stdio: ["ignore", "pipe", "ignore"]
|
|
136
153
|
}).trim();
|
|
137
154
|
const match = output.match(/^browser-rs (\d+)\.(\d+)\.(\d+)$/);
|
|
@@ -441,12 +458,29 @@ if (isBun) {
|
|
|
441
458
|
}
|
|
442
459
|
|
|
443
460
|
// ../../packages/core/src/storage/storage-host.ts
|
|
444
|
-
var
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
461
|
+
var STORAGE_HOST_STATE = Symbol.for("negotium.storage-host.state.v1");
|
|
462
|
+
function storageState() {
|
|
463
|
+
const holder = globalThis;
|
|
464
|
+
const existing = holder[STORAGE_HOST_STATE];
|
|
465
|
+
if (existing)
|
|
466
|
+
return existing;
|
|
467
|
+
const created = {
|
|
468
|
+
configuredHost: {},
|
|
469
|
+
fallbackDatabase: null,
|
|
470
|
+
fallbackDatabasePath: null,
|
|
471
|
+
frames: [],
|
|
472
|
+
schemaInitializers: [],
|
|
473
|
+
initializedSchemas: new WeakMap,
|
|
474
|
+
initializingDatabases: new WeakSet
|
|
475
|
+
};
|
|
476
|
+
Object.defineProperty(holder, STORAGE_HOST_STATE, {
|
|
477
|
+
value: created,
|
|
478
|
+
enumerable: false,
|
|
479
|
+
writable: false,
|
|
480
|
+
configurable: false
|
|
481
|
+
});
|
|
482
|
+
return created;
|
|
483
|
+
}
|
|
450
484
|
function envPath(name, fallback) {
|
|
451
485
|
const value = process.env[name]?.trim();
|
|
452
486
|
return resolve3(value || fallback);
|
|
@@ -491,37 +525,40 @@ function initializeDatabase(database) {
|
|
|
491
525
|
}
|
|
492
526
|
function defaultDatabase() {
|
|
493
527
|
const path = defaultSessionsDatabasePath();
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
528
|
+
const state = storageState();
|
|
529
|
+
if (state.fallbackDatabase && state.fallbackDatabasePath === path)
|
|
530
|
+
return state.fallbackDatabase;
|
|
531
|
+
if (state.fallbackDatabase)
|
|
532
|
+
state.fallbackDatabase.close();
|
|
498
533
|
mkdirSync2(dirname2(path), { recursive: true });
|
|
499
|
-
fallbackDatabase = new Database(path, { create: true });
|
|
500
|
-
fallbackDatabasePath = path;
|
|
501
|
-
initializeDatabase(fallbackDatabase);
|
|
502
|
-
return fallbackDatabase;
|
|
534
|
+
state.fallbackDatabase = new Database(path, { create: true });
|
|
535
|
+
state.fallbackDatabasePath = path;
|
|
536
|
+
initializeDatabase(state.fallbackDatabase);
|
|
537
|
+
return state.fallbackDatabase;
|
|
503
538
|
}
|
|
504
539
|
function resolveStorageDatabase() {
|
|
505
|
-
return configuredHost.database ?? defaultDatabase();
|
|
540
|
+
return storageState().configuredHost.database ?? defaultDatabase();
|
|
506
541
|
}
|
|
507
542
|
function resolveStorageDataDir() {
|
|
508
|
-
return configuredHost.dataDir ?? defaultDataDir();
|
|
543
|
+
return storageState().configuredHost.dataDir ?? defaultDataDir();
|
|
509
544
|
}
|
|
510
545
|
function registerStorageSchemaInitializer(initialize, priority = 100) {
|
|
511
|
-
|
|
512
|
-
|
|
546
|
+
const initializers = storageState().schemaInitializers;
|
|
547
|
+
initializers.push({ initialize, priority });
|
|
548
|
+
initializers.sort((a, b) => a.priority - b.priority);
|
|
513
549
|
}
|
|
514
550
|
function ensureStorageSchemas(database = resolveStorageDatabase()) {
|
|
515
|
-
|
|
551
|
+
const state = storageState();
|
|
552
|
+
if (state.initializingDatabases.has(database))
|
|
516
553
|
return;
|
|
517
|
-
let initialized = initializedSchemas.get(database);
|
|
554
|
+
let initialized = state.initializedSchemas.get(database);
|
|
518
555
|
if (!initialized) {
|
|
519
556
|
initialized = new Set;
|
|
520
|
-
initializedSchemas.set(database, initialized);
|
|
557
|
+
state.initializedSchemas.set(database, initialized);
|
|
521
558
|
}
|
|
522
|
-
initializingDatabases.add(database);
|
|
559
|
+
state.initializingDatabases.add(database);
|
|
523
560
|
try {
|
|
524
|
-
for (const entry of schemaInitializers) {
|
|
561
|
+
for (const entry of state.schemaInitializers) {
|
|
525
562
|
if (initialized.has(entry.initialize))
|
|
526
563
|
continue;
|
|
527
564
|
initialized.add(entry.initialize);
|
|
@@ -533,7 +570,7 @@ function ensureStorageSchemas(database = resolveStorageDatabase()) {
|
|
|
533
570
|
}
|
|
534
571
|
}
|
|
535
572
|
} finally {
|
|
536
|
-
initializingDatabases.delete(database);
|
|
573
|
+
state.initializingDatabases.delete(database);
|
|
537
574
|
}
|
|
538
575
|
}
|
|
539
576
|
var internalStorageDatabase = new Proxy({}, {
|
|
@@ -1002,8 +1039,9 @@ function openVaultDatabase(dataDir) {
|
|
|
1002
1039
|
return database;
|
|
1003
1040
|
}
|
|
1004
1041
|
function activeVaultDatabase() {
|
|
1005
|
-
if (!vaultDb)
|
|
1006
|
-
vaultDb = openVaultDatabase(
|
|
1042
|
+
if (!vaultDb) {
|
|
1043
|
+
vaultDb = openVaultDatabase(resolveStorageDataDir());
|
|
1044
|
+
}
|
|
1007
1045
|
return vaultDb;
|
|
1008
1046
|
}
|
|
1009
1047
|
var VAULT_VALUE_MAX_BYTES = 64 * 1024;
|
|
@@ -1327,14 +1365,16 @@ function normalizeBrowserProfileName(name) {
|
|
|
1327
1365
|
}
|
|
1328
1366
|
return value;
|
|
1329
1367
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1368
|
+
registerStorageSchemaInitializer((database) => {
|
|
1369
|
+
database.exec(`
|
|
1370
|
+
CREATE TABLE IF NOT EXISTS browser_profiles (
|
|
1371
|
+
owner_id TEXT NOT NULL,
|
|
1372
|
+
name TEXT NOT NULL,
|
|
1373
|
+
created_at TEXT NOT NULL,
|
|
1374
|
+
PRIMARY KEY (owner_id, name)
|
|
1375
|
+
)
|
|
1376
|
+
`);
|
|
1377
|
+
});
|
|
1338
1378
|
function getBrowserProfileOwner(topicId, fallbackUserId) {
|
|
1339
1379
|
return db.query("SELECT browser_profile_owner FROM api_topics WHERE id = ?").get(topicId)?.browser_profile_owner ?? fallbackUserId;
|
|
1340
1380
|
}
|
|
@@ -2144,4 +2184,4 @@ export {
|
|
|
2144
2184
|
browserProcessMatchesExpectedProfile
|
|
2145
2185
|
};
|
|
2146
2186
|
|
|
2147
|
-
//# debugId=
|
|
2187
|
+
//# debugId=15BDEE130267282864756E2164756E21
|