diff --git a/.agents/skills/ark-ui/SKILL.md b/.agents/skills/ark-ui/SKILL.md index ece243cfe..3d3a918b3 100644 --- a/.agents/skills/ark-ui/SKILL.md +++ b/.agents/skills/ark-ui/SKILL.md @@ -1,6 +1,7 @@ --- name: ark-ui description: Check Ark UI primitives via MCP and integrate them in ds-* components without duplicating internal state. Use before building a custom component, wrapping Ark primitives, or when the user mentions Ark UI MCP. +user-invocable: false --- # Ark UI Skill diff --git a/.agents/skills/ask-matt/SKILL.md b/.agents/skills/ask-matt/SKILL.md new file mode 100644 index 000000000..1b3d2d0d7 --- /dev/null +++ b/.agents/skills/ask-matt/SKILL.md @@ -0,0 +1,53 @@ +--- +name: ask-matt +description: Ask which skill or flow fits your situation. A router over the skills in this repo. +disable-model-invocation: true +--- + +# Ask Matt + +You don't remember every skill, so ask. This is the **flow** view — how the skills chain from idea to shipped component. The file-type → skill map (which reference to read when editing a given file) lives in [AGENTS.md](../../../AGENTS.md#project-skills). + +## Main flow: idea → ship + +The route most component work travels. + +1. **Sharpen** — **`/grill-me`** interviews you relentlessly, one question at a time, until every branch of the decision tree is resolved. Switch to **`/grill-with-docs`** when the work touches domain language or irreversible architecture: it challenges against `CONTEXT.md` + ADRs and updates them inline. +2. **Plan** — **`/to-plan`** packages the locked decisions into a short execution plan for the build session. No re-interview, no scope invention — only what was decided. +3. **Build** — scaffold with **`/component-scaffold`** (or **`/figma-to-component`** from a Figma URL), then build test-first with **`/tdd`**, stories with **`/storybook`**, behavior with **`/browser-tests`**, docs coverage with **`/docs-tests`**. Editing a specific file pulls its reference: `/component-api`, `/react-patterns`, `/ark-ui`, `/scss`, `/ts-standards`. +4. **Ship** — **`/pr-prep`** runs the checks + changeset; **`/code-review`** does the two-axis (Standards + Spec) review of the diff before you push. + +## On-ramps + +A starting situation that generates work, then merges onto the main flow. + +- **Something's broken** → **`/diagnose`**: reproduce → minimize → hypothesize → instrument → fix, refusing to theorize until a **tight feedback loop** goes red on _this_ bug. Lock it down with a **`/tdd`** regression test. +- **Old Storybook `play` tests** → **`/migrate-story-tests`** converts them to **`/browser-tests`**. + +## Codebase health + +Not feature work — upkeep. + +- **`/improve-codebase-architecture`** — surface **deepening opportunities** against `CONTEXT.md`; picking one feeds an idea back into the main flow at `/grill-me`. It's the survey that finds candidates; **`/codebase-design`** is the bench you design the chosen module on. + +## Vocabulary underneath + +Model-invoked references — reach for them when the **words**, not the process, are the problem; or let the skills above pull them in. + +- **`/domain-modeling`** — sharpen the project's _domain_ language: resolve an overloaded term, record a hard-to-reverse decision as an ADR. The discipline `/grill-with-docs` drives to keep `CONTEXT.md` a clean glossary. +- **`/codebase-design`** — deep-module vocabulary (module, interface, depth, seam, leverage, locality) for designing a module's _shape_: a lot of behavior behind a small interface at a clean seam. + +## Crossing sessions + +- **`/handoff`** — compact the conversation into a markdown file so a **fresh session** can pick up. Forks the context; reference the file from the new thread. +- **`/compact`** (built-in) — stay in the **same conversation**, summarizing earlier turns. Use at phase breaks, not mid-phase. `/handoff` forks; `/compact` continues. + +## Standalone + +Off the main flow entirely. + +- **`/research`** — a **background agent** investigates a question against **primary sources** and leaves a cited Markdown file in the repo. Keep working while it reads. +- **`/teach`** — learn a concept over multiple sessions, using the workspace as stateful scratch. +- **`/get-pr-comments`** — fetch and summarize the active PR's review comments. +- **`/deslop`** — strip AI-generated slop and fix style on a diff. +- **`/write-a-skill`** — author a new skill in `.agents/skills/`. diff --git a/.agents/skills/browser-tests/SKILL.md b/.agents/skills/browser-tests/SKILL.md index d280a83d7..968df3da3 100644 --- a/.agents/skills/browser-tests/SKILL.md +++ b/.agents/skills/browser-tests/SKILL.md @@ -1,6 +1,7 @@ --- name: browser-tests description: Write and extend Vitest browser tests for design-system components. Use when adding or editing `*.browser.test.tsx`, writing behavioral coverage, or moving assertions out of Storybook. +user-invocable: false --- # Browser Tests Skill diff --git a/.agents/skills/codebase-design/DEEPENING.md b/.agents/skills/codebase-design/DEEPENING.md new file mode 100644 index 000000000..cab8d3408 --- /dev/null +++ b/.agents/skills/codebase-design/DEEPENING.md @@ -0,0 +1,37 @@ +# Deepening + +How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in [SKILL.md](SKILL.md) — **module**, **interface**, **seam**, **adapter**. + +## Dependency categories + +When assessing a candidate for deepening, classify its dependencies. The category determines how the deepened module is tested across its seam. + +### 1. In-process + +Pure computation, in-memory state, no I/O. Always safe to deepen — merge the modules and test through the new interface directly. No adapter needed. + +### 2. Local-substitutable + +Dependencies that have local test stand-ins (PGLite for Postgres, in-memory filesystem). Safe to deepen if the stand-in exists. The deepened module is tested with the stand-in running in the test suite. The seam is internal; no port at the module's external interface. + +### 3. Remote but owned (Ports & Adapters) + +Your own services across a network boundary (microservices, internal APIs). Define a **port** (interface) at the seam. The deep module owns the logic; the transport is injected as an **adapter**. Tests use an in-memory adapter. Production uses an HTTP/gRPC/queue adapter. + +Recommendation shape: _"Define a port at the seam, implement an HTTP adapter for production and an in-memory adapter for testing, so the logic sits in one deep module even though it's deployed across a network."_ + +### 4. True external (Mock) + +Third-party services (Stripe, Twilio, etc.) you don't control. The deepened module takes the external dependency as an injected port; tests provide a mock adapter. + +## Seam discipline + +- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a port unless at least two adapters are justified (typically production + test). A single-adapter seam is just indirection. +- **Internal seams vs external seams.** A deep module can have internal seams (private to its implementation, used by its own tests) as well as the external seam at its interface. Don't expose internal seams through the interface just because tests use them. + +## Testing strategy: replace, don't layer + +- Old unit tests on shallow modules become waste once tests at the deepened module's interface exist — delete them. +- Write new tests at the deepened module's interface. The **interface is the test surface**. +- Tests assert on observable outcomes through the interface, not internal state. +- Tests should survive internal refactors — they describe behavior, not implementation. If a test has to change when the implementation changes, it's testing past the interface. diff --git a/.agents/skills/codebase-design/DESIGN-IT-TWICE.md b/.agents/skills/codebase-design/DESIGN-IT-TWICE.md new file mode 100644 index 000000000..9462f10fe --- /dev/null +++ b/.agents/skills/codebase-design/DESIGN-IT-TWICE.md @@ -0,0 +1,44 @@ +# Design It Twice + +When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" — your first idea is unlikely to be the best. + +Uses the vocabulary in [SKILL.md](SKILL.md) — **module**, **interface**, **seam**, **adapter**, **leverage**. + +## Process + +### 1. Frame the problem space + +Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate: + +- The constraints any new interface would need to satisfy +- The dependencies it would rely on, and which category they fall into (see [DEEPENING.md](DEEPENING.md)) +- A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete + +Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel. + +### 2. Spawn sub-agents + +Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module. + +Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [DEEPENING.md](DEEPENING.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint: + +- Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximize leverage per entry point." +- Agent 2: "Maximize flexibility — support many use cases and extension." +- Agent 3: "Optimize for the most common caller — make the default case trivial." +- Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies." + +Include both [SKILL.md](SKILL.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language. + +Each sub-agent outputs: + +1. Interface (types, methods, params — plus invariants, ordering, error modes) +2. Usage example showing how callers use it +3. What the implementation hides behind the seam +4. Dependency strategy and adapters (see [DEEPENING.md](DEEPENING.md)) +5. Trade-offs — where leverage is high, where it's thin + +### 3. Present and compare + +Present designs sequentially so the user can absorb each one, then compare them in prose. Contrast by **depth** (leverage at the interface), **locality** (where change concentrates), and **seam placement**. + +After comparing, give your own recommendation: which design you think is strongest and why. If elements from different designs would combine well, propose a hybrid. Be opinionated — the user wants a strong read, not a menu. diff --git a/.agents/skills/codebase-design/SKILL.md b/.agents/skills/codebase-design/SKILL.md new file mode 100644 index 000000000..6c42f1f0f --- /dev/null +++ b/.agents/skills/codebase-design/SKILL.md @@ -0,0 +1,114 @@ +--- +name: codebase-design +description: Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary. +--- + +# Codebase Design + +Design **deep modules**: a lot of behavior behind a small interface, placed at a clean seam, testable through that interface. Use this language and these principles wherever code is being designed or restructured. The aim is leverage for callers, locality for maintainers, and testability for everyone. + +## Glossary + +Use these terms exactly — don't substitute "component," "service," "API," or "boundary." Consistent language is the whole point. + +**Module** — anything with an interface and an implementation. Deliberately scale-agnostic: a function, class, package, or tier-spanning slice. _Avoid_: unit, component, service. + +**Interface** — everything a caller must know to use the module correctly: the type signature, but also invariants, ordering constraints, error modes, required configuration, and performance characteristics. _Avoid_: API, signature (too narrow — they refer only to the type-level surface). + +**Implementation** — what's inside a module, its body of code. Distinct from **Adapter**: a thing can be a small adapter with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake). Reach for "adapter" when the seam is the topic; "implementation" otherwise. + +**Depth** — leverage at the interface: the amount of behavior a caller (or test) can exercise per unit of interface they have to learn. A module is **deep** when a large amount of behavior sits behind a small interface, **shallow** when the interface is nearly as complex as the implementation. + +**Seam** _(Michael Feathers)_ — a place where you can alter behavior without editing in that place; the _location_ at which a module's interface lives. Where to put the seam is its own design decision, distinct from what goes behind it. _Avoid_: boundary (overloaded with DDD's bounded context). + +**Adapter** — a concrete thing that satisfies an interface at a seam. Describes _role_ (what slot it fills), not substance (what's inside). + +**Leverage** — what callers get from depth: more capability per unit of interface they learn. One implementation pays back across N call sites and M tests. + +**Locality** — what maintainers get from depth: change, bugs, knowledge, and verification concentrate in one place rather than spreading across callers. Fix once, fixed everywhere. + +## Deep vs shallow + +**Deep module** = small interface + lots of implementation: + +``` +┌─────────────────────┐ +│ Small Interface │ ← Few methods, simple params +├─────────────────────┤ +│ │ +│ Deep Implementation│ ← Complex logic hidden +│ │ +└─────────────────────┘ +``` + +**Shallow module** = large interface + little implementation (avoid): + +``` +┌─────────────────────────────────┐ +│ Large Interface │ ← Many methods, complex params +├─────────────────────────────────┤ +│ Thin Implementation │ ← Just passes through +└─────────────────────────────────┘ +``` + +When designing an interface, ask: + +- Can I reduce the number of methods? +- Can I simplify the parameters? +- Can I hide more complexity inside? + +## Principles + +- **Depth is a property of the interface, not the implementation.** A deep module can be internally composed of small, mockable, swappable parts — they just aren't part of the interface. A module can have **internal seams** (private to its implementation, used by its own tests) as well as the **external seam** at its interface. +- **The deletion test.** Imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep. +- **The interface is the test surface.** Callers and tests cross the same seam. If you want to test _past_ the interface, the module is probably the wrong shape. +- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a seam unless something actually varies across it. + +## Designing for testability + +Good interfaces make testing natural: + +1. **Accept dependencies, don't create them.** + + ```typescript + // Testable + function processOrder(order, paymentGateway) {} + + // Hard to test + function processOrder(order) { + const gateway = new StripeGateway(); + } + ``` + +2. **Return results, don't produce side effects.** + + ```typescript + // Testable + function calculateDiscount(cart): Discount {} + + // Hard to test + function applyDiscount(cart): void { + cart.total -= discount; + } + ``` + +3. **Small surface area.** Fewer methods = fewer tests needed. Fewer params = simpler test setup. + +## Relationships + +- A **Module** has exactly one **Interface** (the surface it presents to callers and tests). +- **Depth** is a property of a **Module**, measured against its **Interface**. +- A **Seam** is where a **Module**'s **Interface** lives. +- An **Adapter** sits at a **Seam** and satisfies the **Interface**. +- **Depth** produces **Leverage** for callers and **Locality** for maintainers. + +## Rejected framings + +- **Depth as ratio of implementation-lines to interface-lines**: rewards padding the implementation. We use depth-as-leverage instead. +- **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow — interface here includes every fact a caller must know. +- **"Boundary"**: overloaded with DDD's bounded context. Say **seam** or **interface**. + +## Going deeper + +- **Deepening a cluster given its dependencies** — see [DEEPENING.md](DEEPENING.md): dependency categories, seam discipline, and replace-don't-layer testing. +- **Exploring alternative interfaces** — see [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md): spin up parallel sub-agents to design the interface several radically different ways, then compare on depth, locality, and seam placement. diff --git a/.agents/skills/component-api/SKILL.md b/.agents/skills/component-api/SKILL.md index bfb202e60..6fc53edb9 100644 --- a/.agents/skills/component-api/SKILL.md +++ b/.agents/skills/component-api/SKILL.md @@ -1,6 +1,7 @@ --- name: component-api description: Design public props for ds-* components in *.types.ts files. Use when editing ds-*.types.ts, Ds*Props interfaces, variant as const arrays, locale prop, onXChange callbacks, or changing component public API. +user-invocable: false --- # Component API Skill diff --git a/.agents/skills/component-scaffold/SKILL.md b/.agents/skills/component-scaffold/SKILL.md index 74dc29330..49a448b53 100644 --- a/.agents/skills/component-scaffold/SKILL.md +++ b/.agents/skills/component-scaffold/SKILL.md @@ -1,6 +1,8 @@ --- name: component-scaffold description: Scaffold a new ds-* component (files, barrel export, validation). Use when the user asks to create, scaffold, or add a new component. +user-invocable: false +disable-model-invocation: true --- # Component Scaffold Skill @@ -66,23 +68,3 @@ export type { Ds{Name}Props } from './ds-{name}.types'; ``` Set `displayName` on the component in `ds-{name}.tsx` (or `index.ts` if wrapped). Stories must import from `./index` when a barrel/HOC is the public API. - -Use `.ts` extension on barrel file, not `.tsx`. - -## Validate - -```bash -pnpm eslint packages/design-system/src/components/ds-{name}/ -pnpm --filter @drivenets/design-system typecheck -``` - -With browser tests: - -```bash -pnpm --filter @drivenets/design-system test packages/design-system/src/components/ds-{name}/__tests__/ds-{name}.browser.test.tsx --run -``` - -## Related - -- Figma URL: [figma-to-component](../figma-to-component/SKILL.md) then this flow -- PR checks: [pr-prep](../pr-prep/SKILL.md) diff --git a/.agents/skills/docs-tests/SKILL.md b/.agents/skills/docs-tests/SKILL.md index c91411106..05244e55b 100644 --- a/.agents/skills/docs-tests/SKILL.md +++ b/.agents/skills/docs-tests/SKILL.md @@ -1,6 +1,7 @@ --- name: docs-tests description: Write and run Storybook docs snippet tests (`*.docs.test.ts`) for Show code and MCP manifest verification against production storybook-static. Use when adding or editing docs tests or verifying Autodocs snippets after story changes. +user-invocable: false --- # Docs Tests Skill diff --git a/.agents/skills/domain-modeling/ADR-FORMAT.md b/.agents/skills/domain-modeling/ADR-FORMAT.md new file mode 100644 index 000000000..54664fba4 --- /dev/null +++ b/.agents/skills/domain-modeling/ADR-FORMAT.md @@ -0,0 +1,47 @@ +# ADR Format + +ADRs live in `docs/adr/` and use sequential numbering: `0001-slug.md`, `0002-slug.md`, etc. + +Create the `docs/adr/` directory lazily — only when the first ADR is needed. + +## Template + +```md +# {Short title of the decision} + +{1-3 sentences: what's the context, what did we decide, and why.} +``` + +That's it. An ADR can be a single paragraph. The value is in recording _that_ a decision was made and _why_ — not in filling out sections. + +## Optional sections + +Only include these when they add genuine value. Most ADRs won't need them. + +- **Status** front matter (`proposed | accepted | deprecated | superseded by ADR-NNNN`) — useful when decisions are revisited +- **Considered Options** — only when the rejected alternatives are worth remembering +- **Consequences** — only when non-obvious downstream effects need to be called out + +## Numbering + +Scan `docs/adr/` for the highest existing number and increment by one. + +## When to offer an ADR + +All three of these must be true: + +1. **Hard to reverse** — the cost of changing your mind later is meaningful +2. **Surprising without context** — a future reader will look at the code and wonder "why on earth did they do it this way?" +3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons + +If a decision is easy to reverse, skip it — you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing." + +### What qualifies + +- **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres." +- **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP." +- **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out. +- **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s. +- **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate. +- **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract." +- **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months. diff --git a/.agents/skills/domain-modeling/CONTEXT-FORMAT.md b/.agents/skills/domain-modeling/CONTEXT-FORMAT.md new file mode 100644 index 000000000..eaf2a1857 --- /dev/null +++ b/.agents/skills/domain-modeling/CONTEXT-FORMAT.md @@ -0,0 +1,60 @@ +# CONTEXT.md Format + +## Structure + +```md +# {Context Name} + +{One or two sentence description of what this context is and why it exists.} + +## Language + +**Order**: +{A one or two sentence description of the term} +_Avoid_: Purchase, transaction + +**Invoice**: +A request for payment sent to a customer after delivery. +_Avoid_: Bill, payment request + +**Customer**: +A person or organization that places orders. +_Avoid_: Client, buyer, account +``` + +## Rules + +- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others under `_Avoid_`. +- **Keep definitions tight.** One or two sentences max. Define what it IS, not what it does. +- **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs. +- **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine. + +## Single vs multi-context repos + +**Single context (most repos):** One `CONTEXT.md` at the repo root. + +**Multiple contexts:** A `CONTEXT-MAP.md` at the repo root lists the contexts, where they live, and how they relate to each other: + +```md +# Context Map + +## Contexts + +- [Ordering](./src/ordering/CONTEXT.md) — receives and tracks customer orders +- [Billing](./src/billing/CONTEXT.md) — generates invoices and processes payments +- [Fulfillment](./src/fulfillment/CONTEXT.md) — manages warehouse picking and shipping + +## Relationships + +- **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking +- **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices +- **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money` +``` + +The skill infers which structure applies: + +- If `CONTEXT-MAP.md` exists, read it to find contexts +- If only a root `CONTEXT.md` exists, single context +- If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved + +When multiple contexts exist, infer which one the current topic relates to. If unclear, ask. diff --git a/.agents/skills/domain-modeling/SKILL.md b/.agents/skills/domain-modeling/SKILL.md new file mode 100644 index 000000000..7021a5906 --- /dev/null +++ b/.agents/skills/domain-modeling/SKILL.md @@ -0,0 +1,74 @@ +--- +name: domain-modeling +description: Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model. +--- + +# Domain Modeling + +Actively build and sharpen the project's domain model as you design. This is the _active_ discipline — challenging terms, inventing edge-case scenarios, and writing the glossary and decisions down the moment they crystallize. (Merely _reading_ `CONTEXT.md` for vocabulary is not this skill — that's a one-line habit any skill can do. This skill is for when you're changing the model, not just consuming it.) + +## File structure + +Most repos have a single context: + +``` +/ +├── CONTEXT.md +├── docs/ +│ └── adr/ +│ ├── 0001-event-sourced-orders.md +│ └── 0002-postgres-for-write-model.md +└── src/ +``` + +If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives: + +``` +/ +├── CONTEXT-MAP.md +├── docs/ +│ └── adr/ ← system-wide decisions +├── src/ +│ ├── ordering/ +│ │ ├── CONTEXT.md +│ │ └── docs/adr/ ← context-specific decisions +│ └── billing/ +│ ├── CONTEXT.md +│ └── docs/adr/ +``` + +Create files lazily — only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed. + +## During the session + +### Challenge against the glossary + +When the user uses a term that conflicts with the existing language in `CONTEXT.md`, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?" + +### Sharpen fuzzy language + +When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things." + +### Discuss concrete scenarios + +When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts. + +### Cross-reference with code + +When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?" + +### Update CONTEXT.md inline + +When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md). + +`CONTEXT.md` should be totally devoid of implementation details. Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else. + +### Offer ADRs sparingly + +Only offer to create an ADR when all three are true: + +1. **Hard to reverse** — the cost of changing your mind later is meaningful +2. **Surprising without context** — a future reader will wonder "why did they do it this way?" +3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons + +If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md). diff --git a/.agents/skills/figma-to-component/SKILL.md b/.agents/skills/figma-to-component/SKILL.md index 748fdaa76..d0eafb7de 100644 --- a/.agents/skills/figma-to-component/SKILL.md +++ b/.agents/skills/figma-to-component/SKILL.md @@ -1,6 +1,7 @@ --- name: figma-to-component description: Orchestrate a Figma URL to a ds-* component. Trust-boundary pre-step, Figma MCP for design context, DS MCP for guidelines and inventory, then component-scaffold. Use when the user provides a Figma link and asks to implement it. +user-invocable: false --- # Figma-to-Component Skill diff --git a/.agents/skills/fix/SKILL.md b/.agents/skills/fix/SKILL.md new file mode 100644 index 000000000..1199f7b80 --- /dev/null +++ b/.agents/skills/fix/SKILL.md @@ -0,0 +1,46 @@ +--- +name: fix +description: Fast path for a small bug or adjustment in the design system — regression test, minimal fix, verify. Lightweight sibling to implement (no ticket, no plan gate). Use when the user reports a bug, says something is off/broken, or asks for a small tweak to an existing component. +--- + +# Fix (small bug / adjustment) + +The fast path for small changes to **existing** code. No ticket file, no plan gate, no grilling. One vertical slice: pin the bug, fix it, prove it stays fixed. + +For net-new features or ticket-driven work, use [implement](../implement/SKILL.md) instead. For pure style/cleanup with no behavior change, use [deslop](../deslop/SKILL.md). + +## Step 0 — Restate + +One line: expected vs actual (bug) or before vs after (adjustment). Name the component/file. If you can't state it crisply, ask — don't guess. + +## Step 1 — Reproduce + +- Behavior bug with an unclear cause → escalate to [diagnose](../diagnose/SKILL.md) (reproduce → minimize → hypothesize → instrument), then come back. +- Obvious repro (visual off-by, wrong prop default, clear logic slip) → skip `diagnose`, go straight to Step 2. + +## Step 2 — Regression test first (do not skip) + +Write ONE failing test that pins the bug via the public interface ([tdd](../tdd/SKILL.md), [browser-tests](../browser-tests/SKILL.md) for interaction). It must fail for the right reason **before** you touch the fix. A fix without a test that would have caught the bug is not done. + +Exception: pure style-only adjustment with no behavioral contract (e.g. a token/spacing tweak) — a `*.browser.test.tsx` may not apply; say so explicitly and rely on Step 4 + visual check instead. + +## Step 3 — Minimal fix + +Smallest change that turns the test green. No refactoring past the bug, no drive-by "while I'm here" edits (open a separate `fix` for those). Root cause, not a patch over the symptom. + +## Step 4 — Verify (do not skip) + +`ds-verifier` subagent (readonly) — lint, typecheck, tests on **changed paths only** per [AGENTS.md#code-quality-checkers](../../../AGENTS.md#code-quality-checkers). Never mark done while red. + +## Step 5 — Wrap + +- Changeset: patch-level, user-facing wording ("Fix X in Ds{Name}"). Remind the user to run `pnpm changelog` if none exists. +- Leave changes uncommitted (per repo branch rules) unless the user asks to commit. +- Report: bug → test → fix in one block, plus checker results. + +## Done when + +- [ ] A test fails before the fix and passes after (or style-only exception stated) +- [ ] Fix is minimal and addresses root cause +- [ ] `ds-verifier` is green on changed paths +- [ ] Patch changeset added (or gap reported) diff --git a/.agents/skills/grill-me/SKILL.md b/.agents/skills/grill-me/SKILL.md index aeeddbab2..56c40f5b7 100644 --- a/.agents/skills/grill-me/SKILL.md +++ b/.agents/skills/grill-me/SKILL.md @@ -1,6 +1,7 @@ --- name: grill-me description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me". +disable-model-invocation: true --- Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer. diff --git a/.agents/skills/grill-with-docs/SKILL.md b/.agents/skills/grill-with-docs/SKILL.md index 0247f88dd..8d6e2ef7c 100644 --- a/.agents/skills/grill-with-docs/SKILL.md +++ b/.agents/skills/grill-with-docs/SKILL.md @@ -1,6 +1,7 @@ --- name: grill-with-docs description: Like grill-me, but challenges against CONTEXT.md and ADRs and updates glossary/ADR files inline as decisions land. Use for cross-cutting domain language or irreversible architecture — not the default for design-system feature work (use grill-me → to-plan instead). +disable-model-invocation: true --- diff --git a/.agents/skills/handoff/SKILL.md b/.agents/skills/handoff/SKILL.md index 7406e6468..62a59e091 100644 --- a/.agents/skills/handoff/SKILL.md +++ b/.agents/skills/handoff/SKILL.md @@ -2,6 +2,7 @@ name: handoff description: Compact the current conversation into a handoff document for another agent to pick up. argument-hint: 'What will the next session be used for?' +disable-model-invocation: true --- Write a handoff document summarizing the current conversation so a fresh agent can continue the work. Save it to a path from the shell temp-file command `mktemp -t handoff-XXXXXX.md` (read that path before you write to it). diff --git a/.agents/skills/implement/SKILL.md b/.agents/skills/implement/SKILL.md new file mode 100644 index 000000000..4c05a5c88 --- /dev/null +++ b/.agents/skills/implement/SKILL.md @@ -0,0 +1,69 @@ +--- +name: implement +description: Drive a markdown ticket file to a tested, checker-clean implementation. Orchestrates plan, build, test, and verify using existing skills and subagents. Assumes the ticket is already grilled/clear. Use when the user points to a .md ticket, spec, or issue file and says implement, build, or ship it. +--- + +# Implement (ticket → tested code) + +Orchestrator only — read each linked skill **fully** before the step that uses it. Delegate heavy work to subagents to keep this context clean. + +## Input + +A markdown file acting as the ticket/spec (path given by the user, e.g. `tasks/AR-12345.md`). If no file is given, ask for the path — do not invent requirements. + +## Step 0 — Parse the ticket + +Read the file and extract: + +- **Goal** — one or two sentences. +- **Acceptance criteria** — the checkable behaviors. If absent, list what you infer and confirm with the user before building. +- **Scope / out-of-scope** — paths, components, packages to touch. +- **Design source** — Figma URL? → route through [figma-to-component](../figma-to-component/SKILL.md). + +Restate the goal + criteria back to the user in one short block before proceeding. + +## Step 1 — Plan (skip only if trivial) + +The ticket is assumed already grilled — decisions are locked in the file. **Do not grill the user.** If the ticket is genuinely ambiguous or self-contradictory, stop and surface it rather than inventing requirements. + +- Ticket already has **Steps** + **Skills per step** (authored by [to-plan](../to-plan/SKILL.md)) → use them as-is, skip planning. +- Loose ticket (human/Jira), non-trivial → run [to-plan](../to-plan/SKILL.md) to add the execution structure. +- Trivial (1–2 obvious steps, no architectural choice) → skip planning. + +Track the plan steps with the todo tool so nothing is dropped. + +## Step 2 — Build + +Choose the path from the ticket: + +| Ticket is about | Delegate to | +| ------------------------------------- | -------------------------------------------------------------------------------------------- | +| New / extended `ds-*` component | `ds-component-builder` subagent (wraps [component-scaffold](../component-scaffold/SKILL.md)) | +| Figma design → component | [figma-to-component](../figma-to-component/SKILL.md) → `ds-component-builder` | +| Logic / util / plugin (non-component) | [tdd](../tdd/SKILL.md) here, red-green-refactor | +| Bug fix | [diagnose](../diagnose/SKILL.md) → [tdd](../tdd/SKILL.md) regression test | + +Prefer test-first ([tdd](../tdd/SKILL.md)) for anything with behavior. One vertical slice at a time. + +## Step 3 — Test + +Behavioral coverage lives in `*.browser.test.tsx`. Delegate to the `ds-browser-test-writer` subagent (wraps [browser-tests](../browser-tests/SKILL.md)) when the ticket adds interaction. Every acceptance criterion from Step 0 must map to at least one assertion — no render-only smoke tests. + +## Step 4 — Verify (do not skip) + +1. `ds-verifier` subagent (readonly) — lint, typecheck, tests on **changed paths only** per [AGENTS.md#code-quality-checkers](../../../AGENTS.md#code-quality-checkers). Never mark done while red. +2. `ds-review` subagent (readonly) — reviews the branch diff for rule violations the checkers can't catch (forwardRef, cross-component imports, hardcoded colors, AI test slop, stale Code Connect). Returns ≤10 findings. + +Fix findings from both, then re-run. Do not proceed while either is red. + +## Step 5 — Wrap + +- [pr-prep](../pr-prep/SKILL.md) — full pre-submission checklist + changeset. +- Report: files changed, acceptance criteria → test mapping, checker results. Leave changes uncommitted (per repo branch rules) unless the user asks to commit. + +## Done when + +- [ ] Every acceptance criterion is covered by a passing test +- [ ] `ds-verifier` is green on changed paths +- [ ] `ds-review` findings are resolved (or consciously deferred) +- [ ] `pr-prep` checklist passes (or gaps are reported) diff --git a/.agents/skills/improve-codebase-architecture/SKILL.md b/.agents/skills/improve-codebase-architecture/SKILL.md index 1c4193dce..1ad623a8b 100644 --- a/.agents/skills/improve-codebase-architecture/SKILL.md +++ b/.agents/skills/improve-codebase-architecture/SKILL.md @@ -1,6 +1,7 @@ --- name: improve-codebase-architecture description: Find deepening opportunities in a codebase, informed by the domain language in CONTEXT.md and the decisions in docs/adr/. Use when the user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable. +disable-model-invocation: true --- # Improve Codebase Architecture diff --git a/.agents/skills/react-patterns/SKILL.md b/.agents/skills/react-patterns/SKILL.md index a185bcb03..54886dd27 100644 --- a/.agents/skills/react-patterns/SKILL.md +++ b/.agents/skills/react-patterns/SKILL.md @@ -1,6 +1,7 @@ --- name: react-patterns description: React patterns for design-system TSX including ds-* components, subcomponents, *.stories.tsx, and __tests__/*.browser.test.tsx. Use when editing hooks, useState, useEffect, ref prop, memoization, controlled state, or event handlers in @drivenets/design-system. +user-invocable: false --- # React Patterns Skill @@ -75,6 +76,10 @@ const DsButton = ({ ref, ...props }: DsButtonProps) =>