@dextinity/agent-features 2.0.0-canary-20260806092023 → 10.0.0-beta.0

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.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@dextinity/agent-features",
3
- "version": "2.0.0-canary-20260806092023",
3
+ "version": "10.0.0-beta.0",
4
4
  "description": "Agent features (skills and rules) for Dextinity projects",
5
5
  "repository": {
6
6
  "directory": "packages/agent-features",
7
7
  "type": "git",
8
- "url": "https://github.com/vivid-planet/comet"
8
+ "url": "https://github.com/vivid-planet/dextinity"
9
9
  },
10
10
  "license": "BSD-2-Clause",
11
11
  "files": [
@@ -5,7 +5,7 @@ description: Run, restart, stop, and inspect logs/status of long-running develop
5
5
 
6
6
  # dev-pm Skill
7
7
 
8
- `dev-pm` (`@comet/dev-process-manager`) supervises long-running dev processes (servers, watchers, codegen, storybook, docker, …). Available scripts and groups are defined in `dev-pm.config.ts` at the repo root — read it to discover what can be started.
8
+ `dev-pm` (`dev-process-manager`) supervises long-running dev processes (servers, watchers, codegen, storybook, docker, …). Available scripts and groups are defined in `dev-pm.config.ts` at the repo root — read it to discover what can be started.
9
9
 
10
10
  ## Critical rules
11
11
 
@@ -29,10 +29,11 @@ after the system genuinely can't express what you need.
29
29
  3. **Consistency.** Every screen built from the same components and tokens looks and behaves the
30
30
  same way.
31
31
 
32
- This holds **even when a project's design deliberately differs** from the current library
33
- defaults: prefer the Dextinity component or token, and apply that project-specific difference by
34
- configuring the theme — not by re-styling individual components. Add custom styling only when
35
- explicitly instructed, or when no component, prop, or token can produce the result.
32
+ This holds **even when a project's design deliberately differs** from the current library defaults —
33
+ a permanent design decision, not a gap a later library upgrade will close. Prefer the Dextinity component
34
+ or token, and apply that project-specific difference by configuring the theme — not by re-styling
35
+ individual components. Add custom styling only when explicitly instructed, or when no component, prop,
36
+ or token can produce the result.
36
37
 
37
38
  ## Decision framework
38
39
 
@@ -291,7 +292,7 @@ Don't use `Grid` or `Stack` to lay out form fields: Dextinity stacks them vertic
291
292
  grouped with `FieldSet` or `FormSection`.
292
293
 
293
294
  `sx` is fine for an occasional layout property that no `Stack` or `Grid` prop covers, such as
294
- `flexGrow`. It is not for visual styling — that goes through `styled()`.
295
+ `flexGrow`. On your own markup, it is not for visual styling — that goes through `styled()`.
295
296
 
296
297
  ### Page structure: `MainContent`, `Toolbar`, and their parts
297
298
 
@@ -490,3 +491,54 @@ import { Delete } from "@dextinity/admin-icons";
490
491
 
491
492
  <Delete fontSize="small" color="error" />;
492
493
  ```
494
+
495
+ ## Customizing an existing Dextinity Admin component
496
+
497
+ When a Dextinity Admin component needs to look or behave differently than its defaults, customize it
498
+ through the mechanisms it already supports: the component's own props, a per-slot `slotProps` prop,
499
+ and theme-level `styleOverrides` and `defaultProps`. A _slot_ is a named inner element of a component;
500
+ only `root` is universal — a component lists its own slot names on its props type. Which mechanism you
501
+ pick depends on whether you're changing behavior or appearance.
502
+
503
+ ### Behavior
504
+
505
+ Start with the component's own props. To reach an inner element, use `slotProps`: it forwards props
506
+ to a named slot, letting you override that slot's props. This configures the component rather than
507
+ restyling it.
508
+
509
+ ```tsx
510
+ // Override an inner slot's props — here, disable the button behind the content
511
+ <ContentOverflow slotProps={{ clickableContent: { disabled: true } }}>{children}</ContentOverflow>
512
+ ```
513
+
514
+ ### Appearance
515
+
516
+ To change how a Dextinity component looks, configure the theme rather than the component itself — the core
517
+ principle's rule for a project-specific design difference. `createDextinityTheme`'s `components` map takes
518
+ a `DextinityAdmin*` key (MUI components use their `Mui*` key); `styleOverrides` restyles a component's
519
+ slots and `defaultProps` sets default prop values, such as swapping an icon through `iconMapping`.
520
+ Both apply to every instance, so the deviation stays consistent and is defined in one reviewable place.
521
+
522
+ Styling a single instance directly is the rare exception — for a change genuinely specific to that
523
+ instance, or when you're explicitly told to. Which tool you use is then the same as anywhere else:
524
+ `sx` (or `slotProps.<slot>.sx` for a slot) for small layout, `styled()` for other custom styling, per
525
+ the styling section above. Use this only for a true single-instance change; a difference that recurs
526
+ belongs in the theme, not repeated on each instance.
527
+
528
+ ```tsx
529
+ // Avoid — a styled() wrapper for a design difference that belongs in the theme
530
+ const HighlightedContentOverflow = styled(ContentOverflow)`
531
+ background-color: ${({ theme }) => theme.palette.grey[50]};
532
+ `;
533
+
534
+ // Prefer — configure the theme, applied to every instance
535
+ const theme = createDextinityTheme({
536
+ components: {
537
+ DextinityAdminContentOverflow: {
538
+ styleOverrides: {
539
+ root: ({ theme }) => ({ backgroundColor: theme.palette.grey[50] }),
540
+ },
541
+ },
542
+ },
543
+ });
544
+ ```
@@ -41,7 +41,7 @@ This applies to seemingly simple things: `border-radius`, `background-image`, `f
41
41
 
42
42
  ### Library Documentation
43
43
 
44
- Full documentation for `@dextinity/mail-react`: https://docs.comet-dxp.com/docs/features-modules/building-html-emails/
44
+ Full documentation for `@dextinity/mail-react`: https://cms-docs.dextinity.com/docs/features-modules/building-html-emails/
45
45
 
46
46
  ---
47
47
 
@@ -125,6 +125,24 @@ Always use `theme.breakpoints.*.belowMediaQuery` inside `registerStyles` instead
125
125
 
126
126
  ## Common Pitfalls
127
127
 
128
+ ### Start Raw Content Inside a Column With `<tr>`
129
+
130
+ `mj-column` wraps every child in its own `<tr><td>` — except `MjmlRaw` content, which goes straight into the column's table unwrapped. A `<table>`, `<div>`, or `<img>` in that position ends up outside the column's table instead, and MJML reports no error. This covers the `Html*` components. Open with a `<tr>` and put the markup in a `<td>`:
131
+
132
+ ```tsx
133
+ <MjmlColumn>
134
+ <MjmlRaw>
135
+ <tr>
136
+ <td>{/* your raw markup */}</td>
137
+ </tr>
138
+ </MjmlRaw>
139
+ </MjmlColumn>
140
+ ```
141
+
142
+ `HtmlText` is the exception: it renders the `<td>` itself, so a surrounding `<tr>` is all it needs — unless its `element` prop renders something else, which needs a `<td>` again.
143
+
144
+ `MjmlColumn` and `MjmlHero` are both affected — `MjmlSection` and `MjmlWrapper` already place their children inside a shared cell, so any root element is safe there. `MjmlDivider` supplies both the row and the cell; use it instead of a hand-wrapped `HtmlDivider` whenever you are in an `MjmlColumn`.
145
+
128
146
  ### Avoid Block-Level HTML Elements Inside Ending Tags
129
147
 
130
148
  Don't use `<p>`, `<h1>`, `<h2>`, or other block-level HTML elements inside ending tags. They have wildly inconsistent default margins and spacing across email clients and add no rendering value in email HTML. Instead, use `<td>`, `<div>`, and `<span>` for structure, and build your typography hierarchy through `MjmlText`/`HtmlText` variants rather than HTML semantics. If a block-level element is truly unavoidable, always reset its margins inline: `style={{ margin: 0 }}`.
@@ -303,6 +321,8 @@ All components are imported from `@dextinity/mail-react` — never from `@faire/
303
321
  | `MjmlPixelImageBlock` | re-exported `MjmlImage` | an `MjmlColumn` (standard MJML layout) |
304
322
  | `HtmlPixelImageBlock` | raw `<img>` | raw HTML or MJML ending tags such as `MjmlRaw` |
305
323
 
324
+ Inside `MjmlRaw` in an `MjmlColumn`, `HtmlPixelImageBlock` needs its own `<tr>` and `<td>` — see _Start Raw Content Inside a Column With `<tr>`_ above.
325
+
306
326
  ```tsx
307
327
  <MjmlSection indent>
308
328
  <MjmlColumn>
@@ -361,6 +381,8 @@ export const { MjmlRichTextBlock, HtmlRichTextBlock } = createRichTextBlock({
361
381
  | `MjmlRichTextBlock` | `MjmlText` | an `MjmlColumn` (standard MJML layout) |
362
382
  | `HtmlRichTextBlock` | `HtmlText` (`<div>`) | raw HTML or MJML ending tags such as `MjmlRaw` |
363
383
 
384
+ Inside `MjmlRaw` in an `MjmlColumn`, `HtmlRichTextBlock` needs its own `<tr>` and `<td>` — see _Start Raw Content Inside a Column With `<tr>`_ above.
385
+
364
386
  Usage sites pass only `data`:
365
387
 
366
388
  ```tsx
@@ -392,6 +414,8 @@ Key behaviors:
392
414
  );
393
415
  ```
394
416
 
417
+ For a list block type, target `.<className> .richTextBlock__listItemText` instead of `> div` — the list's cells carry their own font styles, which outrank a rule on the block's element.
418
+
395
419
  - **Multiple configurations per app.** Each factory call is independent — rename the destructured components per use case:
396
420
 
397
421
  ```tsx
@@ -426,9 +450,11 @@ Key behaviors:
426
450
  });
427
451
  ```
428
452
 
429
- - **Lists** render flat (`<ul>` / `<ol>` inside one text component per list); nesting by draft depth isn't supported.
453
+ - **Lists** render as a table inside one text component, with a row per item, a marker cell and a text cell — the indent and the marker gap are cell padding, which is the only spacing Outlook on Windows applies reliably.
454
+ - **List spacing** comes from the theme's `list.indent` (before the marker), `list.markerGap` (between the marker and the text) and `list.itemSpacing` (between items), all responsive and all applying to every list the block renders. To override it, register a rule scoped to a list's type or variant modifier with `{ inline: true }`, which has MJML write the declaration into the cell's `style` attribute at compile time so it also reaches Outlook.
455
+ - **List markers** come from the theme's `list.unorderedMarker` and `list.orderedMarker`, each either a fixed node (`unorderedMarker: "▪"`) or a function of the item's `index` and its list's `depth`.
430
456
  - Spacing between blocks comes from the theme's `bottomSpacing` (the last block gets none); headings are styled text, not semantic `<h1>` elements.
431
- - Rendered elements carry `richTextBlock__text`, `richTextBlock__list`, `richTextBlock__listItem`, and `richTextBlock__link` class names for targeting with `registerStyles`.
457
+ - Rendered elements carry `richTextBlock__text`, `richTextBlock__list`, `richTextBlock__listItem`, `richTextBlock__listItemMarker`, `richTextBlock__listItemText`, and `richTextBlock__link` class names for targeting with `registerStyles`. The list table also carries `richTextBlock__list--ordered` or `richTextBlock__list--unordered`, plus a modifier naming the text variant its items render with, such as `richTextBlock__list--variantBody`. Its rows carry `richTextBlock__listItem--itemSpacing`, or `richTextBlock__listItem--blockSpacing` on the last row when spacing follows the list. Its cells restate the text styles inline, so a rule targeting list text needs `!important`.
432
458
 
433
459
  ---
434
460
 
@@ -617,5 +643,5 @@ Storybook previews show how the email renders in a web browser, but email client
617
643
 
618
644
  The `@dextinity/mail-react` package focuses on building email markup. For sending emails and managing templates in a Dextinity project:
619
645
 
620
- - **Mail Templates Module** — server-side template registration, dependency injection, and sending. Integrates with `@dextinity/mail-react` via `renderMailHtml`. Docs: https://docs.comet-dxp.com/docs/features-modules/mail-templates-module/
621
- - **Mailer Module** — lower-level mail sending service. Docs: https://docs.comet-dxp.com/docs/features-modules/mailer-module/
646
+ - **Mail Templates Module** — server-side template registration, dependency injection, and sending. Integrates with `@dextinity/mail-react` via `renderMailHtml`. Docs: https://cms-docs.dextinity.com/docs/features-modules/mail-templates-module/
647
+ - **Mailer Module** — lower-level mail sending service. Docs: https://cms-docs.dextinity.com/docs/features-modules/mailer-module/
@@ -43,11 +43,28 @@ const theme = createTheme({
43
43
  sizes: {
44
44
  contentIndentation: { default: 40, tablet: 30, mobile: 20 },
45
45
  },
46
+ list: {
47
+ indent: { default: 24, tablet: 16, mobile: 8 },
48
+ },
46
49
  });
47
50
  ```
48
51
 
49
52
  The `default` key provides the base value (rendered inline). Other keys generate media query overrides automatically.
50
53
 
54
+ ### List Markers
55
+
56
+ `list.unorderedMarker` and `list.orderedMarker` set the markers of the lists the RichText block renders: a fixed node, or a function receiving the item's zero-based `index` and the `depth` of its list. Use plain HTML and React elements, not MJML components:
57
+
58
+ ```tsx
59
+ const theme = createTheme({
60
+ list: {
61
+ unorderedMarker: ({ depth }) => ["▪", "–", "·"][depth % 3],
62
+ // 97 is the code of "a", so nested items are lettered a., b., c.
63
+ orderedMarker: ({ index, depth }) => (depth === 0 ? `${index + 1}.` : `${String.fromCharCode(97 + index)}.`),
64
+ },
65
+ });
66
+ ```
67
+
51
68
  ---
52
69
 
53
70
  ## Module Augmentation Interfaces
@@ -279,13 +296,13 @@ Themed text for use inside ending tags (`MjmlText`, `MjmlRaw`) or custom HTML st
279
296
  **CSS classes:** `.htmlText`, `.htmlText--{variant}`, `.htmlText--bottomSpacing`.
280
297
 
281
298
  ```tsx
282
- <MjmlRaw>
283
- <table>
299
+ <MjmlColumn>
300
+ <MjmlRaw>
284
301
  <tr>
285
- <HtmlText variant="body">Themed text inside a raw table</HtmlText>
302
+ <HtmlText variant="body">Themed text in a row of the column's table</HtmlText>
286
303
  </tr>
287
- </table>
288
- </MjmlRaw>
304
+ </MjmlRaw>
305
+ </MjmlColumn>
289
306
 
290
307
  <MjmlText>
291
308
  <HtmlText element="div" variant="caption">Rendered as a div</HtmlText>
@@ -14,10 +14,10 @@ Do NOT use for minor or patch upgrades, or for ongoing feature work on a project
14
14
  ## Locate the migration guide
15
15
 
16
16
  1. **Find out the target major** from the user if not specified.
17
- 2. **Browse the index:** https://github.com/vivid-planet/comet/tree/main/docs/docs/7-migration-guide — use a GitHub MCP tool if available, otherwise `WebFetch`.
17
+ 2. **Browse the index:** https://github.com/vivid-planet/dextinity/tree/main/docs/docs/7-migration-guide — use a GitHub MCP tool if available, otherwise `WebFetch`.
18
18
  3. **Download the raw Markdown** so all content is in context:
19
19
  ```
20
- https://raw.githubusercontent.com/vivid-planet/comet/refs/heads/main/docs/docs/7-migration-guide/migration-from-v{N}-to-v{N+1}.md
20
+ https://raw.githubusercontent.com/vivid-planet/dextinity/refs/heads/main/docs/docs/7-migration-guide/migration-from-v{N}-to-v{N+1}.md
21
21
  ```
22
22
  4. **If no guide exists** for the target version, stop and tell the user. Don't migrate without an official guide.
23
23
 
@@ -73,7 +73,7 @@ Record the resolved site list durably (e.g. a note on the first `TaskCreate` tas
73
73
 
74
74
  If a step is ambiguous or doesn't match the project, consult before guessing:
75
75
 
76
- - **https://github.com/vivid-planet/comet** — the monorepo. Check the source of the package the guide discusses for the new public API shape.
76
+ - **https://github.com/vivid-planet/dextinity** — the monorepo. Check the source of the package the guide discusses for the new public API shape.
77
77
  - **https://github.com/vivid-planet/comet-starter** — the canonical reference project, always kept on the current major. Use it for questions like "how should `tsconfig.json` look after this migration?"
78
78
 
79
79
  Prefer the GitHub MCP; fall back to `WebFetch` on `raw.githubusercontent.com`. If still unclear, ask the user — don't guess.
@@ -16,7 +16,7 @@ Two rules hold across every `@dextinity/*` core package in the project, before a
16
16
  - **Pinned versions only.** Every core `@dextinity/*` entry must be an exact version (e.g. `8.21.0`), never a range (`^8.21.0`, `~8.21.0`, `>=…`). If you see a caret or tilde on a core package, the project is in a broken state — stop and tell the user.
17
17
  - **All core packages on the same version.** Every core `@dextinity/*` package in the project must be pinned to the same version across every `package.json`. There is no supported mix-and-match.
18
18
 
19
- These rules apply only to the core set (packages released together from the Dextinity monorepo). Satellite packages like `@comet/dev-process-manager` are out of scope — see Step 1.
19
+ These rules apply only to the core set (packages released together from the Dextinity monorepo). Any other `@dextinity/*` package a project happens to depend on is out of scope — see Step 1.
20
20
 
21
21
  ## When to use
22
22
 
@@ -60,8 +60,8 @@ grep -n '"@dextinity/' package.json api/package.json admin/package.json \
60
60
 
61
61
  Notes:
62
62
 
63
- - Not every `@dextinity/*` package follows the core release cadence. Packages that live outside the core monorepo (for example `@comet/dev-process-manager`) may use a different versioning scheme (often `^x.y.z`). **Only** bump packages whose current version matches the core Dextinity version (the one shared by `@dextinity/cms-api`, `@dextinity/admin`, `@dextinity/site-nextjs`, etc.). Leave the others untouched.
64
- - Use the invariants to tell core from satellite: core packages are all pinned to the same exact version, with no caret or tilde. Anything with a range or a different version is not core — verify before touching it.
63
+ - Not every `@dextinity/*` dependency you find follows the core release cadence. **Only** bump packages whose current version matches the core Dextinity version (the one shared by `@dextinity/cms-api`, `@dextinity/admin`, `@dextinity/site-nextjs`, etc.). Leave the others untouched.
64
+ - Use the invariants to tell core from non-core: core packages are all pinned to the same exact version, with no caret or tilde. Anything with a range or a different version is not core — verify before touching it.
65
65
  - If you find core packages on different versions, or any core package using a range (`^`, `~`), the project violates the invariants. Stop and tell the user — don't paper over it by bumping.
66
66
 
67
67
  Confirm the **current major** from the version string (e.g. `8.20.4` → major `8`).
@@ -100,7 +100,7 @@ grep -n '<OLD_VERSION>' package.json api/package.json admin/package.json \
100
100
 
101
101
  If every match is a `@dextinity/*` line, you can safely edit each file. If there are non-`@dextinity` matches, edit the `@dextinity` lines individually.
102
102
 
103
- **Do not touch** packages like `@comet/dev-process-manager` that don't share the core version — see Step 1.
103
+ **Do not touch** `@dextinity/*` packages that don't share the core version — see Step 1.
104
104
 
105
105
  ---
106
106
 
@@ -181,11 +181,11 @@ Tell the user:
181
181
 
182
182
  ## Common pitfalls
183
183
 
184
- | Pitfall | How to avoid |
185
- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
186
- | Picking a canary/beta as "newest" | Filter out any version containing `-` in Step 2. |
187
- | Bumping `@comet/dev-process-manager` (or similar) by accident | Only bump packages pinned to the shared core version — see Step 1. |
188
- | Forgetting the root `package.json` | The repo root has its own `package.json` with `@dextinity/cli`. Always include it in the grep. |
189
- | Assuming "up to date" means the install did nothing | It means the lockfile already satisfies the new range. Verify with `grep` against the lockfile. |
190
- | Running installs in parallel in a sandbox | If `&` backgrounding fails, just run the installs sequentially. Takes a bit longer, works reliably. |
191
- | Crossing a major version | This skill is minor/patch only. Stop and warn the user. |
184
+ | Pitfall | How to avoid |
185
+ | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
186
+ | Picking a canary/beta as "newest" | Filter out any version containing `-` in Step 2. |
187
+ | Bumping a non-core `@dextinity/*` package by accident | Only bump packages pinned to the shared core version — see Step 1. |
188
+ | Forgetting the root `package.json` | The repo root has its own `package.json` with `@dextinity/cli`. Always include it in the grep. |
189
+ | Assuming "up to date" means the install did nothing | It means the lockfile already satisfies the new range. Verify with `grep` against the lockfile. |
190
+ | Running installs in parallel in a sandbox | If `&` backgrounding fails, just run the installs sequentially. Takes a bit longer, works reliably. |
191
+ | Crossing a major version | This skill is minor/patch only. Stop and warn the user. |