@ericrisco/rsc 0.1.44 → 0.1.45
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 +1 -1
- package/manifest.json +110 -86
- package/package.json +1 -1
- package/scripts/lib/domains.js +1 -1
- package/scripts/skill-migration-brief.md +104 -0
- package/skills/ab-testing/SKILL.md +9 -41
- package/skills/accessibility/SKILL.md +5 -7
- package/skills/ads/SKILL.md +9 -24
- package/skills/agent-eval/SKILL.md +7 -33
- package/skills/agent-safety/SKILL.md +7 -14
- package/skills/ai-media/SKILL.md +4 -20
- package/skills/analytics/SKILL.md +8 -30
- package/skills/analyze/SKILL.md +24 -59
- package/skills/angular/SKILL.md +12 -25
- package/skills/api-connector-builder/SKILL.md +10 -27
- package/skills/api-design/SKILL.md +7 -14
- package/skills/article-writing/SKILL.md +1 -18
- package/skills/astro/SKILL.md +36 -54
- package/skills/author-skill/SKILL.md +41 -74
- package/skills/author-skill/evals/README.md +5 -5
- package/skills/author-skill/evals/cases.yaml +8 -8
- package/skills/author-skill/references/description-recipe.md +25 -26
- package/skills/author-skill/references/eval-authoring.md +1 -1
- package/skills/author-skill/references/rsc-conventions.md +1 -1
- package/skills/automation-flows/SKILL.md +6 -16
- package/skills/automation-strategy/SKILL.md +1 -9
- package/skills/aws-essentials/SKILL.md +6 -23
- package/skills/backups/SKILL.md +1 -7
- package/skills/bash-scripting/SKILL.md +5 -9
- package/skills/bookkeeping/SKILL.md +2 -10
- package/skills/brand-identity/SKILL.md +18 -44
- package/skills/brand-voice/SKILL.md +4 -31
- package/skills/building-agents/SKILL.md +20 -103
- package/skills/business-intelligence/SKILL.md +9 -23
- package/skills/calendar-scheduling/SKILL.md +11 -27
- package/skills/case-studies/SKILL.md +3 -8
- package/skills/chatbot/SKILL.md +6 -23
- package/skills/chrome-extension/SKILL.md +2 -2
- package/skills/clarify/SKILL.md +31 -72
- package/skills/clickhouse-analytics/SKILL.md +2 -8
- package/skills/client-onboarding/SKILL.md +17 -19
- package/skills/cloudflare/SKILL.md +3 -8
- package/skills/code-review/SKILL.md +10 -23
- package/skills/codebase-onboarding/SKILL.md +2 -7
- package/skills/cold-outreach/SKILL.md +9 -30
- package/skills/community/SKILL.md +4 -31
- package/skills/competitor-watch/SKILL.md +20 -35
- package/skills/compliance/SKILL.md +10 -37
- package/skills/compose-multiplatform/SKILL.md +1 -1
- package/skills/constitution/SKILL.md +8 -35
- package/skills/content-engine/SKILL.md +4 -16
- package/skills/context-budget/SKILL.md +3 -21
- package/skills/continuous-learning/SKILL.md +10 -40
- package/skills/contracts/SKILL.md +6 -17
- package/skills/coolify/SKILL.md +8 -14
- package/skills/cost-tracking/SKILL.md +3 -11
- package/skills/course-builder/SKILL.md +17 -45
- package/skills/course-storytelling/SKILL.md +26 -94
- package/skills/cpp/SKILL.md +26 -71
- package/skills/csharp-dotnet/SKILL.md +19 -38
- package/skills/customer-support/SKILL.md +14 -37
- package/skills/dashboard/SKILL.md +6 -26
- package/skills/data-cleaning/SKILL.md +37 -63
- package/skills/data-policy/SKILL.md +8 -21
- package/skills/data-scraper/SKILL.md +1 -7
- package/skills/debug/SKILL.md +10 -49
- package/skills/deployment/SKILL.md +38 -101
- package/skills/design/SKILL.md +34 -116
- package/skills/fable-operator/SKILL.md +1 -4
- package/skills/fastapi/SKILL.md +50 -82
- package/skills/flutter/SKILL.md +41 -89
- package/skills/go/SKILL.md +57 -105
- package/skills/harness/SKILL.md +52 -68
- package/skills/implement/SKILL.md +1 -1
- package/skills/init/SKILL.md +152 -168
- package/skills/marketing/SKILL.md +30 -80
- package/skills/nextjs/SKILL.md +42 -116
- package/skills/orient/SKILL.md +25 -20
- package/skills/parallel/SKILL.md +9 -75
- package/skills/plan/SKILL.md +92 -165
- package/skills/postgresdb/SKILL.md +52 -72
- package/skills/presentations/SKILL.md +49 -87
- package/skills/python/SKILL.md +23 -72
- package/skills/react/SKILL.md +19 -67
- package/skills/review/SKILL.md +22 -52
- package/skills/rust/SKILL.md +40 -115
- package/skills/sdd-init/SKILL.md +9 -14
- package/skills/secure-coding/SKILL.md +80 -109
- package/skills/ship/SKILL.md +25 -55
- package/skills/tasks/SKILL.md +37 -61
- package/skills/typescript/SKILL.md +22 -55
- package/skills/verify/SKILL.md +8 -32
- package/skills/viral-score/SKILL.md +122 -0
- package/skills/viral-score/evals/README.md +16 -0
- package/skills/viral-score/evals/cases.yaml +50 -0
- package/skills/vue-nuxt/SKILL.md +45 -106
- package/skills/worktrees/SKILL.md +24 -69
package/skills/fastapi/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: fastapi
|
|
3
|
-
description: "Use when building, reviewing, testing, securing or
|
|
3
|
+
description: "Use when building, reviewing, testing, securing or shipping a FastAPI / async Python service — routers, Pydantic v2 schemas, dependency injection, async SQLAlchemy 2.0, OAuth2/JWT, ASGITransport tests, production wiring. NOT language-level Python or packaging (that is `python`), NOT engine-level SQL (that is `postgresdb`), NOT framework-agnostic REST contracts (that is `api-design`)."
|
|
4
4
|
tags: [python, api, async, backend, rest]
|
|
5
5
|
recommends: [postgresdb, secure-coding, deployment]
|
|
6
6
|
origin: risco
|
|
@@ -20,25 +20,16 @@ pytest 8 + pytest-asyncio 1.0+ (`asyncio_mode=auto`), ruff 0.7+, mypy 1.13+ stri
|
|
|
20
20
|
uv 0.5+, uvicorn 0.32+ / gunicorn 23+ + uvicorn-worker 0.3+, PyJWT 2.10+, argon2-cffi 23+,
|
|
21
21
|
pip-audit 2.7+, PostgreSQL 16. (All lower bounds; install the latest in each line.)
|
|
22
22
|
|
|
23
|
-
## When to use
|
|
24
|
-
|
|
25
23
|
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- Django / Flask / DRF apps → not this skill.
|
|
37
|
-
- Sync WSGI services, data-science notebooks, CLI-only scripts with no HTTP surface.
|
|
38
|
-
- Pure REST contract questions (status codes, URL naming, versioning, cursor vs offset) → general REST-design territory (this skill covers the FastAPI *implementation* of those contracts).
|
|
39
|
-
- Frontend/Next.js, Go, Flutter work → their own skills.
|
|
40
|
-
- Generic secure-coding rules not specific to Python/FastAPI → **See Also `secure-coding`**.
|
|
41
|
-
- Container/Compose/CI deploy mechanics → **See Also `deployment`** (this skill keeps only a Docker *note*).
|
|
25
|
+
Out of scope, and where it goes instead: [`django`](../django/SKILL.md) for Django; Flask / sync WSGI,
|
|
26
|
+
notebooks and CLI-only scripts (no skill); language-level Python, typing and packaging →
|
|
27
|
+
[`python`](../python/SKILL.md); framework-agnostic REST contracts — status codes, URL naming, versioning,
|
|
28
|
+
cursor vs offset → [`api-design`](../api-design/SKILL.md) (this skill covers their FastAPI *implementation*);
|
|
29
|
+
engine-level schema, indexing, EXPLAIN, zero-downtime migrations, PgBouncer →
|
|
30
|
+
[`postgresdb`](../postgresdb/SKILL.md); language-agnostic injection / secret / authz theory →
|
|
31
|
+
[`secure-coding`](../secure-coding/SKILL.md); Dockerfile, Compose and CI/CD mechanics →
|
|
32
|
+
[`deployment`](../deployment/SKILL.md) (this skill keeps only a Docker *note*).
|
|
42
33
|
|
|
43
34
|
## Decision rules
|
|
44
35
|
|
|
@@ -140,11 +131,11 @@ app = create_app()
|
|
|
140
131
|
Accepting an optional `settings` argument lets tests build the app with overridden config
|
|
141
132
|
without touching the `get_settings` cache. **Bad** = `allow_origins=["*"]` with
|
|
142
133
|
`allow_credentials=True` — browsers reject it and Starlette refuses to echo `*` for
|
|
143
|
-
credentialed requests.
|
|
134
|
+
credentialed requests. → [`references/production.md`](references/production.md) for proxy headers / logging wiring at
|
|
144
135
|
startup.
|
|
145
136
|
|
|
146
137
|
To inject servers / security schemes / a logo into the generated OpenAPI doc, assign a
|
|
147
|
-
custom builder to `app.openapi` inside `create_app()`.
|
|
138
|
+
custom builder to `app.openapi` inside `create_app()`. → [`references/production.md`](references/production.md)
|
|
148
139
|
(Customizing the OpenAPI schema).
|
|
149
140
|
|
|
150
141
|
## Configuration (pydantic-settings)
|
|
@@ -229,7 +220,7 @@ v2 migration cheats: use `.model_dump()` not `.dict()`; `.model_validate(obj)` n
|
|
|
229
220
|
`field_validator`/`model_validator` not `@validator`/`@root_validator`.
|
|
230
221
|
|
|
231
222
|
**Bad** = a response model with `hashed_password: str` (leaks the hash). **Good** = the
|
|
232
|
-
`UserResponse` above (no secret fields).
|
|
223
|
+
`UserResponse` above (no secret fields). → [`references/security.md`](references/security.md).
|
|
233
224
|
|
|
234
225
|
## Dependency injection
|
|
235
226
|
|
|
@@ -275,7 +266,7 @@ def get_pagination(
|
|
|
275
266
|
PageParams = Annotated[Pagination, Depends(get_pagination)]
|
|
276
267
|
```
|
|
277
268
|
|
|
278
|
-
|
|
269
|
+
→ [`references/database.md`](references/database.md) for `async_session_factory` wiring; → [`references/security.md`](references/security.md)
|
|
279
270
|
for `get_current_user` and `require_roles`.
|
|
280
271
|
|
|
281
272
|
## Routers & endpoints
|
|
@@ -361,8 +352,9 @@ def register_exception_handlers(app: FastAPI) -> None:
|
|
|
361
352
|
Keep this envelope identical across every handler — one `code`/`message`/`details` shape so
|
|
362
353
|
clients parse errors once. Subclass `AppError` per failure (each fixes a `code` + status):
|
|
363
354
|
`NotFoundError` (404), `ConflictError` (409), `Unauthorized` (401), `Forbidden` (403) — full
|
|
364
|
-
hierarchy in
|
|
365
|
-
|
|
355
|
+
hierarchy in → [`references/production.md`](references/production.md) (AppError subclasses).
|
|
356
|
+
[`secure-coding`](../secure-coding/SKILL.md) has the why: error responses must never leak internals
|
|
357
|
+
(stack traces, SQL, secrets).
|
|
366
358
|
|
|
367
359
|
## Async SQLAlchemy 2.0 (essentials)
|
|
368
360
|
|
|
@@ -401,7 +393,9 @@ async def list_users(db: AsyncSession, limit: int, offset: int) -> list[User]:
|
|
|
401
393
|
return list(result.scalars().all())
|
|
402
394
|
```
|
|
403
395
|
|
|
404
|
-
|
|
396
|
+
Fetch by PK with `await db.get(Model, pk)`, by unique key with `.scalar_one_or_none()`; eager-load with
|
|
397
|
+
`selectinload` (collections) / `joinedload` (many-to-one).
|
|
398
|
+
→ [`references/database.md`](references/database.md) for relationships, N+1 / eager loading, repository, Alembic, pooling.
|
|
405
399
|
|
|
406
400
|
## Background tasks vs real queues
|
|
407
401
|
|
|
@@ -428,74 +422,48 @@ a transactional fixture — so every test rolls back. Use `pytest-asyncio` with
|
|
|
428
422
|
`asyncio_mode = "auto"` (no `@pytest.mark.asyncio`), and assert secrets never serialize (e.g.
|
|
429
423
|
`assert "hashed_password" not in resp.json()`). TDD red→green→refactor. Full fixtures
|
|
430
424
|
(transactional `begin_nested`, auth overrides, respx, coverage gate) in
|
|
431
|
-
|
|
425
|
+
→ [`references/testing.md`](references/testing.md).
|
|
432
426
|
|
|
433
427
|
## Security
|
|
434
428
|
|
|
435
429
|
Full hardening playbook — argon2 hashing, OAuth2 + JWT (claims validated, `algorithms`
|
|
436
430
|
pinned), `get_current_user`/`require_roles` RBAC, CORS, shared-store rate limiting, injection,
|
|
437
431
|
`SecretStr` + log redaction, security headers, `pip-audit` — lives in
|
|
438
|
-
|
|
439
|
-
|
|
432
|
+
→ [`references/security.md`](references/security.md) — including the exact `argon2.PasswordHasher().hash(pw)` and
|
|
433
|
+
`jwt.decode(t, key, algorithms=[...], audience=..., issuer=...)` calls. See
|
|
434
|
+
[`secure-coding`](../secure-coding/SKILL.md) for the language-agnostic theory.
|
|
440
435
|
|
|
441
436
|
## Production
|
|
442
437
|
|
|
443
438
|
ASGI/worker math, structured JSON logging + request-id, liveness vs readiness probes, graceful
|
|
444
439
|
shutdown, keyset pagination, caching, `ORJSONResponse` and proxy headers all live in
|
|
445
|
-
|
|
440
|
+
→ [`references/production.md`](references/production.md). See [`deployment`](../deployment/SKILL.md) for the
|
|
441
|
+
Dockerfile and CI/CD pipeline.
|
|
446
442
|
|
|
447
|
-
## Anti-patterns
|
|
443
|
+
## Anti-patterns
|
|
448
444
|
|
|
449
|
-
|
|
|
450
|
-
|---|---|
|
|
451
|
-
| "I'll just call `requests` in this async route, it's one call" | Blocks the event loop → use `httpx.AsyncClient`. |
|
|
452
|
-
| "`.dict()` still works" | Pydantic v2: use `.model_dump()`; `.dict()`/`from_orm` are deprecated. |
|
|
453
|
-
| "Return the ORM object directly, FastAPI will handle it" | Leaks columns + lazy-loads in serializer → declare `response_model`. |
|
|
454
|
-
| "`allow_origins=['*']` + credentials is fine for now" | Browser rejects it; Starlette blocks it. Pin origins. |
|
|
455
|
-
| "I'll decode the JWT without checking `exp`/`aud`" | Forged/replayed tokens. Validate exp/iss/aud + pin alg. |
|
|
456
|
-
| "Build the WHERE with an f-string, it's internal" | SQLi. Bound params / SQLAlchemy expressions only. |
|
|
457
|
-
| "One global session for the whole app is simpler" | Cross-request data bleed + concurrency bugs. One session per request. |
|
|
458
|
-
| "Catch `Exception` and return the message to the client" | Leaks internals. Log it, return generic 500. |
|
|
459
|
-
| "`BackgroundTasks` is good enough for the payment webhook retry" | No durability/retry. Use a real broker. |
|
|
460
|
-
| "mypy strict is too noisy, I'll skip it" | Strict catches the bugs FastAPI's runtime won't. Keep it. |
|
|
461
|
-
| "Commit inside the handler so I control it" | Let `get_db` own commit/rollback; handlers stay thin. |
|
|
462
|
-
| "Default-mutable arg / module-level engine at import is fine" | Mutable defaults bite; engine must live in lifespan. |
|
|
463
|
-
|
|
464
|
-
## Quick reference
|
|
465
|
-
|
|
466
|
-
| Task | Idiom |
|
|
445
|
+
| Anti-pattern | Why it breaks → do this |
|
|
467
446
|
|---|---|
|
|
468
|
-
|
|
|
469
|
-
|
|
|
470
|
-
|
|
|
471
|
-
|
|
|
472
|
-
|
|
|
473
|
-
|
|
|
474
|
-
|
|
|
475
|
-
|
|
|
476
|
-
|
|
|
477
|
-
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
`
|
|
485
|
-
|
|
486
|
-
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
No `02-DOCS/` layer? Skip silently (optionally suggest `harness`). Technical conventions are
|
|
493
|
-
*recorded, not gated* — never block the task on this.
|
|
494
|
-
|
|
495
|
-
## See Also
|
|
496
|
-
|
|
497
|
-
- [`secure-coding`](../secure-coding/SKILL.md) — language-agnostic injection / secret / authz hardening behind this skill's security rules.
|
|
498
|
-
- [`postgresdb`](../postgresdb/SKILL.md) — engine-level schema design, indexing, EXPLAIN, zero-downtime migrations, PgBouncer (below the SQLAlchemy layer this skill drives).
|
|
499
|
-
- [`deployment`](../deployment/SKILL.md) — Dockerfile, Compose, CI/CD, container runtime (this skill keeps only a Docker note).
|
|
500
|
-
- References: [`references/testing.md`](references/testing.md), [`references/database.md`](references/database.md), [`references/security.md`](references/security.md), [`references/production.md`](references/production.md).
|
|
501
|
-
- Verify gate: [`scripts/verify.sh`](scripts/verify.sh).
|
|
447
|
+
| `requests` (or any blocking call) inside an `async def` route | Blocks the event loop → use `httpx.AsyncClient`. |
|
|
448
|
+
| `.dict()` / `from_orm()` on a model | Pydantic v2: use `.model_dump()`; `.dict()`/`from_orm` are deprecated. |
|
|
449
|
+
| Returning the ORM object with no `response_model` | Leaks columns + lazy-loads in serializer → declare `response_model`. |
|
|
450
|
+
| `allow_origins=['*']` together with credentials | Browser rejects it; Starlette blocks it. Pin origins. |
|
|
451
|
+
| Decoding a JWT without checking `exp`/`aud` | Forged/replayed tokens. Validate exp/iss/aud + pin alg. |
|
|
452
|
+
| Building the WHERE clause with an f-string | SQLi. Bound params / SQLAlchemy expressions only. |
|
|
453
|
+
| One global session shared by the whole app | Cross-request data bleed + concurrency bugs. One session per request. |
|
|
454
|
+
| Catching `Exception` and returning its message | Leaks internals. Log it, return generic 500. |
|
|
455
|
+
| `BackgroundTasks` for a payment-webhook retry | No durability/retry. Use a real broker. |
|
|
456
|
+
| Skipping `mypy --strict` because it is noisy | Strict catches the bugs FastAPI's runtime won't. Keep it. |
|
|
457
|
+
| Committing inside the handler | Let `get_db` own commit/rollback; handlers stay thin. |
|
|
458
|
+
| Default-mutable arg / engine built at import time | Mutable defaults bite; engine must live in lifespan. |
|
|
459
|
+
|
|
460
|
+
## Project grounding
|
|
461
|
+
|
|
462
|
+
In a project with a `02-DOCS/` layer ([`harness`](../harness/SKILL.md)), read
|
|
463
|
+
`02-DOCS/wiki/stack/fastapi.md` first and stay consistent with it; create or update it with this
|
|
464
|
+
project's real choices — auth model (JWT/OAuth2 provider, token TTLs), DB session + migration tool,
|
|
465
|
+
error-envelope shape, settings/secrets approach, deployment target — bump its `Updated` date, and index
|
|
466
|
+
it in `02-DOCS/wiki/index.md`. No `02-DOCS/`? Skip silently. Conventions are *recorded, not gated* —
|
|
467
|
+
never block the task on this.
|
|
468
|
+
|
|
469
|
+
Verify gate: [`scripts/verify.sh`](scripts/verify.sh).
|
package/skills/flutter/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: flutter
|
|
3
|
-
description: "Use when building, structuring, testing or optimizing a Flutter app
|
|
3
|
+
description: "Use when building, structuring, testing or optimizing a Flutter app — feature-first layering, Riverpod 3 or Bloc, typed go_router, freezed models, a dio data layer, Material 3, jank hunting, widget/golden tests. Targets Flutter 3.44 / Dart 3.12. NOT React Native (that is `react-native`), NOT Compose Multiplatform (that is `compose-multiplatform`)."
|
|
4
4
|
tags: [flutter, dart, mobile, app, ios, android]
|
|
5
5
|
recommends: [design, deployment]
|
|
6
6
|
origin: risco
|
|
@@ -8,35 +8,28 @@ origin: risco
|
|
|
8
8
|
|
|
9
9
|
# Flutter & Dart app architecture
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The opinionated default stack for a production Flutter app: **feature-first + layered** folders,
|
|
12
|
+
**Riverpod 3** with codegen for shared/async state, a **typed go_router**, **freezed** immutable
|
|
13
|
+
models, a **dio** data layer, and explicit `Result<T, Failure>` error modeling — all on **Material 3**.
|
|
14
|
+
Escape hatches are first-class: **Bloc/Cubit** instead of Riverpod when the team already runs Bloc,
|
|
15
|
+
and raw `http`/`get_it` are allowed — but **pick one of each per app, never mix two**. Pinned versions
|
|
16
|
+
this skill targets: **Flutter 3.44 / Dart 3.12**, **Riverpod 3.0**, **go_router 17.2.x**
|
|
17
|
+
(+ `go_router_builder 4.3.x`), **freezed 3.x** / `json_serializable`, **dio 5.x**, **mocktail 1.x**.
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
folders, **Riverpod 3** with codegen for shared/async state, a **typed go_router**, **freezed**
|
|
15
|
-
immutable models, a **dio** data layer, and explicit `Result<T, Failure>` error modeling — all on
|
|
16
|
-
**Material 3**. Escape hatches exist and are first-class: use **Bloc/Cubit** instead of Riverpod when
|
|
17
|
-
the team already runs Bloc, and raw `http`/`get_it` are allowed — but **pick one of each per app, never
|
|
18
|
-
mix two**. Pinned versions this skill targets: **Flutter 3.44 / Dart 3.12**, **Riverpod 3.0**,
|
|
19
|
-
**go_router 17.2.x** (+ `go_router_builder 4.3.x`), **freezed 3.x** / `json_serializable`, **dio 5.x**,
|
|
20
|
-
**mocktail 1.x**. When you load this skill inside the user's repo, it touches only the `pubspec.yaml`
|
|
21
|
-
subproject — never the FastAPI/Go/Next.js siblings.
|
|
22
|
-
|
|
23
|
-
## When to use / When NOT to use
|
|
19
|
+
## Boundaries
|
|
24
20
|
|
|
25
21
|
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
This skill owns the `pubspec.yaml` subproject and nothing else in the repo. Hand off when the UI is
|
|
24
|
+
Compose Multiplatform (`compose-multiplatform`), SwiftUI/native iOS (`swift-ios`) or React Native
|
|
25
|
+
(`react-native`); when the work is on a FastAPI/Go/Next.js sibling in the same monorepo (use that
|
|
26
|
+
skill). For a pure Dart **server/CLI** with no widget tree, general Dart applies but skip the
|
|
27
|
+
UI/nav/perf references. For a single-file throwaway sample, say architecture is overkill and do not
|
|
28
|
+
impose layering.
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
- It is a pure Dart **server/CLI** with no widget tree — general Dart applies, but skip the UI/nav/perf references.
|
|
38
|
-
- The work is on a FastAPI/Go/Next.js sibling in the same monorepo — use that skill; this one only owns the Flutter subproject.
|
|
39
|
-
- It is a single-file throwaway sample — note that architecture is overkill, do not impose layering.
|
|
30
|
+
Around the edges: `harness` owns the workspace `01-TOOLS`/`02-DOCS` layer and flavor secrets; `fastapi`,
|
|
31
|
+
`go` and `nextjs` build the backends this app talks to; `secure-coding` reviews token handling and
|
|
32
|
+
deep-link validation; `deployment` handles store/CI release; `design` owns the Material 3 token system.
|
|
40
33
|
|
|
41
34
|
## Decision rules
|
|
42
35
|
|
|
@@ -379,70 +372,29 @@ encapsulation → `references/i18n-and-dependencies.md`.
|
|
|
379
372
|
- Dependency hygiene: `pubspec.lock` committed for apps, `flutter pub outdated` audited on a cadence,
|
|
380
373
|
dependencies vetted by pub points before adding.
|
|
381
374
|
- No `print()` → `dart:developer` `log()`.
|
|
375
|
+
- Gate the branch with `scripts/verify.sh`, run inside the Flutter project (format / codegen / analyze / tests).
|
|
382
376
|
|
|
383
|
-
## Anti-patterns
|
|
377
|
+
## Anti-patterns
|
|
384
378
|
|
|
385
|
-
|
|
|
379
|
+
| Anti-pattern | Why it fails / do instead |
|
|
386
380
|
|---|---|
|
|
387
|
-
|
|
|
388
|
-
|
|
|
389
|
-
|
|
|
390
|
-
|
|
|
391
|
-
|
|
|
392
|
-
|
|
|
393
|
-
|
|
|
394
|
-
|
|
|
395
|
-
|
|
|
396
|
-
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
| sync state | `Notifier` / `Cubit` | `references/architecture-and-state.md` |
|
|
408
|
-
| async state | `AsyncNotifier` / `AsyncValue` | `references/architecture-and-state.md` |
|
|
409
|
-
| DI | `@riverpod` providers / `get_it` | `references/architecture-and-state.md` |
|
|
410
|
-
| routing | typed `go_router` | `references/ui-and-navigation.md` |
|
|
411
|
-
| errors | `Result` / sealed | `references/architecture-and-state.md` |
|
|
412
|
-
| http | `dio` + interceptor | `references/architecture-and-state.md` |
|
|
413
|
-
| long list | `ListView.builder` | `references/performance.md` |
|
|
414
|
-
| off-thread | `Isolate.run` | `references/performance.md` |
|
|
415
|
-
| unit test | `ProviderContainer.test()` | `references/testing.md` |
|
|
416
|
-
| widget test | `ProviderScope` override | `references/testing.md` |
|
|
417
|
-
| golden | `matchesGoldenFile` | `references/testing.md` |
|
|
418
|
-
| l10n | ARB + `gen_l10n` + `intl` | `references/i18n-and-dependencies.md` |
|
|
419
|
-
| deps | `flutter pub outdated` / `melos` | `references/i18n-and-dependencies.md` |
|
|
420
|
-
| verify | `scripts/verify.sh` | `scripts/verify.sh` |
|
|
421
|
-
|
|
422
|
-
## Project grounding (02-DOCS + CLAUDE.md)
|
|
423
|
-
|
|
424
|
-
When this skill runs in a project with a `02-DOCS/` layer (the
|
|
425
|
-
[`harness`](../harness/SKILL.md) Karpathy wiki), record this
|
|
426
|
-
project's app decisions there and index them in `02-DOCS/wiki/index.md`, so the next
|
|
427
|
-
agent inherits the conventions instead of re-deriving them.
|
|
428
|
-
|
|
429
|
-
1. **Find the article** `02-DOCS/wiki/stack/flutter.md`, indexed in `02-DOCS/wiki/index.md` (the Knowledge map index; root `CLAUDE.md` points to it).
|
|
430
|
-
2. **If missing or stale**, create/update it with the project's real choices — the state-management choice (Riverpod/Bloc), the architecture layers, routing, the Material 3 token system, and codegen setup —
|
|
431
|
-
then index it in `02-DOCS/wiki/index.md` (the Knowledge map; root `CLAUDE.md` keeps only a short pointer to it).
|
|
432
|
-
3. **Read it first on every use** and stay consistent; when a convention changes, update the
|
|
433
|
-
article (bump its `Updated` date) in the same change.
|
|
434
|
-
|
|
435
|
-
No `02-DOCS/` layer? Skip silently (optionally suggest `harness`). Unlike the
|
|
436
|
-
brand study, technical conventions are *recorded, not gated* — never block the task on this.
|
|
437
|
-
|
|
438
|
-
## See Also
|
|
439
|
-
|
|
440
|
-
- `references/architecture-and-state.md` — layering, DI, Result/Failure, Riverpod 3 & Bloc deep dives.
|
|
441
|
-
- `references/ui-and-navigation.md` — widgets, Material 3 tokens, responsive, typed go_router, a11y.
|
|
442
|
-
- `references/testing.md` — unit/widget/golden/integration + coverage.
|
|
443
|
-
- `references/performance.md` — rebuilds, paint, jank, isolates, build flavors.
|
|
444
|
-
- `references/i18n-and-dependencies.md` — ARB/ICU l10n, RTL, locale-aware formatting, pub points, `melos`.
|
|
445
|
-
- `scripts/verify.sh` — run inside your Flutter project to gate format/codegen/analyze/tests.
|
|
446
|
-
- Sibling skills: `harness` (workspace `01-TOOLS`/`02-DOCS`, flavor secrets); `fastapi`,
|
|
447
|
-
`go` and `nextjs` for the backends this app talks to; `secure-coding` for token handling and deep-link
|
|
448
|
-
validation; `deployment` for store/CI release; `design` for the Material 3 token system.
|
|
381
|
+
| `user!` to unwrap | bang crashes in prod; use `?.`/`??` or an if-case pattern. |
|
|
382
|
+
| `_buildHeader()` helper methods | extract to a `const` widget class — enables element reuse + const propagation. |
|
|
383
|
+
| `setState` at the top of the page | rebuilds the whole subtree; scope it or `.select()`. |
|
|
384
|
+
| `Navigator.push` mixed into go_router for one screen | one router; mixing breaks deep links + back stack. |
|
|
385
|
+
| `context` used after an `await` | guard `context.mounted` / `ref.mounted`; a stale context crashes. |
|
|
386
|
+
| hardcoded `Colors.blue` | use `colorScheme`; hardcoding breaks dark mode + theming. |
|
|
387
|
+
| `ListView(children: [...])` for a feed | use `.builder`; the concrete form builds all children eagerly. |
|
|
388
|
+
| `catch (e)` on everything | use `on`-typed clauses; never catch `Error` (it is a bug). |
|
|
389
|
+
| raw `DioException.toString()` shown to the user | map to a `Failure` with a localized message. |
|
|
390
|
+
| `print()` for logging | use `dart:developer` `log()` — has levels and can be filtered. |
|
|
391
|
+
|
|
392
|
+
## Project grounding (02-DOCS)
|
|
393
|
+
|
|
394
|
+
In a project with a `02-DOCS/` layer (the [`harness`](../harness/SKILL.md) wiki), this app's decisions
|
|
395
|
+
live in `02-DOCS/wiki/stack/flutter.md`, indexed in `02-DOCS/wiki/index.md`. Read it first and stay
|
|
396
|
+
consistent. Missing or stale? Write the real choices there — state management (Riverpod/Bloc), the
|
|
397
|
+
architecture layers, routing, the Material 3 token system, codegen setup — index it, and bump its
|
|
398
|
+
`Updated` date in the same change a convention changes, so the next agent inherits it instead of
|
|
399
|
+
re-deriving it. No `02-DOCS/` layer? Skip silently: technical conventions are *recorded, not gated*,
|
|
400
|
+
so never block the task on this.
|