reviw 0.14.5 → 0.15.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.
- package/README.ja.md +16 -2
- package/README.md +61 -4
- package/cli.cjs +50 -9
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -151,7 +151,14 @@ plugin/
|
|
|
151
151
|
│ ├── do.md # /reviw:doコマンド定義
|
|
152
152
|
│ └── done.md # /reviw:doneコマンド定義
|
|
153
153
|
├── agents/
|
|
154
|
-
│
|
|
154
|
+
│ ├── report-builder.md # レポート生成エージェント
|
|
155
|
+
│ ├── e2e-health-reviewer.md # E2Eテスト健全性チェック
|
|
156
|
+
│ ├── review-code-quality.md # コード品質レビュー
|
|
157
|
+
│ ├── review-security.md # セキュリティ監査
|
|
158
|
+
│ ├── review-a11y-ux.md # アクセシビリティ & UX
|
|
159
|
+
│ ├── review-figma-fidelity.md # デザイン忠実度
|
|
160
|
+
│ ├── review-copy-consistency.md # テキスト整合性
|
|
161
|
+
│ └── review-e2e-integrity.md # E2Eテスト整合性
|
|
155
162
|
├── skills/
|
|
156
163
|
│ ├── artifact-proof/
|
|
157
164
|
│ │ └── SKILL.md # エビデンス収集スキル
|
|
@@ -171,8 +178,15 @@ plugin/
|
|
|
171
178
|
| 種類 | 名前 | 説明 |
|
|
172
179
|
|------|------|------|
|
|
173
180
|
| **コマンド** | `/reviw:do` | タスク開始 - worktree作成、計画、todo登録 |
|
|
174
|
-
| **コマンド** | `/reviw:done` | 完了チェックリスト -
|
|
181
|
+
| **コマンド** | `/reviw:done` | 完了チェックリスト - 7レビューエージェント実行、エビデンス収集、レビュー開始 |
|
|
175
182
|
| **エージェント** | `report-builder` | ユーザーレビュー用レポート準備 |
|
|
183
|
+
| **エージェント** | `review-code-quality` | コード品質: 可読性、DRY、型安全性、エラーハンドリング |
|
|
184
|
+
| **エージェント** | `review-security` | セキュリティ: XSS、インジェクション、OWASP Top 10、秘密情報検出 |
|
|
185
|
+
| **エージェント** | `review-a11y-ux` | アクセシビリティ: WCAG 2.2 AA、キーボード操作、UXフロー |
|
|
186
|
+
| **エージェント** | `review-figma-fidelity` | デザイン: トークン準拠、視覚的一貫性 |
|
|
187
|
+
| **エージェント** | `review-copy-consistency` | コピー: テキスト整合性、トーン&マナー、i18n |
|
|
188
|
+
| **エージェント** | `review-e2e-integrity` | E2E: ユーザーフロー再現、モック汚染検出 |
|
|
189
|
+
| **エージェント** | `e2e-health-reviewer` | E2E: goto制限、レコードアサーション、ハードコード検出 |
|
|
176
190
|
| **スキル** | `artifact-proof` | エビデンス収集(スクリーンショット、動画、ログ) |
|
|
177
191
|
| **スキル** | `webapp-testing` | Playwrightによるブラウザ自動化と検証 |
|
|
178
192
|
| **フック** | PreToolUse | git commit/push前にレビューを促すリマインダー |
|
package/README.md
CHANGED
|
@@ -151,7 +151,14 @@ plugin/
|
|
|
151
151
|
│ ├── do.md # /reviw:do command definition
|
|
152
152
|
│ └── done.md # /reviw:done command definition
|
|
153
153
|
├── agents/
|
|
154
|
-
│
|
|
154
|
+
│ ├── report-builder.md # Report generation agent
|
|
155
|
+
│ ├── e2e-health-reviewer.md # E2E test health check
|
|
156
|
+
│ ├── review-code-quality.md # Code quality review
|
|
157
|
+
│ ├── review-security.md # Security audit
|
|
158
|
+
│ ├── review-a11y-ux.md # Accessibility & UX
|
|
159
|
+
│ ├── review-figma-fidelity.md # Design fidelity
|
|
160
|
+
│ ├── review-copy-consistency.md # Text consistency
|
|
161
|
+
│ └── review-e2e-integrity.md # E2E test integrity
|
|
155
162
|
├── skills/
|
|
156
163
|
│ ├── artifact-proof/
|
|
157
164
|
│ │ └── SKILL.md # Evidence collection skill
|
|
@@ -171,8 +178,15 @@ plugin/
|
|
|
171
178
|
| Type | Name | Description |
|
|
172
179
|
|------|------|-------------|
|
|
173
180
|
| **Command** | `/reviw:do` | Start a task - create worktree, plan, register todos |
|
|
174
|
-
| **Command** | `/reviw:done` | Complete checklist - collect evidence, start review |
|
|
181
|
+
| **Command** | `/reviw:done` | Complete checklist - run 7 review agents, collect evidence, start review |
|
|
175
182
|
| **Agent** | `report-builder` | Prepare reports and evidence for user review |
|
|
183
|
+
| **Agent** | `review-code-quality` | Code quality: readability, DRY, type safety, error handling |
|
|
184
|
+
| **Agent** | `review-security` | Security: XSS, injection, OWASP Top 10, secrets detection |
|
|
185
|
+
| **Agent** | `review-a11y-ux` | Accessibility: WCAG 2.2 AA, keyboard nav, UX flow |
|
|
186
|
+
| **Agent** | `review-figma-fidelity` | Design: token compliance, visual consistency |
|
|
187
|
+
| **Agent** | `review-copy-consistency` | Copy: text consistency, tone & manner, i18n |
|
|
188
|
+
| **Agent** | `review-e2e-integrity` | E2E: user flow reproduction, mock contamination |
|
|
189
|
+
| **Agent** | `e2e-health-reviewer` | E2E: goto restrictions, record assertions, hardcoding |
|
|
176
190
|
| **Skill** | `artifact-proof` | Collect evidence (screenshots, videos, logs) |
|
|
177
191
|
| **Skill** | `webapp-testing` | Browser automation and verification with Playwright |
|
|
178
192
|
| **Hook** | PreToolUse | Remind to review before git commit/push |
|
|
@@ -224,14 +238,43 @@ Validates completion criteria before allowing task completion.
|
|
|
224
238
|
|
|
225
239
|
---
|
|
226
240
|
|
|
227
|
-
###
|
|
241
|
+
### Agents
|
|
242
|
+
|
|
243
|
+
#### Review Agents (7 agents run in parallel)
|
|
244
|
+
|
|
245
|
+
When `/reviw:done` is executed, 7 review agents run simultaneously and append their findings to `REPORT.md`:
|
|
246
|
+
|
|
247
|
+
| Agent | Focus | Output Section |
|
|
248
|
+
|-------|-------|----------------|
|
|
249
|
+
| `review-code-quality` | Readability, DRY, type safety, error handling | Code Quality Review |
|
|
250
|
+
| `review-security` | XSS, injection, OWASP Top 10, secrets | Security Review |
|
|
251
|
+
| `review-a11y-ux` | WCAG 2.2 AA, keyboard nav, focus management | A11y & UX Review |
|
|
252
|
+
| `review-figma-fidelity` | Design tokens, visual consistency | Figma Fidelity Review |
|
|
253
|
+
| `review-copy-consistency` | Text consistency, i18n, tone & manner | Copy Consistency Review |
|
|
254
|
+
| `review-e2e-integrity` | User flow reproduction, mock contamination | E2E Integrity Review |
|
|
255
|
+
| `e2e-health-reviewer` | goto restrictions, record assertions | E2E Health Review |
|
|
256
|
+
|
|
257
|
+
**Total score:** Each agent scores X/5, combined for X/35 total.
|
|
258
|
+
|
|
259
|
+
**Invocation (parallel):**
|
|
260
|
+
```
|
|
261
|
+
Task tool with 7 parallel calls:
|
|
262
|
+
subagent_type: "review-code-quality"
|
|
263
|
+
subagent_type: "review-security"
|
|
264
|
+
subagent_type: "review-a11y-ux"
|
|
265
|
+
subagent_type: "review-figma-fidelity"
|
|
266
|
+
subagent_type: "review-copy-consistency"
|
|
267
|
+
subagent_type: "review-e2e-integrity"
|
|
268
|
+
subagent_type: "e2e-health-reviewer"
|
|
269
|
+
```
|
|
228
270
|
|
|
229
271
|
#### `report-builder`
|
|
230
272
|
|
|
231
|
-
Specialized agent for preparing review materials.
|
|
273
|
+
Specialized agent for preparing review materials (runs after review agents).
|
|
232
274
|
|
|
233
275
|
**Role:**
|
|
234
276
|
- Organize implementation into a structured report
|
|
277
|
+
- Calculate total review score (X/35)
|
|
235
278
|
- Collect and arrange evidence (screenshots, videos)
|
|
236
279
|
- Prepare `REPORT.md` for reviw review
|
|
237
280
|
- Parse reviw feedback and register as todos
|
|
@@ -321,6 +364,20 @@ Build & Verify (webapp-testing)
|
|
|
321
364
|
↓
|
|
322
365
|
/reviw:done
|
|
323
366
|
↓
|
|
367
|
+
┌─────────────────────────────────────────────┐
|
|
368
|
+
│ 7 Review Agents (parallel execution) │
|
|
369
|
+
│ │
|
|
370
|
+
│ review-code-quality ──┐ │
|
|
371
|
+
│ review-security ──────┤ │
|
|
372
|
+
│ review-a11y-ux ───────┼──→ REPORT.md │
|
|
373
|
+
│ review-figma-fidelity ┤ (append) │
|
|
374
|
+
│ review-copy-consistency │
|
|
375
|
+
│ review-e2e-integrity ─┤ │
|
|
376
|
+
│ e2e-health-reviewer ──┘ │
|
|
377
|
+
└─────────────────────────────────────────────┘
|
|
378
|
+
↓
|
|
379
|
+
report-builder (organize + score)
|
|
380
|
+
↓
|
|
324
381
|
Collect evidence (artifact-proof)
|
|
325
382
|
↓
|
|
326
383
|
npx reviw opens report (foreground)
|
package/cli.cjs
CHANGED
|
@@ -29,21 +29,25 @@ const allowedTags = new Set([
|
|
|
29
29
|
'ul', 'ol', 'li',
|
|
30
30
|
'blockquote', 'pre', 'code',
|
|
31
31
|
'em', 'strong', 'del', 's',
|
|
32
|
-
'a', 'img',
|
|
32
|
+
'a', 'img', 'video',
|
|
33
33
|
'table', 'thead', 'tbody', 'tr', 'th', 'td',
|
|
34
34
|
'div', 'span', // Markdown拡張用
|
|
35
|
+
'details', 'summary', // 折りたたみ用
|
|
35
36
|
]);
|
|
36
37
|
|
|
37
38
|
// 許可属性リスト(タグごとに定義)
|
|
38
39
|
const allowedAttributes = {
|
|
39
40
|
'a': ['href', 'title', 'target', 'rel'],
|
|
40
41
|
'img': ['src', 'alt', 'title', 'width', 'height'],
|
|
42
|
+
'video': ['src', 'controls', 'width', 'height', 'poster', 'preload', 'muted', 'loop'],
|
|
41
43
|
'code': ['class'], // 言語ハイライト用
|
|
42
44
|
'pre': ['class'],
|
|
43
45
|
'div': ['class'],
|
|
44
46
|
'span': ['class'],
|
|
45
47
|
'th': ['align'],
|
|
46
48
|
'td': ['align'],
|
|
49
|
+
'details': ['open'],
|
|
50
|
+
'summary': [],
|
|
47
51
|
};
|
|
48
52
|
|
|
49
53
|
// HTMLエスケープ関数(XSS対策用)
|
|
@@ -149,12 +153,13 @@ marked.use({
|
|
|
149
153
|
}
|
|
150
154
|
var titleAttr = title ? ' title="' + escapeHtmlForXss(title) + '"' : "";
|
|
151
155
|
var altAttr = text ? ' alt="' + escapeHtmlForXss(text) + '"' : "";
|
|
152
|
-
// Check if this is a video file -
|
|
156
|
+
// Check if this is a video file - render as video element with thumbnail
|
|
153
157
|
var videoExtensions = /\.(mp4|mov|webm|avi|mkv|m4v|ogv)$/i;
|
|
154
158
|
if (videoExtensions.test(href)) {
|
|
155
|
-
// For videos,
|
|
159
|
+
// For videos, render as video element with controls and thumbnail preview
|
|
156
160
|
var displayText = text || href.split('/').pop();
|
|
157
|
-
return '<
|
|
161
|
+
return '<video src="' + escapeHtmlForXss(href) + '" controls preload="metadata" class="video-preview"' + titleAttr + '>' +
|
|
162
|
+
'<a href="' + escapeHtmlForXss(href) + '">📹' + escapeHtmlForXss(displayText) + '</a></video>';
|
|
158
163
|
}
|
|
159
164
|
return '<img src="' + escapeHtmlForXss(href) + '"' + altAttr + titleAttr + '>';
|
|
160
165
|
}
|
|
@@ -719,8 +724,28 @@ function loadMarkdown(filePath) {
|
|
|
719
724
|
}
|
|
720
725
|
|
|
721
726
|
// Parse markdown content (without frontmatter)
|
|
722
|
-
|
|
723
|
-
|
|
727
|
+
let contentText = lines.slice(contentStart).join("\n");
|
|
728
|
+
|
|
729
|
+
// Preprocess <details> blocks to preserve their content
|
|
730
|
+
// marked splits HTML blocks on blank lines, so we need to handle details specially
|
|
731
|
+
const detailsBlocks = [];
|
|
732
|
+
contentText = contentText.replace(/<details>([\s\S]*?)<\/details>/gi, function(match, inner) {
|
|
733
|
+
const placeholder = `<!--DETAILS_PLACEHOLDER_${detailsBlocks.length}-->`;
|
|
734
|
+
// Parse the inner content as markdown, preserving the details structure
|
|
735
|
+
const summaryMatch = inner.match(/<summary>([\s\S]*?)<\/summary>/i);
|
|
736
|
+
const summary = summaryMatch ? summaryMatch[1] : '';
|
|
737
|
+
const content = summaryMatch ? inner.replace(/<summary>[\s\S]*?<\/summary>/i, '').trim() : inner.trim();
|
|
738
|
+
const parsedContent = marked.parse(content, { breaks: true });
|
|
739
|
+
detailsBlocks.push(`<details><summary>${summary}</summary>${parsedContent}</details>`);
|
|
740
|
+
return placeholder;
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
let preview = frontmatterHtml + marked.parse(contentText, { breaks: true });
|
|
744
|
+
|
|
745
|
+
// Restore details blocks
|
|
746
|
+
detailsBlocks.forEach((block, i) => {
|
|
747
|
+
preview = preview.replace(`<!--DETAILS_PLACEHOLDER_${i}-->`, block);
|
|
748
|
+
});
|
|
724
749
|
|
|
725
750
|
return {
|
|
726
751
|
rows: lines.map((line) => [line]),
|
|
@@ -2224,6 +2249,14 @@ function htmlTemplate(dataRows, cols, projectRoot, relativePath, mode, previewHt
|
|
|
2224
2249
|
}
|
|
2225
2250
|
.md-preview p { margin: 0.3em 0; line-height: 1.5; }
|
|
2226
2251
|
.md-preview img { max-width: 100%; height: auto; border-radius: 8px; }
|
|
2252
|
+
.md-preview video.video-preview { max-width: 100%; height: auto; border-radius: 8px; background: #000; }
|
|
2253
|
+
.md-preview table video.video-preview {
|
|
2254
|
+
display: block;
|
|
2255
|
+
width: auto;
|
|
2256
|
+
height: auto;
|
|
2257
|
+
max-width: 200px;
|
|
2258
|
+
max-height: 300px;
|
|
2259
|
+
}
|
|
2227
2260
|
.md-preview code { background: rgba(255,255,255,0.08); padding: 2px 4px; border-radius: 4px; }
|
|
2228
2261
|
.md-preview pre {
|
|
2229
2262
|
background: var(--code-bg);
|
|
@@ -2350,19 +2383,27 @@ function htmlTemplate(dataRows, cols, projectRoot, relativePath, mode, previewHt
|
|
|
2350
2383
|
}
|
|
2351
2384
|
/* Markdown tables in preview */
|
|
2352
2385
|
.md-preview table:not(.frontmatter-table table) {
|
|
2353
|
-
width:
|
|
2386
|
+
width: max-content;
|
|
2354
2387
|
border-collapse: collapse;
|
|
2388
|
+
table-layout: auto;
|
|
2355
2389
|
margin: 16px 0;
|
|
2356
2390
|
border: 1px solid var(--border);
|
|
2357
2391
|
border-radius: 8px;
|
|
2358
|
-
overflow: hidden;
|
|
2359
2392
|
}
|
|
2360
2393
|
.md-preview table:not(.frontmatter-table table) th,
|
|
2361
2394
|
.md-preview table:not(.frontmatter-table table) td {
|
|
2362
|
-
width: 50%;
|
|
2363
2395
|
padding: 10px 16px;
|
|
2364
2396
|
text-align: left;
|
|
2365
2397
|
border-bottom: 1px solid var(--border);
|
|
2398
|
+
vertical-align: top;
|
|
2399
|
+
white-space: nowrap;
|
|
2400
|
+
}
|
|
2401
|
+
.md-preview table:not(.frontmatter-table table) td:has(video),
|
|
2402
|
+
.md-preview table:not(.frontmatter-table table) td:has(img) {
|
|
2403
|
+
padding: 0;
|
|
2404
|
+
width: 1%;
|
|
2405
|
+
white-space: nowrap;
|
|
2406
|
+
line-height: 0;
|
|
2366
2407
|
}
|
|
2367
2408
|
.md-preview table:not(.frontmatter-table table) th {
|
|
2368
2409
|
background: var(--panel);
|