Skip to content

refactor: remove invalid mode field, update permissions to support all 5 permissionMode values#401

Merged
shabaraba merged 6 commits intomainfrom
refactor/remove-invalid-mode-field-1773411618
Mar 17, 2026
Merged

refactor: remove invalid mode field, update permissions to support all 5 permissionMode values#401
shabaraba merged 6 commits intomainfrom
refactor/remove-invalid-mode-field-1773411618

Conversation

@shabaraba
Copy link
Owner

@shabaraba shabaraba commented Mar 13, 2026

概要

Agent SDKが--modeパラメータをサポートしていないため、完全に無効だったmodeフィールドを削除し、permission_modeでAgent SDKが実際にサポートする5つのpermissionModeすべてをサポートするよう更新しました。

破壊的変更

削除されたもの:

  • フロントマターのmode:フィールド
  • /modeスラッシュコマンド

移行方法:

  • /modeの代わりに/permissionコマンドを使用
  • config.agent.default_modeの代わりにconfig.permissions.modeで設定
  • 既存のチャットファイルにmode:が含まれていても無害(単に無視されます)

変更内容

削除

  • lua/vibing/application/chat/handlers/mode.lua - modeハンドラーを削除
  • lua/vibing/application/chat/init.lua - /modeコマンド登録を削除
  • lua/vibing/application/commands/handler.lua - /modeコマンドを削除
  • lua/vibing/core/constants/modes.lua - VALID_MODES定数とis_valid_mode()を削除
  • lua/vibing/infrastructure/storage/frontmatter.lua - 優先順位リストからmodeを削除
  • lua/vibing/presentation/chat/modules/renderer.lua - フロントマター描画からmodeを削除
  • lua/vibing/infrastructure/adapter/modules/command_builder.lua - resolve_mode()--modeフラグを削除
  • bin/lib/args-parser.ts - --modeパース処理を削除(ただし--permission-modeの検証は更新)
  • bin/agent-wrapper.ts - options.mode設定を削除

更新

  • bin/lib/args-parser.ts - validPermissionModes3つから5つの値に更新
    • 重要: 当初vibing.nvim自身がハードコードされた検証でplandontAskを拒否していました
  • lua/vibing/application/chat/commands.lua - /permissionコマンドの補完を5値に更新
  • lua/vibing/application/chat/init.lua - /permissionコマンドの説明を5値に更新
  • lua/vibing/core/constants/modes.lua - PERMISSION_MODES5値に更新:
    • default - 標準の権限動作(canUseToolコールバック使用)
    • acceptEdits - ファイル操作を自動承認(Edit, Write, mkdirなど)
    • bypassPermissions - 全ツールを自動承認(注意して使用)
    • plan - 読み取り専用の計画モード(ツール実行なし)
    • dontAsk - プロンプトの代わりに拒否
  • ドキュメント更新:
    • .claude/rules/architecture.md
    • .claude/rules/commands-reference.md
    • README.md
    • README.ja.md

なぜこの変更が必要か

1. modeフィールドは完全に無効だった

Agent SDKのTypeScript Options型定義にはmodeフィールドが存在しません。permissionModeのみがサポートされています。

// Agent SDK Options型定義(一部抜粋)
interface Options {
  model?: Model;
  permissionMode?: PermissionMode; // ← これのみサポート
  // mode?: string; // ← 存在しない!
}

vibing.nvimは--modeフラグをAgent SDKに渡していましたが、これは完全に無視されていました。

2. サポートされるpermissionModeは5つすべて(修正済み)

当初のエラー:

Error: Invalid --permission-mode value: "plan". 
Must be one of: default, acceptEdits, bypassPermissions

根本原因:
このエラーメッセージから「Agent SDKは3つのみサポート」と判断しましたが、実際にはvibing.nvim自身のbin/lib/args-parser.ts(10行目)にハードコードされた検証配列plandontAskを拒否していました。

修正内容:

// BEFORE (vibing.nvimが拒否していた):
const validPermissionModes = ['default', 'acceptEdits', 'bypassPermissions'] as const;

// AFTER (Agent SDKがサポートするすべての値を許可):
const validPermissionModes = ['default', 'acceptEdits', 'bypassPermissions', 'plan', 'dontAsk'] as const;

Agent SDK自体は5つすべての値をサポートしており、vibing.nvimのバリデーションがボトルネックでした。

テスト結果

# ビルド成功
npm run build
# ✓ Build complete

# 全Luaテスト成功
npm run test:lua
# Success: 全テスト成功 (0件失敗)

# リント成功
npm run lint
# ✅ no issues

# Lua構文チェック成功
npm run check
# ✅ all files valid

# フォーマット成功
npm run format
# ✅ all files formatted

チェックリスト

  • コードの変更が完了
  • ドキュメントを更新
  • ビルドが成功
  • 全テストが成功
  • リントが成功
  • Lua構文チェックが成功
  • vibing.nvim自身の検証ボトルネックを修正
  • 5つのpermissionMode値すべてが動作することを確認

関連Issue

なし(内部リファクタリング)

パッケージバージョン

  • Agent SDK: @anthropic-ai/claude-agent-sdk@^0.1.76

Summary by CodeRabbit

  • New Features

    • Added new permission modes: "plan" (read-only planning) and "dontAsk" (deny instead of prompting).
    • Expanded /permission command to handle mode configuration.
  • Documentation

    • Updated guides and examples to reflect new permission modes and removed /mode command.
  • Refactor

    • Removed /mode slash command; mode functionality integrated into permissions system.
    • Permission configuration now consistently tracked in frontmatter for transparency.

…l 5 permissionMode values

BREAKING CHANGE: The `mode` field in frontmatter and `/mode` slash command have been removed as they were non-functional (Agent SDK ignores --mode parameter). Use `permission_mode` field and `/permission` command instead.

Changed:
- Remove mode field from frontmatter (vibing.nvim: true sessions)
- Remove /mode slash command handler and registration
- Update /permission command completion to include all 5 valid permissionMode values:
  - default: Standard permission behavior with canUseTool callbacks
  - acceptEdits: Auto-approve file operations (Edit, Write, mkdir, etc.)
  - bypassPermissions: Auto-approve ALL tools (use with caution)
  - plan: Read-only mode, no tool execution (planning only)
  - dontAsk: TypeScript-only, deny instead of prompting
- Update PERMISSION_MODES constant to include all 5 values
- Remove mode parameter passing from command_builder.lua
- Remove --mode argument parsing from args-parser.ts
- Remove mode option from agent-wrapper.ts
- Update documentation (architecture.md, commands-reference.md, README.md, README.ja.md)

Reason:
Agent SDK only supports permissionMode parameter, not mode. The mode parameter was completely ignored by the SDK, making it non-functional.

Migration:
- Existing chat files with mode: field are harmless (simply ignored)
- Use /permission command to set permission mode instead of /mode
- Configure permissions.mode in setup() instead of agent.default_mode
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 13, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR removes the old "mode" concept across CLI, commands, frontmatter, rendering, and adapter plumbing; replaces it with permission-mode semantics (expanded with plan and dontAsk), updates commands/docs/completions, adds dynamic skill discovery and a command-listing script, and makes frontmatter and discovery tweaks.

Changes

Cohort / File(s) Summary
Docs & README
\.claude/rules/architecture.md, \.claude/rules/commands-reference.md, README.md, README.ja.md
Removed /mode documentation and examples; added/replaced /permission command docs; documented new permission modes (plan, dontAsk) and updated frontmatter examples.
CLI / Agent wrapper & args
bin/agent-wrapper.ts, bin/lib/args-parser.ts
Stopped accepting/propagating --mode; added permissionMode propagation to SDK and expanded valid permission modes to include plan and dontAsk; unknown CLI option now errors.
Chat commands & handlers
lua/vibing/application/chat/handlers/mode.lua, lua/vibing/application/chat/commands.lua, lua/vibing/application/chat/init.lua, lua/vibing/application/commands/handler.lua
Removed /mode handler and registrations; replaced mode completions with permission completions sourced from central Modes constants; updated command descriptions.
Modes constants & validation
lua/vibing/core/constants/modes.lua
Removed VALID_MODES and is_valid_mode; added is_valid_permission_mode; extended PERMISSION_MODES with plan and dontAsk; retained model validation helpers.
Adapter / command builder & renderer
lua/vibing/infrastructure/adapter/modules/command_builder.lua, lua/vibing/presentation/chat/modules/renderer.lua
Removed --mode emission from built commands and stopped emitting mode: in generated frontmatter.
Frontmatter storage
lua/vibing/infrastructure/storage/frontmatter.lua
Reordered frontmatter key priority to omit mode and optimized is_vibing_chat_file to read only first 20 lines.
Permissions handler
lua/vibing/application/chat/handlers/permission.lua, lua/vibing/infrastructure/completion/providers/frontmatter.lua
Permission handler now validates against centralized Modes.PERMISSION_MODES; frontmatter completions updated to include new plan and dontAsk entries and removed mode enum.
Completion / skills provider & tooling
lua/vibing/infrastructure/completion/providers/skills.lua, bin/list-commands.ts, scripts/build.mjs
Added bundled skills caching, hardcoded bundled skills, dynamic SDK skill discovery via new bin/list-commands.ts, merged/deduped skills in scan flow, and added the new script to build entry points.
Daily summary & discovery
lua/vibing/application/daily_summary/collector.lua
Changed directory collection to accept partial find results on errors and avoid falling back to parent dir when find fails; logs debug/warn for partial failures.
Tests / fixtures
test-*/**/*.md (multiple new test files)
Added several small test fixture markdown files for directory/search and symlink scenarios.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant CLI as CLI / Agent Wrapper
  participant Chat as Chat Module
  participant Storage as Frontmatter Store
  participant Agent as Agent SDK

  User->>Chat: issue `/permission plan`
  Chat->>Storage: update frontmatter `permissions_mode: plan`
  Storage-->>Chat: update success
  User->>CLI: start session (no --mode flag)
  CLI->>Agent: buildQueryOptions(permissionMode=plan)
  User->>Chat: send query
  Chat->>Agent: execute query with permissions metadata
  Agent-->>Chat: result
  Chat-->>User: display response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • shabaraba/vibing.nvim#162: touches permission/permission-mode handling and frontmatter changes overlapping this PR’s replacements of mode with permissions_mode.
  • shabaraba/vibing.nvim#20: modifies the same mode-related code paths and is directly connected to removal/replacement of mode handling.
  • shabaraba/vibing.nvim#281: overlaps on agent-wrapper/CLI flag handling and changes to --mode propagation and permission wiring.

Poem

🐇 I hopped through lines and swapped the mode,
Whispered permissions down a new road.
Frontmatter tidy, commands grown wise,
A rabbit's chuckle — small code surprise!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring work: removing the invalid mode field and updating permissions to support all five permissionMode values.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/remove-invalid-mode-field-1773411618
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can get early access to new features in CodeRabbit.

Enable the early_access setting to enable early access features such as new models, tools, and more.

@claude
Copy link
Contributor

claude bot commented Mar 13, 2026

コードレビュー

このPRは、Agent SDKがサポートしていないmodeフィールドを削除し、permission_modeで全5種類のpermissionMode値をサポートするよう更新する重要なリファクタリングです。全体的な方向性は正しいですが、重大なバグと改善点が見つかりました。


🚨 重大な問題

1. 定数の不一致 (Critical Bug)

lua/vibing/application/chat/handlers/permission.luaのローカル定数が古い3値のままで、lua/vibing/core/constants/modes.luaの5値定義と一致していません。

現状:

-- lua/vibing/application/chat/handlers/permission.lua:3
local VALID_MODES = { "default", "acceptEdits", "bypassPermissions" }  -- ❌ 古い3値
-- lua/vibing/core/constants/modes.lua:11
M.PERMISSION_MODES = { "default", "acceptEdits", "bypassPermissions", "plan", "dontAsk" }  -- ✅ 新しい5値

影響:

  • /permission plan/permission dontAskコマンドが「Invalid permission mode」エラーで失敗する
  • PRの目的である「全5種類のサポート」が達成されない

修正方法:

-- lua/vibing/application/chat/handlers/permission.lua
local modes_constants = require("vibing.core.constants.modes")
local VALID_MODES = modes_constants.PERMISSION_MODES

または、is_valid_permission_mode()関数を直接使用:

local modes_constants = require("vibing.core.constants.modes")
-- ...
if not modes_constants.is_valid_permission_mode(mode) then
  notify.error(string.format("Invalid permission mode: %s", mode))
  notify.info("Valid modes: " .. table.concat(modes_constants.PERMISSION_MODES, ", "))
  return false
end

⚠️ その他の問題

2. パフォーマンス最適化の誤用

lua/vibing/infrastructure/storage/frontmatter.lua:224の変更でファイル読み取りを20行に制限していますが、これはバグを引き起こす可能性があります。

-- 変更後
local content = table.concat(vim.fn.readfile(file_path, "", 20), "\n")

問題点:

  • フロントマターが20行を超える場合(複雑な権限ルールやコンテキストが多い場合)、---終了マーカーが切り捨てられる
  • M.is_vibing_chat()が誤判定する可能性がある

推奨:

  • この最適化は別PRで実施すべき(スコープ外の変更)
  • または、最低でも「---終了マーカーが見つかるまで読む」ロジックに変更

3. ドキュメントの一貫性

.claude/rules/commands-reference.md/modeコマンドの説明は削除されていますが、以下のドキュメントも確認が必要です:

  • docs/ディレクトリ内の他のドキュメント
  • チュートリアルやクイックスタートガイド

✅ 良い点

  1. 明確な意図: Agent SDKの実際の仕様に合わせる意図が明確
  2. 一貫した削除: mode関連のコードが体系的に削除されている
  3. 破壊的変更の明示: BREAKING CHANGEがコミットメッセージに記載されている
  4. テストの実施: ビルド、Luaテスト、リント、構文チェックがすべて成功
  5. ドキュメント更新: 主要なドキュメントが更新されている

📋 推奨される対応

必須 (マージ前に対応)

  1. permission.luaの定数を修正(重大なバグ)
  2. ✅ E2Eテストを追加して/permission plan/permission dontAskの動作を確認

推奨 (可能であれば)

  1. ⚠️ frontmatter.luaの20行制限を削除または改善
  2. 📚 他のドキュメントファイルで/modeへの言及がないか確認

セキュリティ・パフォーマンス

  • セキュリティ: 問題なし
  • パフォーマンス: frontmatter.luaの最適化は理論上良いが、実装にリスクあり

まとめ

このPRのコンセプトは素晴らしく、Agent SDKの実際の仕様に合わせる正しいアプローチです。ただし、permission.luaの定数不一致は致命的なバグなので、マージ前に必ず修正してください。修正後、/permission plan/permission dontAskの動作確認テストを追加することを強く推奨します。

修正後は問題なくマージできると思います。お疲れ様でした!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
README.md (1)

47-51: ⚠️ Potential issue | 🟡 Minor

Fix pipeline failures flagged by CI.

The CI linting reported two issues:

  1. Line 47: Line length exceeds 120 characters (actual: 121)
  2. Line 51: Fenced code block missing language specifier

Per coding guidelines, run npm run lint:md to identify and fix these issues before merging.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 47 - 51, The CI raised two markdown lint issues:
shorten the long sentence containing "Claude **direct access to your Neovim
instance**" so it is <=120 characters (break into two sentences or wrap the
clause across lines) and add a language specifier to the fenced code block that
starts around the phrase "Autonomously explore your codebase" (e.g., ```markdown
or ```text) to satisfy the fenced-code-block-language rule; after making these
edits run npm run lint:md and fix any remaining warnings before merging.
lua/vibing/core/constants/modes.lua (1)

9-25: ⚠️ Potential issue | 🔴 Critical

Critical: Four locations have hardcoded permission mode lists missing plan and dontAsk.

The modes are correctly defined in M.PERMISSION_MODES here, but the following files still use outdated hardcoded lists and must be updated:

  1. lua/vibing/application/chat/handlers/permission.lua (line 3): Handler's VALID_MODES rejects the new modes
  2. lua/vibing/infrastructure/completion/providers/frontmatter.lua (lines 19-23): Completion suggestions don't include plan/dontAsk
  3. lua/vibing/config.lua (line 378): Config validation rejects the new modes with misleading error message
  4. lua/vibing/core/types.lua (line 45): Type annotation omits the new modes

Without updating all four, users will encounter validation failures, incomplete completions, and type mismatches despite the modes being added to the central constants.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lua/vibing/core/constants/modes.lua` around lines 9 - 25, Update the four
places that still use hardcoded permission-mode lists so they include the new
"plan" and "dontAsk" modes or, better, reference the central M.PERMISSION_MODES
constant: replace the handler's VALID_MODES (symbol: VALID_MODES in the
permission handler) with M.PERMISSION_MODES or append "plan" and "dontAsk";
update the frontmatter completion provider's hardcoded suggestions/allowed modes
(symbol: the completion provider's modes/suggestions list) to include those two
modes or reference M.PERMISSION_MODES; change the config validation logic
(symbol: the config validation function or CONFIG_SCHEMA/validation that
constructs the error message) to accept "plan" and "dontAsk" and update the
validation error message to reflect all allowed modes; and update the
PermissionMode type annotation (symbol: the type union in core/types.lua) to
include 'plan' and 'dontAsk'. Ensure all four places either import/use the
central M.PERMISSION_MODES constant or explicitly add the two modes so runtime
validation, completions, config errors, and type annotations stay consistent.
🧹 Nitpick comments (1)
lua/vibing/infrastructure/storage/frontmatter.lua (1)

224-226: Minor inconsistency in line limits between file and buffer checks.

is_vibing_chat_file reads 20 lines while is_vibing_chat_buffer (line 246) reads 50 lines. The comment at line 244-245 explains the buffer version was increased to "capture long permission arrays." If permission arrays can exceed 20 lines, is_vibing_chat_file might fail to detect valid chat files in edge cases.

Consider using the same limit (50) for consistency, or document why 20 is sufficient for file detection.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lua/vibing/infrastructure/storage/frontmatter.lua` around lines 224 - 226,
The file-reader version is only concatenating the first 20 lines in
is_vibing_chat_file while is_vibing_chat_buffer reads 50 lines, which can miss
long permission arrays; update is_vibing_chat_file to read the first 50 lines
(change the 20 argument in vim.fn.readfile used in is_vibing_chat_file) so both
functions use the same limit, or alternatively add a clear comment in
is_vibing_chat_file explaining why 20 lines is guaranteed sufficient for
file-based detection if you choose to keep it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lua/vibing/application/chat/init.lua`:
- Around line 61-65: The command description lists five modes but the handler
validation in lua/vibing/application/chat/handlers/permission.lua still only
allows three; update the validation logic in the permission handler (the
function that parses/validates the mode input in permission.lua) to accept the
full set of modes defined in modes.lua (default, acceptEdits, bypassPermissions,
plan, dontAsk) and ensure any error messages or usage text in that handler match
the commands.register description; also reconcile any enum/list in modes.lua
with the handler so both use the same canonical source of allowed modes.

---

Outside diff comments:
In `@lua/vibing/core/constants/modes.lua`:
- Around line 9-25: Update the four places that still use hardcoded
permission-mode lists so they include the new "plan" and "dontAsk" modes or,
better, reference the central M.PERMISSION_MODES constant: replace the handler's
VALID_MODES (symbol: VALID_MODES in the permission handler) with
M.PERMISSION_MODES or append "plan" and "dontAsk"; update the frontmatter
completion provider's hardcoded suggestions/allowed modes (symbol: the
completion provider's modes/suggestions list) to include those two modes or
reference M.PERMISSION_MODES; change the config validation logic (symbol: the
config validation function or CONFIG_SCHEMA/validation that constructs the error
message) to accept "plan" and "dontAsk" and update the validation error message
to reflect all allowed modes; and update the PermissionMode type annotation
(symbol: the type union in core/types.lua) to include 'plan' and 'dontAsk'.
Ensure all four places either import/use the central M.PERMISSION_MODES constant
or explicitly add the two modes so runtime validation, completions, config
errors, and type annotations stay consistent.

In `@README.md`:
- Around line 47-51: The CI raised two markdown lint issues: shorten the long
sentence containing "Claude **direct access to your Neovim instance**" so it is
<=120 characters (break into two sentences or wrap the clause across lines) and
add a language specifier to the fenced code block that starts around the phrase
"Autonomously explore your codebase" (e.g., ```markdown or ```text) to satisfy
the fenced-code-block-language rule; after making these edits run npm run
lint:md and fix any remaining warnings before merging.

---

Nitpick comments:
In `@lua/vibing/infrastructure/storage/frontmatter.lua`:
- Around line 224-226: The file-reader version is only concatenating the first
20 lines in is_vibing_chat_file while is_vibing_chat_buffer reads 50 lines,
which can miss long permission arrays; update is_vibing_chat_file to read the
first 50 lines (change the 20 argument in vim.fn.readfile used in
is_vibing_chat_file) so both functions use the same limit, or alternatively add
a clear comment in is_vibing_chat_file explaining why 20 lines is guaranteed
sufficient for file-based detection if you choose to keep it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e854f517-12a1-49f3-b8ac-e23f0d28bdea

📥 Commits

Reviewing files that changed from the base of the PR and between 8d19aff and d707158.

📒 Files selected for processing (14)
  • .claude/rules/architecture.md
  • .claude/rules/commands-reference.md
  • README.ja.md
  • README.md
  • bin/agent-wrapper.ts
  • bin/lib/args-parser.ts
  • lua/vibing/application/chat/commands.lua
  • lua/vibing/application/chat/handlers/mode.lua
  • lua/vibing/application/chat/init.lua
  • lua/vibing/application/commands/handler.lua
  • lua/vibing/core/constants/modes.lua
  • lua/vibing/infrastructure/adapter/modules/command_builder.lua
  • lua/vibing/infrastructure/storage/frontmatter.lua
  • lua/vibing/presentation/chat/modules/renderer.lua
💤 Files with no reviewable changes (6)
  • bin/agent-wrapper.ts
  • lua/vibing/infrastructure/adapter/modules/command_builder.lua
  • lua/vibing/application/commands/handler.lua
  • lua/vibing/application/chat/handlers/mode.lua
  • lua/vibing/presentation/chat/modules/renderer.lua
  • bin/lib/args-parser.ts

Agent SDK only supports 3 permissionMode values, not 5:
- default
- acceptEdits
- bypassPermissions

Removed unsupported values (plan, dontAsk) from:
- PERMISSION_MODES constant
- /permission command completion
- Command description
- Documentation (architecture.md, commands-reference.md, README.md, README.ja.md)

This fixes the error: Invalid --permission-mode value: "plan". Must be one of: default, acceptEdits, bypassPermissions
@claude
Copy link
Contributor

claude bot commented Mar 14, 2026

コードレビュー結果

このPRはmodeフィールドの削除と権限モードの整理を行う重要なリファクタリングです。全体的な方向性は正しいですが、いくつかの問題点と改善点があります。

🔴 重大な問題

1. PRタイトルが不正確

問題: タイトルに「update permissions to support all 5 permissionMode values」とありますが、実際にサポートするのは3つのみ(default, acceptEdits, bypassPermissions)です。

推奨対応:

gh pr edit 401 --title "refactor: remove invalid mode field, update permissions to support 3 permissionMode values"

2. default_modeへの参照が複数ファイルに残存

問題: 以下のファイルでconfig.agent.default_modeへの参照が残っており、削除されたmodeフィールドを使用しようとしています:

  • lua/vibing/ui/inline_preview.lua:507-508 - フロントマターにmodeを書き込み
  • lua/vibing/application/chat/use_cases/fork.lua:44 - フォーク時にmodeをコピー
  • lua/vibing/application/chat/use_case.lua:26 - 新規チャット作成時にmodeを設定

影響範囲:

  • インラインアクションの保存機能(Save as vibing
  • チャットフォーク機能
  • 新規チャット作成機能

推奨対応:
これらのファイルからmode関連のコードを完全に削除してください。

3. テストファイルの更新漏れ

問題: tests/init_spec.luadefault_modeのアサーションが残っています:

assert.equals("plan", config.agent.default_mode)
assert.equals("code", config.agent.default_mode)

推奨対応:
このテストを削除するか、権限モードのテストに書き換えてください。

🟡 軽微な問題

4. bin/lib/args-parser.tsの未使用フィールド

問題: AgentConfig型のmodeフィールド(56行目)がまだ宣言されていますが、使用されていません。

推奨対応:

// 削除すべき
mode: null,

5. フロントマターの優先順位リストのコメント不足

問題: lua/vibing/infrastructure/storage/frontmatter.lua:130-141の優先順位リストでmodeが削除されましたが、変更の意図を示すコメントがありません。

推奨対応:

-- mode field removed - no longer supported by Agent SDK
local priority = {
  ...
}

✅ 良い点

  1. 一貫性のある削除: modeハンドラー、/modeコマンド、--modeフラグの削除が適切に行われています
  2. ドキュメント更新: README、architecture.md、commands-reference.mdが適切に更新されています
  3. 権限モードの検証: args-parser.tsで3つの有効な値のみを受け入れるバリデーションが実装されています
  4. パフォーマンス改善: frontmatter.lua:224で最初の20行のみを読み込む最適化が追加されています(良い副次的改善)

🔍 セキュリティ/パフォーマンス

問題なし - このリファクタリングはセキュリティやパフォーマンスに悪影響を与えません。

📝 テストカバレッジ

不十分 - mode削除後の動作を検証するE2Eテストがありません。

推奨対応:

  • 新規チャット作成時にフロントマターにmodeフィールドが含まれないことを確認
  • 既存のmodeフィールドを含むチャットファイルを開いても正常に動作することを確認(後方互換性)
  • /permissionコマンドの動作確認

📋 マージ前のチェックリスト

  • PRタイトルを修正(5→3に変更)
  • inline_preview.luaからmode関連コード削除
  • use_cases/fork.luaからmode関連コード削除
  • use_case.luaからmode関連コード削除
  • tests/init_spec.luadefault_modeテスト削除
  • args-parser.tsの未使用modeフィールド削除
  • E2Eテストの追加(推奨)
  • 全テストが成功することを確認

総評

判定: 🟡 要修正

このPRは正しい方向性ですが、不完全なmode削除により既存機能が破損する可能性があります。上記の修正を行った後、再度レビューをお願いします。


Generated by Claude Code レビュー機能

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
lua/vibing/core/constants/modes.lua (1)

23-25: Use this validator as the single source of truth across handlers.

lua/vibing/application/chat/handlers/permission.lua still keeps its own VALID_MODES and manual loop (Lines 3, 25-30). Consider routing that handler through M.is_valid_permission_mode(mode) (and shared constants for display text) to prevent future drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lua/vibing/core/constants/modes.lua` around lines 23 - 25, The handler
duplicates VALID_MODES and a manual loop; replace that local constant and loop
in lua/vibing/application/chat/handlers/permission.lua with the shared
M.PERMISSION_MODES and the validator M.is_valid_permission_mode(mode), and pull
any user-facing display text from the shared constants module instead of
inlining strings so the permission validation and display values are single
sources of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lua/vibing/core/constants/modes.lua`:
- Around line 23-25: The handler duplicates VALID_MODES and a manual loop;
replace that local constant and loop in
lua/vibing/application/chat/handlers/permission.lua with the shared
M.PERMISSION_MODES and the validator M.is_valid_permission_mode(mode), and pull
any user-facing display text from the shared constants module instead of
inlining strings so the permission validation and display values are single
sources of truth.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5efbbb59-b112-41b9-a1c8-17513d5e1ce8

📥 Commits

Reviewing files that changed from the base of the PR and between d707158 and ab238bc.

📒 Files selected for processing (7)
  • .claude/rules/architecture.md
  • .claude/rules/commands-reference.md
  • README.ja.md
  • README.md
  • lua/vibing/application/chat/commands.lua
  • lua/vibing/application/chat/init.lua
  • lua/vibing/core/constants/modes.lua
💤 Files with no reviewable changes (2)
  • .claude/rules/commands-reference.md
  • lua/vibing/application/chat/init.lua
🚧 Files skipped from review as they are similar to previous changes (3)
  • lua/vibing/application/chat/commands.lua
  • README.md
  • README.ja.md

Root cause: vibing.nvim's args-parser.ts had hardcoded validation
that was rejecting valid Agent SDK permissionMode values (plan and dontAsk).
The error message made it appear as if Agent SDK didn't support these values,
but they were being blocked by vibing.nvim's own validation.

Changes:
- Updated bin/lib/args-parser.ts validPermissionModes array from 3 to 5 values
- Restored lua/vibing/core/constants/modes.lua PERMISSION_MODES to 5 values
- Restored lua/vibing/application/chat/commands.lua completion to 5 values
- Restored lua/vibing/application/chat/init.lua command description to 5 values
- Updated documentation to reflect all 5 supported permissionMode values:
  - default: Standard permission behavior with canUseTool callbacks
  - acceptEdits: Auto-approve file operations
  - bypassPermissions: Auto-approve ALL tools (dangerous)
  - plan: Read-only planning mode (no tool execution)
  - dontAsk: Deny instead of prompting

Verification:
- Build successful
- All tests passing
- Agent SDK version: @anthropic-ai/claude-agent-sdk ^0.1.76

Fixes #401 (partial - validation bottleneck identified and fixed)
@claude
Copy link
Contributor

claude bot commented Mar 14, 2026

コードレビュー

このPRを詳細にレビューしました。全体的に非常に良い品質のリファクタリングです。以下、詳細なフィードバックを提供します。


✅ 高評価ポイント

1. 正確な問題把握と解決

  • Agent SDKが--modeパラメータをサポートしていない事実を正しく特定
  • permissionModeのみがサポートされる3つの値(default, acceptEdits, bypassPermissions)を実際のエラーメッセージから確認
  • 無効なコードを削除し、正しい実装に置き換えている

2. 一貫性のある変更

  • Luaコード、TypeScriptコード、ドキュメントすべてでmodeフィールドを削除
  • /modeコマンドの完全な削除(ハンドラー、登録、補完)
  • フロントマター、レンダリング、コマンドビルダーでの一貫した削除

3. 優れたドキュメント更新

  • README.ja.md、README.md、.claude/rules/の全ドキュメントを更新
  • PRの説明が非常に詳細で、破壊的変更の移行方法も明記
  • テスト結果も記載されている

4. 後方互換性への配慮

  • 既存のチャットファイルにmode:が含まれていても無害(単に無視される)
  • ユーザーへの影響を最小限に抑えている

⚠️ 重大な問題

1. 型定義と実装の不一致 (Critical)

問題箇所: bin/types.ts:85

permissionMode: 'default' | 'acceptEdits' | 'bypassPermissions';

問題: 型定義では3つの値のみですが、args-parser.ts:10-16では5つの値(plan, dontAskを追加)をサポートしています。

const validPermissionModes = [
  'default',
  'acceptEdits',
  'bypassPermissions',
  'plan',      // ← 型定義にない
  'dontAsk',   // ← 型定義にない
] as const;

影響:

  • TypeScriptコンパイラが型エラーを検出できない
  • ランタイムでplandontAskを渡すとAgent SDKがエラーを返す可能性が高い

修正方法:

// bin/types.ts:85
permissionMode: 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'dontAsk';

もしくは、実際にAgent SDKが受け付ける3つのみにするなら:

// bin/lib/args-parser.ts:10-16
const validPermissionModes = [
  'default',
  'acceptEdits',
  'bypassPermissions',
] as const;

推奨: PRの説明では「Agent SDKは3つのみサポート」とあるため、plandontAskを削除すべきです。


🐛 潜在的なバグ

2. modeフィールドが残存 (High)

問題箇所: bin/types.ts:83

mode: string | null;

問題: modeフィールドを削除するPRなのに、AgentConfig型定義に残っています。

影響:

  • 削除したはずのmodeが型システム上は存在する矛盾
  • 将来的に誤って使用される可能性

修正方法:

// bin/types.ts:83を削除
export interface AgentConfig {
  prompt: string;
  cwd: string;
  contextFiles: string[];
  sessionId: string | null;
  forkSession: boolean;
  allowedTools: string[];
  deniedTools: string[];
  askedTools: string[];
  sessionAllowedTools: string[];
  sessionDeniedTools: string[];
  permissionRules: PermissionRule[];
  // mode: string | null; ← 削除
  model: string | null;
  permissionMode: 'default' | 'acceptEdits' | 'bypassPermissions';
  // ...
}

また、args-parser.ts:62の初期化も削除すべきです:

const config: AgentConfig = {
  prompt: '',
  cwd: process.cwd(),
  contextFiles: [],
  sessionId: null,
  forkSession: false,
  allowedTools: [],
  deniedTools: [],
  askedTools: [],
  sessionAllowedTools: [],
  sessionDeniedTools: [],
  permissionRules: [],
  // mode: null, ← 削除
  model: null,
  permissionMode: 'acceptEdits',
  // ...
};

📝 軽微な改善提案

3. 新規ファイルのエラーハンドリング (Medium)

問題箇所: bin/list-commands.ts:28-32

try {
  if (typeof result.cancel === 'function') {
    await result.cancel();
  }
} catch {
  // Ignore cancel errors
}

提案: 空のcatchブロックではなく、少なくともログ出力を検討してください。

} catch (error) {
  // Cancel may fail in older SDK versions - this is non-critical
  // console.error('Warning: Failed to cancel query:', error);
}

4. ドキュメントの矛盾 (Low)

問題箇所:

  • .claude/rules/architecture.md:85 では5つの値をサポートと記載
  • .claude/rules/commands-reference.md:113 でも5つの値
permissions_mode: acceptEdits # default, acceptEdits, bypassPermissions, plan, or dontAsk

問題: PR説明では「Agent SDKは3つのみサポート」とあるが、ドキュメントでは5つ

推奨: 実際にサポートされる値のみをドキュメントに記載すべきです。もしplandontAskが動作しないなら削除してください。


🔍 セキュリティとパフォーマンス

5. 最適化の良い事例 (Positive)

lua/vibing/infrastructure/storage/frontmatter.lua:224でファイル読み込みを最適化:

-- Read only the first 20 lines to check frontmatter (performance optimization)
local content = table.concat(vim.fn.readfile(file_path, "", 20), "\n")

これは優れた最適化です!フロントマターチェックで全ファイルを読む必要がないため、大きなチャットファイルでもパフォーマンスが良好です。

6. セキュリティ懸念なし

  • 入力検証が適切(isValidPermissionMode)
  • パーミッションルールのバリデーションも実装済み
  • セキュリティ上の問題は見当たりません

🧪 テストカバレッジ

7. E2Eテストの追加を推奨 (Medium)

現在のテスト結果は良好ですが、以下のテストケースを追加することを推奨します:

-- tests/e2e/permission_mode_spec.lua
describe("Permission mode validation", function()
  it("should accept valid permission modes", function()
    -- Test: default, acceptEdits, bypassPermissions
  end)
  
  it("should reject invalid permission modes", function()
    -- Test: plan, dontAsk (if they are truly unsupported)
  end)
end)

📊 総合評価

項目 評価
コード品質 ⭐⭐⭐⭐☆ (4/5)
一貫性 ⭐⭐⭐⭐⭐ (5/5)
ドキュメント ⭐⭐⭐⭐☆ (4/5)
テストカバレッジ ⭐⭐⭐⭐☆ (4/5)
後方互換性 ⭐⭐⭐⭐⭐ (5/5)

総合: ⭐⭐⭐⭐☆ (4.2/5)


✅ マージ推奨度

条件付きでマージ推奨 - 以下の修正後:

  1. 必須: 型定義の不一致を修正(bin/types.ts:85, permissionModeの型)
  2. 必須: modeフィールドをAgentConfigから完全削除(bin/types.ts:83)
  3. 推奨: plandontAskのサポート状況を明確化(サポートしないなら削除)
  4. 推奨: ドキュメントの矛盾を解消

上記の修正後であれば、このPRは非常に価値のあるリファクタリングとして自信を持ってマージできます。


素晴らしいリファクタリング作業でした!お疲れ様です 👏

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
bin/lib/args-parser.ts (1)

199-200: ⚠️ Potential issue | 🟠 Major

Unknown CLI flags are silently accepted and can corrupt prompt parsing.

After removing --mode, unsupported flags (including legacy ones) are not rejected. Their next token can be treated as a positional prompt, producing misleading behavior instead of a clear CLI error.

💡 Proposed fix
-    } else if (!args[i].startsWith('--')) {
+    } else if (!args[i].startsWith('--')) {
       config.prompt = args[i];
+    } else {
+      console.error(`Unknown option: ${args[i]}`);
+      process.exit(1);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/args-parser.ts` around lines 199 - 200, The parser currently treats
any non-flag token as the prompt (config.prompt) which lets unknown/legacy flags
like "--legacy" be skipped and their next token become the prompt; update the
arg parsing logic (the code that iterates over args and sets config.prompt) to
explicitly validate flags: if a token startsWith('--') but is not a recognized
known flag, throw or return a CLI error instead of skipping it, and only assign
config.prompt for tokens that do NOT start with '--' and when config.prompt is
currently unset; ensure you reference the same identifiers (args[],
config.prompt) and the parsing function that contains this loop so unknown flags
are rejected and cannot corrupt prompt parsing.
♻️ Duplicate comments (1)
lua/vibing/application/chat/init.lua (1)

64-64: ⚠️ Potential issue | 🟠 Major

/permission description may still be out of sync with handler validation.

If lua/vibing/application/chat/handlers/permission.lua still validates only three values, /permission plan and /permission dontAsk will be advertised but rejected at runtime.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lua/vibing/application/chat/init.lua` at line 64, The command help string in
init.lua advertises "/permission plan" and "/permission dontAsk" but the
permission handler in lua/vibing/application/chat/handlers/permission.lua only
validates three values; fix this by making the handler accept the additional
modes advertised (add "plan" and "dontAsk" to its validation/allowed-values
check in the handler function, e.g., the validate/allowed-values list or switch
inside the permission handler), or alternatively update the description string
in init.lua to only list the modes the handler currently accepts; modify
whichever is appropriate so the advertised description and the handler's
validation (in the permission handler function) match.
🧹 Nitpick comments (2)
lua/vibing/infrastructure/completion/providers/skills.lua (1)

86-88: Cache variable name is misleading.

_bundled_cache currently stores only dynamic SDK results, not the merged bundled list. Renaming it (e.g., _dynamic_cache) would reduce confusion.

Also applies to: 155-156

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lua/vibing/infrastructure/completion/providers/skills.lua` around lines 86 -
88, The variable _bundled_cache is misleading because it only holds dynamic SDK
results; rename it to _dynamic_cache throughout the file (declaration,
assignments and all references such as the checks at _bundled_cache and uses
later around the second occurrence) and update any comments to reflect that it
contains only dynamic SDK results, ensuring the true merged/ bundled list
remains a separate variable name.
lua/vibing/application/chat/commands.lua (1)

200-200: Use shared constants for permission completions to avoid drift.

permission completions are hardcoded here and can diverge from lua/vibing/core/constants/modes.lua.

♻️ Proposed refactor
+local Modes = require("vibing.core.constants.modes")
+
 function M.get_argument_completions(command_name)
   local completions = {
-    permission = { "default", "acceptEdits", "bypassPermissions", "plan", "dontAsk" },
+    permission = vim.deepcopy(Modes.PERMISSION_MODES),
     model = { "opus", "sonnet", "haiku" },
   }
   return completions[command_name]
 end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lua/vibing/application/chat/commands.lua` at line 200, The permission list in
the command definition (permission = { "default", "acceptEdits",
"bypassPermissions", "plan", "dontAsk" }) is hardcoded and can drift from the
canonical set in lua/vibing/core/constants/modes.lua; replace the literal array
with the shared constant exported from modes.lua (e.g., require the module and
reference Modes.PERMISSIONS or the exact exported name used there) or merge any
command-specific extras into that constant, updating the commands.lua definition
to use that imported symbol instead of duplicating the values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lua/vibing/infrastructure/completion/providers/skills.lua`:
- Around line 101-116: The code uses config.node.executable (resolved into local
executable) directly when building cmd for vim.fn.systemlist, which can be
"auto" and thus invalid; resolve/validate the runtime like in
command_builder.lua before calling systemlist: detect "auto" or missing
executable, choose a concrete runtime (node, bun, or ts-node) based on
availability and dev_mode (for dev_mode ensure .ts uses ts-node or bun), fall
back to returning {} if no runtime found, and then build cmd from the resolved
executable, script_path, and any dev flags so that vim.fn.systemlist(cmd) is
always invoked with a real executable name (refer to executable, dev_mode,
script_path, list_commands_script and systemlist in this file).

---

Outside diff comments:
In `@bin/lib/args-parser.ts`:
- Around line 199-200: The parser currently treats any non-flag token as the
prompt (config.prompt) which lets unknown/legacy flags like "--legacy" be
skipped and their next token become the prompt; update the arg parsing logic
(the code that iterates over args and sets config.prompt) to explicitly validate
flags: if a token startsWith('--') but is not a recognized known flag, throw or
return a CLI error instead of skipping it, and only assign config.prompt for
tokens that do NOT start with '--' and when config.prompt is currently unset;
ensure you reference the same identifiers (args[], config.prompt) and the
parsing function that contains this loop so unknown flags are rejected and
cannot corrupt prompt parsing.

---

Duplicate comments:
In `@lua/vibing/application/chat/init.lua`:
- Line 64: The command help string in init.lua advertises "/permission plan" and
"/permission dontAsk" but the permission handler in
lua/vibing/application/chat/handlers/permission.lua only validates three values;
fix this by making the handler accept the additional modes advertised (add
"plan" and "dontAsk" to its validation/allowed-values check in the handler
function, e.g., the validate/allowed-values list or switch inside the permission
handler), or alternatively update the description string in init.lua to only
list the modes the handler currently accepts; modify whichever is appropriate so
the advertised description and the handler's validation (in the permission
handler function) match.

---

Nitpick comments:
In `@lua/vibing/application/chat/commands.lua`:
- Line 200: The permission list in the command definition (permission = {
"default", "acceptEdits", "bypassPermissions", "plan", "dontAsk" }) is hardcoded
and can drift from the canonical set in lua/vibing/core/constants/modes.lua;
replace the literal array with the shared constant exported from modes.lua
(e.g., require the module and reference Modes.PERMISSIONS or the exact exported
name used there) or merge any command-specific extras into that constant,
updating the commands.lua definition to use that imported symbol instead of
duplicating the values.

In `@lua/vibing/infrastructure/completion/providers/skills.lua`:
- Around line 86-88: The variable _bundled_cache is misleading because it only
holds dynamic SDK results; rename it to _dynamic_cache throughout the file
(declaration, assignments and all references such as the checks at
_bundled_cache and uses later around the second occurrence) and update any
comments to reflect that it contains only dynamic SDK results, ensuring the true
merged/ bundled list remains a separate variable name.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 82ecacc2-b185-4edd-aae6-87a4015a941d

📥 Commits

Reviewing files that changed from the base of the PR and between ab238bc and 0710480.

📒 Files selected for processing (12)
  • .claude/rules/architecture.md
  • .claude/rules/commands-reference.md
  • README.ja.md
  • README.md
  • bin/lib/args-parser.ts
  • bin/list-commands.ts
  • lua/vibing/application/chat/commands.lua
  • lua/vibing/application/chat/init.lua
  • lua/vibing/application/daily_summary/collector.lua
  • lua/vibing/core/constants/modes.lua
  • lua/vibing/infrastructure/completion/providers/skills.lua
  • scripts/build.mjs
🚧 Files skipped from review as they are similar to previous changes (3)
  • README.ja.md
  • .claude/rules/commands-reference.md
  • README.md

Comment on lines +101 to +116
local executable = config.node and config.node.executable or "node"
local dev_mode = config.node and config.node.dev_mode or false
local script_path = list_commands_script

if not dev_mode then
-- Production mode: use compiled JS
script_path = plugin_dir .. "/dist/bin/list-commands.js"
if vim.fn.filereadable(script_path) ~= 1 then
-- Fallback to empty list if compiled version doesn't exist
return {}
end
end

-- Execute the script to get SDK-provided skills
local cmd = { executable, script_path }
local result = vim.fn.systemlist(cmd)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Inspect Node config contract/defaults"
rg -n --type=lua -C2 'NodeConfig|node\.executable|dev_mode|"auto"|executable\s*=' lua/vibing/config.lua

echo
echo "2) Inspect executable resolution call sites"
rg -n --type=lua -C3 'config\.node\.executable|systemlist\(|list-commands\.ts|list-commands\.js' lua

echo
echo "Expected: either (a) executable is normalized from \"auto\" before use, and dev_mode TS execution runtime is explicit, or (b) this path can fail and return empty skills."

Repository: shabaraba/vibing.nvim

Length of output: 13532


Resolve config.node.executable before invoking systemlist.

config.node.executable defaults to "auto", but this code passes it directly to systemlist() without resolution. When executable = "auto", the command becomes systemlist({"auto", script_path}), which will fail. In dev mode, the .ts script execution also lacks explicit runtime handling (bun or ts-node requirement). While failures gracefully return an empty skill list, the code should properly resolve or validate the executable before attempting execution, similar to the pattern used in command_builder.lua.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lua/vibing/infrastructure/completion/providers/skills.lua` around lines 101 -
116, The code uses config.node.executable (resolved into local executable)
directly when building cmd for vim.fn.systemlist, which can be "auto" and thus
invalid; resolve/validate the runtime like in command_builder.lua before calling
systemlist: detect "auto" or missing executable, choose a concrete runtime
(node, bun, or ts-node) based on availability and dev_mode (for dev_mode ensure
.ts uses ts-node or bun), fall back to returning {} if no runtime found, and
then build cmd from the resolved executable, script_path, and any dev flags so
that vim.fn.systemlist(cmd) is always invoked with a real executable name (refer
to executable, dev_mode, script_path, list_commands_script and systemlist in
this file).

Previously, permissionMode was parsed from CLI args but not passed to
Agent SDK's query() function. This caused 'plan' mode to not work as
expected - tools could still execute instead of read-only planning.

Changes:
- Add permissionMode to query options in buildQueryOptions()
- Ensures Agent SDK respects all 5 permissionMode values:
  default, acceptEdits, bypassPermissions, plan, dontAsk
- Use shared PERMISSION_MODES constant in handlers and completions
- Fix README.md markdown linting issues (line length, code block language)
- Add validation to reject unknown CLI flags in args-parser
@claude
Copy link
Contributor

claude bot commented Mar 17, 2026

コードレビュー結果

このPRは、無効なmodeフィールドを削除し、Agent SDKがサポートする5つのpermissionMode値すべてをサポートするための重要なリファクタリングです。全体的に良い方向性ですが、いくつかの重大な問題と改善点を発見しました。


🔴 Critical Issues (修正必須)

1. TypeScript型定義の不整合

ファイル: bin/types.ts:85

問題:
AgentConfigpermissionMode型定義が古いままで、新しいplandontAsk値を含んでいません。

現在の定義:

permissionMode: 'default' | 'acceptEdits' | 'bypassPermissions';

期待される定義:

permissionMode: 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'dontAsk';

影響: TypeScriptの型安全性が損なわれる

修正方法: bin/types.tsの85行目を更新してください。


2. 未使用のmodeフィールドが型定義に残存

ファイル: bin/types.ts:83

AgentConfig.modeフィールドが削除されていません。実装とインターフェースの不整合があります。完全に削除してください。


⚠️ Medium Priority Issues (推奨修正)

3. テストファイルの意図が不明確

test-vibing-files/, test-recursive/などのテストファイルが含まれていますが、変更の意図が不明です。これらはこのPRの目的と関連していますか?

4. リソースリークの可能性

bin/list-commands.ts:26-32result.cancel()のエラーを無視しています。コメントで理由を説明してください。


💡 Low Priority Suggestions (任意)

5. ドキュメント強化

plandontAskモードの具体的なユースケースを説明すると良いでしょう。

6. Skills Provider実装

ハードコードされたbundled skillsリストはメンテナンス上の懸念があります。コメントで理由を説明してください。


✅ Good Practices

  1. 一貫した変更
  2. 検証の強化
  3. 後方互換性の維持
  4. 明確なコミットメッセージ

総評

このPRは重要なリファクタリングであり、コンセプトは良好です。ただし、TypeScript型定義の修正が必須です。

推奨アクション:

  1. bin/types.tsの型定義を修正(Critical)
  2. テストファイルの変更意図を説明(Medium)

型定義の修正後、マージ可能と判断します。


生成者: Claude Sonnet 4.5 🤖

@shabaraba shabaraba merged commit f4aa08d into main Mar 17, 2026
4 of 5 checks passed
@shabaraba shabaraba deleted the refactor/remove-invalid-mode-field-1773411618 branch March 17, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant