overlord-cli 0.2608271506.0 → 0.2608301049.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,7 +29,7 @@ From an OpenOverlord checkout:
29
29
  ovld agent-setup codex
30
30
  ```
31
31
 
32
- This copies managed plugin files to `~/.codex/plugins/overlord`, merges protocol permission rules into `~/.codex/rules/default.rules`, writes the personal marketplace entry at `~/.agents/plugins/marketplace.json`, and runs `codex plugin add overlord@overlord-local` when the Codex CLI is available.
32
+ This copies managed plugin files to `~/.codex/plugins/overlord`, merges protocol permission rules into `~/.codex/rules/default.rules`, asks before merging the Overlord workspace permission profile into `~/.codex/config.toml`, writes the personal marketplace entry at `~/.agents/plugins/marketplace.json`, and runs `codex plugin add overlord@overlord-local` when the Codex CLI is available. The profile makes `overlord` the default, disables the JS REPL, enables Codex's network proxy, and permits network access only to `**.ovld.ai`.
33
33
 
34
34
  Re-run safely any time the connector contract version changes:
35
35
 
@@ -97,6 +97,7 @@ Requirements:
97
97
  code changes.
98
98
  - Include permission hook to record tool permission requests.
99
99
  - Install protocol permission rules for `ovld protocol`.
100
+ - During interactive Codex setup, ask `Configure Codex permissions to allow it to communicate with the Overlord server?` (default yes). On acceptance, merge the `overlord` workspace permission profile into `~/.codex/config.toml`: make it the default permission profile, disable `js_repl`, enable the network proxy, and allow only `**.ovld.ai` network access for that profile. Non-interactive `ovld agent-setup codex` applies the same idempotent merge so scripted setup remains usable.
100
101
  - Avoid generating or relying on a repository-local `AGENTS.md` for Overlord itself.
101
102
  - Detect or receive Codex native session/thread IDs when possible.
102
103
  - Launch with model and reasoning effort mapping:
package/dist/index.js CHANGED
@@ -2420,6 +2420,7 @@ __export(connectors_exports, {
2420
2420
  expandInstallPath: () => expandInstallPath,
2421
2421
  inspectConnector: () => inspectConnector,
2422
2422
  listAvailableConnectors: () => listAvailableConnectors,
2423
+ mergeCodexConfig: () => mergeCodexConfig,
2423
2424
  parseConnectorManifestYaml: () => parseConnectorManifestYaml,
2424
2425
  readConnectorManifest: () => readConnectorManifest,
2425
2426
  resolveHome: () => resolveHome,
@@ -2442,6 +2443,80 @@ import {
2442
2443
  import os2 from "node:os";
2443
2444
  import path6 from "node:path";
2444
2445
  import { fileURLToPath as fileURLToPath4 } from "node:url";
2446
+ function escapeRegExp(value) {
2447
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2448
+ }
2449
+ function setTomlScalar({
2450
+ content,
2451
+ section,
2452
+ key,
2453
+ value
2454
+ }) {
2455
+ const assignment = `${key} = ${value}`;
2456
+ const keyPattern = new RegExp(`^([ \\t]*)${escapeRegExp(key)}[ \\t]*=.*$`, "m");
2457
+ if (!section) {
2458
+ const firstSection = content.search(/^[ \t]*\[/m);
2459
+ const prefix = firstSection === -1 ? content : content.slice(0, firstSection);
2460
+ const suffix = firstSection === -1 ? "" : content.slice(firstSection);
2461
+ if (keyPattern.test(prefix)) return content.replace(keyPattern, assignment);
2462
+ return `${assignment}
2463
+ ${prefix ? `
2464
+ ${prefix.replace(/^\n+/, "")}` : ""}${suffix}`;
2465
+ }
2466
+ const header = new RegExp(`^[ \\t]*\\[${escapeRegExp(section)}\\][ \\t]*(?:#.*)?$`, "m");
2467
+ const match = header.exec(content);
2468
+ if (!match || match.index === void 0) {
2469
+ const separator = content.trimEnd() ? "\n\n" : "";
2470
+ return `${content.trimEnd()}${separator}[${section}]
2471
+ ${assignment}
2472
+ `;
2473
+ }
2474
+ const sectionStart = match.index;
2475
+ const bodyStart = sectionStart + match[0].length;
2476
+ const nextSectionOffset = content.slice(bodyStart).search(/^[ \t]*\[/m);
2477
+ const sectionEnd = nextSectionOffset === -1 ? content.length : bodyStart + nextSectionOffset;
2478
+ const body = content.slice(bodyStart, sectionEnd);
2479
+ if (keyPattern.test(body)) {
2480
+ return `${content.slice(0, bodyStart)}${body.replace(keyPattern, assignment)}${content.slice(sectionEnd)}`;
2481
+ }
2482
+ const normalizedBody = body.endsWith("\n") ? body : `${body}
2483
+ `;
2484
+ return `${content.slice(0, bodyStart)}${normalizedBody}${assignment}
2485
+ ${content.slice(sectionEnd)}`;
2486
+ }
2487
+ function mergeCodexConfig(existingContent) {
2488
+ let content = setTomlScalar({
2489
+ content: existingContent,
2490
+ key: "default_permissions",
2491
+ value: '"overlord"'
2492
+ });
2493
+ content = setTomlScalar({ content, section: "features", key: "js_repl", value: "false" });
2494
+ content = setTomlScalar({ content, section: "features", key: "network_proxy", value: "true" });
2495
+ content = setTomlScalar({
2496
+ content,
2497
+ section: "permissions.overlord",
2498
+ key: "description",
2499
+ value: '"Workspace access with ovld.ai network access."'
2500
+ });
2501
+ content = setTomlScalar({
2502
+ content,
2503
+ section: "permissions.overlord",
2504
+ key: "extends",
2505
+ value: '":workspace"'
2506
+ });
2507
+ content = setTomlScalar({
2508
+ content,
2509
+ section: "permissions.overlord.network",
2510
+ key: "enabled",
2511
+ value: "true"
2512
+ });
2513
+ return setTomlScalar({
2514
+ content,
2515
+ section: "permissions.overlord.network.domains",
2516
+ key: '"**.ovld.ai"',
2517
+ value: '"allow"'
2518
+ });
2519
+ }
2445
2520
  function connectorsRoot() {
2446
2521
  const override = process.env.OVERLORD_CONNECTORS_DIR;
2447
2522
  if (override) return override;
@@ -2715,11 +2790,13 @@ ${managedBlock}
2715
2790
  function configureCodexHarness({
2716
2791
  home,
2717
2792
  installPath,
2793
+ configurePermissions = true,
2718
2794
  dryRun = false
2719
2795
  }) {
2720
2796
  const warnings = [];
2721
2797
  const marketplacePath = path6.join(home, ".agents", "plugins", "marketplace.json");
2722
2798
  const rulesPath = path6.join(home, ".codex", "rules", "default.rules");
2799
+ const configPath = path6.join(home, ".codex", "config.toml");
2723
2800
  const legacyAgentsPath = path6.join(home, ".codex", "AGENTS.md");
2724
2801
  const hooksPath = path6.join(installPath, ".codex-plugin", "hooks.json");
2725
2802
  const currentMarketplace = readJsonObject(marketplacePath) ?? {
@@ -2742,6 +2819,9 @@ function configureCodexHarness({
2742
2819
  if (dryRun) {
2743
2820
  warnings.push(`Would update Codex marketplace at ${marketplacePath}.`);
2744
2821
  warnings.push(`Would merge protocol permission rules into ${rulesPath}.`);
2822
+ if (configurePermissions) {
2823
+ warnings.push(`Would configure Overlord permissions in ${configPath}.`);
2824
+ }
2745
2825
  if (existsSync6(legacyAgentsPath)) {
2746
2826
  warnings.push(`Would remove legacy Codex bundle at ${legacyAgentsPath}.`);
2747
2827
  }
@@ -2769,6 +2849,10 @@ function configureCodexHarness({
2769
2849
  const existingRules = existsSync6(rulesPath) ? readFileSync6(rulesPath, "utf8") : "";
2770
2850
  mkdirSync3(path6.dirname(rulesPath), { recursive: true });
2771
2851
  writeFileSync3(rulesPath, mergeCodexRules(existingRules));
2852
+ if (configurePermissions) {
2853
+ const existingConfig = existsSync6(configPath) ? readFileSync6(configPath, "utf8") : "";
2854
+ writeFileSync3(configPath, mergeCodexConfig(existingConfig));
2855
+ }
2772
2856
  if (!readJsonObject(hooksPath)) {
2773
2857
  warnings.push(`Codex hook manifest missing or invalid at ${hooksPath}.`);
2774
2858
  }
@@ -2867,6 +2951,7 @@ function configureClaudeHarness({
2867
2951
  function setupConnector({
2868
2952
  agentKey,
2869
2953
  home,
2954
+ configureCodexPermissions = true,
2870
2955
  dryRun = false
2871
2956
  }) {
2872
2957
  const manifest = readConnectorManifest(agentKey);
@@ -2951,7 +3036,14 @@ function setupConnector({
2951
3036
  warnings.push(...configureCursorHarness({ home: resolvedHome, dryRun }));
2952
3037
  }
2953
3038
  if (agentKey === "codex") {
2954
- warnings.push(...configureCodexHarness({ home: resolvedHome, installPath, dryRun }));
3039
+ warnings.push(
3040
+ ...configureCodexHarness({
3041
+ home: resolvedHome,
3042
+ installPath,
3043
+ configurePermissions: configureCodexPermissions,
3044
+ dryRun
3045
+ })
3046
+ );
2955
3047
  }
2956
3048
  if (agentKey === "claude") {
2957
3049
  warnings.push(...configureClaudeHarness({ home: resolvedHome, installPath, dryRun }));
@@ -2989,13 +3081,16 @@ function setupConnector({
2989
3081
  }
2990
3082
  function setupAllConnectors({
2991
3083
  home,
3084
+ configureCodexPermissions = true,
2992
3085
  dryRun = false
2993
3086
  }) {
2994
3087
  const agents = listAvailableConnectors();
2995
3088
  if (agents.length === 0) {
2996
3089
  throw new CliError({ message: "No connector adapters found under connectors/adapters." });
2997
3090
  }
2998
- return agents.map((agentKey) => setupConnector({ agentKey, home, dryRun }));
3091
+ return agents.map(
3092
+ (agentKey) => setupConnector({ agentKey, home, configureCodexPermissions, dryRun })
3093
+ );
2999
3094
  }
3000
3095
  function readInstallState(agentKey, home) {
3001
3096
  const statePath = installStatePath(agentKey, home);
@@ -3653,7 +3748,14 @@ async function configureAgentsForSetup() {
3653
3748
  defaultValue: "all"
3654
3749
  });
3655
3750
  const selected = parseAgentSelection(answer);
3656
- const results = selected.map((agentKey) => setupConnector({ agentKey }));
3751
+ const results = [];
3752
+ for (const agentKey of selected) {
3753
+ const configureCodexPermissions = agentKey !== "codex" || await promptYesNo(
3754
+ "Configure Codex permissions to allow it to communicate with the Overlord server?",
3755
+ true
3756
+ );
3757
+ results.push(setupConnector({ agentKey, configureCodexPermissions }));
3758
+ }
3657
3759
  for (const result of results) {
3658
3760
  printHumanResult(result);
3659
3761
  }
@@ -3922,6 +4024,13 @@ async function runAgentSetupCommand({
3922
4024
  const target = parsed.positional[0];
3923
4025
  const dryRun = flagBoolean(parsed.flags, "--dry-run");
3924
4026
  const home = flagValue(parsed.flags, "--home");
4027
+ const shouldConfigureCodexPermissions = async (agentKey) => {
4028
+ if (agentKey !== "codex" || dryRun || json2 || !process.stdin.isTTY) return true;
4029
+ return promptYesNo(
4030
+ "Configure Codex permissions to allow it to communicate with the Overlord server?",
4031
+ true
4032
+ );
4033
+ };
3925
4034
  if (!target) {
3926
4035
  const available = listAvailableConnectors();
3927
4036
  if (json2) {
@@ -3936,7 +4045,18 @@ async function runAgentSetupCommand({
3936
4045
  }
3937
4046
  return;
3938
4047
  }
3939
- const results = target === "all" ? setupAllConnectors({ home, dryRun }) : [setupConnector({ agentKey: target, home, dryRun })];
4048
+ const results = target === "all" ? setupAllConnectors({
4049
+ home,
4050
+ dryRun,
4051
+ configureCodexPermissions: await shouldConfigureCodexPermissions("codex")
4052
+ }) : [
4053
+ setupConnector({
4054
+ agentKey: target,
4055
+ home,
4056
+ dryRun,
4057
+ configureCodexPermissions: await shouldConfigureCodexPermissions(target)
4058
+ })
4059
+ ];
3940
4060
  if (json2) {
3941
4061
  printJson({ ok: true, dryRun, results });
3942
4062
  } else {