@wardby/cli 0.4.0 → 0.4.1

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/env.js CHANGED
@@ -17,4 +17,9 @@ const projectDir = resolve(process.env.WARDBY_PROJECT_DIR || process.cwd());
17
17
  // process variable, preserving explicit shell/container configuration as the
18
18
  // highest-priority source in either mode.
19
19
  dotenvFlow.config({ path: join(projectDir, ".wardby"), silent: true });
20
- dotenvFlow.config({ path: projectDir });
20
+ // The application's own .env files are optional: dotenv-flow reports "no .env*
21
+ // files" as a failure, so only load when some exist. Not `silent: true`, which
22
+ // would also hide parse errors in a real .env.
23
+ if (dotenvFlow.listFiles({ path: projectDir, node_env: process.env.NODE_ENV }).length > 0) {
24
+ dotenvFlow.config({ path: projectDir });
25
+ }
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Arguments for `<client> mcp add`. The server name comes right after `add`:
3
+ * Claude Code's `-e/--env <env...>` is variadic and would otherwise read the
4
+ * name as another KEY=value ("Invalid environment variable format: wardby").
5
+ */
6
+ export declare function mcpAddArgs(client: "codex" | "claude", projectDir: string, packageSpec: string): string[];
1
7
  export declare function quickstartCommand(args: string[]): Promise<void>;
2
8
  /** The closing "build your first agent" hint; the assistant prompts only make sense once an MCP client is configured. */
3
9
  export declare function nextStepLines(mcpConfigured: boolean): string[];
@@ -263,6 +263,16 @@ function runDemo(paths) {
263
263
  function clientInstalled(command) {
264
264
  return runCommand(command, ["--version"]).status === 0;
265
265
  }
266
+ /**
267
+ * Arguments for `<client> mcp add`. The server name comes right after `add`:
268
+ * Claude Code's `-e/--env <env...>` is variadic and would otherwise read the
269
+ * name as another KEY=value ("Invalid environment variable format: wardby").
270
+ */
271
+ export function mcpAddArgs(client, projectDir, packageSpec) {
272
+ const env = `WARDBY_PROJECT_DIR=${projectDir}`;
273
+ const options = client === "codex" ? ["--env", env] : ["--scope", "local", "-e", env];
274
+ return ["mcp", "add", "wardby", ...options, "--", "npx", "--yes", packageSpec, "mcp"];
275
+ }
266
276
  function configureOneMcpClient(client, paths) {
267
277
  if (!clientInstalled(client)) {
268
278
  console.warn(`! ${client} is not installed; skipped its MCP configuration.`);
@@ -273,34 +283,7 @@ function configureOneMcpClient(client, paths) {
273
283
  console.log(`✓ ${client} already has an MCP server named wardby.`);
274
284
  return true;
275
285
  }
276
- const packageSpec = `@wardby/cli@${packageJson.version}`;
277
- const args = client === "codex"
278
- ? [
279
- "mcp",
280
- "add",
281
- "--env",
282
- `WARDBY_PROJECT_DIR=${paths.projectDir}`,
283
- "wardby",
284
- "--",
285
- "npx",
286
- "--yes",
287
- packageSpec,
288
- "mcp",
289
- ]
290
- : [
291
- "mcp",
292
- "add",
293
- "--scope",
294
- "local",
295
- "-e",
296
- `WARDBY_PROJECT_DIR=${paths.projectDir}`,
297
- "wardby",
298
- "--",
299
- "npx",
300
- "--yes",
301
- packageSpec,
302
- "mcp",
303
- ];
286
+ const args = mcpAddArgs(client, paths.projectDir, `@wardby/cli@${packageJson.version}`);
304
287
  const result = runCommand(client, args, { cwd: paths.projectDir });
305
288
  if (result.status !== 0)
306
289
  commandFailure(`${client} MCP configuration`, result);
@@ -168,10 +168,37 @@ deeply to process is refused with `request_nesting_too_deep`.
168
168
  forces `store: false` and `background: false` and adds a
169
169
  `max_output_tokens` ceiling when Codex omits it.
170
170
 
171
- Upgrading the pinned `@openai/codex-sdk` means re-recording that fixture
172
- against a local fake upstream and rerunning the compatibility test. A Codex
173
- release that sends a new key or item type fails closed at the proxy rather
174
- than silently widening what reaches OpenAI.
171
+ A Codex release that sends a new key or item type fails closed at the proxy
172
+ rather than silently widening what reaches OpenAI. Upgrading the pinned
173
+ `@openai/codex-sdk` is therefore one command plus a review:
174
+
175
+ 1. Change the pin in `src/coding-worker/package.json` (a dependency bot's
176
+ pull request does this). Until the fixture is re-recorded, the "pinned
177
+ Codex version" test fails with `Codex SDK bump detected (...)`.
178
+ 2. On that branch, run `npm run codex:rerecord` on a machine where npm
179
+ installs the host's Codex binary. It sets the root devDependency
180
+ `@openai/codex-sdk` to the worker's pin and installs it, drives the pinned
181
+ Codex CLI through a fixed set of scenarios (responses-lite and classic tool
182
+ layouts, code-mode `exec` with `view_image` and `apply_patch`, namespaced
183
+ tool calls, a spawned sub-agent, local context compaction) against a local
184
+ fake of the proxy's `/v1/responses` endpoint — nothing is sent to OpenAI —
185
+ and writes `codex-<version>-responses-requests.json`, replacing the
186
+ previous version's fixture. Paths, ids, timestamps and long prompt texts
187
+ are normalized so a re-record of the same version is byte-identical. It
188
+ then runs the compatibility test (the real Codex through the real proxy)
189
+ and the proxy's fixture-replay tests, and prints a request-shape diff
190
+ against the previous fixture: new or removed top-level keys, input item
191
+ and content types, tool types, `include`/`reasoning`/`text`/`tool_choice`/
192
+ `service_tier` values and `client_metadata` keys.
193
+ 3. Review that diff. If the tests pass and the diff is empty or shows only
194
+ shapes the allowlist already accepts, commit the new fixture with
195
+ `package.json` and `package-lock.json`. If the proxy refuses a request
196
+ (an `openai_*_not_allowed` code in the test output), do not widen the
197
+ allowlist to make it pass: first find out what the new key, item, tool
198
+ type or value does (Codex's changelog and source) and whether it can
199
+ reach anything outside the worker or bill outside the metered tokens,
200
+ then widen `parseOpenAiRequest` only for what that review accepts, and
201
+ document it in the list above.
175
202
 
176
203
  The proxy also binds a second listener, the **deny port** (`8788`,
177
204
  `CODING_PROXY_DENY_PORT`), which serves nothing: it accepts a connection,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wardby/cli",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Self-hosted control plane for budget-guarded AI agents.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/wardby/wardby#readme",
@@ -60,6 +60,7 @@
60
60
  "prepare": "npm run build:vendor && PRISMA_HIDE_UPDATE_MESSAGE=1 prisma generate",
61
61
  "prepack": "npm run build",
62
62
  "cli": "tsx --conditions=wardby-source src/cli.ts",
63
+ "codex:rerecord": "tsx --conditions=wardby-source src/tools/codex-rerecord.ts",
63
64
  "capture:autopilot": "tsx --conditions=wardby-source src/tools/capture-autopilot-dry-run.ts",
64
65
  "test": "npm run build:vendor && vitest run",
65
66
  "test:package": "node scripts/npm-package-acceptance.mjs",
@@ -122,7 +123,7 @@
122
123
  },
123
124
  "devDependencies": {
124
125
  "@eslint/js": "^10.0.1",
125
- "@openai/codex-sdk": "0.153.4",
126
+ "@openai/codex-sdk": "0.159.2",
126
127
  "@types/node": "^24.0.0",
127
128
  "@types/papaparse": "^5.5.2",
128
129
  "@types/pg": "8.23.1",