diff --git a/.github/scripts/check_plugin_source_compatibility.py b/.github/scripts/check_plugin_source_compatibility.py index 4c4def985..e840a4982 100644 --- a/.github/scripts/check_plugin_source_compatibility.py +++ b/.github/scripts/check_plugin_source_compatibility.py @@ -13,6 +13,7 @@ MAX_SOURCE_FILE_BYTES = 150_000 MAX_DEPENDENCY_LOCK_BYTES = 2_000_000 DEPENDENCY_LOCK_NAMES = { + "bun.lock", "Cargo.lock", "package-lock.json", "pnpm-lock.yaml", diff --git a/.github/scripts/test_check_plugin_source_compatibility.py b/.github/scripts/test_check_plugin_source_compatibility.py index f49a80420..678678eda 100644 --- a/.github/scripts/test_check_plugin_source_compatibility.py +++ b/.github/scripts/test_check_plugin_source_compatibility.py @@ -46,15 +46,16 @@ def test_reports_tracked_source_violations_in_stable_order(tmp_path: Path) -> No ] -def test_accepts_valid_source_and_ignores_untracked_files(tmp_path: Path) -> None: +@pytest.mark.parametrize("lock_name", ["package-lock.json", "bun.lock"]) +def test_accepts_valid_source_and_ignores_untracked_files(tmp_path: Path, lock_name: str) -> None: (tmp_path / "README.md").write_text("A complete sentence.\n", encoding="utf-8") - (tmp_path / "package-lock.json").write_bytes(b"x" * 150_001) + (tmp_path / lock_name).write_bytes(b"x" * 150_001) (tmp_path / "untracked.md").write_text( "This untracked prose continues\nonto another source line.\n", encoding="utf-8", ) initialize_repository(tmp_path) - track(tmp_path, "README.md", "package-lock.json") + track(tmp_path, "README.md", lock_name) result = run_checker(tmp_path) @@ -120,15 +121,16 @@ def test_accepts_wraps_adjacent_to_inline_markup(tmp_path: Path, content: str) - assert result.returncode == 0, result.stderr -def test_rejects_dependency_lock_files_above_two_megabytes(tmp_path: Path) -> None: - (tmp_path / "pnpm-lock.yaml").write_bytes(b"x" * 2_000_001) +@pytest.mark.parametrize("lock_name", ["pnpm-lock.yaml", "bun.lock"]) +def test_rejects_dependency_lock_files_above_two_megabytes(tmp_path: Path, lock_name: str) -> None: + (tmp_path / lock_name).write_bytes(b"x" * 2_000_001) initialize_repository(tmp_path) - track(tmp_path, "pnpm-lock.yaml") + track(tmp_path, lock_name) result = run_checker(tmp_path) assert result.returncode == 1 - assert result.stderr == ("pnpm-lock.yaml: file is 2000001 bytes; maximum is 2000000 bytes\n") + assert result.stderr == f"{lock_name}: file is 2000001 bytes; maximum is 2000000 bytes\n" @pytest.mark.skipif(os.name == "nt", reason="creating symlinks requires elevated Windows access") diff --git a/.github/workflows/node-ci.yml b/.github/workflows/node-ci.yml index 024dc5a15..69356cd78 100644 --- a/.github/workflows/node-ci.yml +++ b/.github/workflows/node-ci.yml @@ -87,14 +87,17 @@ jobs: run: | python .github/scripts/check_plugin_source_compatibility.py - - name: Set up pnpm + - name: Set up Bun if: steps.scope.outputs.check-markdown == 'true' - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: - package_json_file: package.json - cache: true - cache_dependency_path: sdk/typescript/pnpm-lock.yaml - + bun-version: "1.3.14" + - name: Cache Bun downloads + if: steps.scope.outputs.check-markdown == 'true' + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-${{ runner.arch }}-bun-1.3.14-${{ hashFiles('sdk/typescript/bun.lock', 'plugins/codex-security/mcp-app/bun.lock') }} - name: Set up Node.js if: steps.scope.outputs.check-markdown == 'true' uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 @@ -103,7 +106,7 @@ jobs: - name: Install dependencies if: steps.scope.outputs.check-markdown == 'true' - run: pnpm --dir sdk/typescript install --frozen-lockfile + run: bun install --cwd sdk/typescript --frozen-lockfile - name: Check Markdown formatting if: steps.scope.outputs.check-markdown == 'true' @@ -117,7 +120,7 @@ jobs: fi done < <(git diff --no-renames --name-only -z HEAD^1 HEAD) if ((${#files[@]} > 0)); then - pnpm --dir sdk/typescript exec prettier --check "${files[@]}" + bun run --cwd sdk/typescript prettier --check "${files[@]}" fi static-checks: @@ -131,26 +134,27 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Set up pnpm - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - with: - package_json_file: package.json - cache: true - cache_dependency_path: | - sdk/typescript/pnpm-lock.yaml - plugins/codex-security/mcp-app/pnpm-lock.yaml + - name: Set up Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 + with: + bun-version: "1.3.14" + - name: Cache Bun downloads + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-${{ runner.arch }}-bun-1.3.14-${{ hashFiles('sdk/typescript/bun.lock', 'plugins/codex-security/mcp-app/bun.lock') }} - name: Set up Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version: "22.13.0" - name: Install dependencies run: | - pnpm --dir sdk/typescript install --frozen-lockfile - pnpm --dir plugins/codex-security/mcp-app install --frozen-lockfile + bun install --cwd sdk/typescript --frozen-lockfile + bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile - name: Typecheck - run: pnpm --dir sdk/typescript run types + run: bun run --cwd sdk/typescript types - name: Check formatting - run: pnpm --dir sdk/typescript run format + run: bun run --cwd sdk/typescript format package: name: build and check package @@ -165,28 +169,29 @@ jobs: persist-credentials: false - name: Check plugin source boundary run: node sdk/typescript/scripts/check-plugin-source.mjs - - name: Set up pnpm - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - with: - package_json_file: package.json - cache: true - cache_dependency_path: | - sdk/typescript/pnpm-lock.yaml - plugins/codex-security/mcp-app/pnpm-lock.yaml + - name: Set up Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 + with: + bun-version: "1.3.14" + - name: Cache Bun downloads + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-${{ runner.arch }}-bun-1.3.14-${{ hashFiles('sdk/typescript/bun.lock', 'plugins/codex-security/mcp-app/bun.lock') }} - name: Set up Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version: "22.13.0" - name: Install dependencies run: | - pnpm --dir sdk/typescript install --frozen-lockfile - pnpm --dir plugins/codex-security/mcp-app install --frozen-lockfile + bun install --cwd sdk/typescript --frozen-lockfile + bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile - name: Audit production dependencies continue-on-error: true - run: pnpm --dir sdk/typescript run audit:prod + run: bun run --cwd sdk/typescript audit:prod - name: Pack working-directory: sdk/typescript - run: pnpm pack --pack-destination ../../dist + run: bun pm pack --destination ../../dist - name: Inspect archive contents working-directory: sdk/typescript run: node scripts/check-package.mjs ../../dist/*.tgz ../../plugins/codex-security/plugin-files.json @@ -215,14 +220,6 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Set up pnpm - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - with: - package_json_file: package.json - cache: true - cache_dependency_path: | - sdk/typescript/pnpm-lock.yaml - plugins/codex-security/mcp-app/pnpm-lock.yaml - name: Set up Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: @@ -231,10 +228,15 @@ jobs: uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: "1.3.14" + - name: Cache Bun downloads + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-${{ runner.arch }}-bun-1.3.14-${{ hashFiles('sdk/typescript/bun.lock', 'plugins/codex-security/mcp-app/bun.lock') }} - name: Install dependencies run: | - pnpm --dir sdk/typescript install --frozen-lockfile - pnpm --dir plugins/codex-security/mcp-app install --frozen-lockfile + bun install --cwd sdk/typescript --frozen-lockfile + bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile - name: Download package for this commit uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -294,7 +296,7 @@ jobs: with: node-version: ${{ matrix.node }} cache: npm - cache-dependency-path: sdk/typescript/pnpm-lock.yaml + cache-dependency-path: sdk/typescript/bun.lock - name: Download package for this commit uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -315,18 +317,21 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Set up pnpm - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 + - name: Set up Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 + with: + bun-version: "1.3.14" + - name: Cache Bun downloads + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: - package_json_file: package.json - cache: true - cache_dependency_path: plugins/codex-security/mcp-app/pnpm-lock.yaml + path: ~/.bun/install/cache + key: ${{ runner.os }}-${{ runner.arch }}-bun-1.3.14-${{ hashFiles('sdk/typescript/bun.lock', 'plugins/codex-security/mcp-app/bun.lock') }} - name: Set up Node.js uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version: "22.13.0" - name: Install dependencies - run: pnpm --dir plugins/codex-security/mcp-app install --frozen-lockfile + run: bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile - name: Install ripgrep run: | sudo apt-get update @@ -339,7 +344,7 @@ jobs: - name: Restore bundled plugin run: tar -xzf dist/*.tgz --strip-components=1 -C sdk/typescript package/_bundled_plugin - name: Test MCP app - run: pnpm --dir plugins/codex-security/mcp-app run test:mcp + run: bun run --cwd plugins/codex-security/mcp-app test:mcp - name: Upload MCP test reports if: always() continue-on-error: true @@ -445,18 +450,19 @@ jobs: uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version: "22.13.0" - - name: Set up pnpm - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - with: - package_json_file: package.json - name: Set up Bun uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: "1.3.14" + - name: Cache Bun downloads + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-${{ runner.arch }}-bun-1.3.14-${{ hashFiles('sdk/typescript/bun.lock', 'plugins/codex-security/mcp-app/bun.lock') }} - name: Install dependencies run: | - pnpm --dir sdk/typescript install --frozen-lockfile - pnpm --dir plugins/codex-security/mcp-app install --frozen-lockfile + bun install --cwd sdk/typescript --frozen-lockfile + bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile - name: Download package for this commit uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -518,7 +524,7 @@ jobs: with: node-version: ${{ matrix.node }} cache: npm - cache-dependency-path: sdk/typescript/pnpm-lock.yaml + cache-dependency-path: sdk/typescript/bun.lock - name: Download package for this commit uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: diff --git a/.github/workflows/node-release.yml b/.github/workflows/node-release.yml index 10c2975ee..54f4b32f7 100644 --- a/.github/workflows/node-release.yml +++ b/.github/workflows/node-release.yml @@ -19,8 +19,6 @@ jobs: contents: read env: NPM_CONFIG_REGISTRY: https://openai.firewall.socket.dev/npm/ - PNPM_CONFIG_REGISTRY: https://openai.firewall.socket.dev/npm/ - COREPACK_NPM_REGISTRY: https://openai.firewall.socket.dev/npm/ BUN_CONFIG_REGISTRY: https://openai.firewall.socket.dev/npm/ outputs: artifact-id: ${{ steps.upload.outputs.artifact-id }} @@ -56,9 +54,6 @@ jobs: { printf 'NPM_CONFIG_REGISTRY=%s\n' "$npm_registry" printf 'npm_config_registry=%s\n' "$npm_registry" - printf 'PNPM_CONFIG_REGISTRY=%s\n' "$npm_registry" - printf 'pnpm_config_registry=%s\n' "$npm_registry" - printf 'COREPACK_NPM_REGISTRY=%s\n' "$npm_registry" printf 'YARN_NPM_REGISTRY_SERVER=%s\n' "$npm_registry" printf 'BUN_CONFIG_REGISTRY=%s\n' "$npm_registry" printf 'UV_DEFAULT_INDEX=%s\n' "$pypi_registry" @@ -72,10 +67,6 @@ jobs: bun-version: "1.3.14" no-cache: true - - name: Enable pnpm - shell: bash - run: corepack enable && corepack prepare "$(node -p 'require("./package.json").packageManager')" --activate - - name: Validate release tag id: release shell: bash @@ -135,8 +126,8 @@ jobs: - name: Install dependencies run: | - sfw pnpm --dir sdk/typescript install --frozen-lockfile - sfw pnpm --dir plugins/codex-security/mcp-app install --frozen-lockfile + sfw bun install --cwd sdk/typescript --frozen-lockfile + sfw bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile - name: Install ripgrep run: | @@ -145,14 +136,14 @@ jobs: - name: Audit production dependencies continue-on-error: true - run: sfw pnpm --dir sdk/typescript run audit:prod + run: sfw bun run --cwd sdk/typescript audit:prod - name: Verify run: | - pnpm --dir sdk/typescript run types - pnpm --dir sdk/typescript run test - pnpm --dir sdk/typescript run test:mcp - pnpm --dir sdk/typescript run format + bun run --cwd sdk/typescript types + bun run --cwd sdk/typescript test + bun run --cwd sdk/typescript test:mcp + bun run --cwd sdk/typescript format - name: Pack working-directory: sdk/typescript @@ -160,14 +151,14 @@ jobs: run: | set -euo pipefail npm pkg set "gitHead=$GITHUB_SHA" - pnpm pack --pack-destination ../../dist + bun pm pack --destination ../../dist - name: Inspect package working-directory: sdk/typescript shell: bash env: CODEX_SECURITY_EXPECTED_GIT_HEAD: ${{ github.sha }} - run: pnpm run check:package ../../dist/*.tgz + run: bun run check:package ../../dist/*.tgz - name: Recover the published npm release archive if: steps.release.outputs.mode == 'recover' diff --git a/.github/workflows/test-quality.yml b/.github/workflows/test-quality.yml index 1400b02bc..07afcf54c 100644 --- a/.github/workflows/test-quality.yml +++ b/.github/workflows/test-quality.yml @@ -66,21 +66,18 @@ jobs: - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version: "22.13.0" - - name: Set up pnpm - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - with: - package_json_file: package.json - cache: true - cache_dependency_path: | - sdk/typescript/pnpm-lock.yaml - plugins/codex-security/mcp-app/pnpm-lock.yaml - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: "1.3.13" + - name: Cache Bun downloads + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-${{ runner.arch }}-bun-1.3.13-${{ hashFiles('sdk/typescript/bun.lock', 'plugins/codex-security/mcp-app/bun.lock') }} - name: Install dependencies run: | - pnpm --dir sdk/typescript install --frozen-lockfile - pnpm --dir plugins/codex-security/mcp-app install --frozen-lockfile + bun install --cwd sdk/typescript --frozen-lockfile + bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile - name: Prepare private Windows test root if: runner.os == 'Windows' id: windows-temp @@ -93,7 +90,7 @@ jobs: TMPDIR: ${{ steps.windows-temp.outputs.path || runner.temp }} run: | node -e "require('node:fs').mkdirSync('sdk/typescript/reports',{recursive:true})" - pnpm --dir sdk/typescript run test ${{ runner.os == 'Windows' && '--timeout=120000' || '' }} ${{ matrix.args }} --seed=${{ env.CODEX_SECURITY_PROPERTY_SEED }} --reporter=junit --reporter-outfile=reports/runner-${{ matrix.os }}-${{ matrix.mode }}.xml + bun run --cwd sdk/typescript test ${{ runner.os == 'Windows' && '--timeout=120000' || '' }} ${{ matrix.args }} --seed=${{ env.CODEX_SECURITY_PROPERTY_SEED }} --reporter=junit --reporter-outfile=reports/runner-${{ matrix.os }}-${{ matrix.mode }}.xml - name: Upload runner report if: always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -141,18 +138,18 @@ jobs: - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version: "22.13.0" - - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - with: - package_json_file: package.json - cache: true - cache_dependency_path: sdk/typescript/pnpm-lock.yaml - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: "1.3.14" + - name: Cache Bun downloads + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-${{ runner.arch }}-bun-1.3.14-${{ hashFiles('sdk/typescript/bun.lock', 'plugins/codex-security/mcp-app/bun.lock') }} - name: Install dependencies - run: pnpm --dir sdk/typescript install --frozen-lockfile + run: bun install --cwd sdk/typescript --frozen-lockfile - name: Run mutation trial - run: pnpm --dir sdk/typescript run test:mutation + run: bun run --cwd sdk/typescript test:mutation - name: Upload mutation report if: always() continue-on-error: true diff --git a/.ona/automations.yml b/.ona/automations.yml index 1024108ae..7a1c1d7a7 100644 --- a/.ona/automations.yml +++ b/.ona/automations.yml @@ -2,16 +2,15 @@ tasks: install: name: Install dependencies command: | - pnpm_package="$(node -p 'require("./package.json").packageManager.split("+")[0]')" - npm install --global "$pnpm_package" bun@1.3.14 --no-audit --no-fund + npm install --global bun@1.3.14 --no-audit --no-fund if ! command -v rg >/dev/null 2>&1; then sudo apt-get update \ -o Dir::Etc::sourcelist=/etc/apt/sources.list.d/ubuntu.sources \ -o Dir::Etc::sourceparts=- sudo apt-get install --yes ripgrep fi - pnpm --dir sdk/typescript install --frozen-lockfile - pnpm --dir plugins/codex-security/mcp-app install --frozen-lockfile + bun install --cwd sdk/typescript --frozen-lockfile + bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile python -m pip install --disable-pip-version-check --no-input -e 'plugins/codex-security[test]' triggeredBy: - manual @@ -19,7 +18,7 @@ tasks: build: name: Build - command: pnpm --dir sdk/typescript run build + command: bun run --cwd sdk/typescript build dependsOn: - install triggeredBy: @@ -29,8 +28,8 @@ tasks: test: name: Run tests command: | - pnpm --dir sdk/typescript run test - pnpm --dir sdk/typescript run test:mcp + bun run --cwd sdk/typescript test + bun run --cwd sdk/typescript test:mcp python -m pytest plugins/codex-security/tests -q dependsOn: - build diff --git a/AGENTS.md b/AGENTS.md index a395c4c4a..3fa12da60 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,6 +23,22 @@ python -m ruff format --check --config plugins/codex-security/pyproject.toml .gi python .github/scripts/check_plugin_source_compatibility.py ``` +## Development tools + +- Use Bun for JavaScript dependency installs, maintainer scripts, and packing. + The required version is in `sdk/typescript/package.json` under `packageManager`. +- The SDK, MCP app, and triage evals are separate install roots with their own + `bun.lock` and `bunfig.toml`. Use frozen installs; there is no root JavaScript workspace. +- Keep Node.js as the CLI, SDK, and build runtime. Keep npm for publication, + provenance, and consumer-install checks; consumer npm/pnpm/Yarn instructions + and scanned-repository lockfile support are separate from maintainer tooling. +- Repository Python tests require Python 3.12+ and the pinned test dependencies + in `plugins/codex-security/pyproject.toml`. + +Follow [CONTRIBUTING.md](CONTRIBUTING.md#local-development) for setup and +[the SDK testing guide](sdk/typescript/TESTING.md) for checks and the separate +Bun pin used by optional runner experiments. + ## Avoid speculative defenses - Do not add sanitization, redaction, validation, or fallback logic for diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 667813f94..81ef735dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ maintainers. plugin. Make plugin changes there. The npm runtime under `sdk/typescript/_bundled_plugin/` is generated from the -plugin source by `pnpm run build:plugin` and automatically during `prepack` for +plugin source by `bun run build:plugin` in `sdk/typescript`, and automatically during `prepack` for packages and releases. Do not edit or commit files in that directory. See the [SDK testing guide](sdk/typescript/TESTING.md) for the generation and validation commands. @@ -18,6 +18,40 @@ commands. Search [existing issues](https://github.com/openai/codex-security/issues) before opening a new one. +## Local development + +Use Bun 1.3.14, matching `packageManager` in `sdk/typescript/package.json`, +and a [supported Node.js version](sdk/typescript/README.md#install). Node.js 24.x +works with both the SDK and the separate triage eval runner. Bun manages +dependencies and maintainer commands; the CLI, SDK, and builds still use Node.js. + +Repository tests also need Python 3.12+ in a virtual environment and ripgrep +(`rg`) on `PATH`. The Python test requirement comes from +`plugins/codex-security/pyproject.toml`; it is separate from the published +CLI's Python 3.10+ runtime support. + +With those tools installed and the virtual environment active, run from the +repository root: + +```bash +python -m pip install -e 'plugins/codex-security[test]' +bun install --cwd sdk/typescript --frozen-lockfile +bun install --cwd plugins/codex-security/mcp-app --frozen-lockfile +bun run --cwd sdk/typescript build:plugin +bun run --cwd sdk/typescript build +node sdk/typescript/bin/codex-security.mjs --help +``` + +Install both JavaScript packages before building the bundled plugin. Each +package owns its lockfile; there is no `package.json` at the repository root. +Use `bun run --cwd