@seanyao/roll 0.5.0 → 2.602.1
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/CHANGELOG.md +717 -0
- package/LICENSE +21 -0
- package/README.md +65 -165
- package/bin/dream-test-quality-scan +110 -0
- package/bin/roll +14897 -815
- package/conventions/config.yaml +17 -1
- package/conventions/global/AGENTS.md +146 -100
- package/conventions/global/CLAUDE.md +1 -21
- package/conventions/global/GEMINI.md +8 -22
- package/conventions/global/project_rules.md +9 -0
- package/conventions/templates/backend-service/AGENTS.md +30 -81
- package/conventions/templates/backend-service/GEMINI.md +3 -3
- package/conventions/templates/backend-service/project_rules.md +16 -0
- package/conventions/templates/cli/AGENTS.md +31 -58
- package/conventions/templates/cli/CLAUDE.md +3 -5
- package/conventions/templates/cli/GEMINI.md +3 -3
- package/conventions/templates/cli/project_rules.md +16 -0
- package/conventions/templates/frontend-only/AGENTS.md +29 -64
- package/conventions/templates/frontend-only/GEMINI.md +3 -3
- package/conventions/templates/frontend-only/project_rules.md +14 -0
- package/conventions/templates/fullstack/AGENTS.md +31 -79
- package/conventions/templates/fullstack/CLAUDE.md +1 -1
- package/conventions/templates/fullstack/GEMINI.md +3 -3
- package/conventions/templates/fullstack/project_rules.md +15 -0
- package/lib/README.md +42 -0
- package/lib/__pycache__/github_sync.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop-fmt.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_result_eval.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_unstick.cpython-314.pyc +0 -0
- package/lib/__pycache__/model_prices.cpython-314.pyc +0 -0
- package/lib/__pycache__/prices_fetcher.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll-home.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll-loop-status.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll_git.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll_render.cpython-314.pyc +0 -0
- package/lib/__pycache__/slides-render.cpython-314.pyc +0 -0
- package/lib/agent_usage/README.md +49 -0
- package/lib/agent_usage/__init__.py +108 -0
- package/lib/agent_usage/__pycache__/__init__.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/gemini.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/kimi.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/openai.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/pi.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/pi_emit.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/qwen.cpython-314.pyc +0 -0
- package/lib/agent_usage/gemini.py +127 -0
- package/lib/agent_usage/kimi.py +278 -0
- package/lib/agent_usage/kimi_emit.py +123 -0
- package/lib/agent_usage/openai.py +126 -0
- package/lib/agent_usage/pi.py +200 -0
- package/lib/agent_usage/pi_emit.py +135 -0
- package/lib/agent_usage/qwen.py +128 -0
- package/lib/backfill-pi-usage.py +243 -0
- package/lib/changelog_audit.py +155 -0
- package/lib/changelog_generate.py +263 -0
- package/lib/context_feed_budget.sh +194 -0
- package/lib/github_sync.py +876 -0
- package/lib/i18n/README.md +54 -0
- package/lib/i18n/agent.sh +75 -0
- package/lib/i18n/alert.sh +20 -0
- package/lib/i18n/backlog.sh +96 -0
- package/lib/i18n/brief.sh +5 -0
- package/lib/i18n/changelog.sh +5 -0
- package/lib/i18n/ci.sh +15 -0
- package/lib/i18n/debug.sh +0 -0
- package/lib/i18n/doctor.sh +44 -0
- package/lib/i18n/dream.sh +0 -0
- package/lib/i18n/init.sh +91 -0
- package/lib/i18n/lang.sh +10 -0
- package/lib/i18n/loop.sh +140 -0
- package/lib/i18n/migrate.sh +74 -0
- package/lib/i18n/offboard.sh +31 -0
- package/lib/i18n/onboard.sh +0 -0
- package/lib/i18n/peer.sh +41 -0
- package/lib/i18n/peer_help.sh +25 -0
- package/lib/i18n/peer_reset.sh +7 -0
- package/lib/i18n/peer_status.sh +5 -0
- package/lib/i18n/prices.sh +3 -0
- package/lib/i18n/prices_refresh.sh +17 -0
- package/lib/i18n/prices_show.sh +7 -0
- package/lib/i18n/propose.sh +0 -0
- package/lib/i18n/release.sh +0 -0
- package/lib/i18n/research.sh +0 -0
- package/lib/i18n/review_pr.sh +0 -0
- package/lib/i18n/sentinel.sh +0 -0
- package/lib/i18n/setup.sh +3 -0
- package/lib/i18n/shared.sh +157 -0
- package/lib/i18n/skills/roll-brief.sh +47 -0
- package/lib/i18n/skills/roll-build.sh +97 -0
- package/lib/i18n/skills/roll-design.sh +18 -0
- package/lib/i18n/skills/roll-fix.sh +53 -0
- package/lib/i18n/skills/roll-loop.sh +28 -0
- package/lib/i18n/skills/roll-onboard.sh +33 -0
- package/lib/i18n/skills_catalog.sh +30 -0
- package/lib/i18n/slides.sh +3 -0
- package/lib/i18n/slides_build.sh +38 -0
- package/lib/i18n/slides_delete.sh +19 -0
- package/lib/i18n/slides_list.sh +14 -0
- package/lib/i18n/slides_logs.sh +12 -0
- package/lib/i18n/slides_new.sh +15 -0
- package/lib/i18n/slides_preview.sh +14 -0
- package/lib/i18n/slides_templates.sh +7 -0
- package/lib/i18n/status.sh +21 -0
- package/lib/i18n/update.sh +24 -0
- package/lib/i18n.sh +211 -0
- package/lib/loop-exit-summary.py +393 -0
- package/lib/loop-fmt.py +589 -0
- package/lib/loop_pick_agent.py +316 -0
- package/lib/loop_result_eval.py +469 -0
- package/lib/loop_unstick.py +180 -0
- package/lib/model_prices.py +186 -0
- package/lib/prices/README.md +35 -0
- package/lib/prices/snapshot-2026-05-22.json +22 -0
- package/lib/prices/snapshot-2026-05-23-deepseek.json +15 -0
- package/lib/prices/snapshot-2026-05-23-kimi.json +14 -0
- package/lib/prices_fetcher.py +285 -0
- package/lib/roll-backlog.py +225 -0
- package/lib/roll-brief.py +286 -0
- package/lib/roll-help.py +158 -0
- package/lib/roll-home.py +556 -0
- package/lib/roll-init.py +156 -0
- package/lib/roll-loop-status.py +1683 -0
- package/lib/roll-loop-story.py +191 -0
- package/lib/roll-onboard-render.py +378 -0
- package/lib/roll-peer.py +252 -0
- package/lib/roll-plan-validate.py +386 -0
- package/lib/roll-setup.py +102 -0
- package/lib/roll-status.py +367 -0
- package/lib/roll_git.py +41 -0
- package/lib/roll_render.py +414 -0
- package/lib/slides/components/README.md +123 -0
- package/lib/slides/components/cards-2.html +9 -0
- package/lib/slides/components/cards-3.html +9 -0
- package/lib/slides/components/cards-4.html +9 -0
- package/lib/slides/components/compare.html +22 -0
- package/lib/slides/components/highlight.html +9 -0
- package/lib/slides/components/pipeline.html +12 -0
- package/lib/slides/components/plain.html +7 -0
- package/lib/slides/components/quote.html +4 -0
- package/lib/slides/components/timeline.html +9 -0
- package/lib/slides/templates/introduction-v3.html +571 -0
- package/lib/slides/templates/pitch.html +0 -0
- package/lib/slides-render.py +778 -0
- package/lib/slides-validate.py +357 -0
- package/lib/test_quality_gate.py +143 -0
- package/package.json +8 -7
- package/skills/roll-.changelog/SKILL.md +406 -33
- package/skills/roll-.clarify/SKILL.md +5 -2
- package/skills/roll-.dream/SKILL.md +374 -0
- package/skills/roll-.echo/SKILL.md +5 -2
- package/skills/roll-.qa/SKILL.md +57 -3
- package/skills/roll-.review/SKILL.md +42 -3
- package/skills/roll-brief/SKILL.md +209 -0
- package/skills/roll-build/SKILL.md +308 -63
- package/skills/roll-debug/SKILL.md +341 -162
- package/skills/roll-debug/injectable-bb.js +263 -0
- package/skills/roll-deck/SKILL.md +296 -0
- package/skills/roll-design/ENGINEERING_CHECKLIST.md +1 -1
- package/skills/roll-design/SKILL.md +727 -94
- package/skills/roll-doc/SKILL.md +595 -0
- package/skills/roll-doctor/SKILL.md +192 -0
- package/skills/roll-fix/SKILL.md +149 -32
- package/skills/{roll-jot → roll-idea}/SKILL.md +18 -10
- package/skills/roll-loop/SKILL.md +578 -0
- package/skills/roll-notes/SKILL.md +103 -0
- package/skills/roll-onboard/SKILL.md +234 -0
- package/skills/roll-peer/SKILL.md +336 -0
- package/skills/roll-propose/SKILL.md +157 -0
- package/skills/roll-review-pr/SKILL.md +58 -0
- package/skills/roll-sentinel/SKILL.md +11 -2
- package/skills/roll-spar/SKILL.md +8 -6
- package/template/.github/workflows/ci.yml +5 -2
- package/template/AGENTS.md +20 -74
- package/skills/roll-research/SKILL.md +0 -307
- package/skills/roll-research/references/schema.json +0 -162
- package/skills/roll-research/scripts/md_to_pdf.py +0 -289
- package/tools/roll-fetch/SKILL.md +0 -182
- package/tools/roll-fetch/package.json +0 -15
- package/tools/roll-fetch/smart-web-fetch.js +0 -558
- package/tools/roll-probe/SKILL.md +0 -84
- /package/template/{BACKLOG.md → .roll/backlog.md} +0 -0
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
## Stack
|
|
6
6
|
|
|
7
|
-
- Node.js / TypeScript
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Distribution: npm package with bin entry
|
|
7
|
+
- Runtime / Language: {e.g. Node.js / TypeScript, Go, Python, Bash}
|
|
8
|
+
- Test framework: {e.g. Vitest, pytest, bats}
|
|
9
|
+
- Distribution: {e.g. npm, Homebrew, binary release}
|
|
11
10
|
|
|
12
11
|
## Claude Code Notes
|
|
13
12
|
|
|
@@ -15,4 +14,3 @@
|
|
|
15
14
|
- Test commands by running them in Bash, not just unit tests.
|
|
16
15
|
- Use `$roll-design` to plan command structure and options before implementation.
|
|
17
16
|
- Verify `--help` output is clear and complete for each command.
|
|
18
|
-
- Run `npm run build && node dist/index.js --help` before pushing.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Project Preferences — CLI Tool (
|
|
1
|
+
# Project Preferences — CLI Tool (Antigravity)
|
|
2
2
|
|
|
3
|
-
> Extends global GEMINI.md + project AGENTS.md.
|
|
3
|
+
> Extends global GEMINI.md (Antigravity) + project AGENTS.md.
|
|
4
4
|
|
|
5
5
|
## Stack
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
- CLI framework: commander or citty
|
|
9
9
|
- Testing: Vitest
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Antigravity (agy) Notes
|
|
12
12
|
|
|
13
13
|
- No server, no frontend. CLI tool only.
|
|
14
14
|
- Test commands by running them, not just unit tests.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Project Preferences — CLI Tool (Trae IDE)
|
|
2
|
+
|
|
3
|
+
> Extends global project_rules.md + project AGENTS.md.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- Node.js / TypeScript
|
|
8
|
+
- CLI framework: commander or citty
|
|
9
|
+
- Testing: Vitest
|
|
10
|
+
|
|
11
|
+
## Trae Notes
|
|
12
|
+
|
|
13
|
+
- No server, no frontend. CLI tool only.
|
|
14
|
+
- Test commands by running them, not just unit tests.
|
|
15
|
+
- Run `npm run build && node dist/index.js --help` before pushing.
|
|
16
|
+
- Follow the project AGENTS.md for architecture constraints and Roll workflow.
|
|
@@ -1,71 +1,36 @@
|
|
|
1
1
|
# Project Conventions — Frontend Only
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- **
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- **Data Schema First**: define types/schemas before writing business logic.
|
|
22
|
-
- No backend code in this project. API consumption only.
|
|
23
|
-
|
|
24
|
-
## State Management
|
|
25
|
-
|
|
26
|
-
- Prefer React built-in state (useState, useReducer, useContext) for simple cases.
|
|
27
|
-
- Use a state library (Zustand, Jotai) only when shared state gets complex.
|
|
28
|
-
- Server state via TanStack Query (React Query) for API data fetching and caching.
|
|
29
|
-
|
|
30
|
-
## Project Structure
|
|
31
|
-
|
|
3
|
+
> Reference for skills to infer frontend project conventions.
|
|
4
|
+
>
|
|
5
|
+
> **Foundation**: extends the shared rules in `~/.<agent>/AGENTS.md`
|
|
6
|
+
> (installed by `roll setup`). For BACKLOG row format, identity, TCR
|
|
7
|
+
> rhythm, and other cross-project rules, see that file's §4. Only
|
|
8
|
+
> project-specific stack / structure / domain rules live below.
|
|
9
|
+
|
|
10
|
+
## 1. Stack
|
|
11
|
+
- **Core**: React 18+ / TS / Vite / Tailwind / shadcn/ui.
|
|
12
|
+
- **State**: React state (simple), Zustand/Jotai (complex), TanStack Query (server).
|
|
13
|
+
- **Structure**: `src/domains/{domain}/` for DDD.
|
|
14
|
+
|
|
15
|
+
## 2. Architecture
|
|
16
|
+
- **DDD**: Logic in hooks/services, not components.
|
|
17
|
+
- **Decoupling**: UI renders only, logic in hooks.
|
|
18
|
+
- **Data**: Define schemas before logic.
|
|
19
|
+
|
|
20
|
+
## 3. Structure
|
|
32
21
|
```
|
|
33
22
|
src/
|
|
34
|
-
├── components/ui/
|
|
35
|
-
├── domains/
|
|
36
|
-
|
|
37
|
-
│ ├── components/ # domain-specific UI
|
|
38
|
-
│ ├── hooks/ # domain logic + state
|
|
39
|
-
│ ├── services/ # API client calls
|
|
40
|
-
│ └── types.ts # domain types
|
|
41
|
-
├── shared/
|
|
42
|
-
│ ├── api/ # HTTP client, interceptors
|
|
43
|
-
│ ├── types/ # shared type definitions
|
|
44
|
-
│ └── utils/ # utility functions
|
|
45
|
-
├── App.tsx
|
|
46
|
-
└── main.tsx
|
|
47
|
-
|
|
48
|
-
tests/
|
|
49
|
-
├── unit/ # Vitest + Testing Library
|
|
50
|
-
└── e2e/ # Playwright
|
|
23
|
+
├── components/ui/ # shadcn (don't edit)
|
|
24
|
+
├── domains/ # DDD components/hooks/services
|
|
25
|
+
└── shared/ # api/types/utils
|
|
51
26
|
```
|
|
52
27
|
|
|
53
|
-
##
|
|
54
|
-
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
- **Verification Gate**: Before marking done, provide fresh evidence (test output, screenshot). "I confirmed it works" is not evidence.
|
|
58
|
-
- **Complete delivery**: push to GitHub + CI passes + deployed online. Local-only done is not done.
|
|
59
|
-
|
|
60
|
-
## Testing Requirements
|
|
61
|
-
|
|
62
|
-
- All hooks and domain logic must have unit tests (Vitest + Testing Library, coverage >80%).
|
|
63
|
-
- Critical user flows must have E2E tests (Playwright).
|
|
64
|
-
- Run existing tests before pushing to verify no regressions.
|
|
65
|
-
|
|
66
|
-
## Workspace Structure
|
|
28
|
+
## 4. Discipline
|
|
29
|
+
- **TCR**: Mandatory.
|
|
30
|
+
- **Testing**: Unit (hooks/logic) >80%, E2E (Playwright).
|
|
31
|
+
- **Workspace**: `.roll/backlog.md` + `.roll/features/`.
|
|
67
32
|
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
33
|
+
## 5. Where to Look
|
|
34
|
+
- **Domain model**: `.roll/domain/context-map.md` — Bounded Contexts and relationships
|
|
35
|
+
- **Story details**: `.roll/features/` — AC, implementation specs, dependencies
|
|
36
|
+
- **Design decisions**: `.roll/domain/` — DDD models, architecture records
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# Project Preferences — Frontend Only (
|
|
1
|
+
# Project Preferences — Frontend Only (Antigravity)
|
|
2
2
|
|
|
3
|
-
> Extends global GEMINI.md + project AGENTS.md.
|
|
3
|
+
> Extends global GEMINI.md (Antigravity) + project AGENTS.md.
|
|
4
4
|
|
|
5
5
|
## Stack
|
|
6
6
|
|
|
7
7
|
- React + shadcn/ui + Tailwind CSS + Vite
|
|
8
8
|
- Testing: Vitest + Playwright
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Antigravity (agy) Notes
|
|
11
11
|
|
|
12
12
|
- No backend in this project. All data via external API consumption.
|
|
13
13
|
- Run `npm run build` to verify production bundle compiles before pushing.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Project Preferences — Frontend Only (Trae IDE)
|
|
2
|
+
|
|
3
|
+
> Extends global project_rules.md + project AGENTS.md.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- React + shadcn/ui + Tailwind CSS + Vite
|
|
8
|
+
- Testing: Vitest + Playwright
|
|
9
|
+
|
|
10
|
+
## Trae Notes
|
|
11
|
+
|
|
12
|
+
- No backend in this project. All data via external API consumption.
|
|
13
|
+
- Run `npm run build` to verify production bundle compiles before pushing.
|
|
14
|
+
- Follow the project AGENTS.md for architecture constraints and Roll workflow.
|
|
@@ -1,87 +1,39 @@
|
|
|
1
1
|
# Project Conventions — Fullstack Web
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- Folder structure:
|
|
22
|
-
- `src/routes/` or `api/routes/` — route handlers
|
|
23
|
-
- `src/services/` or `api/services/` — business logic
|
|
24
|
-
- `src/models/` or `api/models/` — data models and schemas
|
|
25
|
-
- Health check endpoint: `GET /api/health`
|
|
26
|
-
- Authentication: JWT in httpOnly cookies.
|
|
27
|
-
|
|
28
|
-
## Architecture
|
|
29
|
-
|
|
30
|
-
- **Domain Driven Design**: organize code by business domain, not technical layer.
|
|
31
|
-
- **Clean Architecture**: UI → Application (hooks) → Domain (services) → Infrastructure (API/DB).
|
|
32
|
-
- **Decoupling**: UI renders only, logic lives in hooks. API calls wrapped in services.
|
|
33
|
-
- **Data Schema First**: define types/schemas before writing business logic.
|
|
34
|
-
- **Frontend-Backend Contract**: API changes must sync `shared/types/`. Errors use unified format.
|
|
35
|
-
|
|
36
|
-
## Project Structure
|
|
37
|
-
|
|
3
|
+
> Reference for skills to infer fullstack project conventions.
|
|
4
|
+
>
|
|
5
|
+
> **Foundation**: extends the shared rules in `~/.<agent>/AGENTS.md`
|
|
6
|
+
> (installed by `roll setup`). For BACKLOG row format, identity, TCR
|
|
7
|
+
> rhythm, and other cross-project rules, see that file's §4. Only
|
|
8
|
+
> project-specific stack / structure / domain rules live below.
|
|
9
|
+
|
|
10
|
+
## 1. Stack
|
|
11
|
+
- **Frontend**: React 18+ / TS / Vite / Tailwind / shadcn/ui.
|
|
12
|
+
- **Backend**: Node.js REST API.
|
|
13
|
+
- **Structure**: `src/domains/{domain}/` for DDD. `api/` for backend.
|
|
14
|
+
|
|
15
|
+
## 2. Architecture
|
|
16
|
+
- **DDD**: Logic in hooks/services, not components.
|
|
17
|
+
- **Contract**: API changes must sync `shared/types/`.
|
|
18
|
+
- **Data**: Define schemas before logic.
|
|
19
|
+
|
|
20
|
+
## 3. Structure
|
|
38
21
|
```
|
|
39
22
|
src/
|
|
40
|
-
├── components/ui/
|
|
41
|
-
├── domains/
|
|
42
|
-
|
|
43
|
-
│ ├── components/ # domain-specific UI
|
|
44
|
-
│ ├── hooks/ # domain logic
|
|
45
|
-
│ ├── services/ # API calls
|
|
46
|
-
│ └── types.ts # domain types
|
|
47
|
-
├── shared/
|
|
48
|
-
│ ├── api/ # HTTP client, interceptors
|
|
49
|
-
│ ├── types/ # shared type definitions
|
|
50
|
-
│ └── utils/ # utility functions
|
|
51
|
-
├── App.tsx
|
|
52
|
-
└── main.tsx
|
|
53
|
-
|
|
23
|
+
├── components/ui/ # shadcn (don't edit)
|
|
24
|
+
├── domains/ # DDD components/hooks/services
|
|
25
|
+
└── shared/ # api/types/utils
|
|
54
26
|
api/
|
|
55
|
-
├── routes/
|
|
56
|
-
|
|
57
|
-
├── models/ # data models
|
|
58
|
-
└── types.ts # API contract types
|
|
59
|
-
|
|
60
|
-
schema/ # data contract definitions
|
|
61
|
-
tests/
|
|
62
|
-
├── unit/ # Vitest
|
|
63
|
-
├── e2e/ # Playwright
|
|
64
|
-
└── regression/ # Sentinel regression
|
|
27
|
+
├── routes/ # thin handlers
|
|
28
|
+
└── services/ # business logic
|
|
65
29
|
```
|
|
66
30
|
|
|
67
|
-
##
|
|
68
|
-
|
|
69
|
-
- **
|
|
70
|
-
- **
|
|
71
|
-
- **Verification Gate**: Before marking done, provide fresh evidence (test output, screenshot, curl). "I confirmed it works" is not evidence.
|
|
72
|
-
- **Complete delivery**: push to GitHub + CI passes + deployed online. Local-only done is not done.
|
|
73
|
-
|
|
74
|
-
## Testing Requirements
|
|
75
|
-
|
|
76
|
-
- All business logic must have unit tests (coverage >80%).
|
|
77
|
-
- All API endpoints must have integration tests — no DB mocks, use real database.
|
|
78
|
-
- Critical user flows must have E2E tests (Playwright).
|
|
79
|
-
- New architecture introductions (State/Cache/EventBus) must have data flow integration tests.
|
|
80
|
-
- Sentinel will periodically regression-test completed Stories.
|
|
81
|
-
|
|
82
|
-
## Workspace Structure
|
|
31
|
+
## 4. Discipline
|
|
32
|
+
- **TCR**: Mandatory.
|
|
33
|
+
- **Testing**: Unit >80%, E2E for critical flows.
|
|
34
|
+
- **Workspace**: `.roll/backlog.md` + `.roll/features/`.
|
|
83
35
|
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
36
|
+
## 5. Where to Look
|
|
37
|
+
- **Domain model**: `.roll/domain/context-map.md` — Bounded Contexts and relationships
|
|
38
|
+
- **Story details**: `.roll/features/` — AC, implementation specs, dependencies
|
|
39
|
+
- **Design decisions**: `.roll/domain/` — DDD models, architecture records
|
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
|
|
14
14
|
- Use `$roll-design` to plan features that span frontend and backend.
|
|
15
15
|
- When modifying API contracts, update both `api/types.ts` and `src/shared/types/` in the same commit.
|
|
16
|
-
- Use worktree isolation for parallel frontend/backend Actions in `$roll-
|
|
16
|
+
- Use worktree isolation for parallel frontend/backend Actions in `$roll-build`.
|
|
17
17
|
- Run `npm run build` to verify both frontend and backend compile before pushing.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Project Preferences — Fullstack Web (
|
|
1
|
+
# Project Preferences — Fullstack Web (Antigravity)
|
|
2
2
|
|
|
3
|
-
> Extends global GEMINI.md + project AGENTS.md.
|
|
3
|
+
> Extends global GEMINI.md (Antigravity) + project AGENTS.md.
|
|
4
4
|
|
|
5
5
|
## Stack
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
- Backend: Node.js API (Express/Hono/Fastify)
|
|
9
9
|
- Testing: Vitest (unit) + Playwright (E2E)
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Antigravity (agy) Notes
|
|
12
12
|
|
|
13
13
|
- When modifying API contracts, update both `api/types.ts` and `src/shared/types/` in the same commit.
|
|
14
14
|
- Run `npm run build` to verify both frontend and backend compile before pushing.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Project Preferences — Fullstack Web (Trae IDE)
|
|
2
|
+
|
|
3
|
+
> Extends global project_rules.md + project AGENTS.md.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- Frontend: React + shadcn/ui + Tailwind CSS + Vite
|
|
8
|
+
- Backend: Node.js API (Express/Hono/Fastify)
|
|
9
|
+
- Testing: Vitest (unit) + Playwright (E2E)
|
|
10
|
+
|
|
11
|
+
## Trae Notes
|
|
12
|
+
|
|
13
|
+
- When modifying API contracts, update both `api/types.ts` and `src/shared/types/` in the same commit.
|
|
14
|
+
- Run `npm run build` to verify both frontend and backend compile before pushing.
|
|
15
|
+
- Follow the project AGENTS.md for architecture constraints and Roll workflow.
|
package/lib/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
> **Draft** — auto-generated by roll-doc on 2026-05-28. Review before treating as authoritative.
|
|
2
|
+
|
|
3
|
+
# lib/ — Python helpers and i18n runtime
|
|
4
|
+
|
|
5
|
+
Python scripts and shell libraries that `bin/roll` delegates to for rendering-heavy or data-processing tasks.
|
|
6
|
+
|
|
7
|
+
## Key files
|
|
8
|
+
|
|
9
|
+
| File | Purpose |
|
|
10
|
+
|------|---------|
|
|
11
|
+
| `roll-loop-status.py` | Renders the `roll loop status` health dashboard — reads cycle event NDJSON, computes per-cycle rows, daily rollups, and phase-tracing breakdown |
|
|
12
|
+
| `roll-loop-story.py` | Per-story rollup: aggregates cycles, tokens, cost, and PR outcomes for `roll loop story <ID>` |
|
|
13
|
+
| `roll-status.py` | Renders the `roll status` one-screen sync health view |
|
|
14
|
+
| `roll-init.py` | Init-flow helpers called by `roll init` |
|
|
15
|
+
| `roll-setup.py` | Setup-flow helpers (convention sync, tool config write) |
|
|
16
|
+
| `roll-brief.py` | Brief generation: reads cycle records and produces the feature brief |
|
|
17
|
+
| `roll-backlog.py` | Backlog read/write helpers |
|
|
18
|
+
| `roll-peer.py` | Peer review coordination helpers |
|
|
19
|
+
| `roll-help.py` | Renders `roll --help` output |
|
|
20
|
+
| `roll-plan-validate.py` | Validates plan files before story execution |
|
|
21
|
+
| `model_prices.py` | List-price table for AI model API pricing (per MTok, native currency) |
|
|
22
|
+
| `prices_fetcher.py` | Fetches fresh price snapshots from vendor APIs |
|
|
23
|
+
| `roll_render.py` | Shared rendering utilities (tables, color, formatting) |
|
|
24
|
+
| `loop-fmt.py` | Loop log formatter (ANSI-strip, timestamp alignment) |
|
|
25
|
+
| `loop_unstick.py` | Diagnostic: detects and unsticks hung loop state |
|
|
26
|
+
| `backfill-pi-usage.py` | Backfills pi/deepseek token and cost data into existing cycle records |
|
|
27
|
+
| `changelog_audit.py` | Audits CHANGELOG.md against backlog entries |
|
|
28
|
+
| `i18n.sh` | Shell wrapper that delegates i18n string lookups to `lib/i18n/` |
|
|
29
|
+
| `slides-render.py` | Renders `.deck.md` → HTML slides |
|
|
30
|
+
| `slides-validate.py` | Validates deck file syntax and asset references |
|
|
31
|
+
|
|
32
|
+
## Sub-directories
|
|
33
|
+
|
|
34
|
+
- `agent_usage/` — token-usage capture and cost attribution per agent invocation
|
|
35
|
+
- `i18n/` — localized string tables for all CLI output (EN + ZH)
|
|
36
|
+
- `prices/` — price snapshot JSON files (per-vendor, dated)
|
|
37
|
+
- `slides/` — slide component library for `roll deck`
|
|
38
|
+
|
|
39
|
+
## Dependencies
|
|
40
|
+
|
|
41
|
+
Imported by `bin/roll` via subprocess calls (`python3 lib/<script>.py`).
|
|
42
|
+
No third-party pip dependencies — standard library only (json, sys, os, re, datetime).
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Adding a New Agent Usage Plugin
|
|
2
|
+
|
|
3
|
+
5-step checklist for adding token/cost extraction for a new agent.
|
|
4
|
+
|
|
5
|
+
## 1. Create plugin file
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cp lib/agent_usage/pi.py lib/agent_usage/<agent>.py
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Implement `extract(stdin_lines: list[str]) -> dict | None`.
|
|
12
|
+
|
|
13
|
+
## 2. Register in `__init__.py`
|
|
14
|
+
|
|
15
|
+
In `lib/agent_usage/__init__.py`, add one entry to `_PLUGINS`:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
_PLUGINS = {
|
|
19
|
+
"pi": ".pi",
|
|
20
|
+
"<agent>": ".<agent>", # ← add this line
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The key must match `ROLL_LOOP_AGENT` env var (e.g. `kimi`, `deepseek`).
|
|
25
|
+
|
|
26
|
+
## 3. Capture sample output
|
|
27
|
+
|
|
28
|
+
Run a real cycle with the agent and save the stdout to a fixture:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
roll loop test 2>&1 | tee tests/fixtures/<agent>_output_sample.txt
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or capture from a real cycle log.
|
|
35
|
+
|
|
36
|
+
## 4. Write unit tests
|
|
37
|
+
|
|
38
|
+
See `tests/unit/agent_usage_pi.bats` for reference. Test:
|
|
39
|
+
- Happy path: fixture produces valid dict (all required fields non-None)
|
|
40
|
+
- Edge case: empty lines, missing cost, unmatchable format → returns None
|
|
41
|
+
- Round-trip: known token counts match fixture
|
|
42
|
+
|
|
43
|
+
## 5. Run tests
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm test
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
That's it — no changes to `loop-fmt.py` or any other file.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""
|
|
2
|
+
agent_usage — plugin registry for extracting token/cost usage from
|
|
3
|
+
non-claude agent stdout.
|
|
4
|
+
|
|
5
|
+
Contract
|
|
6
|
+
--------
|
|
7
|
+
Each plugin module exports a single function:
|
|
8
|
+
|
|
9
|
+
def extract(stdin_lines: list[str]) -> dict | None:
|
|
10
|
+
'''Parse agent stdout lines and return structured usage data.
|
|
11
|
+
|
|
12
|
+
Returns None if the format wasn't recognized (caller falls back
|
|
13
|
+
to null payload — fully backward-compatible with US-LOOP-010).
|
|
14
|
+
|
|
15
|
+
Return dict shape:
|
|
16
|
+
{
|
|
17
|
+
"model": str, # e.g. "deepseek-v4-pro"
|
|
18
|
+
"input_tokens": int, # never None
|
|
19
|
+
"output_tokens": int, # never None
|
|
20
|
+
"cost_list_usd": float, # never None
|
|
21
|
+
"duration_ms": int | None,
|
|
22
|
+
}
|
|
23
|
+
'''
|
|
24
|
+
|
|
25
|
+
Adding a new agent
|
|
26
|
+
------------------
|
|
27
|
+
1. Create ``lib/agent_usage/<agent>.py`` implementing ``extract()``
|
|
28
|
+
2. Register it here by adding one entry to ``REGISTRY``
|
|
29
|
+
3. Add a fixture file under ``tests/fixtures/<agent>_output_sample.txt``
|
|
30
|
+
4. Add unit tests in ``tests/unit/agent_usage_<agent>.bats``
|
|
31
|
+
5. Run ``npm test`` to verify no regressions
|
|
32
|
+
"""
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
import importlib
|
|
36
|
+
import logging
|
|
37
|
+
import os
|
|
38
|
+
from typing import Callable, Dict, Optional
|
|
39
|
+
|
|
40
|
+
_log = logging.getLogger(__name__)
|
|
41
|
+
|
|
42
|
+
# Registry: agent name → extract function
|
|
43
|
+
# Agent names match ROLL_LOOP_AGENT env var values (e.g. "pi", "deepseek", "kimi").
|
|
44
|
+
REGISTRY: Dict[str, Callable] = {}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _lazy_import(module_name: str) -> Optional[Callable]:
|
|
48
|
+
"""Import a plugin module and return its extract function, or None on failure."""
|
|
49
|
+
try:
|
|
50
|
+
mod = importlib.import_module(module_name)
|
|
51
|
+
extract = getattr(mod, "extract", None)
|
|
52
|
+
if extract is None:
|
|
53
|
+
_log.warning("agent_usage plugin %s has no extract() function", module_name)
|
|
54
|
+
return None
|
|
55
|
+
if not callable(extract):
|
|
56
|
+
_log.warning("agent_usage plugin %s.extract is not callable", module_name)
|
|
57
|
+
return None
|
|
58
|
+
return extract
|
|
59
|
+
except Exception:
|
|
60
|
+
_log.warning("agent_usage plugin %s failed to load", module_name, exc_info=True)
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# Populate REGISTRY from known plugins
|
|
65
|
+
_PLUGIN_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
66
|
+
_PLUGINS = {
|
|
67
|
+
# agent name → python module name (relative to this package)
|
|
68
|
+
"pi": ".pi",
|
|
69
|
+
"openai": ".openai",
|
|
70
|
+
"gemini": ".gemini",
|
|
71
|
+
"kimi": ".kimi",
|
|
72
|
+
"qwen": ".qwen",
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for _agent, _mod_suffix in _PLUGINS.items():
|
|
76
|
+
_extract = _lazy_import(__package__ + _mod_suffix)
|
|
77
|
+
if _extract is not None:
|
|
78
|
+
REGISTRY[_agent] = _extract
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def extract_usage(agent: str, stdin_lines: list[str]) -> Optional[dict]:
|
|
82
|
+
"""Look up agent in REGISTRY and call its extract().
|
|
83
|
+
|
|
84
|
+
Returns None if agent not registered, plugin not loadable, or
|
|
85
|
+
extract() returns None / raises an exception. The caller falls
|
|
86
|
+
back to the null-payload passthrough path (US-LOOP-010 compatible).
|
|
87
|
+
"""
|
|
88
|
+
extract_fn = REGISTRY.get(agent)
|
|
89
|
+
if extract_fn is None:
|
|
90
|
+
return None
|
|
91
|
+
try:
|
|
92
|
+
result = extract_fn(stdin_lines)
|
|
93
|
+
if result is None:
|
|
94
|
+
return None
|
|
95
|
+
# Validate required fields
|
|
96
|
+
for key in ("model", "input_tokens", "output_tokens", "cost_list_usd"):
|
|
97
|
+
if result.get(key) is None:
|
|
98
|
+
_log.warning(
|
|
99
|
+
"agent_usage plugin %s returned None for required field %r",
|
|
100
|
+
agent, key,
|
|
101
|
+
)
|
|
102
|
+
return None
|
|
103
|
+
return result
|
|
104
|
+
except Exception:
|
|
105
|
+
_log.warning(
|
|
106
|
+
"agent_usage plugin %s raised during extract()", agent, exc_info=True,
|
|
107
|
+
)
|
|
108
|
+
return None
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|