Conversation
The CLI read argv._[0] only, so a batch of paths (a shell glob, a git hook passing every staged file) optimized the first one and dropped the rest silently. Every positional is now an input, file or directory, each one optimized in turn. Missing binaries are collected across the whole run, and --data-url still refuses more than one input. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P72UUX4BDvPvTH3amb6Uza
|
Warning Review limit reached
Next review available in: 29 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThe CLI now accepts multiple files or directories, validates multi-input output modes, and aggregates missing binaries. The package adds Linux x64 ImageMagick provisioning with checksum verification and uses explicit dependency installation steps in workflows. ChangesCLI and ImageMagick integration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant CLI
participant parseInputs
participant Optimizer
participant BinaryResolver
CLI->>parseInputs: parse input arguments and resize
parseInputs-->>CLI: return inputs and resize
loop for each input
CLI->>Optimizer: optimize file or directory
Optimizer->>BinaryResolver: resolve ImageMagick binary
BinaryResolver-->>Optimizer: return system or vendored binary
Optimizer-->>CLI: return processing result
end
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
resolve-binary no longer knows tool names: the vendored fallback is a lookup in vendor.js. postinstall reuses its system-only lookup instead of a second `which`. provision-magick drops the hand-rolled https downloader and streaming hash for fetch + crypto.hash. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P7WibWFEFF8qmd4V5PMDNq
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
package.json (1)
47-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider pinning the formatter version.
The formatter changed from a pinned devDependency to
npx@kikobeats/prettier-standard``. Without a devDependency entry,npxresolves whatever version is available at run time. This reduces formatting reproducibility across contributors and CI runs.Add
@kikobeats/prettier-standardback as a pinned devDependency, or pin an explicit version in thenpxinvocation.Also applies to: 98-98
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@package.json` at line 47, Pin the `@kikobeats/prettier-standard` formatter version to ensure reproducible formatting across contributors and CI. Update the formatter configuration or invocation associated with the package scripts, either by restoring it as a pinned devDependency or by adding an explicit version to the npx command, while preserving the existing formatter behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/main.yml:
- Around line 26-27: Replace --dangerously-allow-all-builds in the install steps
at .github/workflows/main.yml lines 26-27 and 57-58 and
.github/workflows/pull_request.yml lines 28-29 with pnpm’s scoped build approval
configuration. Add or update pnpm-workspace.yaml with allowBuilds listing only
the specifically trusted package(s) required by postinstall or dependency build
scripts, ensuring no unapproved scripts can access release secrets.
In @.npmrc:
- Line 4: Remove the lockfile=false entry from .npmrc and add the lockfile:
false setting to pnpm-workspace.yaml so pnpm v11 install workflows consistently
avoid reading or writing a lockfile.
In `@src/util/parse-inputs.js`:
- Around line 7-17: Update the split-resize parsing logic around unitToken so it
locates the token immediately following the --resize or -r option in the raw
argument sequence, rather than always using positionals[1]. Remove that adjacent
unit token from the inputs and combine it with the numeric resize value;
preserve unsplit resize behavior and add coverage for two input files followed
by kB with resize 100.
In `@test/util/vendor.js`:
- Line 3: Pin AVA to a specific version in devDependencies and add the
corresponding lockfile, then apply the matching CommonJS import shape in
test/util/vendor.js, test/util/ensure-binaries.js, test/util/format-bytes.js,
test/util/format-log.js, test/util/get-media-kind.js, and
test/util/get-output-path.js at lines 3-3.
---
Nitpick comments:
In `@package.json`:
- Line 47: Pin the `@kikobeats/prettier-standard` formatter version to ensure
reproducible formatting across contributors and CI. Update the formatter
configuration or invocation associated with the package scripts, either by
restoring it as a pinned devDependency or by adding an explicit version to the
npx command, while preserving the existing formatter behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 74c126d6-6719-4aa0-ac3f-dcca3266b3fc
📒 Files selected for processing (28)
.github/workflows/main.yml.github/workflows/pull_request.yml.gitignore.npmrcbin/help.jsbin/index.jspackage.jsonscripts/postinstall.jssrc/util/parse-inputs.jssrc/util/provision-magick.jssrc/util/resolve-binary.jssrc/util/vendor.jstest/bin.jstest/compressor/index.jstest/index.jstest/util/colors.jstest/util/ensure-binaries.jstest/util/format-bytes.jstest/util/format-log.jstest/util/get-media-kind.jstest/util/get-output-path.jstest/util/normalize-format.jstest/util/parse-inputs.jstest/util/parse-resize.jstest/util/percentage.jstest/util/resolve-binary.jstest/util/to-data-url.jstest/util/vendor.js
| - name: Install | ||
| run: pnpm install --dangerously-allow-all-builds |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Repository files of interest:\n'
git ls-files '.github/workflows/*' 'pnpm*' 'package.json' 'pnpm-workspace.yaml' 2>/dev/null || true
printf '\nWorkflow snippets:\n'
for f in .github/workflows/main.yml .github/workflows/pull_request.yml; do
if [ -f "$f" ]; then
echo "--- $f"
nl -ba "$f" | sed -n '1,120p'
fi
done
printf '\nLock/package indicators:\n'
for f in pnpm-lock.yaml package.json pnpm-workspace.yaml; do
if [ -f "$f" ]; then
echo "--- $f"
nl -ba "$f" | sed -n '1,140p'
fi
done
printf '\nFind script/build references:\n'
rg -n "(postinstall|preinstall|prepare|build|pnpm approve-builds|allowBuilds|dangerously-allow-all-builds|scripts|dependencyUpdates|pnpm:" . --glob '!node_modules/**' || trueRepository: microlinkhq/optimo
Length of output: 353
🏁 Script executed:
#!/bin/bash
set -u
printf 'Repository files of interest:\n'
git ls-files '.github/workflows/*' 'package.json' 'pnpm*' 'pnpm-workspace.yaml' 2>/dev/null || true
printf '\nWorkflow content:\n'
for f in .github/workflows/main.yml .github/workflows/pull_request.yml; do
if [ -f "$f" ]; then
echo "--- $f"
awk '{printf "%6d %s\n", NR, $0}' "$f" | sed -n '1,140p'
fi
done
printf '\nPackage files:\n'
for f in package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc pnpm-debug.log pnpm-debug.txt; do
if [ -f "$f" ]; then
echo "--- $f"
awk '{printf "%6d %s\n", NR, $0}' "$f" | sed -n '1,220p'
fi
done
printf '\nSearch relevant configuration/scripts:\n'
rg -n "dangerously-allow-all-builds|pnpm install|approve-builds|allowBuilds|postinstall|preinstall|prepare|scripts|NPM_TOKEN|GH_TOKEN|environment|permissions|pull_request|workflow_dispatch|release|contributors" .github package.json package-lock.json pnpm-lock.yaml 2>/dev/null || trueRepository: microlinkhq/optimo
Length of output: 10983
🌐 Web query:
pnpm 10 dangerously-allow-all-builds allowBuilds build script allowlist
💡 Result:
In pnpm v10, security defaults regarding dependency build scripts (such as postinstall) were significantly hardened, leading to the introduction of more granular control mechanisms [1][2]. dangerouslyAllowAllBuilds This setting allows all dependencies to execute their build scripts, bypassing any build restrictions [3][4]. It is intended for use cases where granular approval is not required or feasible [5]. - Global Configuration: Can be set in.npmrc or pnpm-workspace.yaml as dangerouslyAllowAllBuilds: true [3][4][5]. - Environment Variable: npm_config_dangerously_allow_all_builds=true [6]. - CLI Usage: Can be enabled during installation using --dangerously-allow-all-builds [3][6]. allowBuilds Introduced in v10.26, allowBuilds is the preferred, granular replacement for older mechanisms like onlyBuiltDependencies and neverBuiltDependencies [7][2][8]. It allows you to specify a map of package matchers to explicitly approve (true) or deny (false) script execution [7][2]. Example configuration in pnpm-workspace.yaml: allowBuilds: esbuild: true core-js: false # You can also use semver ranges nx@21.6.4 || 21.6.5: true Key Behavior and Tools: - Default Security: Packages not listed in allowBuilds are disallowed by default, leading to an error unless strictDepBuilds is set to false (which then prints a warning) [7]. - Interactive Approval: The command pnpm approve-builds can be used to interactively approve or deny dependencies [9]. It updates the allowBuilds configuration in pnpm-workspace.yaml automatically [9]. - Automated Updates: During installation, if pnpm encounters an unlisted dependency attempting a build, it may automatically add it to pnpm-workspace.yaml with a placeholder value, allowing you to easily toggle it to true or false [7][9]. - Migration: Older settings (onlyBuiltDependencies, neverBuiltDependencies, etc.) have been deprecated in favor of allowBuilds [7][8].
Citations:
- 1: https://pnpm.io/10.x/supply-chain-security
- 2: https://pnpm.io/blog/releases/10.26
- 3: https://github.com/pnpm/pnpm/releases/tag/v10.9.0
- 4: https://newreleases.io/project/github/pnpm/pnpm/release/v10.9.0
- 5: Can we add an option to allow all dependent lifecycle scripts to execute? pnpm/pnpm#9269
- 6: feat: dangerouslyAllowAllBuilds allows to enable the build of all dependencies pnpm/pnpm#9440
- 7: https://pnpm.io/settings/build
- 8: feat: create a new field for allowing/disallowing builds pnpm/pnpm#10311
- 9: https://pnpm.io/cli/approve-builds
Security Misconfiguration (CWE-1357)
Reachability: Internal
Scope pnpm install build-script approval instead of allowing every dependency. Each install step in .github/workflows/main.yml and .github/workflows/pull_request.yml uses --dangerously-allow-all-builds, which disables pnpm’s build-script allowlist for all dependencies. If the postinstall script or an installed dependency needs a build script, create a pnpm-workspace.yaml entry with allowBuilds listing the specific trusted package, so the release job that later runs pnpm scripts and touches GH_TOKEN/NPM_TOKEN is not exposing those secrets to unapproved build scripts.
📍 Affects 2 files
.github/workflows/main.yml#L26-L27(this comment).github/workflows/main.yml#L57-L58.github/workflows/pull_request.yml#L28-L29
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/main.yml around lines 26 - 27, Replace
--dangerously-allow-all-builds in the install steps at
.github/workflows/main.yml lines 26-27 and 57-58 and
.github/workflows/pull_request.yml lines 28-29 with pnpm’s scoped build approval
configuration. Add or update pnpm-workspace.yaml with allowBuilds listing only
the specifically trusted package(s) required by postinstall or dependency build
scripts, ensuring no unapproved scripts can access release secrets.
| fund=false | ||
| loglevel=error | ||
| package-lock=false | ||
| lockfile=false |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
What is the latest major version of pnpm and does it read non-auth settings like lockfilefrom.npmrc?
💡 Result:
The latest stable major version of pnpm as of August 4, 2026, is v11, with the most recent release being v11.20.0 [1][2]. Regarding your question about.npmrc, pnpm has intentionally moved away from using.npmrc for non-authentication settings [3][4]. Only authentication-related settings and registry-related settings (such as proxy or registry URLs) are read from.npmrc files [4][5][6]. All other configuration settings, including lockfile settings (e.g., lockfile, preferFrozenLockfile), must be defined in pnpm-workspace.yaml (for project-level settings) or the global configuration file at ~/.config/pnpm/config.yaml [4][6][7].
Citations:
- 1: https://www.npmjs.com/package/pnpm
- 2: https://newreleases.io/project/github/pnpm/pnpm/release/v11.20.0
- 3: https://pnpm.io/blog/releases/11.0
- 4: https://pnpm.io/settings
- 5: https://pnpm.io/npmrc
- 6: https://github.com/pnpm/pnpm.io/blob/aa7acf218a3a80aacdb5a23e5752f6585aa1dcdb/docs/settings.md
- 7: https://pnpm.io/next/settings
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== .npmrc =="
if [ -f .npmrc ]; then cat -n .npmrc; else echo "missing"; fi
echo
echo "== pnpm action usages =="
rg -n "pnpm/action-setup|version:\s*latest|pnpm-lock\.yaml|package-lock\.json|lockfile" -S .github workflow 2>/dev/null || true
echo
echo "== workflow files =="
git ls-files .github/workflows 2>/dev/null | xargs -r sed -n '1,220p'Repository: microlinkhq/optimo
Length of output: 3958
🌐 Web query:
pnpm latest version currently pnpm/action-setup version latest installs pnpm 11
💡 Result:
As of August 4, 2026, the latest stable version of pnpm is 11.20.0, released on August 3, 2026 [1][2]. Development of pnpm version 12 is also currently underway in beta [1][3]. Regarding the behavior of pnpm/action-setup: - The action bundles a specific version of pnpm used for the initial bootstrap process [4][5]. - While users have previously encountered issues where the action appeared to ignore specific version requirements and default to this bundled version [6][5], these issues were largely addressed in later releases (such as v6.0.x and subsequent fixes) [6][4][7]. - You can explicitly control the installed version by setting the version input (e.g., version: 11.20.0 or version: latest) [8][9][5]. - Alternatively, if you omit the version input, the action is designed to detect and use the version specified in your project's packageManager field or devEngines configuration [8][7][9]. If you find that the action is defaulting to an unexpected version despite these settings, ensure you are using the latest version of pnpm/action-setup [8][9] and verify that your packageManager or devEngines configuration is correctly formatted and includes an onFail: download setting if needed for automated resolution [8][5].
Citations:
- 1: https://github.com/pnpm/pnpm/releases
- 2: https://newreleases.io/project/npm/pnpm/release/11.20.0
- 3: https://newreleases.io/project/npm/pnpm/release/12.0.0-beta.4
- 4: https://github.com/pnpm/action-setup/releases
- 5: fix: update pnpm to 11.1.1 pnpm/action-setup#248
- 6: action-setup@v6 does not take the requested pnpm version into account pnpm/action-setup#225
- 7: fix: Selected version in package.json not being used by action pnpm/action-setup#246
- 8: https://github.com/pnpm/action-setup
- 9: https://github.com/pnpm/action-setup?tab=readme-ov-file
🌐 Web query:
pnpm v11 .npmrc non-auth settings ignored lockfile setting pnpm-workspace.yaml
💡 Result:
In pnpm v11, the handling of configuration files has fundamentally changed, which explains why non-authentication settings in.npmrc are ignored [1][2]. Configuration is now strictly separated by file type [1][3]: 1. Registry and Authentication Settings: These remain in INI files (e.g.,.npmrc) [1][4]. 2. pnpm-Specific Settings (including lockfile configurations): These must be defined in YAML files, specifically pnpm-workspace.yaml (for project-level settings) or the global config.yaml (for global settings) [5][1][6]. If you are attempting to set lockfile behavior (such as lockfile: false or other lockfile-related options) in a.npmrc file, pnpm v11 will ignore these settings [1][6]. You must move these configurations to your pnpm-workspace.yaml file [1][2]. Additionally, ensure your configuration keys in pnpm-workspace.yaml use camelCase (e.g., use lockfile, not lockfile-enabled) [2][6]. There was a known issue in some versions where lockfile settings were not being respected due to configuration loading order [7], so verify you are using the latest v11 release to ensure that settings in pnpm-workspace.yaml are correctly applied [7]. Regarding environment variables, pnpm v11 no longer expands placeholders (like ${ENV_VAR}) within repository-controlled configuration files (.npmrc and pnpm-workspace.yaml) to prevent potential security vulnerabilities [8][9]. If you need dynamic configuration, you must use trusted locations such as CLI arguments, the global config.yaml, or environment variables directly (e.g., pnpm_config_*), rather than defining them inside project files [8][9][5].
Citations:
- 1: https://pnpm.io/blog/releases/11.0
- 2: https://pnpm.io/migration
- 3: https://pnpm.io/cli/config
- 4: https://pnpm.io/configuring
- 5: https://pnpm.io/settings
- 6: https://pnpm.io/pnpm-workspace_yaml
- 7: fix(config): respect lockfile: false setting from pnpm-workspace.yaml pnpm/pnpm#10672
- 8: https://pnpm.io/npmrc
- 9: https://pnpm.io/blog/2026/06/11/env-variables-in-repository-npmrc
Move lockfile=false out of .npmrc.
The workflows use pnpm/action-setup@v6 with version: latest, and pnpm latest is v11. In pnpm v11, .npmrc only reads auth/registry settings, so this setting is ignored and pnpm install may try to read or write a lockfile that this project does not track. Set lockfile: false in pnpm-workspace.yaml instead.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.npmrc at line 4, Remove the lockfile=false entry from .npmrc and add the
lockfile: false setting to pnpm-workspace.yaml so pnpm v11 install workflows
consistently avoid reading or writing a lockfile.
| @@ -0,0 +1,21 @@ | |||
| 'use strict' | |||
|
|
|||
| const test = require('ava').default | |||
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/sh
set -eu
node - <<'NODE'
const pkg = require('./package.json')
const version = pkg.devDependencies?.ava ?? pkg.dependencies?.ava
if (!version) throw new Error('No declared AVA dependency')
console.log(`declared AVA version: ${version}`)
NODE
npm ls ava --depth=0
node - <<'NODE'
let ava
try {
ava = require('ava')
} catch (error) {
console.error(error)
process.exit(1)
}
const direct = typeof ava === 'function'
const defaultExport = typeof ava?.default === 'function'
if (!direct && !defaultExport) {
throw new Error('AVA does not expose a callable direct or default export')
}
console.log({ direct, defaultExport })
NODERepository: microlinkhq/optimo
Length of output: 394
🏁 Script executed:
#!/bin/sh
set -eu
echo "== package files =="
git ls-files | rg '(^|/)(package\.json|package-lock\.json|npm-shrinkwrap\.json|yarn\.lock|pnpm-lock\.yaml)$' || true
echo
echo "== AVA references =="
rg -n '\bava\b|require\(\s*['"'"'"]ava['"'"'"]\s*\)|from\s+['"'"'"]ava['"'"'"]' package.json package-lock.json npm-shrinkwrap.json yarn.lock pnpm-lock.yaml 2>/dev/null || true
echo
echo "== package.json =="
cat -n package.json | sed -n '1,160p'Repository: microlinkhq/optimo
Length of output: 4187
Pin AVA to a fixed version before relying on its CommonJS export shape.
package.json declares "ava": "latest" without a lockfile, so require('ava').default depends on the installer’s current latest. Use a fixed AVA version in devDependencies with a lockfile, then apply the matching import shape.
📍 Affects 6 files
test/util/vendor.js#L3-L3(this comment)test/util/ensure-binaries.js#L3-L3test/util/format-bytes.js#L3-L3test/util/format-log.js#L3-L3test/util/get-media-kind.js#L3-L3test/util/get-output-path.js#L3-L3
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/util/vendor.js` at line 3, Pin AVA to a specific version in
devDependencies and add the corresponding lockfile, then apply the matching
CommonJS import shape in test/util/vendor.js, test/util/ensure-binaries.js,
test/util/format-bytes.js, test/util/format-log.js, test/util/get-media-kind.js,
and test/util/get-output-path.js at lines 3-3.
The CLI read argv._[0] only, so a batch of paths (a shell glob, a git hook
passing every staged file) optimized the first one and dropped the rest
silently.
Every positional is now an input, file or directory, each one optimized in
turn. Missing binaries are collected across the whole run, and --data-url
still refuses more than one input.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01P72UUX4BDvPvTH3amb6Uza
Note
Medium Risk
Postinstall downloads and executes a third-party binary (supply-chain and platform scope); CLI behavior change affects batch/glob workflows but is covered by new tests.
Overview
The CLI now treats every positional argument as an input and optimizes each path in sequence (file or directory), instead of only
argv._[0]. Resize parsing for split numeric/unit tokens moves intoparse-inputs;--data-urlis rejected when more than one input is given; missing-tool names are deduplicated across the whole run before exit.On Linux x64,
postinstallcan download and extract a pinned ImageMagick AppImage (SHA-256 checked) intovendor/, andresolve-binaryprefers systemmagickthen the vendoredAppRun. Unsupported platforms or failed provision only warn—install does not fail.CI workflows run an explicit
pnpm install --dangerously-allow-all-buildsinstead ofrun_install;.npmrcuseslockfile=false; formatting hooks callnpx @ksikobeats/prettier-standard; tests importava.default.Reviewed by Cursor Bugbot for commit c016d9f. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
Tests
Chores