@ethlete/agent-rules 0.1.0-next.15 → 0.1.0-next.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @ethlete/agent-rules
2
2
 
3
+ ## 0.1.0-next.16
4
+
5
+ ### Patch Changes
6
+
7
+ - Name the `take-until-destroyed-last` lint rule in the styleguide lint lookup and the RxJS skill.
8
+ - A design call now lists its drawings as `variants` in `variant-<key>.ts` files, and `et design check` takes `--variant`; the old `options` key and `--option` flag are gone.
9
+
3
10
  ## 0.1.0-next.15
4
11
 
5
12
  ### Minor Changes
@@ -12,12 +12,12 @@ A design exploration is a dialog. **The user is the designer. You find and frame
12
12
  chooses.** A finding is not a licence to pick the fix.
13
13
 
14
14
  The unit of work is a **call**: one open question, with every answer drawn side by side at
15
- the same geometry. An option wins or loses only against the other options of its call.
15
+ the same geometry. A variant wins or loses only against the other variants of its call.
16
16
 
17
17
  ## The rules
18
18
 
19
- 1. **One open call at a time.** Take one question. Draw its options. Stop.
20
- 2. **Put the options in the call, then name your pick.** Two to four options, drawn for
19
+ 1. **One open call at a time.** Take one question. Draw its variants. Stop.
20
+ 2. **Put the variants in the call, then name your pick.** Two to four variants, drawn for
21
21
  real, side by side, labelled, with what each one costs. Your pick is a proposal.
22
22
  3. **Commit only when the user says commit.**
23
23
  4. **A clear rejection starts the next call.** Settle and record the rejected call, then draw
@@ -33,31 +33,31 @@ finished while the user is still talking about it.
33
33
 
34
34
  - The question, in one sentence.
35
35
  - The call slug to look at.
36
- - The options, labelled A, B, C, one line each.
36
+ - The variants, labelled A, B, C, one line each.
37
37
  - Your pick, one line on why.
38
38
  - Nothing else. No next step, no second finding.
39
39
 
40
40
  **Do not send a screenshot.** The user keeps the page open. Screenshot only for your own
41
- check that an option renders.
41
+ check that a variant renders.
42
42
 
43
43
  If a second defect appears, add it to the open list and give it one line. Do not draw it.
44
44
 
45
- ## Where the options are drawn
45
+ ## Where the variants are drawn
46
46
 
47
47
  The exploration's plan file names the tool. Two shapes exist.
48
48
 
49
- **A repository with a `.ethlete/design` folder** draws a call per page, each option in its own
49
+ **A repository with a `.ethlete/design` folder** draws a call per page, each variant in its own
50
50
  iframe. The tool is `et design`, from `@ethlete/cli`, so the repository itself needs no design
51
51
  tooling. A call argues in the repository it is about:
52
52
 
53
53
  ```
54
54
  .ethlete/design/
55
- config.json the port, the default call, and one entry per project
55
+ config.json the port, the default call, and one entry per project
56
56
  calls/<project>/<group>/<slug>/
57
- call.ts the eyebrow, the headline, the intro, frameWidth, the options and the round prose
58
- fixture.ts the data every option shares
59
- option-a.ts one default-exported drawing per option
60
- option-b.ts
57
+ call.ts the eyebrow, the headline, the intro, frameWidth, the variants and the round prose
58
+ fixture.ts the data every variant shares
59
+ variant-a.ts one default-exported drawing per variant
60
+ variant-b.ts
61
61
  ```
62
62
 
63
63
  The first segment of a slug is the **project**. `config.json` gives each project its own
@@ -73,16 +73,16 @@ Ethlete Studio carries its own copy of the tool, so it draws a checkout that ins
73
73
  The machine still needs Node, and the render stage still needs `playwright` where the copy in
74
74
  use can reach it.
75
75
 
76
- `call.ts` calls `defineCall` from `@design-explore`. Each option carries a `key`, a `name`,
76
+ `call.ts` calls `defineCall` from `@design-explore`. Each variant carries a `key`, a `name`,
77
77
  a `claim`, a `cost`, an optional `verdict` of `chosen` or `rejected`, and a `load` that
78
- imports its own module. The host greys a rejected option and shows it on hover.
78
+ imports its own module. The host greys a rejected variant and shows it on hover.
79
79
 
80
- In a call that runs past about a dozen options, every option names the pass that drew it with
80
+ In a call that runs past about a dozen variants, every variant names the pass that drew it with
81
81
  `round: 'r3'`. **That tag is the only thing that makes a round exist.** The host reads the
82
- options, draws one band per round in the order the options introduce them, and lists those
83
- same bands in the sidebar, so a new option can never leave the menu stale. A round whose
84
- options all carry a verdict is **settled**: the page folds it down to its winner plus one row
85
- per rejected option, and a link opens it again.
82
+ variants, draws one band per round in the order the variants introduce them, and lists those
83
+ same bands in the sidebar, so a new variant can never leave the menu stale. A round whose
84
+ variants all carry a verdict is **settled**: the page folds it down to its winner plus one row
85
+ per rejected variant, and a link opens it again.
86
86
 
87
87
  A call whose rounds have all ruled is **resolved**. Its winners usually form a chain, each one
88
88
  the last plus a change, so the page stops drawing them: it leads with a **Result** band holding
@@ -92,36 +92,36 @@ rows. A key in the chain opens the round that drew it.
92
92
  `rounds` is prose only. Each entry gives a `key`, a `title` and a `note` saying what came out
93
93
  of that pass, which is how the intro stays short and each pass reads as a reply to the one
94
94
  before. An untagged round still draws and still gets a menu row - it says the bare key until
95
- somebody writes the entry. A `rounds` entry that no option names is stale prose, and the host
95
+ somebody writes the entry. A `rounds` entry that no variant names is stale prose, and the host
96
96
  and the check both report it. Write the note in the same pass that sets the verdicts, never
97
97
  before the user rules.
98
98
 
99
- A call with one option and no `claim` is a **view**: one reference picture, drawn full
99
+ A call with one variant and no `claim` is a **view**: one reference picture, drawn full
100
100
  width with no verdict tag. Use it for a picture that answers no question.
101
101
 
102
102
  Two views, and a way to compare:
103
103
 
104
104
  - **rounds** is the default. Round headings, the result band, and the folding above.
105
- - **all N** is a contact sheet: every option in the call at about a third size, in one grid, so
106
- a call of two dozen fits on a screen or two. Use it to find the options worth a close look.
107
- - Clicking an option's name anywhere - a heading, a folded row, a thumbnail - puts it in the
105
+ - **all N** is a contact sheet: every variant in the call at about a third size, in one grid, so
106
+ a call of two dozen fits on a screen or two. Use it to find the variants worth a close look.
107
+ - Clicking a variant's name anywhere - a heading, a folded row, a thumbnail - puts it in the
108
108
  **compare overlay** at the top of the page. Two drawings that differ by a few pixels can only
109
109
  be told apart in one place, so the overlay stacks every pick in one box at full size and the
110
110
  reader switches between them: click the box or press space to blink, and with two picks the
111
111
  arrow keys wipe a seam across. Nothing is scaled and nothing moves. The picks live in the URL
112
112
  under `pick`, so a comparison is a link you can send.
113
113
 
114
- Three constraints the tool puts on an option file:
114
+ Three constraints the tool puts on a variant file:
115
115
 
116
116
  - **Never import a package barrel.** The libraries resolve to source, so one barrel makes
117
117
  the browser request every module in the library, and the requests fail with
118
118
  `ERR_INSUFFICIENT_RESOURCES`. Import the one file you need.
119
- - **The fixture is shared, and an option may not change it.** Options drawn at three
119
+ - **The fixture is shared, and a variant may not change it.** Variants drawn at three
120
120
  geometries cannot be compared.
121
- - **One file per option**, so several agents can draw at once, and a broken option breaks
121
+ - **One file per variant**, so several agents can draw at once, and a broken variant breaks
122
122
  its own frame only.
123
123
 
124
- **A repository with a sketch Storybook** draws every option in the **same** story, side by
124
+ **A repository with a sketch Storybook** draws every variant in the **same** story, side by
125
125
  side, under the real geometry the thing ships in. The default Storybook is
126
126
  {%storybookUrl%}; an app with its own sketch Storybook names its port in the plan file.
127
127
 
@@ -130,7 +130,7 @@ Either way:
130
130
  - Sketches take inputs only and stay out of the application's build.
131
131
  - Prototype, never refactor. Do not touch the shipped component until the treatment is
132
132
  settled.
133
- - Keep the rejected options drawn, marked as rejected.
133
+ - Keep the rejected variants drawn, marked as rejected.
134
134
 
135
135
  ## Check before you look
136
136
 
@@ -159,30 +159,30 @@ transpile without type checking, so the render reports `ok` on a file that does
159
159
  compile. Open it only when the check passes and the drawing still does not appear:
160
160
 
161
161
  ```bash
162
- et design check --call <slug> # every option of the call
163
- et design check --call <slug> --option b # one of them
162
+ et design check --call <slug> # every variant of the call
163
+ et design check --call <slug> --variant b # one of them
164
164
  node check-story.mjs --tsconfig <path> --story <story-id>
165
165
  ```
166
166
 
167
167
  ## Delegating a call
168
168
 
169
- A call has one job per option, so it fans out. Every brief names `model: opus`.
169
+ A call has one job per variant, so it fans out. Every brief names `model: opus`.
170
170
 
171
- 1. **One agent per option.** Give it the call folder, the option key, the fixture it must
171
+ 1. **One agent per variant.** Give it the call folder, the variant key, the fixture it must
172
172
  not change, and the one claim its drawing has to support. Tell it to write its own
173
- option file and nothing else, so two agents never touch one file.
173
+ variant file and nothing else, so two agents never touch one file.
174
174
  2. **One check-and-fix agent, after the drawing agents return.** Give it the changed files
175
175
  and the call slug. It runs the check above, fixes what it reports, and repeats until the
176
- check says `ok`. It may not change what an option draws, only what stops it rendering.
176
+ check says `ok`. It may not change what a variant draws, only what stops it rendering.
177
177
  3. **One write-up agent, once the user settles the call.** Give it the verdict in the
178
178
  user's own words and the plan file. It records what won, what lost and why, it sets each
179
- option's `verdict` in `call.ts`, and it writes that round's `note`. It runs while you open
179
+ variant's `verdict` in `call.ts`, and it writes that round's `note`. It runs while you open
180
180
  the next call.
181
181
 
182
182
  ## Screenshots
183
183
 
184
184
  **Off by default.** The user has the page open and sends you a picture when something looks
185
- wrong. Take one only when the code cannot tell you whether two options really differ, and
185
+ wrong. Take one only when the code cannot tell you whether two variants really differ, and
186
186
  never to put in front of the user. Copy {%resource:shoot-template.mjs%} to the repository
187
187
  root.
188
188
 
@@ -198,6 +198,6 @@ node shoot.mjs <story-id> 1100 760 out.png
198
198
  ## Writing it down
199
199
 
200
200
  Every settled call goes in the exploration's plan file: what won, what lost, and why. Keep
201
- an **Open** list for the calls not yet made. A rejected option written down stops the next
201
+ an **Open** list for the calls not yet made. A rejected variant written down stops the next
202
202
  session from drawing it again. After a clear rejection, use that record to frame and draw the
203
203
  next call; do not wait for the user to type “continue”.
@@ -40,9 +40,10 @@ const data = toSignal(obs$);
40
40
  Do not use `takeWhile` as destruction cleanup: without another emission it stays
41
41
  subscribed. Use `take(1)` or `first()` only when one emission is the operation's
42
42
  intended semantics.
43
- - **Place lifecycle teardown after higher-order operators** such as `switchMap`, so their
44
- inner subscriptions are also covered. Other limiting and finalization operators do not
45
- have a universal “last” position; place them where their semantics belong.
43
+ - **`takeUntilDestroyed()` goes last in its pipe** (`ethlete/take-until-destroyed-last`), so
44
+ higher-order operators such as `switchMap` and their inner subscriptions are covered.
45
+ Other limiting and finalization operators do not have a universal “last” position;
46
+ place them where their semantics belong.
46
47
  - **Side effects go in `tap()`**, never in the `subscribe()` callback - keep
47
48
  `subscribe()` empty.
48
49
  - **Don't reach for RxJS inside `effect()`/`computed()`.** Subscribing per run
@@ -28,6 +28,7 @@ convention. Run lint with `--fix`; do not hand-check this table before linting.
28
28
  | No redundant `@internal` | `ethlete/no-redundant-internal` |
29
29
  | Observable names end in `$` | `ethlete/require-dollar-suffix` |
30
30
  | No subscribe body, subscribe in pipe, or RxJS in signal derivations | `ethlete/no-subscribe-with-body`, `ethlete/no-subscribe-in-pipe`, `ethlete/no-rxjs-in-effect` |
31
+ | `takeUntilDestroyed()` is the last operator in its pipe | `ethlete/take-until-destroyed-last` |
31
32
  | Effect teardown uses `onCleanup` or `DestroyRef` | `ethlete/no-effect-cleanup-return` |
32
33
  | Prefer `linkedSignal` for writable derived state | `ethlete/prefer-linked-signal` |
33
34
  | Global component CSS encapsulation | `ethlete/require-view-encapsulation-none` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethlete/agent-rules",
3
- "version": "0.1.0-next.15",
3
+ "version": "0.1.0-next.16",
4
4
  "license": "MIT",
5
5
  "type": "commonjs",
6
6
  "exports": {