debug-mcp 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +83 -0
- data/LICENSE +21 -0
- data/README.ja.md +383 -0
- data/README.md +384 -0
- data/examples/01_simple_bug.rb +43 -0
- data/examples/02_data_pipeline.rb +93 -0
- data/examples/03_recursion.rb +96 -0
- data/examples/RAILS_SCENARIOS.md +350 -0
- data/examples/SCENARIOS.md +142 -0
- data/examples/rails_test_app/setup.sh +428 -0
- data/examples/rails_test_app/testapp/.dockerignore +10 -0
- data/examples/rails_test_app/testapp/.ruby-version +1 -0
- data/examples/rails_test_app/testapp/Dockerfile +23 -0
- data/examples/rails_test_app/testapp/Gemfile +17 -0
- data/examples/rails_test_app/testapp/README.md +65 -0
- data/examples/rails_test_app/testapp/Rakefile +6 -0
- data/examples/rails_test_app/testapp/app/assets/images/.keep +0 -0
- data/examples/rails_test_app/testapp/app/assets/stylesheets/application.css +1 -0
- data/examples/rails_test_app/testapp/app/controllers/application_controller.rb +4 -0
- data/examples/rails_test_app/testapp/app/controllers/concerns/.keep +0 -0
- data/examples/rails_test_app/testapp/app/controllers/dashboard_controller.rb +38 -0
- data/examples/rails_test_app/testapp/app/controllers/health_controller.rb +11 -0
- data/examples/rails_test_app/testapp/app/controllers/orders_controller.rb +100 -0
- data/examples/rails_test_app/testapp/app/controllers/posts_controller.rb +82 -0
- data/examples/rails_test_app/testapp/app/controllers/sessions_controller.rb +25 -0
- data/examples/rails_test_app/testapp/app/controllers/users_controller.rb +44 -0
- data/examples/rails_test_app/testapp/app/helpers/application_helper.rb +2 -0
- data/examples/rails_test_app/testapp/app/models/application_record.rb +3 -0
- data/examples/rails_test_app/testapp/app/models/comment.rb +8 -0
- data/examples/rails_test_app/testapp/app/models/concerns/.keep +0 -0
- data/examples/rails_test_app/testapp/app/models/order.rb +56 -0
- data/examples/rails_test_app/testapp/app/models/order_item.rb +16 -0
- data/examples/rails_test_app/testapp/app/models/post.rb +29 -0
- data/examples/rails_test_app/testapp/app/models/user.rb +34 -0
- data/examples/rails_test_app/testapp/app/services/order_report_service.rb +40 -0
- data/examples/rails_test_app/testapp/app/views/layouts/application.html.erb +28 -0
- data/examples/rails_test_app/testapp/app/views/pwa/manifest.json.erb +22 -0
- data/examples/rails_test_app/testapp/app/views/pwa/service-worker.js +26 -0
- data/examples/rails_test_app/testapp/bin/ci +6 -0
- data/examples/rails_test_app/testapp/bin/dev +2 -0
- data/examples/rails_test_app/testapp/bin/rails +4 -0
- data/examples/rails_test_app/testapp/bin/rake +4 -0
- data/examples/rails_test_app/testapp/bin/setup +35 -0
- data/examples/rails_test_app/testapp/config/application.rb +42 -0
- data/examples/rails_test_app/testapp/config/boot.rb +3 -0
- data/examples/rails_test_app/testapp/config/ci.rb +14 -0
- data/examples/rails_test_app/testapp/config/database.yml +32 -0
- data/examples/rails_test_app/testapp/config/environment.rb +5 -0
- data/examples/rails_test_app/testapp/config/environments/development.rb +54 -0
- data/examples/rails_test_app/testapp/config/environments/production.rb +67 -0
- data/examples/rails_test_app/testapp/config/environments/test.rb +42 -0
- data/examples/rails_test_app/testapp/config/initializers/content_security_policy.rb +29 -0
- data/examples/rails_test_app/testapp/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/rails_test_app/testapp/config/initializers/inflections.rb +16 -0
- data/examples/rails_test_app/testapp/config/locales/en.yml +31 -0
- data/examples/rails_test_app/testapp/config/puma.rb +39 -0
- data/examples/rails_test_app/testapp/config/routes.rb +34 -0
- data/examples/rails_test_app/testapp/config.ru +6 -0
- data/examples/rails_test_app/testapp/db/migrate/20260216002916_create_users.rb +12 -0
- data/examples/rails_test_app/testapp/db/migrate/20260216002919_create_posts.rb +13 -0
- data/examples/rails_test_app/testapp/db/migrate/20260216002922_create_comments.rb +11 -0
- data/examples/rails_test_app/testapp/db/migrate/20260222000001_create_orders.rb +14 -0
- data/examples/rails_test_app/testapp/db/migrate/20260222000002_create_order_items.rb +13 -0
- data/examples/rails_test_app/testapp/db/schema.rb +71 -0
- data/examples/rails_test_app/testapp/db/seeds.rb +85 -0
- data/examples/rails_test_app/testapp/docker-compose.yml +21 -0
- data/examples/rails_test_app/testapp/docker-entrypoint.sh +10 -0
- data/examples/rails_test_app/testapp/lib/tasks/.keep +0 -0
- data/examples/rails_test_app/testapp/log/.keep +0 -0
- data/examples/rails_test_app/testapp/public/400.html +135 -0
- data/examples/rails_test_app/testapp/public/404.html +135 -0
- data/examples/rails_test_app/testapp/public/406-unsupported-browser.html +135 -0
- data/examples/rails_test_app/testapp/public/422.html +135 -0
- data/examples/rails_test_app/testapp/public/500.html +135 -0
- data/examples/rails_test_app/testapp/public/icon.png +0 -0
- data/examples/rails_test_app/testapp/public/icon.svg +3 -0
- data/examples/rails_test_app/testapp/public/robots.txt +1 -0
- data/examples/rails_test_app/testapp/script/.keep +0 -0
- data/examples/rails_test_app/testapp/storage/.keep +0 -0
- data/examples/rails_test_app/testapp/tmp/.keep +0 -0
- data/examples/rails_test_app/testapp/tmp/pids/.keep +0 -0
- data/examples/rails_test_app/testapp/tmp/storage/.keep +0 -0
- data/examples/rails_test_app/testapp/vendor/.keep +0 -0
- data/exe/debug-mcp +39 -0
- data/exe/debug-rails +127 -0
- data/lib/debug_mcp/client_cleanup.rb +102 -0
- data/lib/debug_mcp/code_safety_analyzer.rb +124 -0
- data/lib/debug_mcp/debug_client.rb +1143 -0
- data/lib/debug_mcp/exit_message_builder.rb +112 -0
- data/lib/debug_mcp/pending_http_helper.rb +25 -0
- data/lib/debug_mcp/rails_helper.rb +155 -0
- data/lib/debug_mcp/server.rb +364 -0
- data/lib/debug_mcp/session_manager.rb +436 -0
- data/lib/debug_mcp/stop_event_annotator.rb +152 -0
- data/lib/debug_mcp/tcp_session_discovery.rb +226 -0
- data/lib/debug_mcp/tools/connect.rb +669 -0
- data/lib/debug_mcp/tools/continue_execution.rb +161 -0
- data/lib/debug_mcp/tools/disconnect.rb +169 -0
- data/lib/debug_mcp/tools/evaluate_code.rb +354 -0
- data/lib/debug_mcp/tools/finish.rb +84 -0
- data/lib/debug_mcp/tools/get_context.rb +217 -0
- data/lib/debug_mcp/tools/get_source.rb +193 -0
- data/lib/debug_mcp/tools/inspect_object.rb +107 -0
- data/lib/debug_mcp/tools/list_debug_sessions.rb +60 -0
- data/lib/debug_mcp/tools/list_files.rb +189 -0
- data/lib/debug_mcp/tools/list_paused_sessions.rb +108 -0
- data/lib/debug_mcp/tools/next.rb +70 -0
- data/lib/debug_mcp/tools/rails_info.rb +200 -0
- data/lib/debug_mcp/tools/rails_model.rb +362 -0
- data/lib/debug_mcp/tools/rails_routes.rb +186 -0
- data/lib/debug_mcp/tools/read_file.rb +214 -0
- data/lib/debug_mcp/tools/remove_breakpoint.rb +173 -0
- data/lib/debug_mcp/tools/run_debug_command.rb +55 -0
- data/lib/debug_mcp/tools/run_script.rb +293 -0
- data/lib/debug_mcp/tools/set_breakpoint.rb +206 -0
- data/lib/debug_mcp/tools/step.rb +67 -0
- data/lib/debug_mcp/tools/trigger_request.rb +515 -0
- data/lib/debug_mcp/version.rb +5 -0
- data/lib/debug_mcp.rb +40 -0
- metadata +251 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# debug-mcp Rails デバッグシナリオ
|
|
2
|
+
|
|
3
|
+
## 準備
|
|
4
|
+
|
|
5
|
+
### 1. テスト用Railsアプリのセットアップ
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd /home/rira/rira100000000/girb/debug-mcp/examples/rails_test_app
|
|
9
|
+
bash setup.sh
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
User(admin/editor/member/guest、バリデーション、enum)、Post(published/draft/archived、スコープ)、Comment を持つブログアプリが生成される。
|
|
13
|
+
|
|
14
|
+
### 2. Railsサーバーの起動
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
cd examples/rails_test_app/testapp
|
|
18
|
+
RUBY_DEBUG_OPEN=true bin/rails server -p 3999
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`RUBY_DEBUG_OPEN=true` により、debug gem がソケットを開いた状態で起動する。
|
|
22
|
+
|
|
23
|
+
### 3. debug-mcp の設定
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"debug-mcp": {
|
|
29
|
+
"command": "bundle",
|
|
30
|
+
"args": ["exec", "debug-mcp"],
|
|
31
|
+
"cwd": "/home/rira/rira100000000/girb/debug-mcp"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## シナリオ5: rails_info でアプリ概要を把握
|
|
40
|
+
|
|
41
|
+
**テスト対象:** `rails_info`
|
|
42
|
+
|
|
43
|
+
**背景:** 初めてRailsプロセスに接続した後、まずアプリケーションの基本情報を確認する。
|
|
44
|
+
|
|
45
|
+
### Claude Codeへの指示例
|
|
46
|
+
|
|
47
|
+
> Railsサーバーのデバッグセッションに接続して、アプリケーションの概要を教えてください。
|
|
48
|
+
|
|
49
|
+
### 期待される流れ
|
|
50
|
+
|
|
51
|
+
1. `connect` → Railsプロセスに接続
|
|
52
|
+
2. `rails_info` → アプリ概要を表示
|
|
53
|
+
|
|
54
|
+
### 確認ポイント
|
|
55
|
+
|
|
56
|
+
- [ ] アプリ名が表示される(TestappなどRailsが生成する名前)
|
|
57
|
+
- [ ] Railsバージョンが正しく表示される(例: 7.1.x)
|
|
58
|
+
- [ ] 環境が `development` と表示される
|
|
59
|
+
- [ ] Rubyバージョンが表示される
|
|
60
|
+
- [ ] `Root:` にアプリのパスが表示される
|
|
61
|
+
- [ ] Database セクションに `adapter: sqlite3` が表示される
|
|
62
|
+
- [ ] パスワード等のセンシティブ情報が `[FILTERED]` でマスクされる
|
|
63
|
+
|
|
64
|
+
### 失敗パターンのテスト
|
|
65
|
+
|
|
66
|
+
- 非Railsプロセス(例: `run_script` で普通のRubyスクリプト起動)に対して `rails_info` → `Not a Rails application` エラー
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## シナリオ6: rails_routes でルーティングを確認
|
|
71
|
+
|
|
72
|
+
**テスト対象:** `rails_routes`
|
|
73
|
+
|
|
74
|
+
**背景:** コントローラアクションにブレークポイントを設定する前に、利用可能なルートを確認する。
|
|
75
|
+
|
|
76
|
+
### Claude Codeへの指示例
|
|
77
|
+
|
|
78
|
+
> このRailsアプリのルーティングを教えてください。usersコントローラのルートだけ見せてください。
|
|
79
|
+
|
|
80
|
+
### 期待される流れ
|
|
81
|
+
|
|
82
|
+
1. `rails_routes` → 全ルート表示
|
|
83
|
+
2. `rails_routes(controller: "users")` → usersのみフィルタ
|
|
84
|
+
3. `rails_routes(path: "/login")` → パスでフィルタ
|
|
85
|
+
|
|
86
|
+
### 確認ポイント
|
|
87
|
+
|
|
88
|
+
- [ ] 全ルート表示で以下が含まれる:
|
|
89
|
+
- `GET /users users#index`
|
|
90
|
+
- `POST /users users#create`
|
|
91
|
+
- `GET /users/:id users#show`
|
|
92
|
+
- `POST /login sessions#create`
|
|
93
|
+
- `GET /health health#show`
|
|
94
|
+
- `GET /dashboard dashboard#index`
|
|
95
|
+
- `GET /posts/search posts#search`
|
|
96
|
+
- [ ] `controller: "users"` フィルタでusers関連のルートのみ表示される
|
|
97
|
+
- [ ] `controller: "sessions"` フィルタで login/me/logout が表示される
|
|
98
|
+
- [ ] `path: "/posts"` フィルタでposts関連ルートが表示される
|
|
99
|
+
- [ ] `Total: N routes` が正しいカウントを表示する
|
|
100
|
+
- [ ] ルート名(`users`, `user` 等)がカッコ内に表示される
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## シナリオ7: rails_model でモデル構造を確認
|
|
105
|
+
|
|
106
|
+
**テスト対象:** `rails_model`
|
|
107
|
+
|
|
108
|
+
**背景:** デバッグ中にモデルの構造(カラム、アソシエーション、バリデーション)を把握する。
|
|
109
|
+
|
|
110
|
+
### Claude Codeへの指示例
|
|
111
|
+
|
|
112
|
+
> User モデルの構造を教えてください。Post モデルも確認してください。
|
|
113
|
+
|
|
114
|
+
### 期待される流れ
|
|
115
|
+
|
|
116
|
+
1. `rails_model(model_name: "User")` → User の全情報
|
|
117
|
+
2. `rails_model(model_name: "Post")` → Post の全情報
|
|
118
|
+
3. `rails_model(model_name: "Nonexistent")` → エラー
|
|
119
|
+
|
|
120
|
+
### 確認ポイント(User モデル)
|
|
121
|
+
|
|
122
|
+
- [ ] ヘッダー: `=== User (table: users) ===`
|
|
123
|
+
- [ ] Columns セクション:
|
|
124
|
+
- `id` (integer, NOT NULL, PK)
|
|
125
|
+
- `name` (string)
|
|
126
|
+
- `email` (string)
|
|
127
|
+
- `role` (integer) — default: 0 が表示されるかもしれない
|
|
128
|
+
- `active` (boolean)
|
|
129
|
+
- `created_at`, `updated_at`
|
|
130
|
+
- [ ] Associations セクション:
|
|
131
|
+
- `has_many :posts -> Post`
|
|
132
|
+
- `has_many :comments -> Comment`
|
|
133
|
+
- [ ] Validations セクション:
|
|
134
|
+
- `presence [:name, :email]`
|
|
135
|
+
- `uniqueness [:email]`
|
|
136
|
+
- `length [:name, ...]`
|
|
137
|
+
- `format [:email]`
|
|
138
|
+
- [ ] Enums セクション:
|
|
139
|
+
- `role: { guest: 0, member: 1, editor: 2, admin: 3 }`
|
|
140
|
+
- [ ] Scopes セクション(検出される場合):
|
|
141
|
+
- `active`, `admins`, `recent`
|
|
142
|
+
|
|
143
|
+
### 確認ポイント(Post モデル)
|
|
144
|
+
|
|
145
|
+
- [ ] `belongs_to :user -> User`
|
|
146
|
+
- [ ] `has_many :comments -> Comment`
|
|
147
|
+
- [ ] enum `status: { draft: 0, published: 1, archived: 2 }`
|
|
148
|
+
- [ ] scope: `published`, `drafts`, `recent`
|
|
149
|
+
|
|
150
|
+
### エラーパターン
|
|
151
|
+
|
|
152
|
+
- [ ] `rails_model(model_name: "Nonexistent")` → `Model Nonexistent not found`
|
|
153
|
+
- [ ] `rails_model(model_name: "String")` → `String is not an ActiveRecord model`
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## シナリオ8: trigger_request の CSRF 自動スキップ
|
|
158
|
+
|
|
159
|
+
**テスト対象:** `trigger_request` のCSRF自動無効化
|
|
160
|
+
|
|
161
|
+
**背景:** RailsではPOST/PUT/PATCH/DELETEリクエストにCSRFトークンが必要。debug-mcpはこれを自動的に回避する。
|
|
162
|
+
|
|
163
|
+
### Claude Codeへの指示例
|
|
164
|
+
|
|
165
|
+
> POST /users で新しいユーザーを作成してください。名前は「テスト太郎」、メールは「taro@test.com」、roleはmemberです。
|
|
166
|
+
|
|
167
|
+
### 期待される流れ
|
|
168
|
+
|
|
169
|
+
1. `trigger_request(method: "POST", url: "http://localhost:3999/users", body: '{"name":"テスト太郎","email":"taro@test.com","role":"member","active":true}')`
|
|
170
|
+
2. CSRFが自動的に無効化され、リクエスト成功
|
|
171
|
+
3. レスポンスにJSON(作成されたユーザー情報)が整形表示される
|
|
172
|
+
|
|
173
|
+
### 確認ポイント
|
|
174
|
+
|
|
175
|
+
- [ ] CSRFエラー(`422 Unprocessable Entity` + `Can't verify CSRF token`)にならない
|
|
176
|
+
- [ ] `201 Created` のステータスが返る
|
|
177
|
+
- [ ] JSONレスポンスがpretty-printされる
|
|
178
|
+
- [ ] Content-Typeが自動的に `application/json` に設定される(bodyが `{` で始まるため)
|
|
179
|
+
- [ ] リクエスト後にCSRF保護が復元される(後続の通常リクエストに影響しない)
|
|
180
|
+
|
|
181
|
+
### 追加テスト
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
# skip_csrf: false を指定 → CSRFエラーが発生するはず
|
|
185
|
+
trigger_request(method: "POST", url: "http://localhost:3999/users",
|
|
186
|
+
body: '{"name":"test","email":"test@test.com"}', skip_csrf: false)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- [ ] `422` エラーまたはCSRF関連エラーが返る
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## シナリオ9: trigger_request の Cookie とセッション管理
|
|
194
|
+
|
|
195
|
+
**テスト対象:** `trigger_request` のCookie管理
|
|
196
|
+
|
|
197
|
+
**背景:** ログインしてセッションCookieを取得し、認証済みリクエストを送信する。
|
|
198
|
+
|
|
199
|
+
### Claude Codeへの指示例
|
|
200
|
+
|
|
201
|
+
> alice@example.com でログインして、セッション情報を確認してください。
|
|
202
|
+
|
|
203
|
+
### 期待される流れ
|
|
204
|
+
|
|
205
|
+
1. `trigger_request(method: "POST", url: "http://localhost:3999/login", body: '{"email":"alice@example.com"}')`
|
|
206
|
+
→ ログイン成功、`Set-Cookie` ヘッダーが表示される
|
|
207
|
+
2. レスポンスからセッションCookie値を取得
|
|
208
|
+
3. `trigger_request(method: "GET", url: "http://localhost:3999/me", cookies: {"_session_id": "<取得した値>"})`
|
|
209
|
+
→ ログイン済みのユーザー情報が返る
|
|
210
|
+
|
|
211
|
+
### 確認ポイント
|
|
212
|
+
|
|
213
|
+
- [ ] ログインレスポンスに `Set-Cookie:` が表示される
|
|
214
|
+
- [ ] `cookies` パラメータでCookieを送信できる
|
|
215
|
+
- [ ] `/me` エンドポイントでログイン状態が確認できる
|
|
216
|
+
- [ ] `DELETE /logout` でログアウトできる
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## シナリオ10: trigger_request のレスポンス整形
|
|
221
|
+
|
|
222
|
+
**テスト対象:** JSON整形、HTML切り詰め、リダイレクト表示
|
|
223
|
+
|
|
224
|
+
### テストケース一覧
|
|
225
|
+
|
|
226
|
+
#### 10a. JSON レスポンスの整形
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
trigger_request(method: "GET", url: "http://localhost:3999/health")
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
- [ ] JSONがインデント付きで整形表示される
|
|
233
|
+
- [ ] `HTTP 200 OK` ステータス表示
|
|
234
|
+
|
|
235
|
+
#### 10b. HTML レスポンスの切り詰め
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
trigger_request(method: "GET", url: "http://localhost:3999/dashboard")
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
- [ ] HTMLがそのまま表示される(1000文字以下の場合)
|
|
242
|
+
- [ ] 大きいHTMLの場合 `... (HTML truncated, N bytes total)` と表示される
|
|
243
|
+
|
|
244
|
+
#### 10c. Content-Type 自動検出
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
# JSON body → Content-Type: application/json
|
|
248
|
+
trigger_request(method: "POST", url: "http://localhost:3999/users",
|
|
249
|
+
body: '{"name":"test","email":"auto@test.com"}')
|
|
250
|
+
|
|
251
|
+
# form body → Content-Type: application/x-www-form-urlencoded
|
|
252
|
+
trigger_request(method: "POST", url: "http://localhost:3999/users",
|
|
253
|
+
body: "name=test&email=form@test.com")
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
- [ ] JSON bodyの場合、Content-Typeが `application/json` になる
|
|
257
|
+
- [ ] form bodyの場合、Content-Typeが `application/x-www-form-urlencoded` になる
|
|
258
|
+
|
|
259
|
+
#### 10d. 空レスポンス
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
trigger_request(method: "DELETE", url: "http://localhost:3999/users/1")
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
- [ ] `204 No Content` + `(empty body)` と表示される
|
|
266
|
+
|
|
267
|
+
#### 10e. バリデーションエラー
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
trigger_request(method: "POST", url: "http://localhost:3999/users",
|
|
271
|
+
body: '{"name":"","email":"invalid"}')
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
- [ ] `422 Unprocessable Entity` ステータス
|
|
275
|
+
- [ ] エラーメッセージが整形表示される
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## シナリオ11: ブレークポイント + trigger_request でコントローラをデバッグ
|
|
280
|
+
|
|
281
|
+
**テスト対象:** Rails デバッグの統合ワークフロー
|
|
282
|
+
|
|
283
|
+
**背景:** N+1クエリ問題があるPosts#searchアクションをデバッグする。
|
|
284
|
+
|
|
285
|
+
### Claude Codeへの指示例
|
|
286
|
+
|
|
287
|
+
> `/posts/search?q=Rails` のリクエストをデバッグしたいです。PostsControllerのsearchアクションにブレークポイントを設定して、N+1問題を調査してください。
|
|
288
|
+
|
|
289
|
+
### 期待される流れ
|
|
290
|
+
|
|
291
|
+
1. `connect` → Railsプロセスに接続
|
|
292
|
+
2. `rails_routes(controller: "posts")` → search のルートを確認
|
|
293
|
+
3. `rails_model(model_name: "Post")` → Post のアソシエーションを確認
|
|
294
|
+
4. `set_breakpoint(file: "app/controllers/posts_controller.rb", line: ...)` → searchアクション内にBP設置
|
|
295
|
+
5. `trigger_request(method: "GET", url: "http://localhost:3999/posts/search?q=Rails")`
|
|
296
|
+
6. ブレークポイントでヒット
|
|
297
|
+
7. `get_context` → ローカル変数を確認
|
|
298
|
+
8. `evaluate_code(code: "@posts.to_sql")` → SQLを確認
|
|
299
|
+
9. `next` でステップ実行しながら N+1 を観察
|
|
300
|
+
10. `evaluate_code(code: "post.user")` → 個別クエリが発行されることを確認
|
|
301
|
+
|
|
302
|
+
### 確認ポイント
|
|
303
|
+
|
|
304
|
+
- [ ] ブレークポイントが正しくヒットする
|
|
305
|
+
- [ ] `get_context` でコントローラ内の変数が見える
|
|
306
|
+
- [ ] `evaluate_code` でActiveRecordのメソッドが実行できる
|
|
307
|
+
- [ ] `next` でアクション内をステップ実行できる
|
|
308
|
+
- [ ] デバッグ完了後 `continue_execution` で残りのリクエストが処理される
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## シナリオ12: rails_info → rails_routes → rails_model の連携
|
|
313
|
+
|
|
314
|
+
**テスト対象:** Railsツールの総合テスト
|
|
315
|
+
|
|
316
|
+
**背景:** 見知らぬRailsアプリに接続して、全体像を素早く把握する。
|
|
317
|
+
|
|
318
|
+
### Claude Codeへの指示例
|
|
319
|
+
|
|
320
|
+
> このRailsアプリの全体像を教えてください。どんなモデルがあって、どんなAPIエンドポイントがあるか調べてください。
|
|
321
|
+
|
|
322
|
+
### 期待される流れ
|
|
323
|
+
|
|
324
|
+
1. `connect` → 接続
|
|
325
|
+
2. `rails_info` → アプリ名、Rails/Ruby版、DB情報
|
|
326
|
+
3. `rails_routes` → 全ルート → コントローラ名からモデルを推測
|
|
327
|
+
4. `rails_model(model_name: "User")` → User構造
|
|
328
|
+
5. `rails_model(model_name: "Post")` → Post構造
|
|
329
|
+
6. `rails_model(model_name: "Comment")` → Comment構造
|
|
330
|
+
7. まとめを報告
|
|
331
|
+
|
|
332
|
+
### 確認ポイント
|
|
333
|
+
|
|
334
|
+
- [ ] 3つのRailsツールがエラーなく順次実行できる
|
|
335
|
+
- [ ] 各ツールの出力が一貫性を持つ(モデル間のアソシエーション名が対応する等)
|
|
336
|
+
- [ ] rails_model で User に `has_many :posts` があり、Post に `belongs_to :user` がある
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## 共通ツール使い方ヒント(Rails向け追加分)
|
|
341
|
+
|
|
342
|
+
| やりたいこと | ツール | 例 |
|
|
343
|
+
|---|---|---|
|
|
344
|
+
| アプリ概要を見る | `rails_info` | `rails_info()` |
|
|
345
|
+
| ルーティング確認 | `rails_routes` | `rails_routes(controller: "users")` |
|
|
346
|
+
| モデル構造を見る | `rails_model` | `rails_model(model_name: "User")` |
|
|
347
|
+
| HTTPリクエスト送信 | `trigger_request` | `trigger_request(method: "GET", url: "http://localhost:3999/users")` |
|
|
348
|
+
| JSONをPOST | `trigger_request` | `trigger_request(method: "POST", url: "...", body: '{"key":"value"}')` |
|
|
349
|
+
| Cookie付きリクエスト | `trigger_request` | `trigger_request(method: "GET", url: "...", cookies: {"key": "val"})` |
|
|
350
|
+
| CSRF明示制御 | `trigger_request` | `trigger_request(method: "POST", ..., skip_csrf: true)` |
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# debug-mcp デバッグ実験シナリオ
|
|
2
|
+
|
|
3
|
+
## 準備
|
|
4
|
+
|
|
5
|
+
Claude Codeの設定に debug-mcp を追加する(まだの場合):
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"mcpServers": {
|
|
10
|
+
"debug-mcp": {
|
|
11
|
+
"command": "bundle",
|
|
12
|
+
"args": ["exec", "debug-mcp"],
|
|
13
|
+
"cwd": "/home/rira/rira100000000/girb/debug-mcp"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## シナリオ1: 割引計算のバグを見つける
|
|
22
|
+
|
|
23
|
+
**ファイル:** `examples/01_simple_bug.rb`
|
|
24
|
+
|
|
25
|
+
**背景:** カートの合計金額が1000円以上なら10%割引されるはずだが、合計が期待値と合わない。
|
|
26
|
+
|
|
27
|
+
### 起動
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cd /home/rira/rira100000000/girb/debug-mcp
|
|
31
|
+
rdbg --open --port=12345 --nonstop -- examples/01_simple_bug.rb
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Claude Codeへの指示例
|
|
35
|
+
|
|
36
|
+
> ポート12345のデバッグセッションに接続して、Cartクラスの割引計算にバグがあるようです。原因を調査してください。
|
|
37
|
+
|
|
38
|
+
**期待される調査の流れ:**
|
|
39
|
+
1. `connect` でセッションに接続
|
|
40
|
+
2. `get_context` で現在の状態を確認
|
|
41
|
+
3. `evaluate_code` で `cart.subtotal`, `cart.discount_rate`, `cart.total` を評価
|
|
42
|
+
4. `get_source` で `Cart#total` のソースを確認
|
|
43
|
+
5. `sub + discount` が `sub - discount` であるべきと気づく
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## シナリオ2: データパイプラインのデータ消失を追跡
|
|
48
|
+
|
|
49
|
+
**ファイル:** `examples/02_data_pipeline.rb`
|
|
50
|
+
|
|
51
|
+
**背景:** CSVデータを処理するパイプラインで、5件中2件のレコードが「不正」として除外される。`nil.to_i` が `0` を返すことで、年齢やスコアが未入力のレコードがバリデーションで弾かれている。
|
|
52
|
+
|
|
53
|
+
### 起動
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
rdbg --open --port=12345 --nonstop -- examples/02_data_pipeline.rb
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Claude Codeへの指示例
|
|
60
|
+
|
|
61
|
+
> ポート12345に接続してください。CSVデータ処理パイプラインで一部のレコードが消えているようです。parseからvalidateの各段階でデータがどう変わるか、ステップ実行で追跡してください。
|
|
62
|
+
|
|
63
|
+
**期待される調査の流れ:**
|
|
64
|
+
1. `connect` で接続
|
|
65
|
+
2. `set_breakpoint` で `parse` メソッドの後にブレークポイント設置
|
|
66
|
+
3. `evaluate_code` で `@records` を確認 → age=0, score=0 のレコードがある
|
|
67
|
+
4. `set_breakpoint` で `validate` メソッド内にブレークポイント設置
|
|
68
|
+
5. `step` / `next` でどのレコードがrejectされるか確認
|
|
69
|
+
6. `nil.to_i` が原因と特定
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## シナリオ3: 木構造の探索を観察
|
|
74
|
+
|
|
75
|
+
**ファイル:** `examples/03_recursion.rb`
|
|
76
|
+
|
|
77
|
+
**背景:** 組織図(木構造)を構築し、探索する。再帰的な処理の動きを観察する。
|
|
78
|
+
|
|
79
|
+
### 起動
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
rdbg --open --port=12345 --nonstop -- examples/03_recursion.rb
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Claude Codeへの指示例
|
|
86
|
+
|
|
87
|
+
> ポート12345に接続して、組織図の木構造を調査してください。全体のノード数、最大深度を確認し、"Engineer 3"を検索する際のfindメソッドの動きを追跡してください。
|
|
88
|
+
|
|
89
|
+
**期待される調査の流れ:**
|
|
90
|
+
1. `connect` で接続
|
|
91
|
+
2. `evaluate_code` で `company.to_s` → 組織図全体を表示
|
|
92
|
+
3. `evaluate_code` で `company.total_nodes`, `company.max_depth` を確認
|
|
93
|
+
4. `set_breakpoint` で `TreeNode#find` にブレークポイント設置(条件: `target == "Engineer 3"`)
|
|
94
|
+
5. `continue_execution` → findの再帰呼び出しを観察
|
|
95
|
+
6. `get_context` で各フレームの `value`, `target` を確認
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## シナリオ4: run_scriptでスクリプトを直接起動
|
|
100
|
+
|
|
101
|
+
`run_script` ツールを使って、ターミナルで事前にrdbgを起動せずにClaude Codeだけで完結するパターン。
|
|
102
|
+
|
|
103
|
+
### Claude Codeへの指示例
|
|
104
|
+
|
|
105
|
+
> examples/01_simple_bug.rb をデバッガ付きで起動して、バグの原因を調査してください。
|
|
106
|
+
|
|
107
|
+
**期待される流れ:**
|
|
108
|
+
1. `run_script(file: "examples/01_simple_bug.rb")` でスクリプト起動&接続
|
|
109
|
+
2. 自動的にdebugger文で停止
|
|
110
|
+
3. 以降はシナリオ1と同様の調査
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Rails デバッグシナリオ
|
|
115
|
+
|
|
116
|
+
Rails アプリケーションのデバッグシナリオは [RAILS_SCENARIOS.md](RAILS_SCENARIOS.md) を参照。
|
|
117
|
+
|
|
118
|
+
- シナリオ5: `rails_info` でアプリ概要を把握
|
|
119
|
+
- シナリオ6: `rails_routes` でルーティング確認
|
|
120
|
+
- シナリオ7: `rails_model` でモデル構造確認
|
|
121
|
+
- シナリオ8: `trigger_request` のCSRF自動スキップ
|
|
122
|
+
- シナリオ9: `trigger_request` のCookie/セッション管理
|
|
123
|
+
- シナリオ10: レスポンス整形(JSON/HTML/リダイレクト)
|
|
124
|
+
- シナリオ11: ブレークポイント + `trigger_request` 統合デバッグ
|
|
125
|
+
- シナリオ12: Railsツール連携の総合テスト
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 共通のツール使い方ヒント
|
|
130
|
+
|
|
131
|
+
| やりたいこと | ツール | 例 |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| 変数の値を見る | `evaluate_code` | `evaluate_code(code: "user.name")` |
|
|
134
|
+
| オブジェクトの詳細 | `inspect_object` | `inspect_object(expression: "cart")` |
|
|
135
|
+
| 全変数を一覧 | `get_context` | `get_context()` |
|
|
136
|
+
| メソッドのソースを読む | `get_source` | `get_source(target: "Cart#total")` |
|
|
137
|
+
| 次の行へ | `next` | `next()` |
|
|
138
|
+
| メソッドの中へ | `step` | `step()` |
|
|
139
|
+
| ブレークポイント設定 | `set_breakpoint` | `set_breakpoint(file: "example.rb", line: 10)` |
|
|
140
|
+
| 条件付きブレークポイント | `set_breakpoint` | `set_breakpoint(file: "example.rb", line: 10, condition: "x > 5")` |
|
|
141
|
+
| 実行再開 | `continue_execution` | `continue_execution()` |
|
|
142
|
+
| 任意のデバッガコマンド | `run_debug_command` | `run_debug_command(command: "info threads")` |
|