@bli-cockpit/cli 0.2.253 → 0.2.254

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.
@@ -90,7 +90,7 @@ async function applyCodexMcpTable(options) {
90
90
  if (tableMatches(raw, options.config)) {
91
91
  return { target: "codex_mcp", status: "already", reason: "already_current", path: file };
92
92
  }
93
- const next = upsertTomlTable(raw, MEMORY_TOML_PATH, renderMemoryTable(options.config));
93
+ const next = upsertTomlTable(raw, MEMORY_TOML_PATH, renderMemoryTable(options.config), "memory-install");
94
94
  if (options.dryRun) {
95
95
  return { target: "codex_mcp", status: "would_install", reason: "dry_run", path: file };
96
96
  }
@@ -58,6 +58,40 @@ export function readTomlTable(text, tablePath) {
58
58
  // caller reports a mismatch instead of pretending the field matched.
59
59
  out[key] = parseTomlValue(trimmed.slice(equals + 1).trim());
60
60
  }
61
+ // A sub-table spelling of a key we write inline (`[<path>.env]`) is the same
62
+ // value; the inline key wins when both exist, matching what the writer leaves.
63
+ for (const key of FOLDED_SUBTABLE_KEYS) {
64
+ if (key in out)
65
+ continue;
66
+ const folded = readFoldedSubtable(text, [...tablePath, key]);
67
+ if (folded)
68
+ out[key] = folded;
69
+ }
70
+ return out;
71
+ }
72
+ /**
73
+ * Sub-tables of our table that the renderer writes inline. Only these are
74
+ * absorbed; deeper or unrelated sub-tables (`.tools.x`) are never ours.
75
+ */
76
+ const FOLDED_SUBTABLE_KEYS = ["env"];
77
+ function readFoldedSubtable(text, path) {
78
+ const span = findTomlTableSpan(text, path);
79
+ if (!span)
80
+ return null;
81
+ const out = {};
82
+ for (const line of text.split("\n").slice(span.start_line + 1, span.end_line)) {
83
+ const trimmed = line.trim();
84
+ if (!trimmed || trimmed.startsWith("#"))
85
+ continue;
86
+ const equals = trimmed.indexOf("=");
87
+ if (equals <= 0)
88
+ continue;
89
+ const key = unquoteKey(trimmed.slice(0, equals).trim());
90
+ const value = parseTomlValue(trimmed.slice(equals + 1).trim());
91
+ if (!key || typeof value !== "string")
92
+ return null;
93
+ out[key] = value;
94
+ }
61
95
  return out;
62
96
  }
63
97
  /**
@@ -65,8 +99,19 @@ export function readTomlTable(text, tablePath) {
65
99
  * absent. Everything outside the span is untouched, including trailing
66
100
  * whitespace and comments.
67
101
  */
68
- export function upsertTomlTable(text, tablePath, renderedTable) {
102
+ export function upsertTomlTable(text, tablePath, renderedTable, logTag) {
69
103
  const block = renderedTable.replace(/\n+$/u, "");
104
+ // Writing `env` inline while `[<path>.env]` exists is a duplicate key, which
105
+ // Codex refuses to load. Drop the sub-table; the inline key carries the value.
106
+ for (const key of FOLDED_SUBTABLE_KEYS) {
107
+ if (!new RegExp(`^${key}\\s*=`, "mu").test(block))
108
+ continue;
109
+ const sub = findTomlTableSpan(text, [...tablePath, key]);
110
+ if (!sub)
111
+ continue;
112
+ text = removeTomlTable(text, [...tablePath, key]);
113
+ console.error(`[${logTag ?? "toml-table"}] env_subtable_folded ${JSON.stringify({ key, lines: sub.end_line - sub.start_line })}`);
114
+ }
70
115
  const span = findTomlTableSpan(text, tablePath);
71
116
  if (!span) {
72
117
  if (!text.trim())
@@ -21,7 +21,7 @@ export async function runCockpitCli(argv, io) {
21
21
  }
22
22
 
23
23
  if (command === "--version" || command === "-V" || command === "version") {
24
- writeLine(io?.stdout ?? process.stdout, "0.2.253");
24
+ writeLine(io?.stdout ?? process.stdout, "0.2.254");
25
25
  return 0;
26
26
  }
27
27
 
@@ -23,7 +23,7 @@ export async function installCodexTowerIntegration(options) {
23
23
  if (tableMatches(raw, options.config)) {
24
24
  return { target: "tower_codex_mcp", status: "already", reason: "already_current", path: file };
25
25
  }
26
- const next = upsertTomlTable(raw, TOWER_TOML_PATH, renderTowerTable(options.config));
26
+ const next = upsertTomlTable(raw, TOWER_TOML_PATH, renderTowerTable(options.config), "tower-mcp");
27
27
  if (options.dryRun) {
28
28
  return { target: "tower_codex_mcp", status: "would_install", reason: "dry_run", path: file };
29
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bli-cockpit/cli",
3
- "version": "0.2.253",
3
+ "version": "0.2.254",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {