diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index c75ae416fa..8291ba12d1 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -9888,6 +9888,12 @@ "description": "File modification time in Unix milliseconds when available, otherwise `0`.", "format": "int64", "type": "integer" + }, + "sizeBytes": { + "description": "File size in bytes.", + "format": "uint64", + "minimum": 0.0, + "type": "integer" } }, "required": [ @@ -9895,7 +9901,8 @@ "isDirectory", "isFile", "isSymlink", - "modifiedAtMs" + "modifiedAtMs", + "sizeBytes" ], "title": "FsGetMetadataResponse", "type": "object" diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index a4a0267dc5..aebee6d7f4 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -6173,6 +6173,12 @@ "description": "File modification time in Unix milliseconds when available, otherwise `0`.", "format": "int64", "type": "integer" + }, + "sizeBytes": { + "description": "File size in bytes.", + "format": "uint64", + "minimum": 0.0, + "type": "integer" } }, "required": [ @@ -6180,7 +6186,8 @@ "isDirectory", "isFile", "isSymlink", - "modifiedAtMs" + "modifiedAtMs", + "sizeBytes" ], "title": "FsGetMetadataResponse", "type": "object" diff --git a/codex-rs/app-server-protocol/schema/json/v2/FsGetMetadataResponse.json b/codex-rs/app-server-protocol/schema/json/v2/FsGetMetadataResponse.json index 82481f579e..cfbdb08c85 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/FsGetMetadataResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/FsGetMetadataResponse.json @@ -23,6 +23,12 @@ "description": "File modification time in Unix milliseconds when available, otherwise `0`.", "format": "int64", "type": "integer" + }, + "sizeBytes": { + "description": "File size in bytes.", + "format": "uint64", + "minimum": 0.0, + "type": "integer" } }, "required": [ @@ -30,7 +36,8 @@ "isDirectory", "isFile", "isSymlink", - "modifiedAtMs" + "modifiedAtMs", + "sizeBytes" ], "title": "FsGetMetadataResponse", "type": "object" diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/FsGetMetadataResponse.ts b/codex-rs/app-server-protocol/schema/typescript/v2/FsGetMetadataResponse.ts index a1a127e192..cac27ad959 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/FsGetMetadataResponse.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/FsGetMetadataResponse.ts @@ -18,6 +18,10 @@ isFile: boolean, * Whether the path itself is a symbolic link. */ isSymlink: boolean, +/** + * File size in bytes. + */ +sizeBytes: number, /** * File creation time in Unix milliseconds when available, otherwise `0`. */ diff --git a/codex-rs/app-server-protocol/src/protocol/v2/fs.rs b/codex-rs/app-server-protocol/src/protocol/v2/fs.rs index 0132c6b284..2c8a52511c 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/fs.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/fs.rs @@ -77,6 +77,9 @@ pub struct FsGetMetadataResponse { pub is_file: bool, /// Whether the path itself is a symbolic link. pub is_symlink: bool, + /// File size in bytes. + #[ts(type = "number")] + pub size_bytes: u64, /// File creation time in Unix milliseconds when available, otherwise `0`. #[ts(type = "number")] pub created_at_ms: i64, diff --git a/codex-rs/app-server-protocol/src/protocol/v2/tests.rs b/codex-rs/app-server-protocol/src/protocol/v2/tests.rs index b973b8b4ae..43e99e3988 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/tests.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/tests.rs @@ -813,6 +813,7 @@ fn fs_get_metadata_response_round_trips_minimal_fields() { is_directory: false, is_file: true, is_symlink: false, + size_bytes: 5, created_at_ms: 123, modified_at_ms: 456, }; @@ -824,6 +825,7 @@ fn fs_get_metadata_response_round_trips_minimal_fields() { "isDirectory": false, "isFile": true, "isSymlink": false, + "sizeBytes": 5, "createdAtMs": 123, "modifiedAtMs": 456, }) diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index a6c5ddab7d..c0f44e8a6d 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -185,7 +185,7 @@ Example with notification opt-out: - `fs/readFile` — read an absolute file path and return `{ dataBase64 }`. - `fs/writeFile` — write an absolute file path from base64-encoded `{ dataBase64 }`; returns `{}`. - `fs/createDirectory` — create an absolute directory path; `recursive` defaults to `true`. -- `fs/getMetadata` — return metadata for an absolute path: `isDirectory`, `isFile`, `isSymlink`, `createdAtMs`, and `modifiedAtMs`. +- `fs/getMetadata` — return metadata for an absolute path: `isDirectory`, `isFile`, `isSymlink`, `sizeBytes`, `createdAtMs`, and `modifiedAtMs`. - `fs/readDirectory` — list direct child entries for an absolute directory path; each entry contains `fileName`, `isDirectory`, and `isFile`, and `fileName` is just the child name, not a path. - `fs/remove` — remove an absolute file or directory tree; `recursive` and `force` default to `true`. - `fs/copy` — copy between absolute paths; directory copies require `recursive: true`. @@ -1242,6 +1242,7 @@ All filesystem paths in this section must be absolute. "isDirectory": false, "isFile": true, "isSymlink": false, + "sizeBytes": 5, "createdAtMs": 1730910000000, "modifiedAtMs": 1730910000000 } } @@ -1253,7 +1254,7 @@ All filesystem paths in this section must be absolute. } } ``` -- `fs/getMetadata` returns whether the path resolves to a directory or regular file, whether the path itself is a symlink, plus `createdAtMs` and `modifiedAtMs` in Unix milliseconds. If a timestamp is unavailable on the current platform, that field is `0`. +- `fs/getMetadata` returns whether the path resolves to a directory or regular file, whether the path itself is a symlink, its byte size, plus `createdAtMs` and `modifiedAtMs` in Unix milliseconds. If a timestamp is unavailable on the current platform, that field is `0`. - `fs/createDirectory` defaults `recursive` to `true` when omitted. - `fs/remove` defaults both `recursive` and `force` to `true` when omitted. - `fs/readFile` always returns base64 bytes via `dataBase64`, and `fs/writeFile` always expects base64 bytes in `dataBase64`. diff --git a/codex-rs/app-server/src/request_processors/fs_processor.rs b/codex-rs/app-server/src/request_processors/fs_processor.rs index c18300b1c1..356754cccb 100644 --- a/codex-rs/app-server/src/request_processors/fs_processor.rs +++ b/codex-rs/app-server/src/request_processors/fs_processor.rs @@ -125,6 +125,7 @@ impl FsRequestProcessor { is_directory: metadata.is_directory, is_file: metadata.is_file, is_symlink: metadata.is_symlink, + size_bytes: metadata.size, created_at_ms: metadata.created_at_ms, modified_at_ms: metadata.modified_at_ms, }) diff --git a/codex-rs/app-server/tests/suite/v2/fs.rs b/codex-rs/app-server/tests/suite/v2/fs.rs index 1f4a4dec38..184151d02f 100644 --- a/codex-rs/app-server/tests/suite/v2/fs.rs +++ b/codex-rs/app-server/tests/suite/v2/fs.rs @@ -97,6 +97,7 @@ async fn fs_get_metadata_returns_only_used_fields() -> Result<()> { "isFile".to_string(), "isSymlink".to_string(), "modifiedAtMs".to_string(), + "sizeBytes".to_string(), ] ); @@ -107,6 +108,7 @@ async fn fs_get_metadata_returns_only_used_fields() -> Result<()> { is_directory: false, is_file: true, is_symlink: false, + size_bytes: 5, created_at_ms: stat.created_at_ms, modified_at_ms: stat.modified_at_ms, }