@ericrisco/rsc 0.1.44 → 0.1.46
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 +192 -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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: analytics
|
|
3
|
-
description: "Use when instrumenting product or web analytics —
|
|
3
|
+
description: "Use when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing. NOT charting that data (that is dashboard), NOT choosing which metrics matter (that is kpi-framework), NOT experiment math (that is ab-testing), NOT cookie-policy text (that is gdpr-privacy)."
|
|
4
4
|
tags: [analytics, ga4, posthog, event-tracking, telemetry, consent-mode, funnels, privacy]
|
|
5
5
|
recommends: [kpi-framework, ab-testing, gdpr-privacy, nextjs, dashboard, clickhouse-analytics]
|
|
6
6
|
origin: risco
|
|
@@ -14,23 +14,7 @@ artifacts — an event taxonomy, tracking code (GA4 and/or PostHog), and a conse
|
|
|
14
14
|
downstream of capture (charts, KPI choice, experiment stats, raw-event SQL, legal text) belongs to a
|
|
15
15
|
sibling; see the routing table below.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
**An event name is a contract. Design the taxonomy before you write a single SDK call, and never rename a
|
|
20
|
-
live event in production.** Why: every funnel, audience, dashboard, and saved insight downstream is keyed
|
|
21
|
-
by the exact event name and property keys. Rename `signup_completed` to `sign_up` after launch and you
|
|
22
|
-
silently fork the metric into two — the old funnel flatlines, the new one starts from zero, and nobody
|
|
23
|
-
notices for a week. You can add events forever; you can never safely rename one. So the order of work is
|
|
24
|
-
fixed: **taxonomy → SDK wiring → consent gate → PII scrub → funnel + validation.**
|
|
25
|
-
|
|
26
|
-
## When to use
|
|
27
|
-
|
|
28
|
-
- "Add analytics to my app", "set up GA4", "install PostHog", "track signups and checkout".
|
|
29
|
-
- Designing or auditing an **event taxonomy** — naming convention, event-vs-property, identify-vs-anonymous.
|
|
30
|
-
- Defining a **funnel** (signup → activation → purchase) and the events that feed it.
|
|
31
|
-
- Debugging **double-counting**, missing `client_id`/`distinct_id`, or events that fire on every render.
|
|
32
|
-
- Making collection **privacy-safe**: Consent Mode v2, opt-out, redacting emails/tokens from props.
|
|
33
|
-
- **Server-side** events for actions off the browser (webhook, cron, payment confirmation).
|
|
17
|
+
The order of work is fixed: **taxonomy → SDK wiring → consent gate → PII scrub → funnel + validation.**
|
|
34
18
|
|
|
35
19
|
## When NOT to use
|
|
36
20
|
|
|
@@ -46,9 +30,6 @@ fixed: **taxonomy → SDK wiring → consent gate → PII scrub → funnel + val
|
|
|
46
30
|
| Predict future values from a series | `forecasting` |
|
|
47
31
|
|
|
48
32
|
The load-bearing line: `analytics` = events flow **in**; `dashboard`/`reporting` = events flow **out**.
|
|
49
|
-
`kpi-framework` decides *what* to measure; `analytics` makes the measurement *happen in code*.
|
|
50
|
-
`ab-testing` owns the experiment math; `analytics` owns the event the experiment reads. `gdpr-privacy`
|
|
51
|
-
owns the legal text; `analytics` owns the `gtag('consent', ...)` call and the PII scrubber.
|
|
52
33
|
|
|
53
34
|
## Decision: GA4 vs PostHog vs both
|
|
54
35
|
|
|
@@ -63,6 +44,12 @@ thing everywhere. Do not let the two tools drift into two naming schemes.
|
|
|
63
44
|
|
|
64
45
|
## Step 1 — Event taxonomy first, code second
|
|
65
46
|
|
|
47
|
+
**An event name is a contract: design the taxonomy before you write a single SDK call, and never rename a
|
|
48
|
+
live event in production.** Every funnel, audience, dashboard, and saved insight downstream is keyed by the
|
|
49
|
+
exact event name and property keys. Rename `signup_completed` to `sign_up` after launch and you silently
|
|
50
|
+
fork the metric into two — the old funnel flatlines, the new one starts from zero, and nobody notices for a
|
|
51
|
+
week. You can add events forever; you can never safely rename one.
|
|
52
|
+
|
|
66
53
|
Name events `object_action` in `snake_case`: `signup_completed`, `checkout_started`, `invoice_paid`. The
|
|
67
54
|
**object** is the noun, the **action** is a past-tense verb. Detail goes in **properties**, never in the
|
|
68
55
|
name — `cta_clicked` with `{ location: "navbar" }`, not three events `navbar_cta`, `hero_cta`, `footer_cta`.
|
|
@@ -208,12 +195,3 @@ the ≤ 40-char / leading-letter / charset rule; GA present without a `gtag('con
|
|
|
208
195
|
| Server `user_id` ≠ browser `user_id` | Creates duplicate users; funnel splits | Use the same stable id on both sides; stitch within 48h |
|
|
209
196
|
| `posthog.init` with no proxy host | Ad-blockers eat ~20-40% of events | Serve SDK + ingest under a first-party path (`/ingest`) |
|
|
210
197
|
| Email as GA4 `user_id` | PII leak + Google policy violation | A stable opaque id (DB id / UUID) |
|
|
211
|
-
|
|
212
|
-
## References
|
|
213
|
-
|
|
214
|
-
- `references/ga4-setup.md` — gtag + Next.js install, full Consent Mode v2 with region-scoped defaults,
|
|
215
|
-
Measurement Protocol server event, recommended-event param tables, DebugView.
|
|
216
|
-
- `references/posthog-setup.md` — `init` options, `identified_only`, EU vs US host, reverse proxy,
|
|
217
|
-
`@posthog/next` server capture, feature-flag read, autocapture tuning, `optIn`/`optOut`.
|
|
218
|
-
- `references/event-taxonomy.md` — naming rules, starter SaaS + e-commerce catalog, property conventions,
|
|
219
|
-
identify vs group, the anti-rename rule.
|
package/skills/analyze/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: analyze
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when constitution, spec, plan and tasks all exist and you want them cross-read against each other before any code is written — the rsc-sdd pre-implementation gate. Reports coverage gaps, contradictions, duplication, ambiguity and scope drift; edits nothing. NOT the task breakdown (that is `tasks`), NOT the coding (that is `implement`), NOT the post-code test gate (that is `verify`), NOT resolving ambiguity (that is `clarify`)."
|
|
4
4
|
tags: [sdd, analyze, consistency]
|
|
5
5
|
recommends: [implement]
|
|
6
6
|
profiles: [core, full]
|
|
@@ -9,51 +9,26 @@ origin: risco
|
|
|
9
9
|
|
|
10
10
|
# Analyze — the pre-implementation consistency gate
|
|
11
11
|
|
|
12
|
-
You have a **constitution**, a **spec**, a **plan** and a **task list**. Four artifacts written at four different moments, by a mind that drifted a little each time. `analyze`
|
|
12
|
+
You have a **constitution**, a **spec**, a **plan** and a **task list**. Four artifacts written at four different moments, by a mind that drifted a little each time. `analyze` reads all four *against each other* and surfaces where they disagree. It is the cheapest place in the whole chain to catch a problem — a contradiction found here costs a sentence; the same contradiction found mid-implement costs a rewrite.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Sixth phase of the rsc-sdd chain (`constitution → specify → clarify → plan → tasks → analyze → implement`); the method itself lives in `../sdd/SKILL.md`. It is a **gate, not a worker**: it produces a report and stops. The user reads the findings and decides what to fix, and which phase to send each fix back to.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
**Report only. Resolve nothing.** Never edit the constitution, spec, plan or tasks; never open a code file to "just fix it"; never silently reconcile a contradiction by picking a side. This one is absolute because a gate that quietly fixes things stops being a gate: the user never learns the spec was wrong, the plan built on the old assumption stays stale, and the "consistency check" has manufactured a new inconsistency. Name the conflict, show both sides with locations, propose where it should be resolved, hand the decision back.
|
|
17
17
|
|
|
18
|
-
**
|
|
18
|
+
**Model tier: `heavy`** (adversarial cross-reading). Resolve and apply it per `../sdd/references/model-routing.md`; routing is off unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
**Accompaniment dial.** Read `02-DOCS/wiki/harness/user-profile.md` before reporting — default to **L2** and say the harness has not gauged the user yet if there is no profile. The dial flexes how the report reads, never what gets checked; the six analyses always run in full.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- Implementation stalled because the artifacts seem to contradict each other.
|
|
29
|
-
- You want a requirements-coverage map: which task satisfies which spec requirement, and what is orphaned.
|
|
30
|
-
|
|
31
|
-
Do NOT use when (route elsewhere):
|
|
32
|
-
|
|
33
|
-
- A single spec is fuzzy and you need to ask the user questions and bake answers in → `clarify` (analyze reports the ambiguity; clarify resolves it).
|
|
34
|
-
- The plan or tasks don't exist yet → write them first (`plan`, then `tasks`).
|
|
35
|
-
- You want to run lint/types/tests/acceptance after coding → `verify` (post-implementation gate; analyze is pre-implementation).
|
|
36
|
-
- A test is failing or behavior is wrong → `debug`.
|
|
37
|
-
- You intend to fix what you find right now → that is `implement`/`clarify`/`plan`/`tasks` work, not analyze. Analyze only reports.
|
|
38
|
-
|
|
39
|
-
## Model tier — `heavy` (opt-in routing)
|
|
40
|
-
|
|
41
|
-
This phase's default model tier is **`heavy`** — it is the adversarial consistency gate across constitution ↔ spec ↔ plan ↔ tasks. Routing is **off** unless `models.enabled: true` in `02-DOCS/wiki/sdd/config.yaml`. When on: resolve this phase's tier (`models.overrides` wins over `models.phases`), map it to a model via `models.tiers`, and apply per `../sdd/references/model-routing.md` — announce the switch per the accompaniment dial when it differs from the session model, and dispatch any `Task`/`parallel` subagents on that model. Routing off or no profile → honor the session model silently. Never fake a switch a tool can't make; skip routing on a one-line change.
|
|
42
|
-
|
|
43
|
-
## Read the accompaniment dial first
|
|
44
|
-
|
|
45
|
-
Before reporting, read `02-DOCS/wiki/harness/user-profile.md` for the technical + accompaniment level (the harness dial, L0..L3). It shapes how the report reads — not what gets checked. The six analyses always run in full; verbosity flexes:
|
|
46
|
-
|
|
47
|
-
- **L0** — the finding table only: severity, the two artifacts, the conflict in one line. No prose.
|
|
48
|
-
- **L1** — the table plus a one-line *why it matters* per CRITICAL/HIGH finding.
|
|
49
|
-
- **L2** — the table plus, per finding, the recommended resolution phase and the trade-off of leaving it.
|
|
50
|
-
- **L3** — full walk-through: for each finding, quote both sides, explain the consequence at implement time in plain language, and lay out the options so a non-technical user can choose.
|
|
51
|
-
|
|
52
|
-
If no profile exists, default to L2 and note that the harness has not gauged the user yet.
|
|
22
|
+
| Dial | The report renders as |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| L0 | Finding table only: severity, the two artifacts, the conflict in one line. No prose. |
|
|
25
|
+
| L1 | + a one-line *why it matters* per CRITICAL/HIGH finding. |
|
|
26
|
+
| L2 | + per finding, the recommended resolution phase and the trade-off of leaving it. |
|
|
27
|
+
| L3 | + full walk-through: quote both sides, explain the consequence at implement time in plain language, lay out the options so a non-technical user can choose. |
|
|
53
28
|
|
|
54
29
|
## Inputs — locate the four artifacts
|
|
55
30
|
|
|
56
|
-
Read all four before analyzing. The rsc-sdd artifacts live under `02-DOCS/wiki/sdd
|
|
31
|
+
Read all four before analyzing. The rsc-sdd artifacts live under `02-DOCS/wiki/sdd/`, indexed from `02-DOCS/wiki/index.md` (the Knowledge map; root `CLAUDE.md` keeps only a short pointer to it):
|
|
57
32
|
|
|
58
33
|
| Artifact | Canonical location | Role in the check |
|
|
59
34
|
| --- | --- | --- |
|
|
@@ -110,32 +85,22 @@ Produce a single consistency report:
|
|
|
110
85
|
1. **Verdict line** — `GATE: PASS` (zero CRITICAL/HIGH) or `GATE: BLOCKED` (one or more CRITICAL/HIGH), with the counts.
|
|
111
86
|
2. **Coverage map** — the table above.
|
|
112
87
|
3. **Findings table** — `# | Severity | Type | Artifact A (loc) | Artifact B (loc) | Conflict | Resolve in (phase)`.
|
|
113
|
-
4. **Recommended routing** — group fixes by the phase that owns them (`clarify` for spec ambiguity, `plan` for missing architecture, `tasks` for a missing done-check, `constitution` if a principle itself is wrong).
|
|
88
|
+
4. **Recommended routing** — group fixes by the phase that owns them (`clarify` for spec ambiguity, `plan` for missing architecture, `tasks` for a missing done-check, `constitution` if a principle itself is wrong). If findings pour in across all six checks, the artifacts diverged badly — recommend re-running `clarify`/`plan` before a line-by-line analyze is even useful.
|
|
114
89
|
|
|
115
|
-
Write the report to `02-DOCS/wiki/sdd/analysis/<slug>.md` (create the dir if absent) and index it in `02-DOCS/wiki/index.md`
|
|
90
|
+
Write the report to `02-DOCS/wiki/sdd/analysis/<slug>.md` (create the dir if absent) and index it in `02-DOCS/wiki/index.md` under the `sdd/` topic, so the next phase and the harness can find it. It is an OKF v0.1 wiki article: open it with YAML frontmatter carrying a non-empty `type:` (use `type: analysis`), a `timestamp` in ISO 8601, and standard markdown links — never wikilinks. The report is the artifact analyze owns — it is the *only* thing analyze writes. Per-run point-in-time; overwrite on re-run, the wiki keeps history.
|
|
116
91
|
|
|
117
|
-
|
|
92
|
+
Render it at the dial's verbosity. Do not log a decision to `decisions.md` — analyze decides nothing; the phase that resolves the finding logs its own decision.
|
|
118
93
|
|
|
119
|
-
## Anti-patterns
|
|
94
|
+
## Anti-patterns
|
|
120
95
|
|
|
121
|
-
|
|
|
96
|
+
| Anti-pattern | Why it breaks the gate / do instead |
|
|
122
97
|
| --- | --- |
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
| "I'll fold the findings straight into the task list to save a step" | No. Editing tasks is the `tasks` phase. Report, route, hand back. |
|
|
129
|
-
| "Constitution says Postgres but plan picked Mongo for good reasons — I'll side with the plan" | The constitution wins by definition. Flag CRITICAL. If the principle is wrong, that is a `constitution` change the user makes, not a quiet override here. |
|
|
130
|
-
| "I read the spec and tasks; the constitution is boilerplate, skip it" | The constitution is analysis #1 and the highest severity. Never skip it. |
|
|
131
|
-
|
|
132
|
-
## Red flags — stop and report instead of analyzing
|
|
133
|
-
|
|
134
|
-
- An artifact is missing (no plan, no tasks) → say which, name the phase, do not fabricate it.
|
|
135
|
-
- Multiple specs match the slug → ask which feature; don't analyze the wrong one.
|
|
136
|
-
- You catch yourself opening a source file → you have left the gate; close it.
|
|
137
|
-
- Findings are pouring in across all six checks → the artifacts diverged badly; recommend the user re-runs `clarify`/`plan` before a line-by-line analyze is even useful.
|
|
98
|
+
| Fixing a "trivial" contradiction in the spec yourself | Then you are `clarify`/`plan`/`tasks`, not `analyze`. Report it; the user resolves. |
|
|
99
|
+
| Starting to code because nothing CRITICAL turned up | Analyze never transitions to code. Hand the verdict to `implement`; that phase starts the work. |
|
|
100
|
+
| Waving through plan work the spec never asked for because it's obviously a good idea | That is DRIFT. Flag it. Good ideas still need the spec amended (user's call), or they are silent scope creep. |
|
|
101
|
+
| Siding with the plan when it contradicts the constitution | The constitution wins by definition — flag CRITICAL. If the principle itself is wrong, that is a `constitution` change the user makes, not a quiet override here. |
|
|
102
|
+
| Guessing what a vague requirement meant | Guessing defeats the gate. Mark AMBIGUOUS and route to `clarify`; do not encode your guess. |
|
|
138
103
|
|
|
139
104
|
## Next in the chain
|
|
140
105
|
|
|
141
|
-
|
|
106
|
+
On `GATE: PASS` (or once the user consciously accepts the remaining MEDIUM/LOW findings), proceed to **`implement`** — execute the tasks with TDD discipline, delegating concrete test tooling to the relevant stack skill (`fastapi`, `nextjs`, `go`, `flutter`, `postgresdb`). On `GATE: BLOCKED`, route each CRITICAL/HIGH finding to its owning phase (`clarify`, `plan`, `tasks`, or `constitution`), let the user resolve, then re-run `analyze`. The gate only opens once.
|
package/skills/angular/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: angular
|
|
3
|
-
description: "Use when building, refactoring,
|
|
3
|
+
description: "Use when building, refactoring, or debugging Angular (v20/21+): standalone components, signals, zoneless change detection, @if/@for/@defer control flow, inject() DI, resource()/httpResource(), RxJS interop, NgRx SignalStore, ng CLI. NOT React (that is react), NOT Next.js (that is nextjs), NOT a TypeScript language question (that is typescript)."
|
|
4
4
|
tags: [angular, frontend, web, signals, typescript, spa]
|
|
5
5
|
recommends: [typescript, testing-web, secure-coding]
|
|
6
6
|
origin: risco
|
|
@@ -10,31 +10,23 @@ origin: risco
|
|
|
10
10
|
|
|
11
11
|
> Build Angular the way it ships in 2026: standalone components, signals as the reactivity model, zoneless change detection, built-in control flow, and `inject()` DI. Treat NgModules, `*ngFor`, and `@Input()` decorators as legacy you only touch to migrate.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Not this skill
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- **AngularJS (1.x)** — out of scope entirely. This skill is Angular 2+ only; the APIs do not map.
|
|
25
|
-
- **React** → that is the `react` skill. NOT React (that is react).
|
|
26
|
-
- **Next.js App Router** → `../nextjs/SKILL.md`.
|
|
27
|
-
- **Vue/Nuxt, Svelte, SolidJS, Astro** → `vue-nuxt`, `svelte`, `solid-js`, `../astro/SKILL.md`.
|
|
28
|
-
- **Pure TypeScript language question** (generics, narrowing, tsconfig) with no Angular dimension → `../typescript/SKILL.md`.
|
|
29
|
-
- **A standalone NestJS API** → `../nestjs/SKILL.md`. A generic Node service → `nodejs`. Angular Universal SSR itself stays here.
|
|
30
|
-
- **Cross-framework Playwright e2e strategy** → `testing-web` / `e2e-testing`. Angular's own `ng test` (Vitest) setup stays here.
|
|
15
|
+
**AngularJS (1.x)** is out of scope entirely — this skill is Angular 2+ only and the APIs do not map.
|
|
16
|
+
Route elsewhere for **React** → `../react/SKILL.md`; **Next.js App Router** → `../nextjs/SKILL.md`;
|
|
17
|
+
**Vue/Nuxt, Svelte, SolidJS, Astro** → `../vue-nuxt/SKILL.md`, `../svelte/SKILL.md`,
|
|
18
|
+
`../solid-js/SKILL.md`, `../astro/SKILL.md`; a **pure TypeScript language question** (generics,
|
|
19
|
+
narrowing, tsconfig) with no Angular dimension → `../typescript/SKILL.md`; a **standalone NestJS
|
|
20
|
+
API** → `../nestjs/SKILL.md`; a generic Node service → `../nodejs/SKILL.md`; **cross-framework
|
|
21
|
+
Playwright e2e strategy** → `../testing-web/SKILL.md` / `../e2e-testing/SKILL.md`. Angular Universal
|
|
22
|
+
SSR and Angular's own `ng test` (Vitest) setup stay here.
|
|
31
23
|
|
|
32
24
|
## Decide first
|
|
33
25
|
|
|
34
26
|
| Situation | Do this | Why |
|
|
35
27
|
|-----------|---------|-----|
|
|
36
28
|
| Greenfield app / new feature | Zoneless + signals + standalone by default. `ng new` (Angular 21) already excludes Zone.js. | The defaults shipped stable in v20-v21; fight them and you write more code that the framework now does for you. |
|
|
37
|
-
| Brownfield NgModule + decorator app | Migrate incrementally with schematics; do not rewrite. Keep Zone.js until you flip it on purpose. | A working app that uses `*ngIf` is not a bug. Churn introduces risk for no user value. |
|
|
29
|
+
| Brownfield NgModule + decorator app | Migrate incrementally with the schematics in `references/migration.md` (NgModule→standalone, control flow, decorator→signal inputs, Zone.js→zoneless, Karma→Vitest); do not rewrite. Keep Zone.js until you flip it on purpose. | A working app that uses `*ngIf` is not a bug. Churn introduces risk for no user value. |
|
|
38
30
|
| "View not updating" complaint | Jump to the change-detection section: signal not read in template, `OnPush` without a signal, or stale Zone.js assumption. | Zoneless means a mutation that no signal observes will never repaint — the fix is structural, not a `detectChanges()` call. |
|
|
39
31
|
|
|
40
32
|
## The modern baseline
|
|
@@ -178,7 +170,7 @@ profile = resource({
|
|
|
178
170
|
```
|
|
179
171
|
|
|
180
172
|
- Rule: `httpResource()`/`resource()` give you `value()`, `isLoading()`, `error()`, `reload()` for free — prefer them over a manual `subscribe` that you have to clean up. Why: less boilerplate, no leak, refetches automatically when its source signals change.
|
|
181
|
-
- Rule: when you genuinely need a stream (websocket, debounced search, retry/switchMap), keep `HttpClient` + RxJS and bridge to a signal with `toSignal()`. Why: signals are not streams; do not fake backpressure with effects.
|
|
173
|
+
- Rule: when you genuinely need a stream (websocket, debounced search, retry/switchMap), keep `HttpClient` + RxJS and bridge to a signal with `toSignal()`. Why: signals are not streams; do not fake backpressure with effects. `references/signals-rxjs.md` has the signals-vs-RxJS decision matrix, `toSignal`/`toObservable` interop recipes, `effect` pitfalls (infinite loops, untracked reads), and `takeUntilDestroyed`.
|
|
182
174
|
|
|
183
175
|
## DI & services
|
|
184
176
|
|
|
@@ -280,9 +272,4 @@ it('renders the user name', async () => {
|
|
|
280
272
|
| Nested `subscribe()` inside `subscribe()` | Callback pyramid, lost cancellation | `switchMap`/`concatMap`, one subscription |
|
|
281
273
|
| Constructor DI only (`constructor(private x: X)`) | Legacy ergonomic; can't compose into functions | `private x = inject(X)` |
|
|
282
274
|
|
|
283
|
-
## References
|
|
284
|
-
|
|
285
|
-
- `references/signals-rxjs.md` — signals-vs-RxJS decision matrix, `toSignal`/`toObservable` interop recipes, `effect` pitfalls (infinite loops, untracked reads), `linkedSignal`/`resource()` patterns, `takeUntilDestroyed`.
|
|
286
|
-
- `references/migration.md` — incremental migration checklist + schematics: NgModule→standalone, control-flow migration, decorator-input→signal-input, Zone.js→zoneless go-live, Karma/Jasmine→Vitest.
|
|
287
|
-
|
|
288
275
|
`scripts/verify.sh` is a heuristic copy-banlist lint — it greps your Angular sources for the banned patterns above. It is a hint, not a compiler.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: api-connector-builder
|
|
3
|
-
description: "Use when writing a client
|
|
3
|
+
description: "Use when writing a client for someone else's REST or GraphQL API: auth flow choice and token refresh, pagination to exhaustion, retry-with-jitter on transient failures only, rate-limit-aware throttling. NOT inbound callbacks (that is `webhooks`), NOT chaining services (that is `automation-flows`), NOT designing your own API (that is `api-design`)."
|
|
4
4
|
tags: [api, rest, graphql, oauth, pagination, retries, rate-limiting, http-client, connector]
|
|
5
5
|
recommends: [webhooks, automation-flows, api-design, data-scraper, secure-coding, error-handling, structured-extraction]
|
|
6
6
|
origin: risco
|
|
@@ -12,31 +12,18 @@ You are writing a client for **someone else's** HTTP API. You do not own the
|
|
|
12
12
|
contract; you obey it. The deliverable is one typed connector module per vendor
|
|
13
13
|
that authenticates, walks the whole result set, retries only transient failures
|
|
14
14
|
with backoff, and stays under the rate limit without getting the key banned.
|
|
15
|
+
One connector = one vendor: mixed clients tangle two auth schemes and two
|
|
16
|
+
rate-limit budgets into something no one can reason about.
|
|
15
17
|
|
|
16
18
|
Four pillars, every time: **auth, pagination, retries, rate limits.** If your
|
|
17
19
|
connector skips any one of them it works in the demo and breaks in production —
|
|
18
20
|
on page 2, on token expiry, on the first 429, or on a flaky network.
|
|
19
21
|
|
|
20
|
-
This skill goes **outbound** (you call them). Receiving their callbacks is the
|
|
21
|
-
inverse and lives in `webhooks`.
|
|
22
|
-
|
|
23
|
-
## Operating posture
|
|
24
|
-
|
|
25
|
-
- **Read the vendor docs before writing a line.** Invented endpoints and guessed
|
|
26
|
-
field names 404 in prod. Find the real base URL, version, and error envelope.
|
|
27
|
-
- **Secrets come from env or a secret store, never source.** Hardcoded keys leak
|
|
28
|
-
through git history and screenshots and you cannot rotate them cleanly.
|
|
29
|
-
- **One connector = one vendor.** Mixed clients tangle two auth schemes and two
|
|
30
|
-
rate-limit budgets into one tangle no one can reason about.
|
|
31
|
-
- **Every request gets a timeout.** A hung socket with no timeout stalls the
|
|
32
|
-
whole run forever; the default in most clients is "wait indefinitely".
|
|
33
|
-
- **Log request id + status + attempt, never the token.** Logs get shipped to
|
|
34
|
-
third parties; a logged bearer token is a leaked credential.
|
|
35
|
-
|
|
36
22
|
## Step 0 — read the contract
|
|
37
23
|
|
|
38
|
-
|
|
39
|
-
|
|
24
|
+
Read the vendor docs before writing a line — invented endpoints and guessed
|
|
25
|
+
field names 404 in prod. Extract these first; each one changes what you write,
|
|
26
|
+
so missing one means a rewrite.
|
|
40
27
|
|
|
41
28
|
| Find in their docs | Why it changes your code |
|
|
42
29
|
| ------------------------- | --------------------------------------------------------- |
|
|
@@ -202,8 +189,9 @@ def iter_records(client):
|
|
|
202
189
|
return
|
|
203
190
|
```
|
|
204
191
|
|
|
205
|
-
Full code for every style — offset, keyset, `Link`-header parsing,
|
|
206
|
-
|
|
192
|
+
Full code for every style — offset, keyset, `Link`-header parsing, GraphQL Relay
|
|
193
|
+
connection walking, in Python and TS, plus dedup-on-overlap notes — is in
|
|
194
|
+
`references/pagination.md`.
|
|
207
195
|
|
|
208
196
|
## Putting it together
|
|
209
197
|
|
|
@@ -272,12 +260,7 @@ export async function request(path: string, init: RequestInit = {}, attempt = 0)
|
|
|
272
260
|
| Token in query string | Token ends up in logs / referrers | Bearer in the `Authorization` header |
|
|
273
261
|
| Implicit / password OAuth grant | Removed in OAuth 2.1; insecure | Auth-Code + PKCE, or Client Credentials |
|
|
274
262
|
|
|
275
|
-
##
|
|
276
|
-
|
|
277
|
-
- `references/auth-flows.md` — per-flow walkthroughs, token storage + rotation,
|
|
278
|
-
OAuth 2.1 deltas, RFC 9700 refresh rotation, DPoP note. Python + TS.
|
|
279
|
-
- `references/pagination.md` — full code for offset, cursor/keyset, Link-header,
|
|
280
|
-
and GraphQL Relay walking. Exhaustion-loop and dedup-on-overlap notes.
|
|
263
|
+
## Verify
|
|
281
264
|
|
|
282
265
|
Run `scripts/verify.sh` over the connector you write: it greps for hardcoded
|
|
283
266
|
secrets, asserts a retry mechanism and a pagination loop and a request timeout
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: api-design
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when settling the contract of an API you expose, before implementation: resources/URLs, REST vs GraphQL, versioning, one RFC 9457 error envelope, pagination, idempotency — emitted as OpenAPI 3.1. NOT implementing the endpoints (that is `fastapi`/`nestjs`/`go`/`nodejs`), NOT auth hardening (that is `secure-coding`), NOT consuming a third-party API (that is `api-connector-builder`)."
|
|
4
4
|
tags: [api-design, rest, graphql, openapi, versioning, pagination, http, rfc9457, contract-design]
|
|
5
5
|
recommends: [fastapi, nestjs, go, nodejs, secure-coding, webhooks, api-connector-builder, code-review]
|
|
6
6
|
origin: risco
|
|
@@ -24,7 +24,7 @@ Pick on traffic shape, not fashion. Decide once, write it down.
|
|
|
24
24
|
| Many client shapes, deep nested graphs, mobile over-fetch is real | **GraphQL** | one round-trip, client picks fields; no N endpoints per screen |
|
|
25
25
|
| Stable resource API + one rich read surface for a client app | **Hybrid** | REST for the system of record, a GraphQL read layer on top |
|
|
26
26
|
|
|
27
|
-
Operational gotcha that decides monitoring: **GraphQL returns HTTP 200 even when a field errored** — failures live in an `errors[]` array next to partial `data`. Your dashboards cannot alert on 5xx; you must alert on the `errors[]` payload. REST signals failure with the HTTP status itself. If your ops team lives on status-code SLOs, that is a point for REST.
|
|
27
|
+
Operational gotcha that decides monitoring: **GraphQL returns HTTP 200 even when a field errored** — failures live in an `errors[]` array next to partial `data`. Your dashboards cannot alert on 5xx; you must alert on the `errors[]` payload. REST signals failure with the HTTP status itself. If your ops team lives on status-code SLOs, that is a point for REST. Schema/nullability design, mutation and error-union conventions, and this error model in full: [`references/graphql-design.md`](references/graphql-design.md).
|
|
28
28
|
|
|
29
29
|
## Resource & URL modeling
|
|
30
30
|
|
|
@@ -44,7 +44,7 @@ Rules, each with its reason:
|
|
|
44
44
|
| `GET /projects/active` | `GET /projects?status=active` | filter is a query param |
|
|
45
45
|
| `POST /projects/{id}/delete` | `DELETE /projects/{id}` | method, not path segment |
|
|
46
46
|
|
|
47
|
-
Full query grammar (filter operators, sparse fieldsets, sort syntax)
|
|
47
|
+
Full query grammar (filter operators, sparse fieldsets, sort syntax), content negotiation, rate-limit headers and a HATEOAS note: [`references/rest-conventions.md`](references/rest-conventions.md).
|
|
48
48
|
|
|
49
49
|
## Status codes that matter
|
|
50
50
|
|
|
@@ -67,7 +67,7 @@ You need a small map, used consistently. Don't overload 200.
|
|
|
67
67
|
|
|
68
68
|
Two distinctions agents get wrong:
|
|
69
69
|
- **401 vs 403** — 401 means *unauthenticated* (no/invalid credentials); 403 means *authenticated but unauthorized*. Returning 401 on a permission failure leaks that re-auth might help when it won't.
|
|
70
|
-
- **409 vs 422** — 409 is a *state* conflict (the request fights the current server state: dup key, stale version). 422 is a *content* problem (the body parses but fails business rules). Full table with when-each in `references/rest-conventions.md
|
|
70
|
+
- **409 vs 422** — 409 is a *state* conflict (the request fights the current server state: dup key, stale version). 422 is a *content* problem (the body parses but fails business rules). Full status-code table with when-each in [`references/rest-conventions.md`](references/rest-conventions.md).
|
|
71
71
|
|
|
72
72
|
## Error envelope: RFC 9457
|
|
73
73
|
|
|
@@ -116,7 +116,7 @@ REST cursor envelope — same keys on every list endpoint:
|
|
|
116
116
|
|
|
117
117
|
The next page is `GET /projects?cursor=eyJpZCI6MTI4N30&limit=50`. The cursor is opaque — clients must not parse or construct it.
|
|
118
118
|
|
|
119
|
-
GraphQL has its own de-facto standard: **Relay Connections** — `edges { node, cursor }`, `pageInfo { hasNextPage, endCursor }`, args `first` / `after`. Use it; don't invent a bespoke GraphQL pagination shape. See `references/graphql-design.md
|
|
119
|
+
GraphQL has its own de-facto standard: **Relay Connections** — `edges { node, cursor }`, `pageInfo { hasNextPage, endCursor }`, args `first` / `after`. Use it; don't invent a bespoke GraphQL pagination shape. See [`references/graphql-design.md`](references/graphql-design.md).
|
|
120
120
|
|
|
121
121
|
## Versioning & evolution
|
|
122
122
|
|
|
@@ -135,7 +135,7 @@ Sunset: Sat, 31 Oct 2026 23:59:59 GMT
|
|
|
135
135
|
Link: <https://api.acme.com/v2/projects>; rel="successor-version"
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
Full breaking-vs-non-breaking matrix and the deprecation workflow
|
|
138
|
+
Full breaking-vs-non-breaking matrix, the three versioning mechanisms and the deprecation/sunset workflow: [`references/versioning-and-evolution.md`](references/versioning-and-evolution.md).
|
|
139
139
|
|
|
140
140
|
## Idempotency & concurrency
|
|
141
141
|
|
|
@@ -167,7 +167,7 @@ Idempotency-Key: 9b1f7c2e-...
|
|
|
167
167
|
|
|
168
168
|
## Handoff
|
|
169
169
|
|
|
170
|
-
The contract is the artifact. Emit it as an **OpenAPI 3.1** document
|
|
170
|
+
The contract is the artifact. Emit it as an **OpenAPI 3.1** document — the checkable deliverable a framework skill generates code from. How to shape it, and what `scripts/verify.sh` checks: [`references/openapi-contract.md`](references/openapi-contract.md).
|
|
171
171
|
|
|
172
172
|
Hand off to the builder:
|
|
173
173
|
- Python/async → [`../fastapi/SKILL.md`](../fastapi/SKILL.md)
|
|
@@ -180,10 +180,3 @@ Adjacent concerns you do **not** own:
|
|
|
180
180
|
- Receiving inbound webhooks (HMAC verify, replay, dedupe) → [`../webhooks/SKILL.md`](../webhooks/SKILL.md)
|
|
181
181
|
- Building an outbound client to a third-party API → [`../api-connector-builder/SKILL.md`](../api-connector-builder/SKILL.md)
|
|
182
182
|
- Reviewing handler code (not the design) → [`../code-review/SKILL.md`](../code-review/SKILL.md)
|
|
183
|
-
|
|
184
|
-
## References
|
|
185
|
-
|
|
186
|
-
- `references/rest-conventions.md` — full status-code table, filter/sort/sparse-fieldset grammar, content negotiation, rate-limit headers, HATEOAS note.
|
|
187
|
-
- `references/versioning-and-evolution.md` — breaking-vs-non-breaking matrix, three versioning mechanisms, deprecation/sunset workflow.
|
|
188
|
-
- `references/graphql-design.md` — schema/nullability design, Relay Connections, mutation + error-union conventions, the HTTP-200 error model and its monitoring impact.
|
|
189
|
-
- `references/openapi-contract.md` — capture the contract as OpenAPI 3.1 so frameworks generate from it; what `scripts/verify.sh` checks.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: article-writing
|
|
3
|
-
description: "Use when
|
|
3
|
+
description: "Use when writing one long-form article end to end — answer-first lede, question-shaped headings, plus its on-page surface (title, meta, slug, FAQ, Article/FAQPage JSON-LD) — or fixing a draft that buries the answer or reads AI-padded. NOT keyword research or topic selection (that is `seo-geo`), NOT the editorial calendar (that is `content-engine`)."
|
|
4
4
|
tags: [article, blog, long-form, seo-writing, geo, on-page, eeat, copywriting]
|
|
5
5
|
recommends: [seo-geo, content-engine, brand-voice, landing-copy, technical-writing, case-studies]
|
|
6
6
|
origin: risco
|
|
@@ -12,15 +12,6 @@ Draft one long-form article end to end: the prose **and** the on-page surface th
|
|
|
12
12
|
|
|
13
13
|
You own a single finished article. You do not pick the topic, build the calendar, or define the house voice — those are siblings below.
|
|
14
14
|
|
|
15
|
-
## When to use
|
|
16
|
-
|
|
17
|
-
- Drafting a blog post or long-form article from a topic or a target query.
|
|
18
|
-
- Turning a brief or outline into finished, publishable prose at the right depth.
|
|
19
|
-
- Writing the answer-first lede — the first ~200 words that fully answer the primary query.
|
|
20
|
-
- Restructuring a rambling draft into a question-shaped H2/H3 hierarchy.
|
|
21
|
-
- Writing the on-page surface: title tag, meta description, H1, slug, FAQ section, and Article/FAQPage JSON-LD.
|
|
22
|
-
- Cutting an AI-tell, fluff-padded draft down to the depth the query actually needs.
|
|
23
|
-
|
|
24
15
|
## When NOT to use
|
|
25
16
|
|
|
26
17
|
| You want… | Go to |
|
|
@@ -109,14 +100,6 @@ Every article ships with these. Keep them in the file's front-matter or a clearl
|
|
|
109
100
|
- **Slug**: short, lowercase, hyphenated, keyword-bearing, no stop-word noise — `/compost-in-apartment` not `/how-to-start-composting-in-your-apartment-today`.
|
|
110
101
|
- **FAQ block**: 3–6 real questions from "People also ask", each answered in 2–4 sentences.
|
|
111
102
|
|
|
112
|
-
Quick checklist:
|
|
113
|
-
|
|
114
|
-
- [ ] Title 50–60 chars, keyword in first ~35
|
|
115
|
-
- [ ] Meta 140–160 chars, value-first
|
|
116
|
-
- [ ] Exactly one H1
|
|
117
|
-
- [ ] Slug short + keyword-bearing
|
|
118
|
-
- [ ] FAQ questions match visible page content
|
|
119
|
-
|
|
120
103
|
Full pixel/char tables, slug rules, and copy-ready `Article`/`BlogPosting` + `FAQPage` JSON-LD (JSON-LD only — never microdata) live in [`references/on-page-seo.md`](references/on-page-seo.md). The JSON-LD must describe what is actually on the page; schema that does not match visible content is a quality flag, not a win.
|
|
121
104
|
|
|
122
105
|
## Internal links and topical authority
|