@cratis/pi 7.37.0 → 7.38.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/harnesses/copilot/instructions/ai-distribution.instructions.md +109 -0
- package/package/corpus/harnesses/copilot/instructions/application-profile.instructions.md +81 -0
- package/package/corpus/harnesses/copilot/instructions/capability-is-not-authority.instructions.md +45 -0
- package/package/corpus/harnesses/copilot/instructions/code-quality.csharp.instructions.md +92 -0
- package/package/corpus/harnesses/copilot/instructions/code-quality.instructions.md +83 -0
- package/package/corpus/harnesses/copilot/instructions/code-quality.typescript.instructions.md +90 -0
- package/package/corpus/harnesses/copilot/instructions/components.instructions.md +300 -0
- package/package/corpus/harnesses/copilot/instructions/concepts.instructions.md +138 -0
- package/package/corpus/harnesses/copilot/instructions/cratis-folder-is-configuration.instructions.md +29 -0
- package/package/corpus/harnesses/copilot/instructions/csharp.instructions.md +357 -0
- package/package/corpus/harnesses/copilot/instructions/dialogs.instructions.md +278 -0
- package/package/corpus/harnesses/copilot/instructions/documentation-structure-and-formatting.instructions.md +162 -0
- package/package/corpus/harnesses/copilot/instructions/documentation.instructions.md +90 -0
- package/package/corpus/harnesses/copilot/instructions/editing-cratis-docs.instructions.md +74 -0
- package/package/corpus/harnesses/copilot/instructions/efcore.instructions.md +84 -0
- package/package/corpus/harnesses/copilot/instructions/efcore.specs.instructions.md +45 -0
- package/package/corpus/harnesses/copilot/instructions/elixir.instructions.md +50 -0
- package/package/corpus/harnesses/copilot/instructions/exit-codes-and-wrappers.instructions.md +34 -0
- package/package/corpus/harnesses/copilot/instructions/framework.instructions.md +55 -0
- package/package/corpus/harnesses/copilot/instructions/frontend-quality.instructions.md +60 -0
- package/package/corpus/harnesses/copilot/instructions/frontend-testing.instructions.md +127 -0
- package/package/corpus/harnesses/copilot/instructions/git-commits.instructions.md +139 -0
- package/package/corpus/harnesses/copilot/instructions/github-actions.instructions.md +87 -0
- package/package/corpus/harnesses/copilot/instructions/glossary.instructions.md +63 -0
- package/package/corpus/harnesses/copilot/instructions/go-engineering.instructions.md +61 -0
- package/package/corpus/harnesses/copilot/instructions/go.instructions.md +116 -0
- package/package/corpus/harnesses/copilot/instructions/guards-and-fuses.instructions.md +61 -0
- package/package/corpus/harnesses/copilot/instructions/java.instructions.md +138 -0
- package/package/corpus/harnesses/copilot/instructions/kotlin.instructions.md +175 -0
- package/package/corpus/harnesses/copilot/instructions/local-work-artifacts.instructions.md +56 -0
- package/package/corpus/harnesses/copilot/instructions/new-repository-intake.instructions.md +35 -0
- package/package/corpus/harnesses/copilot/instructions/orleans.instructions.md +97 -0
- package/package/corpus/harnesses/copilot/instructions/profiles.instructions.md +403 -0
- package/package/corpus/harnesses/copilot/instructions/pull-requests.instructions.md +176 -0
- package/package/corpus/harnesses/copilot/instructions/react.instructions.md +203 -0
- package/package/corpus/harnesses/copilot/instructions/reactors.instructions.md +336 -0
- package/package/corpus/harnesses/copilot/instructions/rtk.instructions.md +48 -0
- package/package/corpus/harnesses/copilot/instructions/specs.csharp.instructions.md +147 -0
- package/package/corpus/harnesses/copilot/instructions/specs.instructions.md +133 -0
- package/package/corpus/harnesses/copilot/instructions/specs.scenarios.csharp.instructions.md +281 -0
- package/package/corpus/harnesses/copilot/instructions/specs.typescript.instructions.md +141 -0
- package/package/corpus/harnesses/copilot/instructions/storybook.instructions.md +85 -0
- package/package/corpus/harnesses/copilot/instructions/typescript.instructions.md +151 -0
- package/package/corpus/harnesses/copilot/instructions/verification-discipline.instructions.md +27 -0
- package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +414 -0
- package/package/corpus/harnesses/copilot/instructions/web-fetching.instructions.md +12 -0
- package/package/corpus/harnesses/copilot/instructions/writing-correct-examples.instructions.md +57 -0
- package/package/corpus/harnesses/copilot/instructions/writing-cratis-docs.instructions.md +72 -0
- package/package/corpus/product-sync.json +2 -2
- package/package/corpus/skills/cratis-screenplay-discovery/SKILL.md +11 -6
- package/package/corpus/skills/cratis-screenplay-discovery/references/facilitation.md +9 -5
- package/package/corpus/skills/cratis-screenplay-discovery/references/human-workshop.md +1 -1
- package/package/corpus/skills/cratis-screenplay-discovery/references/plotting-and-handoff.md +28 -4
- package/package/corpus/skills/cratis-screenplay-discovery/references/storming-loop.md +2 -1
- package/package/corpus/skills/cratis-screenplay-discovery/verification.json +5 -0
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +23 -29
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +15 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/model-notes.md +208 -0
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +20 -1
- package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +19 -36
- package/package/corpus/skills/cratis-screenplay-model-review/references/report-template.md +26 -0
- package/package/corpus/skills/cratis-screenplay-model-review/verification.json +7 -0
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +14 -16
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/core-rules-digest.md +8 -3
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/handoff-template.md +5 -2
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/intake.md +21 -0
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/reasoning-notes.md +10 -6
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/stop-or-assume.md +32 -1
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/worked-example.md +5 -2
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/verification.json +5 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +4 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1716 -183
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +40 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*.stories.tsx"
|
|
3
|
+
profile: application
|
|
4
|
+
paths:
|
|
5
|
+
- "**/*.stories.tsx"
|
|
6
|
+
---
|
|
7
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
8
|
+
|
|
9
|
+
# Storybook Story Conventions
|
|
10
|
+
|
|
11
|
+
Stories are visual coverage and documentation for reusable React components built on Cratis Components — **not** the behavior test suite. Non-trivial view-model/helper behavior still needs BDD Vitest specs (see [frontend-testing.md](./frontend-testing.instructions.md)). Every story file is colocated with the component it covers.
|
|
12
|
+
|
|
13
|
+
## When to write a story
|
|
14
|
+
|
|
15
|
+
Write stories for **reusable components**: shared component-library primitives and slice-internal components reused across slices. Do **not** story live slice pages wired directly to Arc query/command hooks or a backend — exercise those in the running app. For a presentational view that needs visual coverage, extract it or render its presentational subcomponents with deterministic fixture props.
|
|
16
|
+
|
|
17
|
+
Good candidates: a presentational card/list-item/form-field with multiple visual states; a component with hover/selected/disabled/error variants; anything reusable across slices.
|
|
18
|
+
|
|
19
|
+
## Preview infrastructure (what you get for free)
|
|
20
|
+
|
|
21
|
+
A configured `.storybook/preview` should wrap every story in `CratisComponentsProvider` (from `@cratis/components`) with `toaster` when stories show notifications. Import one `index.css` containing `@import '@cratis/components/tokens'`, `@import '@cratis/components/styles'` and (for the baseline look) `@import '@cratis/components/theme'`, each terminated by a semicolon — the same entries as the app. CSS imports from TypeScript need ambient declarations on TypeScript 6; keeping the subpaths in CSS avoids TS2882. Mount only one toaster. With that in place:
|
|
22
|
+
|
|
23
|
+
- **Auto prop tables** via `react-docgen-typescript` — a component's `interface` + per-prop JSDoc renders as a Docs prop table, and union props become `select` controls automatically. Keep a JSDoc comment on every prop. **`argTypes` is an override layer** (change control type, group under `table.category`, disable a control) — don't re-list every prop.
|
|
24
|
+
- **Accessibility panel** (`@storybook/addon-a11y`) scans each story with axe-core. Treat new violations as defects.
|
|
25
|
+
|
|
26
|
+
## Meta block
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
30
|
+
import { MyComponent } from './MyComponent';
|
|
31
|
+
|
|
32
|
+
const meta = {
|
|
33
|
+
title: 'Components/MyComponent', // sidebar path
|
|
34
|
+
component: MyComponent,
|
|
35
|
+
parameters: { layout: 'centered' }, // 'centered' | 'padded' | 'fullscreen'
|
|
36
|
+
tags: ['autodocs'], // always include
|
|
37
|
+
} satisfies Meta<typeof MyComponent>;
|
|
38
|
+
|
|
39
|
+
export default meta;
|
|
40
|
+
type Story = StoryObj<typeof meta>;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Use `satisfies Meta<typeof Component>` — never `: Meta<T>` (better inference). `layout`: `centered` for atoms, `padded` for compound/container components, `fullscreen` for layout shells.
|
|
44
|
+
|
|
45
|
+
## Required stories
|
|
46
|
+
|
|
47
|
+
Adapt depth to the component — rich for complex/stateful, trimmed for atoms:
|
|
48
|
+
|
|
49
|
+
1. **`Playground`** — controllable: `args` for the happy path, all props tweakable. Use `fn()` from `storybook/test` for callbacks (not `() => {}`).
|
|
50
|
+
2. **Showcase** — one or more `render:` stories covering the meaningful axes (`Variants`/`Tones`, `Sizes`, `States`, `WithIcons`). Use the Arc story-kit (`StoryContainer`, `StorySection`, `StoryGrid`, `StoryDivider`, `StoryBadge` from `@cratis/arc.react/stories`) for layout. Note: `StorySection` has no `label` prop (use an `<h3>` inside); `StoryGrid` has no `columns` prop (it auto-wraps).
|
|
51
|
+
3. **`InContext`** — the component in a small realistic composition.
|
|
52
|
+
4. **`Interactive`** — for **stateful** components: a local `const Demo: React.FC` owning `useState`, plus a `play:` test. **Omit for presentational atoms.**
|
|
53
|
+
|
|
54
|
+
Add a one-line `/** … */` doc above each story; set `parameters.docs.description.component` on the meta.
|
|
55
|
+
|
|
56
|
+
## Interaction tests (`play:`) — stateful components only
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { expect, fn, userEvent, within } from 'storybook/test';
|
|
60
|
+
|
|
61
|
+
export const Interactive: Story = {
|
|
62
|
+
render: () => <Demo />,
|
|
63
|
+
play: async ({ canvasElement }) => {
|
|
64
|
+
const canvas = within(canvasElement);
|
|
65
|
+
await userEvent.click(canvas.getAllByRole('tab')[1]);
|
|
66
|
+
await expect(canvas.getAllByRole('tab')[1]).toHaveAttribute('aria-selected', 'true');
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- **Stateful only** — presentational atoms get no `play:`. Components' own overlay components (dialogs, dropdowns, toasts) are excluded — their behavior is the library's, not yours.
|
|
72
|
+
- Prefer role/structure queries over localized text. `play:` runs in the Interactions panel (documentation/QA); the enforced behavioral gate is the Vitest spec.
|
|
73
|
+
|
|
74
|
+
## Router-dependent components
|
|
75
|
+
|
|
76
|
+
Wrap with `MemoryRouter` via a story decorator when a component uses `Link`/`useNavigate`.
|
|
77
|
+
|
|
78
|
+
## Gate
|
|
79
|
+
|
|
80
|
+
`build-storybook` should be green in CI — it compiles every story and `play:` function (catching broken imports/decorators) but does not execute play assertions.
|
|
81
|
+
|
|
82
|
+
## See also
|
|
83
|
+
|
|
84
|
+
- [react.md](./react.instructions.md) — component patterns; [components.md](./components.instructions.md) — component structure/styling.
|
|
85
|
+
- [frontend-testing.md](./frontend-testing.instructions.md) — BDD Vitest specs (the behavioral gate).
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*.ts,**/*.tsx"
|
|
3
|
+
paths:
|
|
4
|
+
- "**/*.ts"
|
|
5
|
+
- "**/*.tsx"
|
|
6
|
+
---
|
|
7
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# TypeScript Conventions
|
|
11
|
+
|
|
12
|
+
TypeScript's type system is the primary tool for catching bugs before they reach production. Every rule here pushes toward maximum compiler coverage and self-documenting code. If the types are right, the code almost writes itself.
|
|
13
|
+
|
|
14
|
+
## Enums over Magic Strings
|
|
15
|
+
|
|
16
|
+
String literal unions look concise but provide no refactoring support, no namespace, and no discoverability. Enums give you all three — plus `switch` exhaustiveness checking.
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
// ✅ Correct — refactorable, discoverable, exhaustive
|
|
20
|
+
export enum SliceType {
|
|
21
|
+
StateChange = 'stateChange',
|
|
22
|
+
StateView = 'stateView',
|
|
23
|
+
Automation = 'automation',
|
|
24
|
+
Translator = 'translator',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ❌ Wrong — no refactoring support, invisible to tooling
|
|
28
|
+
export type SliceType = 'stateChange' | 'stateView' | 'automation' | 'translator';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- Use enum members everywhere — `switch` cases, comparisons, defaults.
|
|
32
|
+
- Do **not** import enums as `type`; they are values.
|
|
33
|
+
- Export enums from `index.ts` without the `type` keyword.
|
|
34
|
+
|
|
35
|
+
## One Type or Enum per File
|
|
36
|
+
|
|
37
|
+
Each type gets its own file because it makes the codebase navigable — finding `SliceType` means opening `SliceType.ts`, not hunting through `types.ts`. It also keeps diffs clean and makes imports explicit.
|
|
38
|
+
|
|
39
|
+
- Every interface, type alias, and enum lives in **its own file**, named after the type (e.g. `SliceType.ts`).
|
|
40
|
+
- **Never create** `types.ts`, `models.ts`, `interfaces.ts` grab-bag files — they become dumping grounds that grow without limit.
|
|
41
|
+
- Exception: component props interfaces (`*Props`) may live alongside their component `.tsx` file since they are tightly coupled to that component.
|
|
42
|
+
- Aggregate exports through the folder's `index.ts`.
|
|
43
|
+
|
|
44
|
+
## Type Safety
|
|
45
|
+
|
|
46
|
+
`any` disables the compiler — the one tool that catches bugs for free. Every `any` is a hole in the safety net. Use `unknown` and narrow with type guards instead.
|
|
47
|
+
|
|
48
|
+
- Never use `any` — use `unknown`, `Record<string, unknown>`, or proper generic constraints.
|
|
49
|
+
- Prefer `value as unknown as TargetType` over `value as any`.
|
|
50
|
+
- Use `unknown` as default generic parameter instead of `any`.
|
|
51
|
+
- React synthetic events (`React.MouseEvent<Element, MouseEvent>`) and DOM events (`MouseEvent`) are different types — don't mix them.
|
|
52
|
+
- **`int64`/`uint64` Chronicle fields generate as `bigint`** in the TypeScript proxies (not `number`, which silently truncated past `Number.MAX_SAFE_INTEGER`). Sequence numbers, large counters, and 64-bit ids surface as `bigint` — use `bigint` arithmetic, never `Number()`.
|
|
53
|
+
|
|
54
|
+
## User-facing strings (localization)
|
|
55
|
+
|
|
56
|
+
How user-visible text is handled is **product policy, not a Cratis framework rule** (see [general.md](../../../rules/general.md) — locales belong in a downstream app's own `.cratis/ai/`). Cratis itself has no mandatory i18n layer or `Strings` alias.
|
|
57
|
+
|
|
58
|
+
- If the app has a localization convention (e.g. a translation object behind a `strings`/`Strings` import, or any i18n library), follow it consistently and keep raw string literals to constant, non-user-facing values (CSS class names, `key` props, internal identifiers).
|
|
59
|
+
- If the app ships literal text, literal labels in JSX are fine.
|
|
60
|
+
|
|
61
|
+
Either way, the Cratis-generic rule is only that strings are handled consistently within the app — not a specific file layout or import alias.
|
|
62
|
+
|
|
63
|
+
## Arc Frontend Patterns
|
|
64
|
+
|
|
65
|
+
Arc's proxy generator bridges C# and TypeScript automatically — every `[Command]` and `[ReadModel]` becomes a TypeScript class with `.use()` hooks, `.execute()` methods, and change tracking. This is the foundation of full-stack type safety: change a C# record and the TypeScript proxy updates on the next `dotnet build`.
|
|
66
|
+
|
|
67
|
+
### Commands
|
|
68
|
+
|
|
69
|
+
Auto-generated from C# `[Command]` records. The `.use()` hook returns a tuple: the command instance (with change tracking) and a setter for property values.
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
const [command, setValues] = OpenAccount.use({ name: '', owner: '' });
|
|
73
|
+
await command.execute(); // Sends command to backend, returns CommandResult
|
|
74
|
+
await command.validate(); // Pre-flight validation only, no side effects
|
|
75
|
+
command.hasChanges; // True when any property differs from initial values
|
|
76
|
+
command.revertChanges(); // Reset all properties to initial values
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Queries
|
|
80
|
+
|
|
81
|
+
Auto-generated from C# `[ReadModel]` static query methods. Observable queries (returning `ISubject<T>` on the backend) auto-subscribe via WebSocket — the component re-renders when data changes on the server.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const [result, perform] = AllProjects.use();
|
|
85
|
+
// result.data — the query result
|
|
86
|
+
// result.isPerforming — true while loading
|
|
87
|
+
// result.hasData — true when data has arrived
|
|
88
|
+
// result.isSuccess — true when query completed without errors
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Paginated queries:
|
|
92
|
+
```tsx
|
|
93
|
+
const [result, , setPage] = AllProjects.useWithPaging(10);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### CommandScope
|
|
97
|
+
|
|
98
|
+
Wraps multiple command-using components, aggregating their `hasChanges` state and enabling bulk `execute()` and `revertChanges()`. Useful for forms that span multiple components.
|
|
99
|
+
|
|
100
|
+
### CommandForm
|
|
101
|
+
|
|
102
|
+
Declarative form component with built-in field types, validation timing (`validateOn: blur|change|both`), and automatic server-side validation feedback.
|
|
103
|
+
|
|
104
|
+
## Language — American English Only
|
|
105
|
+
|
|
106
|
+
All identifiers, comments, JSDoc, and string literals must use **American English** spelling (initialize, serialize, behavior, color, organization, center, modeling, dialog, license, judgment, gray). See [general.md](../../../rules/general.md) for the full guidance.
|
|
107
|
+
|
|
108
|
+
## Variables and Naming
|
|
109
|
+
|
|
110
|
+
- Prefer `const` over `let` over `var` when declaring variables.
|
|
111
|
+
- Never use shortened or abbreviated names for variables, parameters, or properties.
|
|
112
|
+
- Use full descriptive names: `deltaX` not `dx`, `index` not `idx`, `event` not `e`, `previous` not `prev`, `direction` not `dir`, `position` not `pos`, `contextMenu` not `ctx`/`ctxMenu`.
|
|
113
|
+
- The only acceptable short names are well-established domain terms (e.g. `id`, `url`, `min`, `max`).
|
|
114
|
+
|
|
115
|
+
## Imports and Compilation
|
|
116
|
+
|
|
117
|
+
- Never leave unused import statements in the code.
|
|
118
|
+
- Always ensure that the code compiles without warnings — use `yarn compile` to verify (successful runs produce no output).
|
|
119
|
+
- Review each file for lint compliance before finalizing.
|
|
120
|
+
- Never use placeholder or temporary types — use proper types from the start.
|
|
121
|
+
- **Never modify any file inside `node_modules/` or any build cache (e.g. `.vite/deps/`).** These are managed by the package manager and will be overwritten on the next install. If something appears broken in a library, look harder at the application code — especially when other usages of the same library work fine. Fixes belong in application code or upstream in the library's own repo.
|
|
122
|
+
|
|
123
|
+
## Folder Structure
|
|
124
|
+
|
|
125
|
+
- **Never give a `.tsx` the same basename as a `.ts` in the same folder.** The Arc proxy generator emits `<Slice>.ts` beside the slice's C#; a component named `<Slice>.tsx` next to it is **silently dropped from the program**: for one basename TypeScript keeps only the `.ts`, so the component's type errors are never reported and `tsc -b` stays green while the file is broken (reproduced on TypeScript 6.0.3 and 7.0.2 with `include: ["src/**/*"]`). At Arc v22.75.0 use `<CratisProxiesUseProxyFileSuffix>true</CratisProxiesUseProxyFileSuffix>` to emit `<Slice>.proxy.ts` with matching barrels; that is the clean generator fix. Otherwise name the component for what it renders (`Listing.tsx`, `RegisterAuthor.tsx`), never for the slice, and consider a repository spec that fails on any `.tsx` with a sibling `.ts` of the same name.
|
|
126
|
+
- Do not prefix a file, component, type, or symbol with the name of its containing folder or the concept it belongs to. Instead, use folder structure to provide that context.
|
|
127
|
+
- Favor functional folder structure over technical folder structure.
|
|
128
|
+
- Group files by the feature or concept they belong to, not by their technical role.
|
|
129
|
+
- Avoid folders like `components/`, `hooks/`, `utils/`, `types/` at the feature level.
|
|
130
|
+
|
|
131
|
+
## Advanced Type Safety
|
|
132
|
+
|
|
133
|
+
Additional patterns for common tricky scenarios:
|
|
134
|
+
|
|
135
|
+
**Storybook:**
|
|
136
|
+
- Use `React.ComponentType<Record<string, never>>` for components with no props.
|
|
137
|
+
- Always use `as unknown as` when converting component imports to avoid type mismatch errors.
|
|
138
|
+
- Properly type story args — never use `any`.
|
|
139
|
+
|
|
140
|
+
**External libraries with strict generic constraints:**
|
|
141
|
+
- Import necessary types (e.g. `Command` from `@cratis/arc/commands`) rather than asserting to `any`.
|
|
142
|
+
- Use type assertions through `unknown`: `props.command as unknown as Constructor<Command<...>>`.
|
|
143
|
+
- Extract tuple results explicitly rather than destructuring when type assertions are needed.
|
|
144
|
+
- Use proper library types when available; use specific property types (e.g. `{ canvas?: HTMLCanvasElement }`) over `any`.
|
|
145
|
+
|
|
146
|
+
**Dynamic and generic types:**
|
|
147
|
+
- Add type guards for unknown function parameters: `if (typeof accessor !== 'function') return ''`.
|
|
148
|
+
- Type parameters with fallbacks: `function<T = unknown>(accessor: ((obj: T) => unknown) | unknown)`.
|
|
149
|
+
- Cast arrays from `unknown` explicitly: `((obj as Record<string, unknown>).items || []) as string[]`.
|
|
150
|
+
- Use `String(value)` for string conversions in generic contexts.
|
|
151
|
+
- Use explicit Date parameter types: `new Date(value as string | number | Date)`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*"
|
|
3
|
+
paths:
|
|
4
|
+
- "**/*"
|
|
5
|
+
---
|
|
6
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
7
|
+
|
|
8
|
+
# Verification Discipline
|
|
9
|
+
|
|
10
|
+
Verification answers whether changed behavior works. It does not establish who
|
|
11
|
+
authored a file or preserve a chain of evidence about how it arrived.
|
|
12
|
+
|
|
13
|
+
- Run the narrowest relevant build, type check, lint, and specifications while iterating; explain when a wider gate is required before completion or push/PR.
|
|
14
|
+
- Run one phase per command with its real exit status. Budget targeted checks around 120 seconds and build/test phases around 300 seconds; explain any longer budget first, and obtain explicit approval before a phase exceeds 600 seconds. Stop on a failure; do not blindly retry or repeat passing tests on unchanged inputs without a flaky-test hypothesis or required matrix.
|
|
15
|
+
- Separate status/fetch from builds, Debug from Release, each test project, and frontend lint/compile/test/build. Do not combine these into an opaque command with a large outer timeout. Expose progress and cancellation; report the precise failed or timed-out phase and do not continue dependent phases after failure.
|
|
16
|
+
- Never use `build/test | grep | sort/head/tail` as gate evidence. Capture the producer's exit status before summarising output; `pipefail` alone is insufficient with early-closing consumers such as `head`. Printed zero-error counts are not proof of success. Preserve needed full diagnostics in task-scoped `.ai-work/` logs rather than hiding them in `/tmp`.
|
|
17
|
+
- Add a focused specification for every behavior or rejection rule you change.
|
|
18
|
+
- Keep each check deterministic and runnable locally and in CI.
|
|
19
|
+
- Never replace a real behavior check with a checksum, inventory, generated
|
|
20
|
+
receipt, or provenance record.
|
|
21
|
+
- Documentary evidence — a receipt, ledger, attestation, hash inventory,
|
|
22
|
+
snapshot, escrow copy, or ad-hoc `verify-*` script — is not verification and
|
|
23
|
+
is not produced unless a repository workflow (such as a governed release) or
|
|
24
|
+
the user asks for it. The check's own output is the evidence.
|
|
25
|
+
- Report the conclusion and any real uncertainty in a line or two, not the
|
|
26
|
+
audit trail. Show the output when asked, when a claim is contested, or when
|
|
27
|
+
the check failed. Report failures and skipped checks honestly.
|