@su-record/vibe 3.2.38 → 3.2.40
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/agents/e2e-tester.md +23 -4
- package/dist/infra/lib/ui-ux/CsvDataLoader.d.ts.map +1 -1
- package/dist/infra/lib/ui-ux/CsvDataLoader.js +29 -2
- package/dist/infra/lib/ui-ux/CsvDataLoader.js.map +1 -1
- package/package.json +1 -1
- package/skills/vibe/SKILL.md +1 -1
- package/skills/vibe.image/SKILL.md +1 -1
- package/skills/vibe.review/SKILL.md +1 -1
- package/skills/vibe.run/references/e2e-and-autofix.md +9 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibe",
|
|
3
3
|
"displayName": "Vibe",
|
|
4
|
-
"version": "3.2.
|
|
4
|
+
"version": "3.2.40",
|
|
5
5
|
"description": "Verification harness for AI coding agents — \"done\" is decided by deterministic gates (test exit codes, run-ledger, regression memory), not the model self-report.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "su-record",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibe",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.40",
|
|
4
4
|
"description": "Verification harness for AI coding agents — \"done\" is decided by deterministic gates (test exit codes, run-ledger, regression memory), not the model self-report.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "su-record",
|
package/agents/e2e-tester.md
CHANGED
|
@@ -26,15 +26,34 @@ failed scenario. The loop, not a human, closes the gap.
|
|
|
26
26
|
|
|
27
27
|
Cheap verification is what makes the closed loop viable. Priority order:
|
|
28
28
|
|
|
29
|
-
1. **Agent Browser
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
1. **Agent Browser** — drives the browser via the accessibility tree, so a
|
|
30
|
+
control costs a ref (`@e2`) instead of a DOM subtree. Two ways in:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g agent-browser && agent-browser install # native CLI (no Node/Playwright at runtime)
|
|
34
|
+
agent-browser mcp # or run it as an MCP server
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
CLI shape — snapshot once, then act on refs:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
agent-browser open localhost:3000
|
|
41
|
+
agent-browser snapshot # accessibility tree with refs
|
|
42
|
+
agent-browser click @e2
|
|
43
|
+
agent-browser fill @e3 "user@example.com"
|
|
44
|
+
agent-browser close
|
|
45
|
+
```
|
|
46
|
+
|
|
32
47
|
2. **Playwright test runner** — write a spec, run
|
|
33
48
|
`npx playwright test --reporter=line`, consume pass/fail only.
|
|
49
|
+
If missing: `npx playwright install chromium`.
|
|
34
50
|
3. **Playwright MCP (DOM-based)** — last resort; full DOM trees exhaust
|
|
35
51
|
context in 2–3 interactions.
|
|
36
52
|
|
|
37
|
-
|
|
53
|
+
> **1순위를 쓰려면 설치돼 있어야 한다.** 이전 판은 Agent Browser 를 1순위로
|
|
54
|
+
> 지정해 놓고 **얻는 방법을 적지 않았다** — 결과적으로 전원이 2순위로 떨어졌다.
|
|
55
|
+
> 설치 여부를 먼저 확인하고(`agent-browser --version`), 없으면 위 명령을 제안한
|
|
56
|
+
> 뒤 사다리를 내려간다. 사다리는 선언이 아니라 실행 가능해야 의미가 있다.
|
|
38
57
|
|
|
39
58
|
## Verification Scope
|
|
40
59
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CsvDataLoader.d.ts","sourceRoot":"","sources":["../../../../src/infra/lib/ui-ux/CsvDataLoader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CsvDataLoader.d.ts","sourceRoot":"","sources":["../../../../src/infra/lib/ui-ux/CsvDataLoader.ts"],"names":[],"mappings":"AA+BA,2BAA2B;AAC3B,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,KAAK,CAAU;gBAEX,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB;IAWvE;;;;;OAKG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,IAAI;IA2CpE;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOjC;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAkBvB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAOjB;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;CASxB"}
|
|
@@ -1,9 +1,28 @@
|
|
|
1
|
-
import Papa from 'papaparse';
|
|
2
1
|
import { readFileSync, existsSync } from 'fs';
|
|
3
2
|
import { join, resolve, relative, isAbsolute } from 'path';
|
|
4
3
|
import { homedir } from 'os';
|
|
5
4
|
import { fileURLToPath } from 'url';
|
|
6
5
|
import { dirname } from 'path';
|
|
6
|
+
import { createRequire } from 'module';
|
|
7
|
+
/**
|
|
8
|
+
* papaparse 를 **호출 시점에** 가져온다 — 모듈 로드 시점이 아니라.
|
|
9
|
+
*
|
|
10
|
+
* WHY: 이 파일은 `dist/tools/index.js` 통합 배럴이 재수출한다. 정적 import 면
|
|
11
|
+
* 배럴을 건드리는 **모든** 소비자가 papaparse 해석에 성공해야 한다 — CSV 를 쓸
|
|
12
|
+
* 생각이 전혀 없는 신호 수집기·비용 게이트까지 포함해서. 실제로 GPT 앱(플러그인
|
|
13
|
+
* 트리에는 node_modules 가 없다)에서 "선택 기능과 무관한 papaparse 누락으로
|
|
14
|
+
* 실패" 가 반복 보고됐다.
|
|
15
|
+
*
|
|
16
|
+
* 선택 기능의 의존성은 그 기능을 쓸 때만 필요해야 한다.
|
|
17
|
+
*/
|
|
18
|
+
function loadPapa() {
|
|
19
|
+
try {
|
|
20
|
+
return createRequire(import.meta.url)('papaparse');
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
7
26
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
27
|
const __dirname = dirname(__filename);
|
|
9
28
|
/**
|
|
@@ -46,7 +65,15 @@ export class CsvDataLoader {
|
|
|
46
65
|
try {
|
|
47
66
|
const rawContent = readFileSync(resolvedPath, 'utf-8');
|
|
48
67
|
const cleanContent = this.removeBom(rawContent);
|
|
49
|
-
const
|
|
68
|
+
const papa = loadPapa();
|
|
69
|
+
if (!papa) {
|
|
70
|
+
// 의존성 부재는 CSV 기능만 끈다 — 호출자를 죽이지 않는다
|
|
71
|
+
if (!this.quiet) {
|
|
72
|
+
console.warn(`[CsvDataLoader] papaparse unavailable — CSV loading disabled (${filename})`);
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const parseResult = papa.parse(cleanContent, {
|
|
50
77
|
header: true,
|
|
51
78
|
skipEmptyLines: true,
|
|
52
79
|
transformHeader: (h) => h.trim(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CsvDataLoader.js","sourceRoot":"","sources":["../../../../src/infra/lib/ui-ux/CsvDataLoader.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"CsvDataLoader.js","sourceRoot":"","sources":["../../../../src/infra/lib/ui-ux/CsvDataLoader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/skills/vibe/SKILL.md
CHANGED
|
@@ -107,7 +107,7 @@ user-invocable: true
|
|
|
107
107
|
stakes 의 결정론 신호(config 유무·임시 디렉토리·git 여부)도 이 한 번의 호출로 함께 받는다:
|
|
108
108
|
|
|
109
109
|
```bash
|
|
110
|
-
node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/index.js').then(t => { console.log(JSON.stringify(t.collectDispatchSignals(process.cwd(), {urls: [], attachments: [], feature: undefined}), null, 2)); })"
|
|
110
|
+
node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/dispatch/index.js').then(t => { console.log(JSON.stringify(t.collectDispatchSignals(process.cwd(), {urls: [], attachments: [], feature: undefined}), null, 2)); })"
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
반환값을 **사실로 받는다**:
|
|
@@ -37,7 +37,7 @@ Generate images using the Antigravity image backend.
|
|
|
37
37
|
**Step 0-b: 비용 게이트 (생성 전 의무)** — 이미지 생성은 되돌릴 수 없는 지출이다. SSOT: `vibe/rules/loop-contract.md` 비용 게이트 절.
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/index.js').then(t => { const op={kind:'paid-generation',provider:'antigravity',label:'이미지 {N}장 생성'}; console.log(t.formatCostGate(op, t.evaluateCostGate(op))); })"
|
|
40
|
+
node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/dispatch/index.js').then(t => { const op={kind:'paid-generation',provider:'antigravity',label:'이미지 {N}장 생성'}; console.log(t.formatCostGate(op, t.evaluateCostGate(op))); })"
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
`ask` 면 생성 전에 무엇을 몇 장 만들지 제시하고 확인받는다. `autonomous` 면 묻지 않고 인박스에 기록한 뒤 진행한다. `.vibe/config.json` 의 `costGate.paidGenerationRequiresApproval: false` 로 끌 수 있다.
|
|
@@ -127,7 +127,7 @@ Detect project tech stack FIRST before launching reviewers.
|
|
|
127
127
|
**스폰 직전 비용 게이트** (SSOT: `vibe/rules/loop-contract.md` 비용 게이트 절). 위 표대로 정한 리뷰어 수를 그대로 넣는다:
|
|
128
128
|
|
|
129
129
|
```bash
|
|
130
|
-
node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/index.js').then(t => { const op={kind:'agent-fanout',agentCount:{N},label:'리뷰어 {N}종 병렬'}; console.log(t.formatCostGate(op, t.evaluateCostGate(op))); })"
|
|
130
|
+
node -e "import('{{VIBE_PATH_URL}}/node_modules/@su-record/vibe/dist/tools/dispatch/index.js').then(t => { const op={kind:'agent-fanout',agentCount:{N},label:'리뷰어 {N}종 병렬'}; console.log(t.formatCostGate(op, t.evaluateCostGate(op))); })"
|
|
131
131
|
```
|
|
132
132
|
|
|
133
133
|
기본 임계값(12)에서 demo 2종·prototype 3종·production 8종은 전부 **통과**한다 — 평상시 규모는 멈추지 않는다. `ask` 가 나오면 스폰 전에 사용자에게 확인하고, `record` (autonomous) 면 묻지 않고 인박스에 남긴 뒤 진행한다.
|
|
@@ -8,11 +8,15 @@
|
|
|
8
8
|
|
|
9
9
|
Browser Tool Priority:
|
|
10
10
|
|
|
11
|
-
| Priority | Tool | 용도 |
|
|
12
|
-
|
|
13
|
-
| 1st | Agent Browser (접근성 트리) | AI 직접 조작, 최소 토큰 |
|
|
14
|
-
| 2nd | Playwright Test Runner | 테스트 코드 실행, pass/fail 반환 |
|
|
15
|
-
| 3rd | Playwright MCP (DOM) | 최후 수단, 토큰 비효율 |
|
|
11
|
+
| Priority | Tool | 용도 | 없을 때 |
|
|
12
|
+
|----------|------|------|---------|
|
|
13
|
+
| 1st | Agent Browser (접근성 트리) | AI 직접 조작, 최소 토큰 | `npm i -g agent-browser && agent-browser install` |
|
|
14
|
+
| 2nd | Playwright Test Runner | 테스트 코드 실행, pass/fail 반환 | `npx playwright install chromium` |
|
|
15
|
+
| 3rd | Playwright MCP (DOM) | 최후 수단, 토큰 비효율 | — |
|
|
16
|
+
|
|
17
|
+
> 1순위는 **설치돼 있어야 1순위다.** 이전 판은 Agent Browser 를 1순위로 지정해
|
|
18
|
+
> 놓고 얻는 방법을 어디에도 적지 않아, 실제로는 전원이 2순위로 떨어졌다.
|
|
19
|
+
> `agent-browser --version` 으로 확인하고 없으면 위 명령을 제안한 뒤 내려간다.
|
|
16
20
|
|
|
17
21
|
**활성화 조건:** Feature 파일에 UI 관련 시나리오 존재 + `.vibe/e2e/config.json`의 `closedLoop.enabled: true` (기본값) + dev server가 실행 중
|
|
18
22
|
|