@longph2102/v-flow 1.5.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/AGENTS.md +265 -0
- package/CHANGELOG.md +318 -0
- package/LICENSE +21 -0
- package/README.md +326 -0
- package/agents/ba-agent.md +437 -0
- package/agents/ba-critic-agent.md +156 -0
- package/agents/ba-to-ptyc-agent.md +112 -0
- package/agents/bugfix-analyst-agent.md +221 -0
- package/agents/constitute-agent.md +155 -0
- package/agents/help-agent.md +168 -0
- package/agents/implement-agent.md +220 -0
- package/agents/import-ba-docs-agent.md +164 -0
- package/agents/master-check-agent.md +228 -0
- package/agents/metrics-agent.md +180 -0
- package/agents/operations-agent.md +123 -0
- package/agents/plan-agent.md +218 -0
- package/agents/prototype-agent.md +191 -0
- package/agents/retrospective-agent.md +196 -0
- package/agents/review-agent.md +210 -0
- package/agents/sprint-agent.md +191 -0
- package/agents/status-agent.md +186 -0
- package/agents/sync-agent.md +201 -0
- package/agents/test-agent.md +166 -0
- package/agents/understand-agent.md +339 -0
- package/cli/commands/check.js +96 -0
- package/cli/commands/dev-quiz.js +107 -0
- package/cli/commands/doctor.js +348 -0
- package/cli/commands/feature.js +259 -0
- package/cli/commands/hooks.js +163 -0
- package/cli/commands/init.js +189 -0
- package/cli/commands/log.js +199 -0
- package/cli/commands/plugin.js +230 -0
- package/cli/commands/score-card.js +203 -0
- package/cli/commands/status.js +269 -0
- package/cli/commands/sync.js +59 -0
- package/cli/commands/upgrade.js +150 -0
- package/cli/commands/validate.js +1259 -0
- package/cli/commands/watch.js +151 -0
- package/cli/index.js +46 -0
- package/cli/lib/ac-test-gate.js +89 -0
- package/cli/lib/activity-log.js +209 -0
- package/cli/lib/cli-error.js +183 -0
- package/cli/lib/constitution-lint.js +561 -0
- package/cli/lib/dev-quiz-grade.js +127 -0
- package/cli/lib/governance.js +78 -0
- package/cli/lib/hook-targets.js +167 -0
- package/cli/lib/i18n.js +375 -0
- package/cli/lib/knowledge-oracle.js +379 -0
- package/cli/lib/logger.js +203 -0
- package/cli/lib/module-card-lint.js +304 -0
- package/cli/lib/module-card-score.js +223 -0
- package/cli/lib/plugins.js +481 -0
- package/cli/lib/scanner.js +692 -0
- package/cli/lib/sync-core.js +232 -0
- package/cli/lib/sync-targets.js +84 -0
- package/cli/lib/templates.js +268 -0
- package/cli/lib/yaml-parser.js +203 -0
- package/commands/v.ba-critic.md +101 -0
- package/commands/v.ba-to-ptyc.md +71 -0
- package/commands/v.bugfix.md +86 -0
- package/commands/v.check.md +131 -0
- package/commands/v.constitute.md +87 -0
- package/commands/v.constitution.md +84 -0
- package/commands/v.fork.md +127 -0
- package/commands/v.help.md +73 -0
- package/commands/v.hotfix.md +200 -0
- package/commands/v.implement.md +92 -0
- package/commands/v.import-ba-docs.md +222 -0
- package/commands/v.metrics.md +74 -0
- package/commands/v.operations.md +70 -0
- package/commands/v.plan.md +78 -0
- package/commands/v.prototype.md +121 -0
- package/commands/v.quickfix.md +169 -0
- package/commands/v.retrospective.md +80 -0
- package/commands/v.review.md +78 -0
- package/commands/v.rewind.md +127 -0
- package/commands/v.specify.md +118 -0
- package/commands/v.sprint.md +75 -0
- package/commands/v.status.md +62 -0
- package/commands/v.sync.md +81 -0
- package/commands/v.test.md +67 -0
- package/commands/v.understand.md +112 -0
- package/package.json +65 -0
- package/skills/_shared/constitution-reader/SKILL.md +109 -0
- package/skills/_shared/constitution-reader/config.json +52 -0
- package/skills/_shared/constitution-reader/examples/good/b1-phase-output.md +48 -0
- package/skills/_shared/constitution-reader/gotchas.md +46 -0
- package/skills/_shared/context-reader/SKILL.md +111 -0
- package/skills/_shared/context-reader/config.json +54 -0
- package/skills/_shared/context-reader/examples/good/legacy-nodejs-output.md +35 -0
- package/skills/_shared/context-reader/gotchas.md +49 -0
- package/skills/_shared/ears-notation/SKILL.md +63 -0
- package/skills/_shared/ears-notation/config.json +55 -0
- package/skills/_shared/ears-notation/examples/good/plan-test-interpretation.md +29 -0
- package/skills/_shared/ears-notation/gotchas.md +43 -0
- package/skills/check/cross-validator/SKILL.md +206 -0
- package/skills/check/cross-validator/config.json +33 -0
- package/skills/check/cross-validator/examples/good/validation-report-pass-with-concerns.md +105 -0
- package/skills/check/cross-validator/gotchas.md +43 -0
- package/skills/implement/constitution-enforcer/SKILL.md +134 -0
- package/skills/implement/constitution-enforcer/config.json +16 -0
- package/skills/implement/constitution-enforcer/examples/bad/vague-report.md +42 -0
- package/skills/implement/constitution-enforcer/examples/good/compliance-report.md +57 -0
- package/skills/implement/constitution-enforcer/gotchas.md +26 -0
- package/skills/implement/constitution-enforcer/scripts/check-constitution.sh +88 -0
- package/skills/implement/no-go-zone-guard/SKILL.md +173 -0
- package/skills/implement/no-go-zone-guard/config.json +28 -0
- package/skills/implement/no-go-zone-guard/examples/good/adapter-workaround.md +46 -0
- package/skills/implement/no-go-zone-guard/gotchas.md +27 -0
- package/skills/implement/no-go-zone-guard/scripts/check-nogo-zones.sh +148 -0
- package/skills/implement/no-go-zone-guard/scripts/nogo-precommit.sh +96 -0
- package/skills/implement/tdd-driver/SKILL.md +159 -0
- package/skills/implement/tdd-driver/config.json +33 -0
- package/skills/implement/tdd-driver/examples/good/tdd-cycle-product-repo.md +81 -0
- package/skills/implement/tdd-driver/gotchas.md +34 -0
- package/skills/metrics/metrics-collector/SKILL.md +133 -0
- package/skills/metrics/metrics-collector/config.json +16 -0
- package/skills/metrics/metrics-collector/examples/bad/incomplete-report.md +48 -0
- package/skills/metrics/metrics-collector/examples/good/full-metrics-report.md +101 -0
- package/skills/metrics/metrics-collector/gotchas.md +26 -0
- package/skills/operations/incident-runbook/SKILL.md +167 -0
- package/skills/operations/incident-runbook/config.json +21 -0
- package/skills/operations/incident-runbook/examples/bad/vague-incident-report.md +48 -0
- package/skills/operations/incident-runbook/examples/good/p1-hotfix-response.md +119 -0
- package/skills/operations/incident-runbook/gotchas.md +26 -0
- package/skills/plan/architecture-designer/SKILL.md +228 -0
- package/skills/plan/architecture-designer/config.json +32 -0
- package/skills/plan/architecture-designer/examples/bad/vague-plan.md +62 -0
- package/skills/plan/architecture-designer/examples/good/expand-contract-migration.md +56 -0
- package/skills/plan/architecture-designer/examples/good/plan-structure.md +58 -0
- package/skills/plan/architecture-designer/gotchas.md +45 -0
- package/skills/plan/task-breakdown/SKILL.md +208 -0
- package/skills/plan/task-breakdown/config.json +26 -0
- package/skills/plan/task-breakdown/examples/bad/vague-tasks.md +77 -0
- package/skills/plan/task-breakdown/examples/good/spike-clarify-tasks.md +66 -0
- package/skills/plan/task-breakdown/examples/good/tasks-login-feature.md +111 -0
- package/skills/plan/task-breakdown/gotchas.md +39 -0
- package/skills/prototype/LOGIC.md +240 -0
- package/skills/prototype/SKILL.md +185 -0
- package/skills/prototype/UI.md +407 -0
- package/skills/prototype/config.json +104 -0
- package/skills/prototype/examples/bad/prototype-notes.md +68 -0
- package/skills/prototype/examples/good/prototype-notes-ui.md +109 -0
- package/skills/prototype/examples/good/prototype-notes.md +67 -0
- package/skills/prototype/gotchas.md +128 -0
- package/skills/prototype/scripts/check-flow-state.ps1 +112 -0
- package/skills/prototype/scripts/check-flow-state.sh +104 -0
- package/skills/prototype/scripts/check-prototype-cleanup.ps1 +124 -0
- package/skills/prototype/scripts/check-prototype-cleanup.sh +109 -0
- package/skills/prototype/scripts/check-prototype-notes.ps1 +107 -0
- package/skills/prototype/scripts/check-prototype-notes.sh +102 -0
- package/skills/review/adversarial-reviewer/SKILL.md +137 -0
- package/skills/review/adversarial-reviewer/config.json +32 -0
- package/skills/review/adversarial-reviewer/examples/good/review-report-template.md +56 -0
- package/skills/review/adversarial-reviewer/gotchas.md +46 -0
- package/skills/review/adversarial-reviewer/scripts/quick-security-scan.sh +52 -0
- package/skills/specify/ba-bpmn-doc-gen/SKILL.md +108 -0
- package/skills/specify/ba-bpmn-doc-gen/reference/reference-bpmn-generation.md +528 -0
- package/skills/specify/ba-bpmn-doc-gen/reference/reference-drawio-flowchart.md +466 -0
- package/skills/specify/ba-critic/SKILL.md +172 -0
- package/skills/specify/ba-critic/config.json +32 -0
- package/skills/specify/ba-critic/examples/good/critic-report-round1.md +51 -0
- package/skills/specify/ba-critic/gotchas.md +40 -0
- package/skills/specify/ba-critic/scripts/check-spec-quality.sh +72 -0
- package/skills/specify/ba-doc-generator/SKILL.md +102 -0
- package/skills/specify/ba-doc-generator/references/template-clevel.md +84 -0
- package/skills/specify/ba-doc-generator/references/template-compliance.md +83 -0
- package/skills/specify/ba-doc-generator/references/template-dev.md +138 -0
- package/skills/specify/ba-doc-generator/references/template-partner.md +167 -0
- package/skills/specify/ba-doc-generator/references/template-pm.md +92 -0
- package/skills/specify/ba-doc-generator/references/template-review.md +114 -0
- package/skills/specify/ba-doc-generator/references/template-tester.md +108 -0
- package/skills/specify/ba-doc-generator/references/template-user.md +98 -0
- package/skills/specify/bugfix-analyst/SKILL.md +296 -0
- package/skills/specify/bugfix-analyst/config.json +41 -0
- package/skills/specify/bugfix-analyst/examples/bad/common-mistakes.md +71 -0
- package/skills/specify/bugfix-analyst/examples/good/email-validation-bugfix.md +53 -0
- package/skills/specify/bugfix-analyst/gotchas.md +51 -0
- package/skills/specify/ears-writer/SKILL.md +129 -0
- package/skills/specify/ears-writer/config.json +20 -0
- package/skills/specify/ears-writer/examples/bad/common-mistakes.md +17 -0
- package/skills/specify/ears-writer/examples/good/login-requirements.md +41 -0
- package/skills/specify/ears-writer/gotchas.md +43 -0
- package/skills/specify/ears-writer/scripts/check-ears-compliance.sh +51 -0
- package/skills/test/test-case-generator/SKILL.md +161 -0
- package/skills/test/test-case-generator/config.json +33 -0
- package/skills/test/test-case-generator/examples/good/test-cases-login.md +104 -0
- package/skills/test/test-case-generator/gotchas.md +43 -0
- package/skills/understand/ba-docs-scanner/SKILL.md +239 -0
- package/skills/understand/ba-docs-scanner/config.json +47 -0
- package/skills/understand/ba-docs-scanner/examples/good/work-order-br-extract.md +28 -0
- package/skills/understand/ba-docs-scanner/gotchas.md +44 -0
- package/skills/understand/ba-docs-scanner/merge-rules.md +47 -0
- package/skills/understand/codebase-scanner/SKILL.md +260 -0
- package/skills/understand/codebase-scanner/config.json +56 -0
- package/skills/understand/codebase-scanner/examples/good/menu-module-output.md +44 -0
- package/skills/understand/codebase-scanner/gotchas.md +42 -0
- package/skills/understand/codebase-scanner/scripts/scan-project-structure.sh +64 -0
- package/templates/DESIGN.md +456 -0
- package/templates/agent-command-template.yaml +240 -0
- package/templates/agent-config-template.md +170 -0
- package/templates/agent-definition-template.md +145 -0
- package/templates/agent-metrics-template.md +150 -0
- package/templates/api-contract-template.md +72 -0
- package/templates/bugfix-report-template.md +195 -0
- package/templates/bugfix-spec-template.md +134 -0
- package/templates/code-review-report-template.md +119 -0
- package/templates/constitution-template.md +234 -0
- package/templates/context-template.md +94 -0
- package/templates/data-model-template.md +95 -0
- package/templates/decision-log-template.md +92 -0
- package/templates/flow-state-template.yaml +208 -0
- package/templates/github/workflows/v-flow-validate.yml +30 -0
- package/templates/knowledge/adr-template.md +70 -0
- package/templates/knowledge/api-contract-template.md +140 -0
- package/templates/knowledge/domain-glossary.md +29 -0
- package/templates/knowledge/golden-tests-readme.md +115 -0
- package/templates/knowledge/lessons-learned.md +41 -0
- package/templates/knowledge/patterns.md +103 -0
- package/templates/module-card/SKILL.md +85 -0
- package/templates/module-card/api-specs.md +96 -0
- package/templates/module-card/business-quiz.md +119 -0
- package/templates/module-card/cross-service.md +125 -0
- package/templates/module-card/db.md +85 -0
- package/templates/module-card/dev-quiz.md +62 -0
- package/templates/module-card/permissions.md +83 -0
- package/templates/module-card/state-diagram.md +64 -0
- package/templates/module-card/tech-context.md +90 -0
- package/templates/module-card/ui-flows.md +91 -0
- package/templates/module-card/use-cases.md +142 -0
- package/templates/module-template.yaml +161 -0
- package/templates/operations-report-template.md +108 -0
- package/templates/plan-template.md +308 -0
- package/templates/prototype-notes-template.md +116 -0
- package/templates/ptyc/PTYC.template.docx +0 -0
- package/templates/ptyc/ptyc.meta.example.yaml +44 -0
- package/templates/retrospective-report-template.md +136 -0
- package/templates/security-review-template.md +84 -0
- package/templates/session-template.md +167 -0
- package/templates/spec-review-log-template.md +75 -0
- package/templates/spec-template.md +229 -0
- package/templates/sprint-status-template.md +101 -0
- package/templates/tasks-template.md +275 -0
- package/templates/test-cases-template.md +124 -0
- package/templates/ux-checklist-template.md +79 -0
- package/templates/validation-report-template.md +125 -0
- package/templates/vflow-config-template.yaml +22 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Logic Prototype
|
|
2
|
+
|
|
3
|
+
A tiny interactive terminal app that lets the user drive a state model by hand. Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
|
|
4
|
+
|
|
5
|
+
If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
|
|
6
|
+
|
|
7
|
+
## When this is the right shape
|
|
8
|
+
|
|
9
|
+
- "State machine xử lý edge case X rồi Y thế nào?"
|
|
10
|
+
- "Data model có thực sự biểu diễn được case này không?"
|
|
11
|
+
- "API nên có shape như thế nào trước khi viết thật?"
|
|
12
|
+
- Bất cứ khi nào user muốn **nhấn nút và xem state thay đổi**.
|
|
13
|
+
|
|
14
|
+
## Process
|
|
15
|
+
|
|
16
|
+
### 1. State the question (từ spec.md)
|
|
17
|
+
|
|
18
|
+
Đọc `spec.md` — tìm REQ-xxx có ambiguity markers. Viết rõ câu hỏi ở đầu prototype (README hoặc comment đầu file):
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
# PROTOTYPE — [Feature NNN]
|
|
22
|
+
# Question: [câu hỏi cụ thể lấy từ spec REQ-xxx]
|
|
23
|
+
# Branch: LOGIC
|
|
24
|
+
# Delete after: verdict captured in prototype-notes.md
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 2. Pick the runtime (auto-detect)
|
|
28
|
+
|
|
29
|
+
Scan project files theo thứ tự:
|
|
30
|
+
|
|
31
|
+
| Signal file | Runtime |
|
|
32
|
+
|------------|---------|
|
|
33
|
+
| `package.json` có `"@angular/core"` | Angular + TypeScript |
|
|
34
|
+
| `package.json` không có Angular | Node.js / TypeScript |
|
|
35
|
+
| `bun.lockb` hoặc `bunfig.toml` | Bun |
|
|
36
|
+
| `pom.xml` hoặc `build.gradle` | Java |
|
|
37
|
+
| `requirements.txt` hoặc `pyproject.toml` | Python |
|
|
38
|
+
| Không detect được | → Hỏi user chọn runtime |
|
|
39
|
+
|
|
40
|
+
Match project's existing tooling conventions — don't add a new package manager or runtime just for the prototype.
|
|
41
|
+
|
|
42
|
+
### 3. Isolate the logic in a portable module
|
|
43
|
+
|
|
44
|
+
Put actual logic behind a small, pure interface. The right shape:
|
|
45
|
+
|
|
46
|
+
- **Pure reducer** — `(state, action) => state`. Khi actions là discrete events.
|
|
47
|
+
- **State machine** — explicit states và transitions. Khi "actions nào legal hiện tại" là một phần câu hỏi.
|
|
48
|
+
- **Pure functions** over plain data type. Khi không có implicit state.
|
|
49
|
+
- **Class/module** với clear method surface. Khi logic cần ongoing internal state.
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
.v-flow/features/NNN/prototype/logic/
|
|
53
|
+
├── logic.ts ← pure module (the thing worth keeping)
|
|
54
|
+
├── tui.ts ← thin shell, throwaway
|
|
55
|
+
├── README.md ← câu hỏi + run command
|
|
56
|
+
└── package.json ← chỉ nếu cần isolate deps
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Keep it pure: **no I/O, no terminal code, no `console.log` for control flow** in the logic module. TUI imports it; nothing flows the other direction. This makes the logic liftable into real code after prototype is done.
|
|
60
|
+
|
|
61
|
+
### 4. Build the smallest TUI that exposes the state
|
|
62
|
+
|
|
63
|
+
Lightweight TUI — on every tick: **clear screen + re-render whole frame**:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
console.clear() // Node/Bun/TypeScript
|
|
67
|
+
print("\033[2J\033[H") // Python
|
|
68
|
+
// Java: ProcessBuilder("clear").inheritIO().start().waitFor()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Each frame has two parts (in this order):
|
|
72
|
+
|
|
73
|
+
1. **Current state** — pretty-printed, one field per line or formatted JSON. Use bold for field names (`\x1b[1m`), dim for less important context (`\x1b[2m`), reset (`\x1b[0m`).
|
|
74
|
+
2. **Keyboard shortcuts** — `[a] add item [d] delete [t] tick [q] quit`. Bold key, dim description.
|
|
75
|
+
|
|
76
|
+
Behavior loop:
|
|
77
|
+
```
|
|
78
|
+
init state → render frame → read keystroke → dispatch handler → mutate state → re-render → loop until [q]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 4.5. Handling Text & Number Inputs (Prompts)
|
|
82
|
+
|
|
83
|
+
Nếu TUI cần nhận dữ liệu đầu vào dài từ bàn phím (ví dụ: nhập số tiền, tên, câu trả lời), **BẮT BUỘC phải tạm thời tắt Raw Mode** để tránh xung đột phím tắt và lỗi crash.
|
|
84
|
+
|
|
85
|
+
#### Node.js (TypeScript) Blueprint:
|
|
86
|
+
```typescript
|
|
87
|
+
import readline from 'readline';
|
|
88
|
+
|
|
89
|
+
async function promptInput(questionText: string): Promise<string> {
|
|
90
|
+
// 1. Tắt Raw Mode & Pause stdin để nhập văn bản bình thường
|
|
91
|
+
process.stdin.setRawMode(false);
|
|
92
|
+
process.stdin.pause();
|
|
93
|
+
|
|
94
|
+
const rl = readline.createInterface({
|
|
95
|
+
input: process.stdin,
|
|
96
|
+
output: process.stdout,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
rl.question(questionText, (answer) => {
|
|
101
|
+
rl.close();
|
|
102
|
+
// 2. Bật lại Raw Mode & Resume stdin để tiếp tục nhận phím tắt menu
|
|
103
|
+
process.stdin.setRawMode(true);
|
|
104
|
+
process.stdin.resume();
|
|
105
|
+
resolve(answer);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Khi muốn gọi nhập liệu trong TUI:
|
|
112
|
+
```typescript
|
|
113
|
+
// Trong event loop handler của tui.ts
|
|
114
|
+
if (key === 'i') { // Ví dụ nhấn 'i' để nhập số tiền
|
|
115
|
+
const amountStr = await promptInput('Nhập số tiền: ');
|
|
116
|
+
const amount = parseFloat(amountStr);
|
|
117
|
+
if (!isNaN(amount)) {
|
|
118
|
+
state = reducer(state, { type: 'INPUT_AMOUNT', amount });
|
|
119
|
+
}
|
|
120
|
+
renderFrame(state);
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 5. Make it runnable in one command
|
|
125
|
+
|
|
126
|
+
Add script to project's existing task runner:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
// package.json
|
|
130
|
+
"scripts": {
|
|
131
|
+
"prototype:NNN": "tsx .v-flow/features/NNN/prototype/logic/tui.ts"
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```toml
|
|
136
|
+
# pyproject.toml
|
|
137
|
+
[tool.taskipy.tasks]
|
|
138
|
+
prototype-NNN = "python .v-flow/features/NNN/prototype/logic/tui.py"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Document the exact command in `prototype-notes.md` → "Run command" field.
|
|
142
|
+
|
|
143
|
+
### 5.5. Runtime Verification (Verify before handover)
|
|
144
|
+
|
|
145
|
+
Trước khi gửi lệnh chạy cho người dùng, Agent **BẮT BUỘC** phải tự chạy thử lệnh chạy đó trên Workspace bằng tool `run_command` để verify:
|
|
146
|
+
- Không bị lỗi biên dịch (TypeScript compile error).
|
|
147
|
+
- Không bị lỗi import path (ví dụ: `@/` path resolution lỗi).
|
|
148
|
+
- Chương trình TUI hiển thị được giao diện ban đầu thành công mà không bị crash ngay lập tức.
|
|
149
|
+
- Bạn có thể chạy thử lệnh với tham số chờ/timeout ngắn (ví dụ: `WaitMsBeforeAsync: 1000` hoặc chạy bất đồng bộ rồi kill task sau 1 giây) để đảm bảo process khởi động thành công và exit code bằng 0 hoặc process vẫn đang run bình thường.
|
|
150
|
+
|
|
151
|
+
### 6. Hand it over
|
|
152
|
+
|
|
153
|
+
Give the user the run command. They'll drive it themselves. Interesting moments: "wait, that shouldn't be possible" or "huh, I assumed X" — những lỗi trong _idea_, đó mới là mục tiêu.
|
|
154
|
+
|
|
155
|
+
### 7. Capture the answer → prototype-notes.md
|
|
156
|
+
|
|
157
|
+
Khi prototype đã trả lời câu hỏi:
|
|
158
|
+
|
|
159
|
+
1. Điền verdict vào `prototype-notes.md` (VALIDATED / REJECTED / INCONCLUSIVE)
|
|
160
|
+
2. Map verdict về REQ-xxx trong spec — prototype finding này ảnh hưởng requirement nào?
|
|
161
|
+
3. Append execution trace vào `_session.md`
|
|
162
|
+
4. Update `artifacts.prototype.*` trong `.flow-state.yaml`
|
|
163
|
+
5. Xóa prototype code — chỉ giữ `prototype-notes.md`
|
|
164
|
+
|
|
165
|
+
## Anti-patterns
|
|
166
|
+
|
|
167
|
+
- **Don't add tests** — prototype that needs tests is no longer a prototype
|
|
168
|
+
- **Don't wire to real DB** — in-memory unless question is specifically about persistence
|
|
169
|
+
- **Don't generalise** — "what if we want X later" is out of scope. Answer one question.
|
|
170
|
+
- **Don't blur logic and TUI** — if reducer references `console.log` or escape codes, it's no longer portable
|
|
171
|
+
- **Don't ship TUI to production** — shell is optimised for hand-driven terminal, not users
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Async / Event-driven State Machines
|
|
176
|
+
|
|
177
|
+
Khi câu hỏi liên quan đến **timers, polling, hoặc external events** (webhooks, queue messages, websocket), TUI cần mô phỏng async mà không cần infrastructure thật.
|
|
178
|
+
|
|
179
|
+
### Pattern: Manual tick command
|
|
180
|
+
|
|
181
|
+
Thêm `[t] tick` vào keyboard shortcuts — mỗi lần nhấn `t` giả lập 1 đơn vị thời gian trôi qua:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
// logic.ts — async events được model thành discrete actions
|
|
185
|
+
type Action =
|
|
186
|
+
| { type: 'SUBMIT' }
|
|
187
|
+
| { type: 'TICK' } // ← giả lập thời gian trôi qua (polling cycle, timer, etc.)
|
|
188
|
+
| { type: 'WEBHOOK_OK' } // ← giả lập external event thành công
|
|
189
|
+
| { type: 'WEBHOOK_FAIL' } // ← giả lập external event thất bại
|
|
190
|
+
|
|
191
|
+
function reducer(state: State, action: Action): State {
|
|
192
|
+
switch (state.status) {
|
|
193
|
+
case 'PENDING':
|
|
194
|
+
if (action.type === 'SUBMIT') return { ...state, status: 'PROCESSING', ticks: 0 };
|
|
195
|
+
break;
|
|
196
|
+
case 'PROCESSING':
|
|
197
|
+
if (action.type === 'TICK') {
|
|
198
|
+
const ticks = state.ticks + 1;
|
|
199
|
+
// Giả lập timeout sau 5 ticks
|
|
200
|
+
return ticks >= 5 ? { ...state, status: 'TIMED_OUT' } : { ...state, ticks };
|
|
201
|
+
}
|
|
202
|
+
if (action.type === 'WEBHOOK_OK') return { ...state, status: 'DONE' };
|
|
203
|
+
if (action.type === 'WEBHOOK_FAIL') return { ...state, status: 'FAILED', retries: state.retries + 1 };
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
return state;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
// tui.ts — keyboard shortcuts map sang actions + external events
|
|
212
|
+
const keyMap: Record<string, Action> = {
|
|
213
|
+
's': { type: 'SUBMIT' },
|
|
214
|
+
't': { type: 'TICK' }, // "[t] tick (simulate time passing)"
|
|
215
|
+
'o': { type: 'WEBHOOK_OK' }, // "[o] webhook ok"
|
|
216
|
+
'f': { type: 'WEBHOOK_FAIL' }, // "[f] webhook fail"
|
|
217
|
+
};
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Frame render hiển thị `ticks` để user biết đang ở đâu trong timeline:
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
Status: PROCESSING
|
|
224
|
+
Ticks elapsed: 3 / 5 (timeout at 5)
|
|
225
|
+
Retries: 0
|
|
226
|
+
|
|
227
|
+
[s] submit [t] tick [o] webhook ok [f] webhook fail [q] quit
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Khi nào dùng pattern này
|
|
231
|
+
|
|
232
|
+
- Câu hỏi về **timeout/retry logic** — bao nhiêu ticks thì timeout? retry có reset counter không?
|
|
233
|
+
- Câu hỏi về **race condition** — submit 2 lần trước khi webhook về thì sao?
|
|
234
|
+
- Câu hỏi về **external event ordering** — nếu webhook về trước khi processing xong thì state là gì?
|
|
235
|
+
|
|
236
|
+
### Anti-patterns (async-specific)
|
|
237
|
+
|
|
238
|
+
- **Đừng dùng `setTimeout` thật trong TUI** — async loop phức tạp, khó debug, khó drive by hand. Manual tick đủ để trả lời câu hỏi.
|
|
239
|
+
- **Đừng mock real HTTP** — dùng keyboard shortcut `[o]`/`[f]` thay vì `fetch()` stub. Mục tiêu là drive state, không phải simulate network.
|
|
240
|
+
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prototype
|
|
3
|
+
description: >
|
|
4
|
+
Tạo throwaway prototype để resolve ambiguity trong spec trước khi lên plan.
|
|
5
|
+
Hai nhánh: LOGIC (validate state machine/data model qua terminal TUI)
|
|
6
|
+
hoặc UI (gen multi-variant UI dùng design tokens của dự án).
|
|
7
|
+
Chỉ dùng khi spec có câu hỏi chưa trả lời được bằng văn bản.
|
|
8
|
+
phase: "S.1.5"
|
|
9
|
+
trigger: "Khi /v.prototype hoặc BA Agent gợi ý prototype do phát hiện ambiguity trong spec"
|
|
10
|
+
used_by:
|
|
11
|
+
- /v.prototype
|
|
12
|
+
- /v.specify (ba-agent-ambiguity-suggest)
|
|
13
|
+
hooks:
|
|
14
|
+
pre_prototype: "Đọc spec.md → xác định câu hỏi + REQ refs → chọn branch"
|
|
15
|
+
post_prototype: "Chạy thử (test-run) để verify → Ghi prototype-notes.md → append _session.md → update .flow-state.yaml → gợi ý cleanup"
|
|
16
|
+
output:
|
|
17
|
+
- "prototype-notes.md"
|
|
18
|
+
- "_session.md append"
|
|
19
|
+
- ".flow-state.yaml update"
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Prototype Skill
|
|
23
|
+
|
|
24
|
+
> ⚠️ Đây là **Skill bắt buộc** cho Prototype Agent khi được kích hoạt.
|
|
25
|
+
> Đọc skill này TRƯỚC khi tạo bất kỳ prototype code nào.
|
|
26
|
+
>
|
|
27
|
+
> → Xem `gotchas.md` cho các lỗi phổ biến — đặc biệt G-001, G-002, G-005.
|
|
28
|
+
> → Xem `examples/good/` và `examples/bad/` cho mẫu `prototype-notes.md` chuẩn.
|
|
29
|
+
> → Xem `config.json` để customize (default_variants, default_framework, ambiguity_markers).
|
|
30
|
+
> → Chạy scripts validate trước khi routing:
|
|
31
|
+
> - **Linux/macOS**: `.v-flow/skills/prototype/scripts/check-prototype-notes.sh`
|
|
32
|
+
> - **Windows (PowerShell)**: `.v-flow/skills/prototype/scripts/check-prototype-notes.ps1`
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Khi nào KHÔNG cần Prototype
|
|
37
|
+
|
|
38
|
+
- Spec đã rõ ràng — mọi REQ có AC cụ thể, không có ambiguity markers
|
|
39
|
+
- Câu hỏi có thể trả lời bằng văn bản trong spec (≤ 2 câu giải thích)
|
|
40
|
+
- Quick Fix hoặc Hotfix flow — không đủ time budget cho prototype
|
|
41
|
+
- Prototype của feature tương tự đã được chạy trong cùng epic (có thể tái dùng verdict)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Pick a branch
|
|
46
|
+
|
|
47
|
+
Identify which question is being answered — từ spec.md, từ `--question`, từ `--req`, hoặc hỏi thẳng user:
|
|
48
|
+
|
|
49
|
+
- **"Logic/behavior/state model có đúng không?"** → [LOGIC.md](LOGIC.md). Terminal TUI cho phép drive state machine qua real cases.
|
|
50
|
+
- **"UI nên trông như thế nào?"** → [UI.md](UI.md). Multi-variant web UI switchable qua URL param.
|
|
51
|
+
|
|
52
|
+
Nếu câu hỏi genuinely ambiguous và user không available, áp dụng theo thứ tự:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
1. --req hoặc --question được chỉ định? → Dùng câu đó, bỏ qua bước 2-4
|
|
56
|
+
2. Chỉ có 1 REQ với ambiguity marker? → Dùng REQ đó
|
|
57
|
+
3. Nhiều REQ có ambiguity markers? → Ưu tiên theo REQ type: S > E > U > O
|
|
58
|
+
Cùng type → chọn REQ đầu tiên trong spec
|
|
59
|
+
4. Không detect được REQ nào? → Báo user: "Spec khá sạch, prototype có thể không cần"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Chọn branch khi ambiguous** (xem `config.json` §auto_rules cho đầy đủ):
|
|
63
|
+
|
|
64
|
+
| Context signal | Branch |
|
|
65
|
+
|---|---|
|
|
66
|
+
| REQ type E hoặc S | LOGIC |
|
|
67
|
+
| Ambiguity nằm trong UI/Layout section của spec | UI |
|
|
68
|
+
| AC có từ khóa state/flow ("trạng thái", "transition", "khi nào") | LOGIC |
|
|
69
|
+
| Module là backend service / API | LOGIC |
|
|
70
|
+
| Module là frontend page / component | UI |
|
|
71
|
+
| Không detect được | LOGIC _(safer default — TUI ít side-effects hơn UI variant)_ |
|
|
72
|
+
|
|
73
|
+
**Bắt buộc khi AFK**: Ghi rõ assumption ở đầu prototype README:
|
|
74
|
+
```
|
|
75
|
+
# ASSUMPTION (User AFK): Defaulted to LOGIC branch
|
|
76
|
+
# Signal detected: REQ-S02 is State type
|
|
77
|
+
# Override: Re-run with --ui nếu assumption sai
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## V Flow Integration Layer
|
|
84
|
+
|
|
85
|
+
### Input
|
|
86
|
+
|
|
87
|
+
Khi được kích hoạt, agent phải đọc theo thứ tự:
|
|
88
|
+
|
|
89
|
+
1. **`spec.md`** — extract câu hỏi cần prototype trả lời (tìm REQ-xxx có ambiguity markers)
|
|
90
|
+
- Nếu user dùng `--req REQ-E01` → focus vào REQ đó, không cần scan toàn bộ spec
|
|
91
|
+
- Nếu user dùng `--question "..."` → dùng câu đó, liên kết ngược về REQ gần nhất
|
|
92
|
+
2. **`DESIGN.md`** (chỉ UI branch) — lookup order:
|
|
93
|
+
- `[project-root]/DESIGN.md` — project override (nếu tồn tại, ưu tiên)
|
|
94
|
+
- `[project-root]/.v-flow/DESIGN.md` — fallback (auto-copy lúc `v-flow init`)
|
|
95
|
+
2b. **`ui/mockups/` + UI Intent (spec §2)** (chỉ UI mode `from-mockup`) — ảnh mockup + Bố cục/Kế thừa trang/Mức ràng buộc. **Cấu trúc** render lấy từ đây; **style** lấy từ `DESIGN.md` (không copy pixel từ ảnh).
|
|
96
|
+
3. **`config.json`** (optional) — override default behavior (variants, framework, subshape)
|
|
97
|
+
|
|
98
|
+
### Ambiguity markers cần detect trong spec
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Keywords VI: "chưa rõ", "cần thảo luận", "phụ thuộc", "có thể là A hoặc B",
|
|
102
|
+
"TBD", "tùy thiết kế", "xem mockup", "cần xác nhận", "đang xem xét"
|
|
103
|
+
Keywords EN: "unclear", "to be decided", "pending", "tbc", "needs clarification"
|
|
104
|
+
Patterns: Acceptance Criteria trống hoặc quá vague
|
|
105
|
+
State transitions có nhiều nhánh chưa được validate
|
|
106
|
+
UI section không có wireframe hoặc reference
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Output bắt buộc
|
|
110
|
+
|
|
111
|
+
- **`prototype-notes.md`** → lưu tại `.v-flow/features/NNN/prototype-notes.md`
|
|
112
|
+
- **Append verdict block** vào `_session.md` (xem template bên dưới)
|
|
113
|
+
- **Update `.flow-state.yaml`** — điền `artifacts.prototype.*`
|
|
114
|
+
|
|
115
|
+
### Verdict levels
|
|
116
|
+
|
|
117
|
+
| Verdict | Ý nghĩa | Routing |
|
|
118
|
+
|---------|---------|---------|
|
|
119
|
+
| `VALIDATED` | Prototype xác nhận hướng đúng | Tiếp tục → `/v.plan + /v.test` |
|
|
120
|
+
| `REJECTED` | Prototype phát hiện hướng sai | Sửa spec → `/v.specify` |
|
|
121
|
+
| `INCONCLUSIVE` | Chưa đủ thông tin | Tạm dừng, chờ stakeholder |
|
|
122
|
+
|
|
123
|
+
### Session append block
|
|
124
|
+
|
|
125
|
+
Sau khi có verdict, append vào `_session.md`:
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
### [S.1.5] Prototype — [YYYY-MM-DD]
|
|
129
|
+
- **Agent**: Prototype Agent
|
|
130
|
+
- **Branch**: [LOGIC | UI]
|
|
131
|
+
- **Mode**: [N/A (LOGIC) | from-mockup | explore]
|
|
132
|
+
- **Sub-shape**: [N/A | A — embedded in existing page | B — new throwaway route]
|
|
133
|
+
- **Question**: [câu hỏi prototype trả lời]
|
|
134
|
+
- **REQ refs**: [REQ-xxx, REQ-xxx]
|
|
135
|
+
- **Verdict**: [VALIDATED | REJECTED | INCONCLUSIVE]
|
|
136
|
+
- **Prototype location**: `.v-flow/features/NNN/prototype/[logic|ui]/`
|
|
137
|
+
- **Approved render**: [`ui/approved/UC-NN.*` (mode=from-mockup) | N/A]
|
|
138
|
+
- **Key findings**: [tóm tắt 1-2 câu]
|
|
139
|
+
- **Spec impact**: [no change | update needed | new REQ added]
|
|
140
|
+
- **Routing**: [→ /v.plan + /v.test | → /v.specify | → awaiting stakeholder]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Nguyên tắc cốt lõi (applies to both branches)
|
|
146
|
+
|
|
147
|
+
1. **Throwaway từ đầu** — đặt tên rõ là prototype, không nhầm với production code
|
|
148
|
+
2. **One command to run** — user chạy được ngay, không cần giải thích path phức tạp
|
|
149
|
+
3. **No persistence by default** — state ở memory, không phụ thuộc DB
|
|
150
|
+
4. **Skip the polish** — không cần test, error handling, abstraction
|
|
151
|
+
5. **Surface the state** — sau mỗi action (LOGIC) hoặc variant switch (UI), hiển thị state đầy đủ
|
|
152
|
+
6. **Delete or absorb when done** — *(Explore)* verdict là thứ duy nhất đáng giữ. *(Reproduce / `--from-mockup`)* render `ui/approved/UC-NN.*` được **GIỮ** làm contract — không xóa.
|
|
153
|
+
|
|
154
|
+
Locate prototype code at **`.v-flow/features/NNN/prototype/logic/`** or **`.v-flow/features/NNN/prototype/ui/`** — trong feature folder, gần spec/plan/test-cases.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## V-Flow Integration Points
|
|
159
|
+
|
|
160
|
+
| File | Role |
|
|
161
|
+
|------|------|
|
|
162
|
+
| `spec.md` | Input chính — source of ambiguity questions + REQ refs + UI Intent |
|
|
163
|
+
| `DESIGN.md` | Design tokens cho UI branch (style authority) |
|
|
164
|
+
| `ui/mockups/` | [from-mockup] Ảnh mockup — nguồn cấu trúc/layout |
|
|
165
|
+
| `ui/approved/` | [from-mockup] Render đã chốt — visual contract (GIỮ) |
|
|
166
|
+
| `config.json` | Customize prototype behavior per-project |
|
|
167
|
+
| `prototype-notes.md` | **Output chính** — verdict + findings (file duy nhất đáng giữ) |
|
|
168
|
+
| `_session.md` | Execution trace — carry-forward cho Plan Agent |
|
|
169
|
+
| `.flow-state.yaml` | Machine-readable state — `artifacts.prototype.*` |
|
|
170
|
+
| `.v-flow/templates/prototype-notes-template.md` | Format chuẩn cho prototype-notes.md |
|
|
171
|
+
| `.v-flow/skills/prototype/scripts/check-prototype-notes.sh` / `.ps1` | Validate prototype-notes.md đủ fields trước khi routing |
|
|
172
|
+
| `.v-flow/skills/prototype/scripts/check-flow-state.sh` / `.ps1` | Verify .flow-state.yaml đã được update |
|
|
173
|
+
| `.v-flow/skills/prototype/scripts/check-prototype-cleanup.sh` / `.ps1` | Kiểm tra prototype/ code đã được cleanup |
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## When done
|
|
178
|
+
|
|
179
|
+
The _answer_ is the only thing worth keeping *(Explore)* — capture it in `prototype-notes.md` trước khi xóa prototype code. *(Reproduce)* ngoài verdict, render `ui/approved/UC-NN.*` cũng được giữ làm contract. Verdict + (nếu có) render chốt là input cho Plan Agent — carry-forward qua `_session.md`.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Gotchas
|
|
184
|
+
|
|
185
|
+
→ Xem `gotchas.md` cho các lỗi phổ biến khi tạo prototype — cập nhật liên tục.
|