byob-cli 0.2.11 → 0.2.13

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "byob-cli",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Codex connector for BYOB projects, backed by Agent MCP with project context, deployment helpers, and coding tools.",
5
5
  "skills": "./skills/byob_cli/",
6
6
  "mcpServers": "./.mcp.json"
package/README.md CHANGED
@@ -30,7 +30,7 @@ Refresh synced coding skills later without rerunning OAuth or changing MCP confi
30
30
  npx -y byob-cli codex sync-skills --project-id <project_id> --token <agent_access_token>
31
31
  ```
32
32
 
33
- For Local Codex billed project editing, the BYOB Agent MCP opens the project container as the active Codex workspace. It is powered by `codex ssh-proxy`:
33
+ For Local Codex billed project editing, the BYOB Agent MCP returns a workspace handle that the Codex host opens as the active Codex workspace. The native handoff uses Codex's `CODEX_EXEC_SERVER_URL` remote execution support; `codex ssh-proxy` remains the fallback transport:
34
34
 
35
35
  ```bash
36
36
  npx -y byob-cli@latest codex ssh-proxy '{"ssh_endpoint":"wss://..."}'
@@ -206,8 +206,8 @@ npx -y byob-cli codex sync-skills --project-id <project_id> --token <agent_acces
206
206
  When a user chooses **Local Codex billed**, open the BYOB project as the active Codex workspace from the start of the edit session:
207
207
 
208
208
  1. Call `byob_codex_status` for the selected project.
209
- 2. If `Local Codex billed` is available, call `byob_codex_connection_create` with `connection_type: "ssh_gateway"`.
210
- 3. Hand the returned workspace metadata to the Codex host so `/home/workspace/app_data` becomes the active workspace.
209
+ 2. If `Local Codex billed` is available, call `byob_codex_connection_create` with `mode: "local_codex_billed"`.
210
+ 3. Hand the returned `workspace_handle` to the Codex host so `/home/workspace/app_data` becomes the active workspace with `CODEX_EXEC_SERVER_URL` set from MCP `_meta`.
211
211
  4. Keep tokens, private keys, and complete proxy commands out of chat.
212
212
  5. Use Codex's normal file, shell, and git workflow inside that active workspace.
213
213
 
package/bin/byob.js CHANGED
@@ -41,7 +41,7 @@ Usage:
41
41
  byob config
42
42
  byob codex install
43
43
  byob codex sync-skills
44
- byob codex ssh-proxy [json_args]
44
+ byob codex ssh-proxy [json_args] # fallback transport only
45
45
 
46
46
  Options:
47
47
  --air-url <url> Default: BYOB_AIR_URL or https://air.api.byob.studio
@@ -60,6 +60,26 @@ Options:
60
60
  `;
61
61
  }
62
62
 
63
+ function codexUsage() {
64
+ return `BYOB Codex Commands
65
+
66
+ Usage:
67
+ byob codex install
68
+ byob codex sync-skills
69
+ byob codex ssh-proxy [json_args]
70
+
71
+ Commands:
72
+ install Authorize BYOB, configure Codex MCP, and install BYOB skills.
73
+ sync-skills Refresh BYOB AIR coding skills for an approved project.
74
+ ssh-proxy Fallback OpenSSH stdio bridge for Local Codex billed workspaces.
75
+
76
+ Local Codex billed workspaces are normally opened by the Codex host from the
77
+ workspace handle returned by BYOB Agent MCP. The native handoff uses Codex's
78
+ exec-server transport; agents should not print or manually handle raw transport
79
+ tokens, private keys, or complete fallback proxy commands.
80
+ `;
81
+ }
82
+
63
83
  function parseArgs(argv) {
64
84
  const opts = {
65
85
  airUrl: DEFAULT_AIR_URL,
@@ -200,15 +220,23 @@ function publicPreviewUrl(projectId) {
200
220
  return id ? `https://preview.${id}.api.byob.studio` : "";
201
221
  }
202
222
 
203
- function sanitizePreviewUrls(value, projectIdHint = "", { sanitizeText = false } = {}) {
223
+ function sanitizePreviewUrls(
224
+ value,
225
+ projectIdHint = "",
226
+ { sanitizeText = false, redactPrivateMeta = false } = {},
227
+ ) {
204
228
  if (Array.isArray(value)) {
205
- return value.map((item) => sanitizePreviewUrls(item, projectIdHint, { sanitizeText }));
229
+ return value.map((item) => sanitizePreviewUrls(item, projectIdHint, { sanitizeText, redactPrivateMeta }));
206
230
  }
207
231
  if (!value || typeof value !== "object") {
208
232
  if (sanitizeText && typeof value === "string") {
209
233
  try {
210
234
  const parsed = JSON.parse(value);
211
- return JSON.stringify(sanitizePreviewUrls(parsed, projectIdHint, { sanitizeText }), null, 2);
235
+ return JSON.stringify(
236
+ sanitizePreviewUrls(parsed, projectIdHint, { sanitizeText, redactPrivateMeta }),
237
+ null,
238
+ 2,
239
+ );
212
240
  } catch {
213
241
  return value;
214
242
  }
@@ -219,19 +247,49 @@ function sanitizePreviewUrls(value, projectIdHint = "", { sanitizeText = false }
219
247
  const localProjectId = value.project_id || value.id || projectIdHint;
220
248
  const sanitized = {};
221
249
  for (const [key, item] of Object.entries(value)) {
250
+ if (
251
+ redactPrivateMeta &&
252
+ key === "_meta" &&
253
+ item &&
254
+ typeof item === "object" &&
255
+ item.byob_local_codex_workspace
256
+ ) {
257
+ sanitized[key] = {
258
+ ...item,
259
+ byob_local_codex_workspace: {
260
+ ...item.byob_local_codex_workspace,
261
+ codex_native: {
262
+ ...item.byob_local_codex_workspace.codex_native,
263
+ env: {
264
+ redacted: true,
265
+ reason: "Use the workspace_handle with a Codex host; direct CLI display omits CODEX_EXEC_SERVER_URL credentials.",
266
+ },
267
+ },
268
+ ssh: {
269
+ redacted: true,
270
+ reason: "Use the workspace_handle with a Codex host; direct CLI display omits raw SSH material.",
271
+ },
272
+ },
273
+ };
274
+ continue;
275
+ }
222
276
  if (key === "preview_url") {
223
277
  sanitized[key] = publicPreviewUrl(localProjectId) || item;
224
278
  continue;
225
279
  }
226
280
  sanitized[key] = sanitizePreviewUrls(item, localProjectId, {
227
281
  sanitizeText: sanitizeText && key === "text",
282
+ redactPrivateMeta,
228
283
  });
229
284
  }
230
285
  return sanitized;
231
286
  }
232
287
 
233
288
  function printJson(payload, projectIdHint = "", sanitizeText = false) {
234
- const safePayload = sanitizePreviewUrls(payload, projectIdHint, { sanitizeText });
289
+ const safePayload = sanitizePreviewUrls(payload, projectIdHint, {
290
+ sanitizeText,
291
+ redactPrivateMeta: true,
292
+ });
235
293
  process.stdout.write(`${JSON.stringify(safePayload, null, 2)}\n`);
236
294
  }
237
295
 
@@ -922,9 +980,14 @@ async function main() {
922
980
  }
923
981
 
924
982
  if (command === "mcp") return serve(opts);
983
+ if (command === "codex" && (!first || first === "help")) {
984
+ process.stdout.write(codexUsage());
985
+ return;
986
+ }
925
987
  if (command === "codex" && first === "install") return codexInstall(opts);
926
988
  if (command === "codex" && first === "sync-skills") return codexSyncSkills(opts);
927
989
  if (command === "codex" && first === "ssh-proxy") return codexSshProxy(opts, second);
990
+ if (command === "codex") throw new Error(`Unknown codex command: ${first || ""}`);
928
991
  if (command === "config") return config(opts);
929
992
  if (command === "device-code") return deviceCode(opts);
930
993
  if (command === "token") return token(opts, first);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "byob-cli",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Codex connector for BYOB projects, backed by an Agent MCP stdio bridge.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -72,10 +72,10 @@ When the user selects **Local Codex billed**, open the BYOB project as the activ
72
72
  1. Establish active project context.
73
73
  2. Ensure the project is started and remote editing is available.
74
74
  3. Call `byob_codex_status`.
75
- 4. Create a Local Codex billed connection with `byob_codex_connection_create`.
76
- 5. Use the returned Local Codex billed workspace details through `byob-cli@latest`'s `codex ssh-proxy`.
75
+ 4. Create a Local Codex billed connection with `byob_codex_connection_create` using `mode: "local_codex_billed"`.
76
+ 5. Hand the returned Local Codex billed `workspace_handle` to the Codex host; the host uses Codex's `CODEX_EXEC_SERVER_URL` remote execution support behind that handle, with `byob-cli@latest`'s `codex ssh-proxy` only as fallback.
77
77
 
78
- Local Codex billed should let Codex inspect and edit the remote project filesystem directly, including protected files such as `src/app.html` when the task requires reading them. Keep all returned tokens, private keys, and complete proxy commands out of chat and logs. Use user-facing language like "Local Codex billed"; avoid internal enum names unless debugging BYOB itself.
78
+ Local Codex billed should let Codex inspect and edit the remote project filesystem directly, including protected files such as `src/app.html` when the task requires reading them. Keep all tokens, private keys, and complete proxy commands out of chat and logs. Use user-facing language like "Local Codex billed"; avoid internal enum names unless debugging BYOB itself.
79
79
 
80
80
  After the workspace is open, use Codex's normal file, shell, git, and verification workflow inside the remote project.
81
81
 
@@ -57,8 +57,8 @@ For **Local Codex billed** project editing, open the BYOB project as the active
57
57
 
58
58
  1. Establish project context with `byob_current_project_context`.
59
59
  2. Call `byob_codex_status` and confirm the Local Codex billed option is available.
60
- 3. Call `byob_codex_connection_create` with the Local Codex billed connection type.
61
- 4. Use the returned Local Codex billed workspace metadata through `byob-cli@latest` so Codex edits the remote project container as its active workspace.
60
+ 3. Call `byob_codex_connection_create` with `mode: "local_codex_billed"`.
61
+ 4. Hand the returned Local Codex billed `workspace_handle` to the Codex host so Codex edits the remote project container as its active workspace through `CODEX_EXEC_SERVER_URL`.
62
62
  5. Do not print tokens, private keys, or full proxy commands in chat.
63
63
 
64
64
  After the workspace is open, use Codex's normal file, shell, git, and verification workflow inside the remote project.
@@ -290,8 +290,8 @@ Use this flow:
290
290
 
291
291
  1. Confirm the project is started and `connectivity.can_remote_edit` is true.
292
292
  2. Call `byob_codex_status`.
293
- 3. If Local Codex billed is available, call `byob_codex_connection_create` for that mode.
294
- 4. Use the returned Local Codex billed workspace details with `byob-cli@latest`'s `codex ssh-proxy`.
293
+ 3. If Local Codex billed is available, call `byob_codex_connection_create` with `mode: "local_codex_billed"`.
294
+ 4. Hand the returned Local Codex billed `workspace_handle` to the Codex host; the host uses Codex's `CODEX_EXEC_SERVER_URL` remote execution support behind that handle, with `byob-cli@latest`'s `codex ssh-proxy` only as fallback.
295
295
  5. Keep credentials out of chat, logs, screenshots, and command transcripts.
296
296
 
297
297
  After the workspace is open, use Codex's normal file, shell, git, and verification workflow inside the remote project.