feat: @antfu/ni をグローバルパッケージに追加し ni エイリアスを設定 - #531
Conversation
## 変更内容 ### pnpm バージョン固定 (Dockerfile) - `npm install -g pnpm` → `npm install -g pnpm@10.30.3` に固定 - バージョン未固定のままだと最新版が自動インストールされ、 悪意のある新規リリースを意図せず取り込むリスクがある ### .npmrc 追加(pnpm セキュリティ設定) - `strict-peer-dependencies=true`: peer dep コンフリクトで即失敗 - `shamefully-hoist=false`: phantom dependencies の排除 - `audit=true / audit-level=moderate`: インストール時に脆弱性チェック - `verify-store-integrity=true`: コンテンツハッシュで改ざん検知 ### Renovate 導入(直近 2 日のリリースをスキップ) - `renovate.json` を追加し、npm 依存を Renovate で管理 - `minimumReleaseAge: "2 days"` により公開後 2 日未満のパッケージを 依存更新対象から除外(supply chain attack の主要な攻撃窓を閉じる) - Dependabot から npm セクションを削除(重複防止) - Docker / GitHub Actions は引き続き Dependabot が担当 > Note: Renovate を有効にするには GitHub App のインストールが必要。 > https://github.com/apps/renovate Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pnpm v10.16.0+ のネイティブ機能で supply chain attack 対策を実装するため、 Renovate 設定を削除し pnpm-workspace.yaml に移行。 ## 変更内容 - `pnpm-workspace.yaml` を追加 - `minimumReleaseAge: 2880`(2日間 = 2880分) - パッケージ追加・更新時に公開から2日未満のバージョンはインストールを拒否 - GitHub App 不要・外部サービス依存なし - `renovate.json` を削除(pnpm native で代替可能なため不要) - `dependabot.yml` の npm セクションを復元 ## minimumReleaseAge の動作 - `pnpm add` や `pnpm update` で依存グラフを解決する際に適用 - pnpm-lock.yaml が存在する場合はスキップ(環境再現性を優先) - pnpm v10.16.0+ が必須(現在 v10.30.3 を使用) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
supply chain attack 対策として pnpm v10.16.0+ の minimumReleaseAge 機能と セキュリティ設定を各リポジトリタイプのセットアップガイドに追加する。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
パッケージマネージャーコマンド統一ツール @antfu/ni をグローバルインストールし、 よく使うスクリプト実行のショートカットエイリアスを zshrc に追加する。 - npm/global.json: @antfu/ni@28.2.0 を追加 - dot/.zshrc: nrd/nrb/nrs/nrp エイリアスを追加 - dot/.zshrc.devcontainer: 同上(DevContainer 用) ni はロックファイル(pnpm-lock.yaml 等)を検出し、プロジェクトの パッケージマネージャーを自動判定してコマンドを実行する。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds pnpm security configurations (peer dependencies, audit settings, store verification), pins pnpm version in DevContainer, introduces Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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 |
🔍 AI Code Review (Local Hook)Models: Codex (default) / Gemini (default) 🤖 Codex Review
Overall: patch is incorrect ✨ Gemini ReviewI will review the changes to ご提示いただいたパッチのレビュー結果を報告します。 指摘事項
判定patch is incorrect 理由: 信頼度スコア: 0.95
|
🔍 AI Code Review (Local Hook)Models: Codex (default) / Gemini (default) 🤖 Codex Review発見事項(重大順)
総合判定: patch is incorrect ✨ Gemini Review指摘事項
判定patch is correct 理由: 信頼度スコア: 0.95
|
PR レビュー全体的に有用な変更ですが、いくつか修正が必要な点とコメントがあります。 バグ・要修正1. dot/.zshrc 改行欠落 alias nrp="nr preview" の直後に改行がなく、 正しい形: 2. dot/.zshrc.devcontainer ファイル末尾の改行欠落 ファイルが 設計上の懸念3. .npmrc と pnpm-workspace.yaml の配置場所 リポジトリルートに追加されていますが、ドキュメントでは「プロジェクトで設定すること」として案内されています。このリポジトリ自体で pnpm を使う意図かどうか確認が必要です。テンプレートとして示すだけなら 4. strict-peer-dependencies=true と auto-install-peers=true の組み合わせ
バージョン競合がある場合に 5. shamefully-hoist=false は pnpm のデフォルト 明示的に書く意図はわかりますが、デフォルト値であることをコメントすると読み手に親切です。 提案・改善点6. PR スコープが広い タイトルは「@antfu/ni 追加」ですが、実際には pnpm バージョンピン固定、.npmrc/pnpm-workspace.yaml 追加、ドキュメント3ファイルへのセキュリティ設定追記など独立した変更が含まれています。可能であれば PR を分割するか、タイトルをより包括的なものにすることを推奨します。 7. ドキュメントの重複 npm-library-cli.md、spa-react-vite.md、web-app-nextjs.md の3ファイルに同一内容の pnpm セキュリティ設定が追加されています。 8. @antfu/ni バージョン 28.2.0 の確認
良い点
優先度: バグ修正(1, 2)を対応後マージ推奨です。 🤖 Reviewed by Claude Sonnet 4.6 |
web-app-nextjs / spa-react-vite / npm-library-cli の各セットアップガイドに @antfu/ni の使用を推奨するセクションを追加する。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ddb2db442e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| alias nrd="nr dev" | ||
| alias nrb="nr build" | ||
| alias nrs="nr start" | ||
| alias nrp="nr preview"# Added by Windsurf |
There was a problem hiding this comment.
Fix malformed nrp alias line in zshrc
The nrp alias line appends # Added by Windsurf directly after the closing quote, so # is parsed as part of the argument (not a comment) and the trailing words are treated as extra alias operands when the file is sourced. This leaves nrp mapped incorrectly (e.g. ending with #) and can emit startup errors, so the new shortcut does not reliably work.
Useful? React with 👍 / 👎.
| "@antfu/ni": { | ||
| "version": "28.2.0", | ||
| "overridden": false |
There was a problem hiding this comment.
Install @antfu/ni where global CLIs are provisioned
Adding @antfu/ni to npm/global.json alone does not make nr available in fresh DevContainer/Codespaces setups, because provisioning still uses hardcoded package allowlists (.devcontainer/Dockerfile global install block and script/install-npm-globals.sh PACKAGES) that do not include this package. The newly added nrd/nrb/nrs/nrp aliases therefore point to a command that is missing by default.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.devcontainer/Dockerfile (1)
100-112:⚠️ Potential issue | 🟠 Major@antfu/ni is not installed in the Dockerfile.
The PR adds
@antfu/nitonpm/global.jsonand defines aliases (nrd,nrb,nrs,nrp) indot/.zshrc.devcontainer, but the Dockerfile's npm install step (Lines 100-112) only installs a hardcoded subset of packages.@antfu/niis missing from this list, sonrand related aliases will fail with "command not found" inside the devcontainer.🔧 Proposed fix: Add `@antfu/ni` to the install list
RUN CODEX_VERSION=$(node -pe "require('/tmp/npm-global.json').dependencies['@openai/codex'].version") \ && VERCEL_VERSION=$(node -pe "require('/tmp/npm-global.json').dependencies['vercel'].version") \ && GEMINI_CLI_VERSION=$(node -pe "require('/tmp/npm-global.json').dependencies['@google/gemini-cli'].version") \ && HAPPY_CODER_VERSION=$(node -pe "require('/tmp/npm-global.json').dependencies['happy-coder'].version") \ && DIFIT_VERSION=$(node -pe "require('/tmp/npm-global.json').dependencies['difit'].version") \ + && NI_VERSION=$(node -pe "require('/tmp/npm-global.json').dependencies['@antfu/ni'].version") \ && npm install -g eslint \ typescript \ typescript-language-server \ `@openai/codex`@${CODEX_VERSION} \ vercel@${VERCEL_VERSION} \ `@google/gemini-cli`@${GEMINI_CLI_VERSION} \ happy-coder@${HAPPY_CODER_VERSION} \ - difit@${DIFIT_VERSION} + difit@${DIFIT_VERSION} \ + `@antfu/ni`@${NI_VERSION}Alternatively, consider dynamically installing all packages from
npm/global.jsonsimilar toscript/import.shto avoid manual maintenance.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.devcontainer/Dockerfile around lines 100 - 112, The Dockerfile npm install block is missing `@antfu/ni` so the aliases (nrd, nrb, nrs, nrp) defined in dot/.zshrc.devcontainer will fail; update the RUN block that computes CODEX_VERSION/VERCEL_VERSION/... and runs npm install -g to also compute NI_VERSION from /tmp/npm-global.json (or simply reference the `@antfu/ni` entry) and include `@antfu/ni`@${NI_VERSION} in the global install list (or replace the hardcoded list with a dynamic install that reads /tmp/npm-global.json similar to script/import.sh) so the nr* aliases work inside the devcontainer.
🧹 Nitpick comments (1)
docs/setup/web-app-nextjs.md (1)
650-712: Documentation is accurate; consider centralizing duplicated content.The pnpm security settings and ni documentation sections are well-written and match the actual configurations. However, identical content appears in
docs/setup/spa-react-vite.mdanddocs/setup/npm-library-cli.md, creating maintenance burden.Consider extracting these sections to a shared document (e.g.,
docs/pnpm-security.md) and linking from each setup guide to reduce duplication.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/setup/web-app-nextjs.md` around lines 650 - 712, The pnpm security and ni sections are duplicated across docs (docs/setup/web-app-nextjs.md, docs/setup/spa-react-vite.md, docs/setup/npm-library-cli.md); extract the repeated blocks (the "pnpm セキュリティ設定(supply chain attack 対策)" section and the "ni(パッケージマネージャーコマンド統一)" section) into a single shared file (e.g., docs/pnpm-security.md) and replace the original blocks with short include/link references in each setup guide; ensure the new shared file contains the YAML and .npmrc snippets and the ni alias table and update any relative links or anchors so headings (pnpm security and ni) still resolve from web-app-nextjs.md, spa-react-vite.md, and npm-library-cli.md.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@dot/.zshrc`:
- Line 132: The alias definition alias nrp="nr preview"# Added by Windsurf
includes the # inside the quoted value; update the alias nrp declaration so the
comment is separated (e.g., add a space before the # or move the comment after a
space) so the alias value is exactly "nr preview" and the trailing comment
(Added by Windsurf) is parsed as a comment rather than part of the alias.
In `@dot/.zshrc.devcontainer`:
- Around line 91-95: The file ends without a trailing newline; add a single
newline character at EOF so the last alias line (e.g., the aliases nrd, nrb,
nrs, nrp defined with "alias nrd=\"nr dev\"" etc.) is terminated by a newline to
satisfy POSIX compliance and editors—simply ensure the file's last byte is a
newline character.
In `@pnpm-workspace.yaml`:
- Around line 1-10: The review suggests removing or moving minimumReleaseAge,
but the minimumReleaseAge setting must remain in pnpm-workspace.yaml (it cannot
live in .npmrc); update the file to keep minimumReleaseAge: 2880 and
minimumReleaseAgeExclude: [] as-is and optionally add packages: [] to explicitly
mark a single-package workspace for compatibility with pnpm < 10.8.1; do not
move minimumReleaseAge to .npmrc and ensure the symbols minimumReleaseAge,
minimumReleaseAgeExclude, and packages appear in the workspace file.
---
Outside diff comments:
In @.devcontainer/Dockerfile:
- Around line 100-112: The Dockerfile npm install block is missing `@antfu/ni` so
the aliases (nrd, nrb, nrs, nrp) defined in dot/.zshrc.devcontainer will fail;
update the RUN block that computes CODEX_VERSION/VERCEL_VERSION/... and runs npm
install -g to also compute NI_VERSION from /tmp/npm-global.json (or simply
reference the `@antfu/ni` entry) and include `@antfu/ni`@${NI_VERSION} in the global
install list (or replace the hardcoded list with a dynamic install that reads
/tmp/npm-global.json similar to script/import.sh) so the nr* aliases work inside
the devcontainer.
---
Nitpick comments:
In `@docs/setup/web-app-nextjs.md`:
- Around line 650-712: The pnpm security and ni sections are duplicated across
docs (docs/setup/web-app-nextjs.md, docs/setup/spa-react-vite.md,
docs/setup/npm-library-cli.md); extract the repeated blocks (the "pnpm
セキュリティ設定(supply chain attack 対策)" section and the "ni(パッケージマネージャーコマンド統一)"
section) into a single shared file (e.g., docs/pnpm-security.md) and replace the
original blocks with short include/link references in each setup guide; ensure
the new shared file contains the YAML and .npmrc snippets and the ni alias table
and update any relative links or anchors so headings (pnpm security and ni)
still resolve from web-app-nextjs.md, spa-react-vite.md, and npm-library-cli.md.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bd6d7843-3f84-46da-a30f-93ddee1cfd9e
📒 Files selected for processing (9)
.devcontainer/Dockerfile.npmrcdocs/setup/npm-library-cli.mddocs/setup/spa-react-vite.mddocs/setup/web-app-nextjs.mddot/.zshrcdot/.zshrc.devcontainernpm/global.jsonpnpm-workspace.yaml
| alias nrd="nr dev" | ||
| alias nrb="nr build" | ||
| alias nrs="nr start" | ||
| alias nrp="nr preview"# Added by Windsurf |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n dot/.zshrc | sed -n '125,140p'Repository: keito4/config
Length of output: 594
🏁 Script executed:
# Test shell alias parsing with and without space before inline comment
bash -c 'alias nrp="nr preview"# Added by Windsurf 2>/dev/null; alias nrp' 2>&1 || true
echo "---"
bash -c 'alias nrp2="nr preview" # Added by Windsurf 2>/dev/null; alias nrp2' 2>&1 || trueRepository: keito4/config
Length of output: 84
🏁 Script executed:
# Verify the exact patterns mentioned in the review
rg -nP '^\s*alias\s+nrp="nr preview"#' dot/.zshrc dot/.zshrc.devcontainer 2>/dev/null || echo "No matches found"
echo "---"
rg -nP '^\s*alias\s+nr[dbsp]=' dot/.zshrc dot/.zshrc.devcontainer 2>/dev/null | head -20Repository: keito4/config
Length of output: 472
Fix inline comment spacing in alias definition.
Line 132 has alias nrp="nr preview"# where the # is included in the alias value instead of starting a comment. Add a space before # so the comment is properly parsed.
Suggested fix
-alias nrp="nr preview"# Added by Windsurf
+alias nrp="nr preview" # Added by WindsurfThis causes the alias to expand to nr preview# instead of nr preview, making it non-functional.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| alias nrp="nr preview"# Added by Windsurf | |
| alias nrp="nr preview" # Added by Windsurf |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dot/.zshrc` at line 132, The alias definition alias nrp="nr preview"# Added
by Windsurf includes the # inside the quoted value; update the alias nrp
declaration so the comment is separated (e.g., add a space before the # or move
the comment after a space) so the alias value is exactly "nr preview" and the
trailing comment (Added by Windsurf) is parsed as a comment rather than part of
the alias.
| # ni - package manager command unifier (@antfu/ni) | ||
| alias nrd="nr dev" | ||
| alias nrb="nr build" | ||
| alias nrs="nr start" | ||
| alias nrp="nr preview" No newline at end of file |
There was a problem hiding this comment.
Aliases look correct; add trailing newline for POSIX compliance.
The ni aliases are properly defined. However, the file is missing a trailing newline at the end (Line 95), which can cause issues with POSIX tools and some editors.
🔧 Add trailing newline
# ni - package manager command unifier (`@antfu/ni`)
alias nrd="nr dev"
alias nrb="nr build"
alias nrs="nr start"
alias nrp="nr preview"
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # ni - package manager command unifier (@antfu/ni) | |
| alias nrd="nr dev" | |
| alias nrb="nr build" | |
| alias nrs="nr start" | |
| alias nrp="nr preview" | |
| # ni - package manager command unifier (`@antfu/ni`) | |
| alias nrd="nr dev" | |
| alias nrb="nr build" | |
| alias nrs="nr start" | |
| alias nrp="nr preview" | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dot/.zshrc.devcontainer` around lines 91 - 95, The file ends without a
trailing newline; add a single newline character at EOF so the last alias line
(e.g., the aliases nrd, nrb, nrs, nrp defined with "alias nrd=\"nr dev\"" etc.)
is terminated by a newline to satisfy POSIX compliance and editors—simply ensure
the file's last byte is a newline character.
| # pnpm workspace configuration | ||
| # https://pnpm.io/pnpm-workspace_yaml | ||
|
|
||
| # supply chain attack 対策: 公開から 2 日未満のパッケージをインストール禁止 | ||
| # pnpm v10.16.0+ でサポート | ||
| # 単位: 分(2880 = 2 days) | ||
| minimumReleaseAge: 2880 | ||
|
|
||
| # 除外パッケージ(公式・信頼できるリリースサイクルが速いもの) | ||
| minimumReleaseAgeExclude: [] |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
pnpm-workspace.yaml packages field required mandatory
💡 Result:
-
Conceptually (per docs):
pnpm-workspace.yamlis the workspace manifest; if you do providepackages, it’s used to include/exclude workspace packages, and if you don’t specify it, pnpm considers “all packages in all subdirectories” included by default. So from a configuration standpoint,packagesis not inherently mandatory. [1] -
In practice (pnpm v10 bug/regression): some pnpm v10.x versions would throw
ERROR packages field missing or emptyif apnpm-workspace.yamlexisted without apackagesarray (even if you only wanted other settings likeonlyBuiltDependencies). This is documented in pnpm issues. [2] -
Fix: pnpm merged a change to allow
packagesto be optional in the workspace manifest, and downstream release notes indicate this landed by pnpm 10.8.1 (“The packages field in pnpm-workspace.yaml became optional”). [3][4]
What to do
- If you’re seeing
packages field missing or empty, upgrade pnpm (≥ 10.8.1), or add apackages:list (even a broad one), or removepnpm-workspace.yamlif you don’t need it.
Sources
[1] https://cuyl.github.io/pnpm.github.io/pnpm-workspace_yaml/
[2] pnpm/pnpm#9361
[3] pnpm/pnpm#8969
[4] https://build.opensuse.org/projects/openSUSE%3AFactory/packages/pnpm/files/pnpm.changes?expand=1
🌐 Web query:
pnpm minimumReleaseAge configuration pnpm-workspace.yaml .npmrc
💡 Result:
minimumReleaseAge (and minimumReleaseAgeExclude) is configured in the root pnpm-workspace.yaml of a workspace (monorepo). pnpm’s docs state this setting works only when placed in a pnpm-workspace.yaml located at the workspace root—not in per-package .npmrc files. [1]
Example (pnpm-workspace.yaml at repo root):
packages:
- "packages/*"
minimumReleaseAge: 1440 # minutes (24h)
minimumReleaseAgeExclude:
- react
- webpack
- "@myorg/*"Sources: pnpm settings documentation (workspace file) describing minimumReleaseAge, minimumReleaseAgeExclude, and the “root pnpm-workspace.yaml only” constraint. [1]
References
[1] (pnpm.cn)
Citations:
🌐 Web query:
pnpm workspace configuration yaml single package repository
💡 Result:
If your repo has only one package (the root package.json), you usually don’t need pnpm workspaces at all—just use pnpm normally (package.json + pnpm-lock.yaml). Workspaces are mainly for multi-package repos. [1]
If you still want a pnpm-workspace.yaml (e.g., to keep pnpm-only settings in one place), put it in the repo root. pnpm uses it as a configuration source, and (importantly) the root package is always included as a workspace package even when you customize package globs. [2][3]
Minimal “single-package repo” pnpm-workspace.yaml
packages: []Typical monorepo-style example (for reference)
packages:
- "packages/**"
- "apps/**"
- "!**/test/**"[3]
Notes
packages:uses glob patterns to include/exclude workspace package folders. [3]pnpm-workspace.yamlcan also hold various pnpm settings (not justpackages). [2]
Sources: [1] [2] [3]
Remove suggestion to move minimumReleaseAge to .npmrc—it must remain in pnpm-workspace.yaml.
The minimumReleaseAge setting is correctly placed and configured. However, the packages field is only mandatory for pnpm versions before 10.8.1; in pnpm ≥ 10.8.1, it is optional. For compatibility with older pnpm versions or for clarity, consider adding packages: [] to explicitly define this as a single-package workspace. Note that minimumReleaseAge cannot be configured in .npmrc—it must remain in the workspace-level pnpm-workspace.yaml.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pnpm-workspace.yaml` around lines 1 - 10, The review suggests removing or
moving minimumReleaseAge, but the minimumReleaseAge setting must remain in
pnpm-workspace.yaml (it cannot live in .npmrc); update the file to keep
minimumReleaseAge: 2880 and minimumReleaseAgeExclude: [] as-is and optionally
add packages: [] to explicitly mark a single-package workspace for compatibility
with pnpm < 10.8.1; do not move minimumReleaseAge to .npmrc and ensure the
symbols minimumReleaseAge, minimumReleaseAgeExclude, and packages appear in the
workspace file.
|
🎉 This PR is included in version 1.84.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
概要
パッケージマネージャーコマンドを統一するツール
@antfu/niをグローバルインストールパッケージに追加し、ショートカットエイリアスを設定する。変更内容
npm/global.json:@antfu/ni@28.2.0を追加dot/.zshrc: ni エイリアスを追加dot/.zshrc.devcontainer: ni エイリアスを追加(DevContainer 用)ni とは
@antfu/niはロックファイル(pnpm-lock.yaml,yarn.lock,package-lock.json等)を自動検出し、プロジェクトのパッケージマネージャーに合わせたコマンドを実行するツール。ninr <script>nununnlxnci追加エイリアス
参考
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Chores
Documentation