negotium 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -518,6 +518,11 @@ function referencesRuntimeSecretStorage(value) {
518
518
  return false;
519
519
  }
520
520
 
521
+ // ../../packages/core/src/platform/mcp-config.ts
522
+ import { accessSync as accessSync2, constants as fsConstants } from "fs";
523
+ import { homedir as homedir2 } from "os";
524
+ import { join as join2 } from "path";
525
+
521
526
  // ../../packages/core/src/mcp/runtime-spec.ts
522
527
  import { createHash, createHmac, timingSafeEqual } from "crypto";
523
528
  var RUNTIME_MCP_KEY = "runtime";
@@ -856,7 +861,8 @@ var COMMON_RUNTIME_MCP_POLICY = {
856
861
  "system-health": { scopes: ["dm", "forum", "manager", "cron"], forumRequired: true },
857
862
  "background-bash": { scopes: ["forum"], forumRequired: true },
858
863
  "agent-health": { scopes: ["forum", "manager", "cron"], forumRequired: true },
859
- vault: { scopes: ["dm", "forum", "manager", "cron"], forumRequired: true }
864
+ vault: { scopes: ["dm", "forum", "manager", "cron"], forumRequired: true },
865
+ "cua-rs": { scopes: ["dm", "forum", "fork"], forumRequired: false }
860
866
  };
861
867
  function classifyForumMcpServers(catalog) {
862
868
  const all = Object.entries(catalog).filter(([, entry]) => entry.scopes.includes("forum")).map(([name]) => name);
@@ -1184,8 +1190,38 @@ var MCP_CATALOG = {
1184
1190
  args.push("--list-only=true");
1185
1191
  return buildBuiltinMcpServer("vault", { ...ctx, userId: vaultUserId ?? userId }, () => buildStdioMcpServer(agent, VAULT_SERVER, args));
1186
1192
  }
1193
+ },
1194
+ "cua-rs": {
1195
+ ...commonRuntimeMcpPolicy("cua-rs"),
1196
+ build() {
1197
+ const bin = resolveCuaRsBinary();
1198
+ if (!bin)
1199
+ return null;
1200
+ return { command: bin, args: cuaRsArgs() };
1201
+ }
1187
1202
  }
1188
1203
  };
1204
+ function cuaRsArgs() {
1205
+ const raw = envText("NEGOTIUM_CUA_RS_ALLOW_HID")?.trim().toLowerCase();
1206
+ const on = raw === "1" || raw === "true" || raw === "yes";
1207
+ return on ? ["--allow-hid"] : [];
1208
+ }
1209
+ function resolveCuaRsBinary(platform = process.platform) {
1210
+ if (platform !== "darwin")
1211
+ return null;
1212
+ const candidates = [
1213
+ envText("NEGOTIUM_CUA_RS_BIN"),
1214
+ join2(homedir2(), ".local", "bin", "cua-rs"),
1215
+ "/usr/local/bin/cua-rs"
1216
+ ].filter((p) => Boolean(p));
1217
+ for (const candidate of candidates) {
1218
+ try {
1219
+ accessSync2(candidate, fsConstants.X_OK);
1220
+ return candidate;
1221
+ } catch {}
1222
+ }
1223
+ return null;
1224
+ }
1189
1225
  var allForumMcpServerNames = [];
1190
1226
  var requiredForumMcpServers = [];
1191
1227
  var REQUIRED_FORUM_MCP_SERVERS = requiredForumMcpServers;
@@ -1413,7 +1449,7 @@ function getMcpServersForQuery(opts) {
1413
1449
 
1414
1450
  // ../../packages/core/src/storage/vault.ts
1415
1451
  import { chmodSync as chmodSync2, mkdirSync as mkdirSync4 } from "fs";
1416
- import { join as join3 } from "path";
1452
+ import { join as join4 } from "path";
1417
1453
 
1418
1454
  // ../../packages/core/src/storage/sqlite.ts
1419
1455
  var isBun = typeof process.versions.bun === "string";
@@ -1468,8 +1504,8 @@ if (isBun) {
1468
1504
 
1469
1505
  // ../../packages/core/src/storage/storage-host.ts
1470
1506
  import { mkdirSync as mkdirSync3 } from "fs";
1471
- import { homedir as homedir2 } from "os";
1472
- import { dirname as dirname3, join as join2, resolve as resolve4 } from "path";
1507
+ import { homedir as homedir3 } from "os";
1508
+ import { dirname as dirname3, join as join3, resolve as resolve4 } from "path";
1473
1509
  var STORAGE_HOST_STATE = Symbol.for("negotium.storage-host.state.v1");
1474
1510
  function storageState() {
1475
1511
  const holder = globalThis;
@@ -1498,13 +1534,13 @@ function envPath(name, fallback) {
1498
1534
  return resolve4(value || fallback);
1499
1535
  }
1500
1536
  function defaultStateDir() {
1501
- return envPath("NEGOTIUM_STATE_DIR", join2(homedir2(), ".negotium"));
1537
+ return envPath("NEGOTIUM_STATE_DIR", join3(homedir3(), ".negotium"));
1502
1538
  }
1503
1539
  function defaultDataDir() {
1504
- return envPath("NEGOTIUM_DATA_DIR", join2(defaultStateDir(), "data"));
1540
+ return envPath("NEGOTIUM_DATA_DIR", join3(defaultStateDir(), "data"));
1505
1541
  }
1506
1542
  function defaultSessionsDatabasePath() {
1507
- return envPath("SESSIONS_DB_PATH", join2(resolveStorageDataDir(), "sessions.db"));
1543
+ return envPath("SESSIONS_DB_PATH", join3(resolveStorageDataDir(), "sessions.db"));
1508
1544
  }
1509
1545
  var SQLITE_INIT_RETRY_MS = 25;
1510
1546
  var SQLITE_INIT_TIMEOUT_MS = 5000;
@@ -1683,8 +1719,8 @@ function initializeVaultDatabase(database) {
1683
1719
  }
1684
1720
  }
1685
1721
  function openVaultDatabase(dataDir) {
1686
- const vaultDir = join3(dataDir, "vault");
1687
- const path = join3(vaultDir, "vault.db");
1722
+ const vaultDir = join4(dataDir, "vault");
1723
+ const path = join4(vaultDir, "vault.db");
1688
1724
  mkdirSync4(vaultDir, { recursive: true, mode: 448 });
1689
1725
  const database = new Database(path, { create: true });
1690
1726
  chmodSync2(path, 384);
@@ -2359,8 +2395,8 @@ async function* claudeProvider(opts) {
2359
2395
  // ../../packages/core/src/agents/codex-provider.ts
2360
2396
  import { execFileSync as execFileSync4 } from "child_process";
2361
2397
  import { existsSync as existsSync6, readFileSync as readFileSync6, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
2362
- import { homedir as homedir3 } from "os";
2363
- import { dirname as dirname8, isAbsolute, join as join7, relative, resolve as resolve7 } from "path";
2398
+ import { homedir as homedir4 } from "os";
2399
+ import { dirname as dirname8, isAbsolute, join as join8, relative, resolve as resolve7 } from "path";
2364
2400
  import { Codex } from "@openai/codex-sdk";
2365
2401
 
2366
2402
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
@@ -2379,10 +2415,10 @@ import {
2379
2415
  } from "fs";
2380
2416
  import { createRequire as createRequire2 } from "module";
2381
2417
  import { tmpdir } from "os";
2382
- import { dirname as dirname5, join as join4 } from "path";
2418
+ import { dirname as dirname5, join as join5 } from "path";
2383
2419
 
2384
2420
  // ../../packages/core/src/version.ts
2385
- var NEGOTIUM_VERSION = "0.4.0";
2421
+ var NEGOTIUM_VERSION = "0.4.2";
2386
2422
 
2387
2423
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
2388
2424
  var moduleRequire = createRequire2(import.meta.url);
@@ -2401,7 +2437,7 @@ var SAFE_BUNDLED_CODEX_VERSION = BUNDLED_CODEX_VERSION.replace(/[^a-zA-Z0-9._-]/
2401
2437
  var NEGOTIUM_MODEL_CACHE = `negotium-models-cache-${SAFE_BUNDLED_CODEX_VERSION}.json`;
2402
2438
  var NEGOTIUM_MODEL_CATALOG = `negotium-model-catalog-${SAFE_BUNDLED_CODEX_VERSION}.json`;
2403
2439
  function codexCliScriptPath() {
2404
- return join4(dirname5(bundledCodexPackagePath), "bin", "codex.js");
2440
+ return join5(dirname5(bundledCodexPackagePath), "bin", "codex.js");
2405
2441
  }
2406
2442
  function parseCodexModelCache(contents, sourcePath) {
2407
2443
  let parsed;
@@ -2442,7 +2478,7 @@ function writePrivateFileAtomic(path, contents) {
2442
2478
  }
2443
2479
  }
2444
2480
  function bundledCodexModelCachePath(authFilePath) {
2445
- return join4(dirname5(authFilePath), NEGOTIUM_MODEL_CACHE);
2481
+ return join5(dirname5(authFilePath), NEGOTIUM_MODEL_CACHE);
2446
2482
  }
2447
2483
  async function bootstrapCodexModelCache(codexHome, cachePath) {
2448
2484
  const child = spawn3(process.execPath, [codexCliScriptPath(), "app-server", "--stdio"], {
@@ -2528,15 +2564,15 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
2528
2564
  }
2529
2565
  async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
2530
2566
  const sourceHome = dirname5(authFilePath);
2531
- const isolatedHome = mkdtempSync(join4(tmpdir(), "negotium-codex-models-"));
2532
- const isolatedCachePath = join4(isolatedHome, "models_cache.json");
2567
+ const isolatedHome = mkdtempSync(join5(tmpdir(), "negotium-codex-models-"));
2568
+ const isolatedCachePath = join5(isolatedHome, "models_cache.json");
2533
2569
  try {
2534
- const isolatedAuthPath = join4(isolatedHome, "auth.json");
2570
+ const isolatedAuthPath = join5(isolatedHome, "auth.json");
2535
2571
  copyFileSync(authFilePath, isolatedAuthPath);
2536
2572
  chmodSync3(isolatedAuthPath, 384);
2537
- const sourceConfigPath = join4(sourceHome, "config.toml");
2573
+ const sourceConfigPath = join5(sourceHome, "config.toml");
2538
2574
  if (existsSync3(sourceConfigPath)) {
2539
- const isolatedConfigPath = join4(isolatedHome, "config.toml");
2575
+ const isolatedConfigPath = join5(isolatedHome, "config.toml");
2540
2576
  copyFileSync(sourceConfigPath, isolatedConfigPath);
2541
2577
  chmodSync3(isolatedConfigPath, 384);
2542
2578
  }
@@ -2557,7 +2593,7 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
2557
2593
  return configuredCachePath;
2558
2594
  }
2559
2595
  const bundledCachePath = bundledCodexModelCachePath(authFilePath);
2560
- const sharedCachePath = join4(codexHome, "models_cache.json");
2596
+ const sharedCachePath = join5(codexHome, "models_cache.json");
2561
2597
  if (existsSync3(sharedCachePath)) {
2562
2598
  try {
2563
2599
  const shared = readCompatibleCodexModelCache(sharedCachePath);
@@ -2577,7 +2613,7 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
2577
2613
  }
2578
2614
  function writeCodexCatalogWithNativeMultiAgentDisabled(authFilePath, sourcePath) {
2579
2615
  const codexHome = dirname5(authFilePath);
2580
- const outputPath = join4(codexHome, NEGOTIUM_MODEL_CATALOG);
2616
+ const outputPath = join5(codexHome, NEGOTIUM_MODEL_CATALOG);
2581
2617
  const parsed = readCodexModelCache(sourcePath).parsed;
2582
2618
  const models = parsed.models.map((model, index) => {
2583
2619
  if (!model || typeof model !== "object" || Array.isArray(model)) {
@@ -2816,10 +2852,12 @@ import { existsSync as existsSync4 } from "fs";
2816
2852
  import { chmod, mkdtemp, rm, writeFile } from "fs/promises";
2817
2853
  import { createServer } from "net";
2818
2854
  import { tmpdir as tmpdir2 } from "os";
2819
- import { dirname as dirname6, join as join5, resolve as resolve5 } from "path";
2855
+ import { dirname as dirname6, join as join6, resolve as resolve5 } from "path";
2820
2856
  import { fileURLToPath as fileURLToPath2 } from "url";
2821
2857
  var MAX_HOOK_REQUEST_BYTES = 1024 * 1024;
2822
2858
  var SENSITIVE_STORAGE_DENIAL = "Runtime secret storage access is not permitted";
2859
+ var HOOK_SOCKET_ENV = "NEGOTIUM_CODEX_VAULT_HOOK_SOCKET";
2860
+ var HOOK_TOKEN_ENV = "NEGOTIUM_CODEX_VAULT_HOOK_TOKEN";
2823
2861
  function evaluateCodexVaultPreToolUse(input, userId, operations) {
2824
2862
  if (operations.referencesSensitiveStorage(input.tool_input)) {
2825
2863
  return {
@@ -2856,9 +2894,11 @@ function hookClientPath() {
2856
2894
  return packaged;
2857
2895
  throw new Error("Codex Vault hook client is missing from this installation");
2858
2896
  }
2859
- function privateCodexWrapper(codexScript) {
2897
+ function privateCodexWrapper(codexScript, socketPath, token) {
2860
2898
  return [
2861
2899
  "#!/bin/sh",
2900
+ `export ${HOOK_SOCKET_ENV}=${shellQuote(socketPath)}`,
2901
+ `export ${HOOK_TOKEN_ENV}=${shellQuote(token)}`,
2862
2902
  'if [ "$1" = "exec" ]; then',
2863
2903
  " shift",
2864
2904
  ` exec ${shellQuote(process.execPath)} ${shellQuote(codexScript)} exec --dangerously-bypass-hook-trust "$@"`,
@@ -2869,10 +2909,10 @@ function privateCodexWrapper(codexScript) {
2869
2909
  `);
2870
2910
  }
2871
2911
  async function createCodexVaultHookBridge(userId) {
2872
- const root = await mkdtemp(join5(tmpdir2(), "negotium-codex-vault-"));
2912
+ const root = await mkdtemp(join6(tmpdir2(), "negotium-codex-vault-"));
2873
2913
  await chmod(root, 448);
2874
- const socketPath = join5(root, "hook.sock");
2875
- const wrapperPath = join5(root, "codex-with-hooks");
2914
+ const socketPath = join6(root, "hook.sock");
2915
+ const wrapperPath = join6(root, "codex-with-hooks");
2876
2916
  const token = randomBytes4(32).toString("hex");
2877
2917
  const connections = new Set;
2878
2918
  const server = createServer((socket) => {
@@ -2921,15 +2961,13 @@ async function createCodexVaultHookBridge(userId) {
2921
2961
  });
2922
2962
  });
2923
2963
  await chmod(socketPath, 384);
2924
- await writeFile(wrapperPath, privateCodexWrapper(codexCliScriptPath()), { mode: 448 });
2925
- const command = [
2926
- shellQuote(process.execPath),
2927
- shellQuote(hookClientPath()),
2928
- shellQuote(socketPath),
2929
- shellQuote(token)
2930
- ].join(" ");
2964
+ await writeFile(wrapperPath, privateCodexWrapper(codexCliScriptPath(), socketPath, token), {
2965
+ mode: 448
2966
+ });
2967
+ const command = [shellQuote(process.execPath), shellQuote(hookClientPath())].join(" ");
2931
2968
  return {
2932
2969
  codexPathOverride: wrapperPath,
2970
+ environment: { [HOOK_SOCKET_ENV]: socketPath, [HOOK_TOKEN_ENV]: token },
2933
2971
  hooks: {
2934
2972
  PreToolUse: [
2935
2973
  {
@@ -2961,9 +2999,9 @@ async function createCodexVaultHookBridge(userId) {
2961
2999
 
2962
3000
  // ../../packages/core/src/agents/rollout/codex.ts
2963
3001
  import { existsSync as existsSync5, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as statSync2, unlinkSync as unlinkSync4 } from "fs";
2964
- import { basename, dirname as dirname7, join as join6, resolve as resolve6 } from "path";
3002
+ import { basename, dirname as dirname7, join as join7, resolve as resolve6 } from "path";
2965
3003
  function codexSessionsDir() {
2966
- return join6(hostedCodexHomePath(), "sessions");
3004
+ return join7(hostedCodexHomePath(), "sessions");
2967
3005
  }
2968
3006
  function canonicalFilePath(path) {
2969
3007
  const absolute = resolve6(path);
@@ -2971,7 +3009,7 @@ function canonicalFilePath(path) {
2971
3009
  return realpathSync2(absolute);
2972
3010
  } catch {
2973
3011
  try {
2974
- return join6(realpathSync2(dirname7(absolute)), basename(absolute));
3012
+ return join7(realpathSync2(dirname7(absolute)), basename(absolute));
2975
3013
  } catch {
2976
3014
  return absolute;
2977
3015
  }
@@ -3201,19 +3239,19 @@ function latestCodexRolloutPath(threadId) {
3201
3239
  try {
3202
3240
  if (buckets) {
3203
3241
  for (const bucket of buckets) {
3204
- const dir = join6(sessionsDir, bucket);
3242
+ const dir = join7(sessionsDir, bucket);
3205
3243
  if (!existsSync5(dir))
3206
3244
  continue;
3207
3245
  const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
3208
3246
  for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
3209
- candidates.push(join6(dir, rel));
3247
+ candidates.push(join7(dir, rel));
3210
3248
  }
3211
3249
  }
3212
3250
  }
3213
3251
  if (candidates.length === 0) {
3214
3252
  const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
3215
3253
  for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
3216
- candidates.push(join6(sessionsDir, rel));
3254
+ candidates.push(join7(sessionsDir, rel));
3217
3255
  }
3218
3256
  }
3219
3257
  return candidates.sort((a, b) => statSync2(b).mtimeMs - statSync2(a).mtimeMs)[0];
@@ -3336,6 +3374,7 @@ function buildNumberedDiffSummary(before, after, startLine = 1) {
3336
3374
  }
3337
3375
 
3338
3376
  // ../../packages/core/src/agents/codex-provider.ts
3377
+ var CODEX_HOOK_TRUST_BYPASS_NOTICE = "`--dangerously-bypass-hook-trust` is enabled. Enabled hooks may run without review for this invocation.";
3339
3378
  function sameCodexUsage(usage, total) {
3340
3379
  return usage.input_tokens === total.inputTokens && usage.output_tokens === total.outputTokens && (usage.cached_input_tokens ?? 0) === total.cachedInputTokens && (usage.cache_write_input_tokens ?? 0) === total.cacheWriteInputTokens;
3341
3380
  }
@@ -3365,7 +3404,7 @@ function codexMcpServerName(name) {
3365
3404
  return CODEX_MCP_SERVER_NAME_OVERRIDES[name] ?? name;
3366
3405
  }
3367
3406
  function globalCodexMcpServerNames(authFilePath) {
3368
- const configPath = join7(dirname8(authFilePath), "config.toml");
3407
+ const configPath = join8(dirname8(authFilePath), "config.toml");
3369
3408
  if (!existsSync6(configPath))
3370
3409
  return [];
3371
3410
  try {
@@ -3727,7 +3766,7 @@ async function* codexProvider(opts) {
3727
3766
  mcpServerCount: Object.keys(codexMcpServers).length
3728
3767
  }, "codexProvider: starting turn");
3729
3768
  const hostedCodexHome = hostedCodexHomePath();
3730
- const inheritedCodexHome = process.env.CODEX_HOME || join7(homedir3(), ".codex");
3769
+ const inheritedCodexHome = process.env.CODEX_HOME || join8(homedir4(), ".codex");
3731
3770
  const codexEnvironment = scopedBrowserCapability || resolve7(hostedCodexHome) !== resolve7(inheritedCodexHome) ? {
3732
3771
  ...Object.fromEntries(Object.entries(process.env).filter((entry) => typeof entry[1] === "string")),
3733
3772
  CODEX_HOME: hostedCodexHome,
@@ -3921,7 +3960,10 @@ async function* codexProvider(opts) {
3921
3960
  yield fileEvent;
3922
3961
  }
3923
3962
  } else if (item.type === "error") {
3924
- yield { type: "error", content: String(item.message ?? "") };
3963
+ const message = String(item.message ?? "");
3964
+ if (message !== CODEX_HOOK_TRUST_BYPASS_NOTICE) {
3965
+ yield { type: "error", content: message };
3966
+ }
3925
3967
  }
3926
3968
  break;
3927
3969
  }
@@ -4151,7 +4193,7 @@ function maestroProvider(opts) {
4151
4193
  // ../../packages/core/src/agents/claude-runtime-inspection.ts
4152
4194
  import { readFileSync as readFileSync7 } from "fs";
4153
4195
  import { createRequire as createRequire3 } from "module";
4154
- import { dirname as dirname9, join as join8 } from "path";
4196
+ import { dirname as dirname9, join as join9 } from "path";
4155
4197
  var cached;
4156
4198
  function inspectBundledClaudeRuntime() {
4157
4199
  if (cached)
@@ -4159,8 +4201,8 @@ function inspectBundledClaudeRuntime() {
4159
4201
  try {
4160
4202
  const require2 = createRequire3(import.meta.url);
4161
4203
  const sdkDir = dirname9(require2.resolve("@anthropic-ai/claude-agent-sdk"));
4162
- const sdkPackage = JSON.parse(readFileSync7(join8(sdkDir, "package.json"), "utf8"));
4163
- const manifest = JSON.parse(readFileSync7(join8(sdkDir, "manifest.json"), "utf8"));
4204
+ const sdkPackage = JSON.parse(readFileSync7(join9(sdkDir, "package.json"), "utf8"));
4205
+ const manifest = JSON.parse(readFileSync7(join9(sdkDir, "manifest.json"), "utf8"));
4164
4206
  const sdkVersion = typeof sdkPackage.version === "string" ? sdkPackage.version : "";
4165
4207
  const claudeCodeVersion = typeof manifest.version === "string" ? manifest.version : "";
4166
4208
  if (!sdkVersion || !claudeCodeVersion) {
@@ -4233,4 +4275,4 @@ export {
4233
4275
  buildClaudeDisallowedTools
4234
4276
  };
4235
4277
 
4236
- //# debugId=5CF9F07311E89AE364756E2164756E21
4278
+ //# debugId=AA00F8568D35B36164756E2164756E21