byob-cli 0.2.10 → 0.2.12

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.10",
3
+ "version": "0.2.12",
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,13 +30,13 @@ 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 creates a short-lived SSH-style project connection and returns an `ssh_proxy_command` that uses:
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 host uses `codex ssh-proxy` behind that handle:
34
34
 
35
35
  ```bash
36
- npx -y byob-cli@0.2.10 codex ssh-proxy '{"ssh_endpoint":"wss://..."}'
36
+ npx -y byob-cli@latest codex ssh-proxy '{"ssh_endpoint":"wss://..."}'
37
37
  ```
38
38
 
39
- Use `byob-cli@0.2.10` or newer for this route. Older published versions do not contain `codex ssh-proxy`, so they cannot bridge the Local Codex billed connection into the running project container.
39
+ Use `byob-cli@latest` for Local Codex billed.
40
40
 
41
41
  Or install it globally:
42
42
 
@@ -201,26 +201,26 @@ npx -y byob-cli codex sync-skills --project-id <project_id> --token <agent_acces
201
201
 
202
202
  `codex sync-skills` downloads AIR coding-skill resources and rewrites their local skill names with `byob_` prefixes. It does not run OAuth, does not call `codex mcp add`, and does not change the active MCP server config.
203
203
 
204
- ### Local Codex Billed SSH Route
204
+ ### Local Codex Billed
205
205
 
206
- When a user chooses **Local Codex billed**, prefer the SSH-backed route from the start of the edit session:
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. Use the returned SSH connection details through `byob-cli@0.2.10` or newer. Do not print tokens, private keys, or the full proxy command in chat.
211
- 4. Connect with the returned SSH proxy and inspect/edit the remote project filesystem directly.
212
- 5. Fall back to Agent MCP coding tools only when the SSH route is unavailable or the host environment cannot launch the proxy.
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.
211
+ 4. Keep tokens, private keys, and complete proxy commands out of chat.
212
+ 5. Use Codex's normal file, shell, and git workflow inside that active workspace.
213
213
 
214
- The proxy command is intentionally a local bridge from OpenSSH stdio to AIR's authenticated WebSocket endpoint:
214
+ The underlying proxy command bridges OpenSSH stdio to AIR's authenticated WebSocket endpoint:
215
215
 
216
216
  ```bash
217
217
  BYOB_CODEX_SSH_TOKEN=<connection_token> \
218
218
  ssh -i <temporary_key_file> \
219
- -o ProxyCommand="npx -y byob-cli@0.2.10 codex ssh-proxy '{\"ssh_endpoint\":\"<ssh_endpoint>\"}'" \
219
+ -o ProxyCommand="npx -y byob-cli@latest codex ssh-proxy '{\"ssh_endpoint\":\"<ssh_endpoint>\"}'" \
220
220
  byob@byob-project
221
221
  ```
222
222
 
223
- Agents should keep this user-facing: say "Local Codex billed connection" or "SSH-backed project connection", not internal labels such as `ssh_gateway`, unless debugging the connector itself. If `npx -y byob-cli codex ssh-proxy` returns `Unknown command: codex`, the installed/published CLI is too old; upgrade to `byob-cli@0.2.10` or newer instead of retrying the same command.
223
+ Agents and hosts should keep this user-facing: say "Local Codex billed", not internal labels such as `ssh_gateway`, unless debugging the connector itself.
224
224
 
225
225
  ## Multiple Projects
226
226
 
package/bin/byob.js CHANGED
@@ -60,6 +60,25 @@ 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 Bridge OpenSSH stdio to a BYOB Local Codex billed workspace.
75
+
76
+ Local Codex billed workspaces are normally opened by the Codex host from the
77
+ workspace handle returned by BYOB Agent MCP. Agents should not print or manually
78
+ handle raw SSH tokens, private keys, or complete proxy commands.
79
+ `;
80
+ }
81
+
63
82
  function parseArgs(argv) {
64
83
  const opts = {
65
84
  airUrl: DEFAULT_AIR_URL,
@@ -200,15 +219,23 @@ function publicPreviewUrl(projectId) {
200
219
  return id ? `https://preview.${id}.api.byob.studio` : "";
201
220
  }
202
221
 
203
- function sanitizePreviewUrls(value, projectIdHint = "", { sanitizeText = false } = {}) {
222
+ function sanitizePreviewUrls(
223
+ value,
224
+ projectIdHint = "",
225
+ { sanitizeText = false, redactPrivateMeta = false } = {},
226
+ ) {
204
227
  if (Array.isArray(value)) {
205
- return value.map((item) => sanitizePreviewUrls(item, projectIdHint, { sanitizeText }));
228
+ return value.map((item) => sanitizePreviewUrls(item, projectIdHint, { sanitizeText, redactPrivateMeta }));
206
229
  }
207
230
  if (!value || typeof value !== "object") {
208
231
  if (sanitizeText && typeof value === "string") {
209
232
  try {
210
233
  const parsed = JSON.parse(value);
211
- return JSON.stringify(sanitizePreviewUrls(parsed, projectIdHint, { sanitizeText }), null, 2);
234
+ return JSON.stringify(
235
+ sanitizePreviewUrls(parsed, projectIdHint, { sanitizeText, redactPrivateMeta }),
236
+ null,
237
+ 2,
238
+ );
212
239
  } catch {
213
240
  return value;
214
241
  }
@@ -219,19 +246,42 @@ function sanitizePreviewUrls(value, projectIdHint = "", { sanitizeText = false }
219
246
  const localProjectId = value.project_id || value.id || projectIdHint;
220
247
  const sanitized = {};
221
248
  for (const [key, item] of Object.entries(value)) {
249
+ if (
250
+ redactPrivateMeta &&
251
+ key === "_meta" &&
252
+ item &&
253
+ typeof item === "object" &&
254
+ item.byob_local_codex_workspace
255
+ ) {
256
+ sanitized[key] = {
257
+ ...item,
258
+ byob_local_codex_workspace: {
259
+ ...item.byob_local_codex_workspace,
260
+ ssh: {
261
+ redacted: true,
262
+ reason: "Use the workspace_handle with a Codex host; direct CLI display omits raw SSH material.",
263
+ },
264
+ },
265
+ };
266
+ continue;
267
+ }
222
268
  if (key === "preview_url") {
223
269
  sanitized[key] = publicPreviewUrl(localProjectId) || item;
224
270
  continue;
225
271
  }
226
272
  sanitized[key] = sanitizePreviewUrls(item, localProjectId, {
227
273
  sanitizeText: sanitizeText && key === "text",
274
+ redactPrivateMeta,
228
275
  });
229
276
  }
230
277
  return sanitized;
231
278
  }
232
279
 
233
280
  function printJson(payload, projectIdHint = "", sanitizeText = false) {
234
- const safePayload = sanitizePreviewUrls(payload, projectIdHint, { sanitizeText });
281
+ const safePayload = sanitizePreviewUrls(payload, projectIdHint, {
282
+ sanitizeText,
283
+ redactPrivateMeta: true,
284
+ });
235
285
  process.stdout.write(`${JSON.stringify(safePayload, null, 2)}\n`);
236
286
  }
237
287
 
@@ -922,9 +972,14 @@ async function main() {
922
972
  }
923
973
 
924
974
  if (command === "mcp") return serve(opts);
975
+ if (command === "codex" && (!first || first === "help")) {
976
+ process.stdout.write(codexUsage());
977
+ return;
978
+ }
925
979
  if (command === "codex" && first === "install") return codexInstall(opts);
926
980
  if (command === "codex" && first === "sync-skills") return codexSyncSkills(opts);
927
981
  if (command === "codex" && first === "ssh-proxy") return codexSshProxy(opts, second);
982
+ if (command === "codex") throw new Error(`Unknown codex command: ${first || ""}`);
928
983
  if (command === "config") return config(opts);
929
984
  if (command === "device-code") return deviceCode(opts);
930
985
  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.10",
3
+ "version": "0.2.12",
4
4
  "description": "Codex connector for BYOB projects, backed by an Agent MCP stdio bridge.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -67,17 +67,17 @@ Do not add BYOB platform helper tools into user containers. Do not ask for BYOB
67
67
 
68
68
  ## Local Codex Billed Route
69
69
 
70
- When the user selects **Local Codex billed**, prefer the SSH-backed project connection before trying lower-fidelity Agent MCP workarounds. The expected path is:
70
+ When the user selects **Local Codex billed**, open the BYOB project as the active Codex workspace before trying lower-fidelity Agent MCP workarounds. The expected path is:
71
71
 
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 SSH connection through `byob-cli@0.2.10` or newer'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 `byob-cli@latest`'s `codex ssh-proxy` behind that handle.
77
77
 
78
- This route 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 connection" or "SSH-backed project connection"; 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
- If `npx -y byob-cli codex ssh-proxy` fails with `Unknown command: codex`, treat it as a BYOB CLI version mismatch. The SSH proxy command requires `byob-cli@0.2.10` or newer. Do not continue by repeatedly trying Agent MCP allowlisted command facades for file reads; those facades are designed for build/check/lint/test commands and will reject arbitrary shell/file inspection.
80
+ After the workspace is open, use Codex's normal file, shell, git, and verification workflow inside the remote project.
81
81
 
82
82
  ## Skill Routing
83
83
 
@@ -53,15 +53,15 @@ Refresh downloaded coding skills later without rerunning OAuth or changing MCP c
53
53
  npx -y byob-cli codex sync-skills --project-id <project_id> --token <agent_access_token>
54
54
  ```
55
55
 
56
- For **Local Codex billed** project editing, prefer the SSH-backed project connection immediately instead of first trying to simulate shell/file access through Agent MCP tools:
56
+ For **Local Codex billed** project editing, open the BYOB project as the active Codex workspace immediately instead of trying to simulate shell/file access through Agent MCP tools:
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 SSH proxy connection through `byob-cli@0.2.10` or newer to inspect and edit files in the remote project container.
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.
62
62
  5. Do not print tokens, private keys, or full proxy commands in chat.
63
63
 
64
- If `npx -y byob-cli codex ssh-proxy` reports `Unknown command: codex`, the local/published CLI is too old for Local Codex billed SSH. Tell the user to use `byob-cli@0.2.10` or newer; do not keep retrying Agent MCP command facades for ordinary file reads. Use Agent MCP project tools as a fallback only when the SSH route is unavailable or the host cannot launch the proxy.
64
+ After the workspace is open, use Codex's normal file, shell, git, and verification workflow inside the remote project.
65
65
 
66
66
  Equivalent raw PRIM flow:
67
67
 
@@ -284,17 +284,17 @@ Do not assume `byob_*` tools exist inside the user container. They are platform
284
284
 
285
285
  ## Local Codex Billed Editing
286
286
 
287
- When the user chooses Local Codex billed, the expected editing path is a short-lived SSH-backed connection into the remote BYOB project container. This gives Codex normal filesystem semantics for reading `src/app.html`, searching source, editing files, and running project-local shell commands through the local Codex account billing path.
287
+ When the user chooses Local Codex billed, the expected editing path is that the remote BYOB project container becomes the active Codex workspace. This gives Codex normal filesystem semantics for reading `src/app.html`, searching source, editing files, and running project-local shell commands through the local Codex account billing path.
288
288
 
289
289
  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 SSH connection details with `byob-cli@0.2.10` or newer'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 `byob-cli@latest`'s `codex ssh-proxy` behind that handle.
295
295
  5. Keep credentials out of chat, logs, screenshots, and command transcripts.
296
296
 
297
- If the SSH proxy cannot be launched because the installed CLI lacks `codex ssh-proxy`, report that as a CLI version mismatch and ask for/choose `byob-cli@0.2.10` or newer. Avoid frustrating loops where Codex repeatedly tries Agent MCP allowlisted commands to read files; those command facades are intentionally limited to build/check/lint/test and are not a replacement for the SSH route.
297
+ After the workspace is open, use Codex's normal file, shell, git, and verification workflow inside the remote project.
298
298
 
299
299
  ## Project Scope
300
300