fchek 1.0.0
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.
- package/README.md +64 -0
- package/bin/fchek.js +107 -0
- package/lib/api.js +110 -0
- package/lib/audit.js +211 -0
- package/lib/bench.js +248 -0
- package/lib/config.js +191 -0
- package/lib/context.js +356 -0
- package/lib/convention.js +526 -0
- package/lib/coverage.js +604 -0
- package/lib/db.js +135 -0
- package/lib/deps-check.js +264 -0
- package/lib/deps.js +374 -0
- package/lib/docker.js +84 -0
- package/lib/doctor.js +149 -0
- package/lib/dom.js +226 -0
- package/lib/fuzz.js +470 -0
- package/lib/git.js +290 -0
- package/lib/goto.js +544 -0
- package/lib/launch.js +182 -0
- package/lib/lint.js +624 -0
- package/lib/new_features.test.js +181 -0
- package/lib/output.js +46 -0
- package/lib/port.js +173 -0
- package/lib/process.js +228 -0
- package/lib/profile.js +453 -0
- package/lib/python.js +41 -0
- package/lib/race.js +186 -0
- package/lib/registry.js +179 -0
- package/lib/repl.js +135 -0
- package/lib/run.js +403 -0
- package/lib/screenshot.js +152 -0
- package/lib/secrets.js +257 -0
- package/lib/state.js +219 -0
- package/lib/test.js +471 -0
- package/lib/vuln.js +253 -0
- package/lib/watch.js +240 -0
- package/lib/winlog.js +123 -0
- package/package.json +27 -0
- package/skills/ACTIVATE.md +274 -0
- package/skills/README.md +163 -0
- package/skills/agent.md +444 -0
- package/skills/api.md +47 -0
- package/skills/bench.md +117 -0
- package/skills/context.md +116 -0
- package/skills/convention.md +143 -0
- package/skills/coverage.md +99 -0
- package/skills/csharp.md +97 -0
- package/skills/db.md +66 -0
- package/skills/deps-check.md +135 -0
- package/skills/deps.md +143 -0
- package/skills/docker.md +61 -0
- package/skills/dom.md +56 -0
- package/skills/fuzz.md +167 -0
- package/skills/goto.md +111 -0
- package/skills/lint.md +123 -0
- package/skills/port.md +57 -0
- package/skills/profile.md +91 -0
- package/skills/race.md +117 -0
- package/skills/repl.md +81 -0
- package/skills/rules.md +318 -0
- package/skills/run.md +135 -0
- package/skills/secrets.md +170 -0
- package/skills/security.md +360 -0
- package/skills/state.md +261 -0
- package/skills/vuln.md +57 -0
- package/skills/windows.md +320 -0
package/skills/agent.md
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
# agent.md — Полная инструкция автономной работы
|
|
2
|
+
|
|
3
|
+
Ты работаешь как опытный разработчик: взял задачу, сделал, проверил, сдал.
|
|
4
|
+
Человек получает только готовый результат — не процесс.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## ЦИКЛ РАЗРАБОТКИ
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
ПОЛУЧИЛ
|
|
12
|
+
└─→ ПОНЯЛ ──────────────────────────────────────────────────┐
|
|
13
|
+
└─→ СПЛАНИРОВАЛ ──────────────────────────────────────┤
|
|
14
|
+
└─→ НАПИСАЛ ───────────────────────────────────┤
|
|
15
|
+
└─→ ПРОВЕРИЛ ─── ✗ ──→ ИСПРАВИЛ ─────────┤
|
|
16
|
+
└─── ✓ ──→ ЗАФИКСИРОВАЛ ┤
|
|
17
|
+
└─→ ДОЛОЖИЛ ────────┘
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Если ПРОВЕРИЛ вернул ошибку — возвращайся к ИСПРАВИЛ, потом снова ПРОВЕРИЛ.
|
|
21
|
+
Не выходи из петли пока все проверки не зелёные.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## КОМАНДЫ ПО ФАЗАМ
|
|
26
|
+
|
|
27
|
+
### ФАЗА: ПОНЯЛ
|
|
28
|
+
|
|
29
|
+
Выполни все три команды перед тем как писать хоть одну строку кода.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
fchek audit .
|
|
33
|
+
```
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"status": "ok",
|
|
37
|
+
"data": {
|
|
38
|
+
"verdict": "healthy",
|
|
39
|
+
"critical_issues": [],
|
|
40
|
+
"next_actions": ["run fchek lint . to clean up 3 warnings"]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
Если `verdict: "needs_attention"` — исправь `critical_issues[]` немедленно.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
fchek convention .
|
|
48
|
+
```
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"status": "ok",
|
|
52
|
+
"data": {
|
|
53
|
+
"conventions": [{
|
|
54
|
+
"framework": "FastAPI",
|
|
55
|
+
"naming_style": "snake_case",
|
|
56
|
+
"error_handling": "HTTPException + custom handlers",
|
|
57
|
+
"async_patterns": "async/await throughout",
|
|
58
|
+
"logging_style": ["structlog", "stdlib logging"]
|
|
59
|
+
}]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
Читай `naming_style`, `error_handling`, `logging_style[0]`. Используй тот же стиль.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
fchek context src/ --names-only
|
|
67
|
+
```
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"status": "ok",
|
|
71
|
+
"data": {
|
|
72
|
+
"name_index": {
|
|
73
|
+
"UserService": [{"file": "src/services/user.py", "line": 12}],
|
|
74
|
+
"validate_email": [{"file": "src/utils.py", "line": 87}]
|
|
75
|
+
},
|
|
76
|
+
"duplicates": []
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
Читай `name_index`. Если нужное имя уже занято — используй существующее или выбери другое.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### ФАЗА: СПЛАНИРОВАЛ
|
|
85
|
+
|
|
86
|
+
Зафиксируй план до написания кода:
|
|
87
|
+
```bash
|
|
88
|
+
fchek state set task "реализовать JWT refresh token rotation"
|
|
89
|
+
fchek state set files "src/auth.py src/middleware.py tests/test_auth.py"
|
|
90
|
+
fchek state set next_step "начать с src/auth.py — функция rotate_refresh_token()"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Проверь зависимости которые собираешься использовать:
|
|
94
|
+
```bash
|
|
95
|
+
fchek deps-check <lib> --lang=<python|js|rust|go|csharp>
|
|
96
|
+
```
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"status": "ok",
|
|
100
|
+
"data": {
|
|
101
|
+
"package": "python-jose",
|
|
102
|
+
"installed_version": "3.3.0",
|
|
103
|
+
"latest_version": "3.3.0",
|
|
104
|
+
"installed_deprecated": null,
|
|
105
|
+
"deprecation_notices": []
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
Если `installed_deprecated` не null или `deprecation_notices` не пуст — сообщи пользователю.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### ФАЗА: НАПИСАЛ
|
|
114
|
+
|
|
115
|
+
Пиши код в стиле который показала `fchek convention`.
|
|
116
|
+
После каждого файла сохраняй прогресс:
|
|
117
|
+
```bash
|
|
118
|
+
fchek state set status "in_progress"
|
|
119
|
+
fchek state set next_step "написать тесты для rotate_refresh_token()"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### ФАЗА: ПРОВЕРИЛ
|
|
125
|
+
|
|
126
|
+
Выполни все четыре проверки строго по порядку:
|
|
127
|
+
|
|
128
|
+
**Проверка 1 — код запускается:**
|
|
129
|
+
```bash
|
|
130
|
+
fchek run src/main.py
|
|
131
|
+
```
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"status": "ok",
|
|
135
|
+
"data": {
|
|
136
|
+
"exit_code": 0,
|
|
137
|
+
"success": true,
|
|
138
|
+
"stdout": "Server started on :8000\n",
|
|
139
|
+
"stderr": ""
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
Ожидаемое: `exit_code: 0`, `success: true`, `stderr: ""`.
|
|
144
|
+
|
|
145
|
+
**Проверка 2 — тесты проходят:**
|
|
146
|
+
```bash
|
|
147
|
+
fchek test .
|
|
148
|
+
```
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"status": "ok",
|
|
152
|
+
"data": {
|
|
153
|
+
"verdict": "all_passed",
|
|
154
|
+
"passed": 24,
|
|
155
|
+
"failed": 0,
|
|
156
|
+
"skipped": 1
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
Ожидаемое: `verdict: "all_passed"`, `failed: 0`.
|
|
161
|
+
|
|
162
|
+
**Проверка 3 — нет секретов:**
|
|
163
|
+
```bash
|
|
164
|
+
fchek secrets .
|
|
165
|
+
```
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"status": "ok",
|
|
169
|
+
"data": {
|
|
170
|
+
"verdict": "clean",
|
|
171
|
+
"total_findings": 0,
|
|
172
|
+
"summary": {"critical": 0, "high": 0, "other": 0}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
Ожидаемое: `verdict: "clean"`, `total_findings: 0`.
|
|
177
|
+
|
|
178
|
+
**Проверка 4 — код чистый:**
|
|
179
|
+
```bash
|
|
180
|
+
fchek lint .
|
|
181
|
+
```
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"status": "ok",
|
|
185
|
+
"data": {
|
|
186
|
+
"issues_count": 0,
|
|
187
|
+
"fixed": 3,
|
|
188
|
+
"remaining_issues": []
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
Ожидаемое: `issues_count: 0` (или ≤ `config.lint_threshold`).
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
### ФАЗА: ИСПРАВИЛ (ПЕТЛЯ ИСПРАВЛЕНИЯ)
|
|
197
|
+
|
|
198
|
+
Если любая проверка упала — входи в петлю:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
ОШИБКА ПОЛУЧЕНА
|
|
202
|
+
↓
|
|
203
|
+
Читай error/reason/verdict — точно что упало?
|
|
204
|
+
↓
|
|
205
|
+
Исправь ОДНУ конкретную причину
|
|
206
|
+
↓
|
|
207
|
+
Запусти ТУ ЖЕ проверку снова
|
|
208
|
+
↓
|
|
209
|
+
Получи зелёный результат
|
|
210
|
+
↓
|
|
211
|
+
Переходи к следующей проверке
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Правила петли:**
|
|
215
|
+
- Исправляй одну причину за раз — не переписывай всё сразу
|
|
216
|
+
- После двух неудачных попыток одного подхода — смени подход
|
|
217
|
+
- Не переходи к следующей проверке пока текущая не зелёная
|
|
218
|
+
- Если застрял более трёх итераций — зафиксируй: `fchek state set blocker "<проблема>"`
|
|
219
|
+
|
|
220
|
+
**Максимальное число итераций на одну ошибку: 5.**
|
|
221
|
+
Если за 5 итераций не исправил — это блокер. Зафиксируй и доложи.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### ФАЗА: ЗАФИКСИРОВАЛ
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
# Убедись что всё в порядке
|
|
229
|
+
fchek git status
|
|
230
|
+
```
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"data": {
|
|
234
|
+
"branch": "feat/jwt-refresh",
|
|
235
|
+
"staged": [],
|
|
236
|
+
"unstaged": ["src/auth.py", "tests/test_auth.py"],
|
|
237
|
+
"is_clean": false
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Поставь в stage только изменённые файлы задачи
|
|
244
|
+
fchek git stage src/auth.py tests/test_auth.py
|
|
245
|
+
|
|
246
|
+
# Коммит с осмысленным сообщением
|
|
247
|
+
fchek git commit "feat: implement JWT refresh token rotation"
|
|
248
|
+
```
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"status": "ok",
|
|
252
|
+
"data": {
|
|
253
|
+
"committed": true,
|
|
254
|
+
"message": "feat: implement JWT refresh token rotation",
|
|
255
|
+
"files_committed": ["src/auth.py", "tests/test_auth.py"],
|
|
256
|
+
"hash": "a3f9c2d"
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Обнови state
|
|
263
|
+
fchek state set status "done"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
### ФАЗА: ДОЛОЖИЛ
|
|
269
|
+
|
|
270
|
+
Доклад состоит из четырёх частей — ни больше, ни меньше:
|
|
271
|
+
|
|
272
|
+
1. **Что сделано** — одно-два предложения
|
|
273
|
+
2. **Какие файлы изменены** — список
|
|
274
|
+
3. **Вывод проверок** — `fchek run` + `fchek test` с реальными значениями
|
|
275
|
+
4. **Что не сделано** (если есть) — блокеры или ограничения
|
|
276
|
+
|
|
277
|
+
Шаблон доклада:
|
|
278
|
+
```
|
|
279
|
+
Реализовал JWT refresh token rotation.
|
|
280
|
+
|
|
281
|
+
Изменённые файлы:
|
|
282
|
+
src/auth.py — функция rotate_refresh_token()
|
|
283
|
+
tests/test_auth.py — 4 новых теста
|
|
284
|
+
|
|
285
|
+
Проверки:
|
|
286
|
+
fchek run src/main.py → exit_code: 0
|
|
287
|
+
fchek test . → verdict: all_passed (24 passed, 0 failed)
|
|
288
|
+
fchek secrets . → verdict: clean
|
|
289
|
+
fchek lint . → issues_count: 0
|
|
290
|
+
|
|
291
|
+
Коммит: feat: implement JWT refresh token rotation (a3f9c2d)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Не добавляй ничего лишнего. Не говори «я» и «постарался». Только факты.
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## ПРИМЕРЫ РЕАЛЬНЫХ ДИАЛОГОВ
|
|
299
|
+
|
|
300
|
+
### Пример 1: простая задача
|
|
301
|
+
|
|
302
|
+
**Задача:** Добавь функцию `calculate_discount(price, percent)` в `src/pricing.py`
|
|
303
|
+
|
|
304
|
+
**Что делает агент:**
|
|
305
|
+
```bash
|
|
306
|
+
fchek context src/ --names-only
|
|
307
|
+
# → name_index не содержит "calculate_discount" ✓
|
|
308
|
+
|
|
309
|
+
fchek convention .
|
|
310
|
+
# → naming_style: snake_case, error_handling: raise ValueError
|
|
311
|
+
|
|
312
|
+
# [пишет функцию]
|
|
313
|
+
|
|
314
|
+
fchek run src/pricing.py
|
|
315
|
+
# → exit_code: 0
|
|
316
|
+
|
|
317
|
+
fchek test .
|
|
318
|
+
# → verdict: all_passed, passed: 8
|
|
319
|
+
|
|
320
|
+
fchek secrets .
|
|
321
|
+
# → verdict: clean
|
|
322
|
+
|
|
323
|
+
fchek lint .
|
|
324
|
+
# → issues_count: 0
|
|
325
|
+
|
|
326
|
+
fchek git stage src/pricing.py
|
|
327
|
+
fchek git commit "feat: add calculate_discount function"
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Что говорит агент:**
|
|
331
|
+
```
|
|
332
|
+
Добавил функцию calculate_discount(price, percent) в src/pricing.py.
|
|
333
|
+
|
|
334
|
+
Изменённые файлы:
|
|
335
|
+
src/pricing.py — calculate_discount() в строке 34
|
|
336
|
+
|
|
337
|
+
Проверки:
|
|
338
|
+
fchek run src/pricing.py → exit_code: 0
|
|
339
|
+
fchek test . → verdict: all_passed (8 passed)
|
|
340
|
+
fchek secrets . → verdict: clean
|
|
341
|
+
|
|
342
|
+
Коммит: feat: add calculate_discount function (b2e8a1f)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
### Пример 2: задача с существующим именем
|
|
348
|
+
|
|
349
|
+
**Задача:** Создай класс `UserValidator` в проекте
|
|
350
|
+
|
|
351
|
+
**Что делает агент:**
|
|
352
|
+
```bash
|
|
353
|
+
fchek context src/ --names-only
|
|
354
|
+
# → name_index содержит "UserValidator": [{"file": "src/validators.py", "line": 45}]
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Что говорит агент:**
|
|
358
|
+
```
|
|
359
|
+
В проекте уже есть UserValidator в src/validators.py:45.
|
|
360
|
+
Использую существующий. Уточни какую именно логику нужно добавить или изменить.
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### Пример 3: задача с секретами
|
|
366
|
+
|
|
367
|
+
**Задача:** Добавь подключение к PostgreSQL
|
|
368
|
+
|
|
369
|
+
**Что делает агент:**
|
|
370
|
+
```bash
|
|
371
|
+
# [пишет код с connection string]
|
|
372
|
+
|
|
373
|
+
fchek secrets .
|
|
374
|
+
# → verdict: "critical", findings[0].file: "src/db.py", findings[0].line: 8
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**Что делает агент (исправляет):**
|
|
378
|
+
```python
|
|
379
|
+
# Было:
|
|
380
|
+
DB_URL = "postgresql://admin:Secret123@prod.db:5432/app"
|
|
381
|
+
|
|
382
|
+
# Стало:
|
|
383
|
+
import os
|
|
384
|
+
DB_URL = os.environ.get("DATABASE_URL")
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
fchek secrets .
|
|
389
|
+
# → verdict: clean ✓
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Что говорит агент:**
|
|
393
|
+
```
|
|
394
|
+
Добавил подключение к PostgreSQL через переменную окружения DATABASE_URL.
|
|
395
|
+
|
|
396
|
+
Изменённые файлы:
|
|
397
|
+
src/db.py — connection через os.environ.get("DATABASE_URL")
|
|
398
|
+
|
|
399
|
+
Проверки:
|
|
400
|
+
fchek secrets . → verdict: clean
|
|
401
|
+
fchek run src/main.py → exit_code: 0
|
|
402
|
+
|
|
403
|
+
Установи переменную перед запуском:
|
|
404
|
+
export DATABASE_URL="postgresql://user:pass@host:5432/db"
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
### Пример 4: задача с блокером
|
|
410
|
+
|
|
411
|
+
**Задача:** Добавь кэширование через Redis
|
|
412
|
+
|
|
413
|
+
**Что делает агент:**
|
|
414
|
+
```bash
|
|
415
|
+
fchek deps-check redis --lang=python
|
|
416
|
+
# → installed_version: null (не установлен)
|
|
417
|
+
|
|
418
|
+
# [пытается запустить после установки]
|
|
419
|
+
fchek run main.py
|
|
420
|
+
# → error: "Runtime not found: redis-server"
|
|
421
|
+
|
|
422
|
+
fchek doctor
|
|
423
|
+
# → redis-server: not found
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
fchek state set blocker "redis-server не установлен на хосте"
|
|
428
|
+
fchek state set next_step "установить Redis: brew install redis / apt install redis-server"
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Что говорит агент:**
|
|
432
|
+
```
|
|
433
|
+
Написал код кэширования через Redis (src/cache.py).
|
|
434
|
+
|
|
435
|
+
Блокер: redis-server не установлен на этой машине.
|
|
436
|
+
fchek doctor → redis-server: not found
|
|
437
|
+
|
|
438
|
+
Что нужно:
|
|
439
|
+
brew install redis # macOS
|
|
440
|
+
apt install redis-server # Linux
|
|
441
|
+
|
|
442
|
+
После установки запусти: fchek run src/main.py
|
|
443
|
+
Код готов, ждёт только Redis.
|
|
444
|
+
```
|
package/skills/api.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# skill: fchek api — Тестирование HTTP/API
|
|
2
|
+
|
|
3
|
+
## Что делает
|
|
4
|
+
|
|
5
|
+
Выполняет HTTP-запросы к веб-сервисам и эндпоинтам для проверки работоспособности API. Возвращает статус-код, заголовки, размер тела ответа и latency.
|
|
6
|
+
|
|
7
|
+
## Синтаксис
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
fchek api <url> [--method=<method>] [--headers=<key:val,key2:val2>] [--body=<body>]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Вывод JSON
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"status": "ok",
|
|
18
|
+
"command": "api",
|
|
19
|
+
"data": {
|
|
20
|
+
"status_code": 200,
|
|
21
|
+
"status_text": "OK",
|
|
22
|
+
"time_ms": 42,
|
|
23
|
+
"headers": {
|
|
24
|
+
"content-type": "application/json; charset=utf-8",
|
|
25
|
+
"connection": "close"
|
|
26
|
+
},
|
|
27
|
+
"body_size_bytes": 17,
|
|
28
|
+
"body": "{\"hello\":\"world\"}",
|
|
29
|
+
"body_truncated": false
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## КАК AI ДОЛЖЕН ИСПОЛЬЗОВАТЬ ЭТО
|
|
35
|
+
|
|
36
|
+
### Сценарии
|
|
37
|
+
|
|
38
|
+
1. **Проверка работоспособности**: после развертывания веб-сервера выполни запрос:
|
|
39
|
+
```bash
|
|
40
|
+
fchek api http://localhost:3000/health
|
|
41
|
+
```
|
|
42
|
+
Убедись, что `"status_code": 200`.
|
|
43
|
+
|
|
44
|
+
2. **Проверка интеграции**: проверь ответ внешнего API:
|
|
45
|
+
```bash
|
|
46
|
+
fchek api https://httpbin.org/post --method=POST --headers="Content-Type:application/json" --body="{\"test\":true}"
|
|
47
|
+
```
|
package/skills/bench.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# skill: fchek bench — бенчмарк до/после рефакторинга
|
|
2
|
+
|
|
3
|
+
## Что делает
|
|
4
|
+
|
|
5
|
+
Запускает два варианта кода (до и после изменений) N раз каждый
|
|
6
|
+
и показывает точный diff по времени и памяти.
|
|
7
|
+
Убирает "я думаю стало быстрее" — заменяет догадки числами.
|
|
8
|
+
|
|
9
|
+
## Синтаксис
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
fchek bench <file> --before=<ver_a> --after=<ver_b> [--runs=5] [--timeout=30000]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- `--before=<path>` — "до" версия (файл или shell-команда)
|
|
16
|
+
- `--after=<path>` — "после" версия
|
|
17
|
+
- `--runs=N` — количество запусков для стабильного среднего (default: 5)
|
|
18
|
+
- `--timeout=ms` — таймаут на один запуск (default: 30000)
|
|
19
|
+
|
|
20
|
+
## Вывод JSON
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"status": "ok",
|
|
25
|
+
"command": "bench",
|
|
26
|
+
"data": {
|
|
27
|
+
"before": {
|
|
28
|
+
"spec": "main_old.py",
|
|
29
|
+
"runs": 5,
|
|
30
|
+
"avg_ms": 842,
|
|
31
|
+
"min_ms": 831,
|
|
32
|
+
"max_ms": 860,
|
|
33
|
+
"stdout_sample": "result: 42\n"
|
|
34
|
+
},
|
|
35
|
+
"after": {
|
|
36
|
+
"spec": "main.py",
|
|
37
|
+
"avg_ms": 201,
|
|
38
|
+
"min_ms": 195,
|
|
39
|
+
"max_ms": 210
|
|
40
|
+
},
|
|
41
|
+
"comparison": {
|
|
42
|
+
"time_delta_ms": -641,
|
|
43
|
+
"speedup_ratio": 4.189,
|
|
44
|
+
"verdict": "faster",
|
|
45
|
+
"pct_change": 318.9
|
|
46
|
+
},
|
|
47
|
+
"stdout_diff": [
|
|
48
|
+
{ "line": 3, "before": "old output", "after": "new output" }
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`verdict`: `"faster"` | `"slower"` | `"no_significant_change"` (порог ±5%)
|
|
55
|
+
|
|
56
|
+
## Как AI должен использовать это
|
|
57
|
+
|
|
58
|
+
### Сценарий: "Провёл рефакторинг — проверить что стало быстрее"
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Сохрани старую версию перед изменениями
|
|
62
|
+
cp main.py main_old.py
|
|
63
|
+
# ... внеси изменения в main.py ...
|
|
64
|
+
|
|
65
|
+
# Бенчмарк
|
|
66
|
+
fchek bench main.py --before=main_old.py --after=main.py --runs=10
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Сценарий: "Сравнить два алгоритма"
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
fchek bench . \
|
|
73
|
+
--before="python algo_v1.py --input=data.json" \
|
|
74
|
+
--after="python algo_v2.py --input=data.json" \
|
|
75
|
+
--runs=5
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Сценарий: "Сравнить Rust релиз vs дебаг"
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
fchek bench . \
|
|
82
|
+
--before="cargo run -- data.txt" \
|
|
83
|
+
--after="cargo run --release -- data.txt" \
|
|
84
|
+
--runs=3
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Алгоритм интерпретации результатов
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
speedup_ratio > 1.0 → after быстрее
|
|
91
|
+
speedup_ratio < 1.0 → after медленнее
|
|
92
|
+
speedup_ratio = 4.2 → после в 4.2× быстрее = +320% производительности
|
|
93
|
+
|
|
94
|
+
verdict = "no_significant_change" → разница < 5%, шум измерений
|
|
95
|
+
→ увеличь --runs=20 для стабильности
|
|
96
|
+
→ проверь что входные данные одинаковые
|
|
97
|
+
|
|
98
|
+
stdout_diff не пустой → результаты различаются!
|
|
99
|
+
→ рефакторинг изменил поведение — баг?
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Ключевые поля для AI
|
|
103
|
+
|
|
104
|
+
| Поле | Что означает |
|
|
105
|
+
|---|---|
|
|
106
|
+
| `comparison.speedup_ratio` | во сколько раз after быстрее before |
|
|
107
|
+
| `comparison.verdict` | `faster` / `slower` / `no_significant_change` |
|
|
108
|
+
| `comparison.pct_change` | % изменения производительности |
|
|
109
|
+
| `stdout_diff` | различия в выводе — если не пустой, поведение изменилось |
|
|
110
|
+
| `before.min_ms` / `after.min_ms` | минимальное время (наиболее стабильная метрика) |
|
|
111
|
+
|
|
112
|
+
## Важные замечания
|
|
113
|
+
|
|
114
|
+
- Используй `min_ms` как основную метрику — она менее подвержена шуму OS
|
|
115
|
+
- `--runs=5` достаточно для первой оценки, `--runs=20` для точных данных
|
|
116
|
+
- Если `stdout_diff` не пустой — сначала проверь правильность, потом скорость
|
|
117
|
+
- Для C/C++ файлы компилируются с `-O2` — убедись что тестируешь то что хочешь
|