@astryxdesign/cli 0.1.7-canary.cecb773 → 0.1.7-canary.d91c851

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.
Files changed (49) hide show
  1. package/package.json +9 -9
  2. package/src/codemods/__tests__/registry.test.mjs +1 -0
  3. package/src/codemods/registry.mjs +1 -0
  4. package/src/codemods/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +42 -7
  5. package/src/codemods/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +43 -0
  6. package/src/codemods/transforms/v0.1.0/drop-xds-prefix-imports.mjs +102 -3
  7. package/src/codemods/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +72 -6
  8. package/src/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +161 -0
  9. package/src/codemods/transforms/v0.1.8/index.mjs +19 -0
  10. package/src/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +234 -0
  11. package/src/commands/agent-docs.mjs +72 -0
  12. package/src/commands/agent-docs.test.mjs +86 -0
  13. package/src/commands/upgrade.mjs +130 -27
  14. package/src/commands/upgrade.test.mjs +154 -0
  15. package/src/types/upgrade.d.ts +39 -2
  16. package/templates/blocks/components/Avatar/AvatarFallbackChain.tsx +4 -4
  17. package/templates/blocks/components/Avatar/AvatarGroup.tsx +2 -2
  18. package/templates/blocks/components/Avatar/AvatarInitialsFallback.tsx +1 -1
  19. package/templates/blocks/components/Avatar/AvatarShowcase.tsx +4 -4
  20. package/templates/blocks/components/Avatar/AvatarUserCard.tsx +1 -1
  21. package/templates/blocks/components/Avatar/AvatarWithImage.tsx +4 -4
  22. package/templates/blocks/components/Avatar/AvatarWithStatus.tsx +3 -3
  23. package/templates/blocks/components/AvatarGroup/AvatarGroupShowcase.tsx +2 -2
  24. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowCustomText.tsx +1 -1
  25. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowDefault.tsx +1 -1
  26. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowShowcase.tsx +2 -2
  27. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotShowcase.tsx +3 -3
  28. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +3 -3
  29. package/templates/blocks/components/Carousel/CarouselSnap.tsx +1 -1
  30. package/templates/blocks/components/ChatMessage/ChatMessageAvatarName.tsx +2 -2
  31. package/templates/blocks/components/ChatMessage/ChatMessageMultiBubble.tsx +1 -1
  32. package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleGrouping.tsx +1 -1
  33. package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleMetadata.tsx +1 -1
  34. package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +5 -9
  35. package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -1
  36. package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -1
  37. package/templates/blocks/components/Item/ItemWithMedia.tsx +2 -2
  38. package/templates/blocks/components/ListItem/ListItemWithMedia.tsx +2 -2
  39. package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -6
  40. package/templates/blocks/components/Stack/StackFillItem.tsx +2 -6
  41. package/templates/blocks/components/TypeaheadItem/TypeaheadItemShowcase.tsx +1 -1
  42. package/templates/pages/ai-chat/page.tsx +4 -4
  43. package/templates/pages/dashboard-portfolio/page.tsx +3 -11
  44. package/templates/pages/detail-page/page.tsx +5 -12
  45. package/templates/pages/documentation-design/page.tsx +1 -1
  46. package/templates/pages/messaging-shell/page.tsx +6 -8
  47. package/templates/pages/table-grouped/page.tsx +9 -14
  48. package/templates/pages/table-page/page.tsx +7 -9
  49. package/templates/pages/table-page-heatmap-status/page.tsx +5 -13
@@ -6,6 +6,7 @@ import * as path from 'node:path';
6
6
  import * as os from 'node:os';
7
7
  import {Command} from 'commander';
8
8
  import {registerUpgrade} from './upgrade.mjs';
9
+ import {generateCompressedIndex} from './agent-docs.mjs';
9
10
 
10
11
  let tmpDir;
11
12
  let originalCwd;
@@ -158,3 +159,156 @@ describe('upgrade --list dedup', () => {
158
159
  expect(names.length).toBe(unique.size);
159
160
  });
160
161
  });
162
+
163
+ // Issue #4168 — `upgrade` must refresh the managed agent-docs block after a
164
+ // version bump, on EVERY path (the block documents the installed library, not
165
+ // the codemod outcome), and must NOT write during a dry run.
166
+ describe('upgrade agent-docs refresh (#4168)', () => {
167
+ /** Write an agent-doc file with a managed block generated for `version`. */
168
+ function writeAgentBlock(rel, version) {
169
+ const filePath = path.join(tmpDir, rel);
170
+ fs.mkdirSync(path.dirname(filePath), {recursive: true});
171
+ fs.writeFileSync(filePath, `# Doc\n\n${generateCompressedIndex(version)}\n`);
172
+ }
173
+
174
+ it('refreshes a stale block with --apply, even when there are no codemods (up-to-date path)', async () => {
175
+ writePkg();
176
+ writeInstalledCore('0.0.15');
177
+ writeAgentBlock('AGENTS.md', '0.0.1');
178
+
179
+ // --from == installed → up-to-date short-circuit: no codemods run, yet the
180
+ // stale block must still be brought current. This is the exact gap in #4168.
181
+ const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
182
+
183
+ expect(result.type).toBe('upgrade.status');
184
+ expect(result.data.status).toBe('up_to_date');
185
+ expect(result.data.agentDocs.status).toBe('stale');
186
+ expect(result.data.agentDocs.action).toBe('refreshed');
187
+ expect(result.data.agentDocs.refreshed).toBe(true);
188
+ expect(result.data.agentDocs.fromVersions).toEqual(['0.0.1']);
189
+ expect(result.data.agentDocs.files).toContain('AGENTS.md');
190
+
191
+ const content = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
192
+ expect(content).toMatch(/Astryx v0\.0\.15 ·/);
193
+ expect(content).not.toMatch(/Astryx v0\.0\.1 ·/);
194
+ });
195
+
196
+ it('reports a stale block on a dry run WITHOUT writing', async () => {
197
+ writePkg();
198
+ writeInstalledCore('0.0.15');
199
+ writeAgentBlock('AGENTS.md', '0.0.1');
200
+ const before = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
201
+
202
+ const result = await runJson(['--json', 'upgrade', '--from', '0.0.15']); // no --apply
203
+
204
+ expect(result.data.agentDocs.status).toBe('stale');
205
+ expect(result.data.agentDocs.action).toBe('would-refresh');
206
+ expect(result.data.agentDocs.refreshed).toBe(false);
207
+ // The file must be untouched by a dry run.
208
+ expect(fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8')).toBe(before);
209
+ });
210
+
211
+ it('refreshes a stale block on the no-codemods path (--apply)', async () => {
212
+ writePkg();
213
+ writeInstalledCore('0.0.11'); // (0.0.10, 0.0.11] has no registered codemods
214
+ writeSourceFile();
215
+ writeAgentBlock('CLAUDE.md', '0.0.1');
216
+
217
+ const result = await runJson(['--json', 'upgrade', '--from', '0.0.10', '--apply', '--path', 'src']);
218
+
219
+ expect(result.type).toBe('upgrade.status');
220
+ expect(result.data.status).toBe('no_codemods');
221
+ expect(result.data.agentDocs.refreshed).toBe(true);
222
+ expect(fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8')).toMatch(/Astryx v0\.0\.11 ·/);
223
+ });
224
+
225
+ it('nudges to run init when core is installed but no managed block exists', async () => {
226
+ writePkg();
227
+ writeInstalledCore('0.0.15');
228
+ // No agent-doc files at all.
229
+
230
+ const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
231
+
232
+ expect(result.data.agentDocs.status).toBe('missing');
233
+ expect(result.data.agentDocs.action).toBe('nudge-init');
234
+ expect(result.data.agentDocs.refreshed).toBe(false);
235
+ // Must NOT silently create docs during an upgrade.
236
+ expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(false);
237
+ expect(fs.existsSync(path.join(tmpDir, '.claude', 'CLAUDE.md'))).toBe(false);
238
+ });
239
+
240
+ it('treats an agent file without our markers as "never initialized" (missing)', async () => {
241
+ writePkg();
242
+ writeInstalledCore('0.0.15');
243
+ fs.writeFileSync(path.join(tmpDir, 'AGENTS.md'), '# Agents\n\nHand-written, no astryx block.\n');
244
+ const before = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
245
+
246
+ const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
247
+
248
+ expect(result.data.agentDocs.status).toBe('missing');
249
+ expect(result.data.agentDocs.action).toBe('nudge-init');
250
+ // An unmarked file is left exactly as-is.
251
+ expect(fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8')).toBe(before);
252
+ });
253
+
254
+ it('does not silently no-op a stale block with malformed markers (START without END)', async () => {
255
+ writePkg();
256
+ writeInstalledCore('0.0.15');
257
+ // A corrupted block: START + version header but no matching END marker, so
258
+ // the writer can't safely splice it. This must not crash, corrupt the file,
259
+ // or falsely claim success — it should surface an error and nudge re-init.
260
+ const corrupted =
261
+ '# A\n\n<!-- ASTRYX:START -->\nAstryx v0.0.1 · 9 components\nguidance, but no end marker\n';
262
+ fs.writeFileSync(path.join(tmpDir, 'AGENTS.md'), corrupted);
263
+
264
+ const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
265
+
266
+ expect(result.data.agentDocs.status).toBe('stale');
267
+ expect(result.data.agentDocs.action).toBe('error');
268
+ expect(result.data.agentDocs.refreshed).toBe(false);
269
+ // File left byte-for-byte intact — never corrupted.
270
+ expect(fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8')).toBe(corrupted);
271
+ });
272
+
273
+ it('stays silent when the block already matches the installed version', async () => {
274
+ writePkg();
275
+ writeInstalledCore('0.0.15');
276
+ writeAgentBlock('AGENTS.md', '0.0.15');
277
+
278
+ const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
279
+
280
+ expect(result.data.agentDocs.status).toBe('current');
281
+ expect(result.data.agentDocs.action).toBe('none');
282
+ expect(result.data.agentDocs.refreshed).toBe(false);
283
+ });
284
+
285
+ it('migrates a legacy XDS block to the current Astryx block (--apply)', async () => {
286
+ writePkg();
287
+ writeInstalledCore('0.0.15');
288
+ fs.writeFileSync(
289
+ path.join(tmpDir, 'CLAUDE.md'),
290
+ '# Claude\n\n<!-- XDS:START -->\nlegacy index\n<!-- XDS:END -->\n\nMore rules.\n',
291
+ );
292
+
293
+ const result = await runJson(['--json', 'upgrade', '--from', '0.0.15', '--apply']);
294
+
295
+ expect(result.data.agentDocs.status).toBe('stale');
296
+ expect(result.data.agentDocs.refreshed).toBe(true);
297
+ const content = fs.readFileSync(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
298
+ expect(content).toContain('<!-- ASTRYX:START -->');
299
+ expect(content).toMatch(/Astryx v0\.0\.15 ·/);
300
+ expect(content).not.toContain('legacy index');
301
+ expect(content).toContain('More rules.');
302
+ });
303
+
304
+ it('surfaces agentDocs in the human output on the up-to-date path', async () => {
305
+ writePkg();
306
+ writeInstalledCore('0.0.15');
307
+ writeAgentBlock('AGENTS.md', '0.0.1');
308
+
309
+ const program = createProgram();
310
+ await program.parseAsync(['node', 'astryx', 'upgrade', '--from', '0.0.15', '--apply']);
311
+ const output = stdoutCalls.join('') + logCalls.join('\n');
312
+ expect(output).toMatch(/Agent docs refreshed/i);
313
+ });
314
+ });
@@ -23,6 +23,31 @@ export interface UpgradeListEntry {
23
23
  version: string;
24
24
  }
25
25
 
26
+ /**
27
+ * State of the managed agent-docs block (`<!-- ASTRYX:START --> … END -->`)
28
+ * relative to the installed core version, plus what `upgrade` did about it.
29
+ * Present on every upgrade response (run, status, and the codemod/config error
30
+ * envelopes) because the block is refreshed independently of codemods.
31
+ *
32
+ * - `refreshed` — a stale block was rewritten (`--apply` only).
33
+ * - `would-refresh` — a stale block was detected in dry-run; nothing written.
34
+ * - `nudge-init` — no managed block exists; user should run `init`.
35
+ * - `error` — refresh was attempted but writing failed.
36
+ * - `none` — nothing to do (block already current).
37
+ */
38
+ export interface AgentDocsSummary {
39
+ status: 'missing' | 'stale' | 'current';
40
+ /** Installed core version the block should reflect. */
41
+ installedVersion: string;
42
+ /** Distinct stale block versions found (the "from" side of the refresh). */
43
+ fromVersions: string[];
44
+ /** Files rewritten (apply) or that would be rewritten (dry-run). */
45
+ files: string[];
46
+ /** True only when a block was actually rewritten (apply mode). */
47
+ refreshed: boolean;
48
+ action: 'refreshed' | 'would-refresh' | 'nudge-init' | 'error' | 'none';
49
+ }
50
+
26
51
  /** xds --json upgrade [--apply] */
27
52
  export interface UpgradeRunResponse {
28
53
  type: 'upgrade.run';
@@ -32,6 +57,7 @@ export interface UpgradeRunResponse {
32
57
  codemods: number;
33
58
  depsUpdated: string[];
34
59
  agentDocsRefreshed: boolean;
60
+ agentDocs: AgentDocsSummary;
35
61
  };
36
62
  }
37
63
 
@@ -49,8 +75,18 @@ export interface UpgradeRunResponse {
49
75
  export interface UpgradeStatusResponse {
50
76
  type: 'upgrade.status';
51
77
  data:
52
- | {status: 'up_to_date'; from: string; to: string}
53
- | {status: 'no_codemods'; from: string; to: string}
78
+ | {
79
+ status: 'up_to_date';
80
+ from: string;
81
+ to: string;
82
+ agentDocs: AgentDocsSummary;
83
+ }
84
+ | {
85
+ status: 'no_codemods';
86
+ from: string;
87
+ to: string;
88
+ agentDocs: AgentDocsSummary;
89
+ }
54
90
  | {
55
91
  status: 'config_fixable';
56
92
  from: string;
@@ -60,5 +96,6 @@ export interface UpgradeStatusResponse {
60
96
  suggestedCommand: string;
61
97
  message: string;
62
98
  note: string;
99
+ agentDocs: AgentDocsSummary;
63
100
  };
64
101
  }
@@ -13,7 +13,7 @@ export default function AvatarFallbackChain() {
13
13
  <Avatar
14
14
  src="https://lookaside.facebook.com/assets/astryx/DATA-Daniela-Gimenez.png"
15
15
  name="Daniela Gimenez"
16
- size="medium"
16
+ size="lg"
17
17
  />
18
18
  <Text type="supporting">Valid src</Text>
19
19
  </HStack>
@@ -22,7 +22,7 @@ export default function AvatarFallbackChain() {
22
22
  src="https://lookaside.facebook.com/assets/astryx/does-not-exist-primary.jpg"
23
23
  fallbackSrc="https://lookaside.facebook.com/assets/astryx/DATA-Ami-Pena.png"
24
24
  name="Invalid User"
25
- size="medium"
25
+ size="lg"
26
26
  />
27
27
  <Text type="supporting">Invalid src, valid fallbackSrc</Text>
28
28
  </HStack>
@@ -31,14 +31,14 @@ export default function AvatarFallbackChain() {
31
31
  src="https://lookaside.facebook.com/assets/astryx/does-not-exist-primary.jpg"
32
32
  fallbackSrc="https://lookaside.facebook.com/assets/astryx/does-not-exist-fallback.jpg"
33
33
  name="Test User"
34
- size="medium"
34
+ size="lg"
35
35
  />
36
36
  <Text type="supporting">Both invalid, has name</Text>
37
37
  </HStack>
38
38
  <HStack gap={3} vAlign="center">
39
39
  <Avatar
40
40
  src="https://lookaside.facebook.com/assets/astryx/does-not-exist-primary.jpg"
41
- size="medium"
41
+ size="lg"
42
42
  />
43
43
  <Text type="supporting">All invalid, no name</Text>
44
44
  </HStack>
@@ -37,7 +37,7 @@ export default function AvatarGroupBlock() {
37
37
  <Text type="supporting" color="secondary">
38
38
  Team members
39
39
  </Text>
40
- <AvatarGroup size="medium">
40
+ <AvatarGroup size="lg">
41
41
  {USERS.map(user => (
42
42
  <Avatar key={user.name} src={user.src} name={user.name} />
43
43
  ))}
@@ -48,7 +48,7 @@ export default function AvatarGroupBlock() {
48
48
  <Text type="supporting" color="secondary">
49
49
  Larger group
50
50
  </Text>
51
- <AvatarGroup size="medium">
51
+ <AvatarGroup size="lg">
52
52
  {USERS.slice(0, 3).map(user => (
53
53
  <Avatar key={user.name} src={user.src} name={user.name} />
54
54
  ))}
@@ -18,7 +18,7 @@ export default function AvatarInitialsFallback() {
18
18
  <Stack direction="horizontal" gap={6} vAlign="center">
19
19
  {NAMES.map(({name, note}) => (
20
20
  <Stack key={name} direction="vertical" gap={2} hAlign="center">
21
- <Avatar name={name} size="medium" />
21
+ <Avatar name={name} size="lg" />
22
22
  <Text type="supporting" color="secondary">
23
23
  {note}
24
24
  </Text>
@@ -11,23 +11,23 @@ export default function AvatarShowcase() {
11
11
  <Avatar
12
12
  src="https://lookaside.facebook.com/assets/astryx/DATA-Ana-Thomas.png"
13
13
  name="Ana Thomas"
14
- size="large"
14
+ size="xl"
15
15
  status={<AvatarStatusDot variant="success" label="Online" />}
16
16
  />
17
17
  <Avatar
18
18
  src="https://lookaside.facebook.com/assets/astryx/DATA-Drew-Young.png"
19
19
  name="Drew Young"
20
- size="large"
20
+ size="xl"
21
21
  />
22
22
  <Avatar
23
23
  src="https://lookaside.facebook.com/assets/astryx/DATA-Jihoo-Song.png"
24
24
  name="Jihoo Song"
25
- size="large"
25
+ size="xl"
26
26
  />
27
27
  <Avatar
28
28
  src="https://lookaside.facebook.com/assets/astryx/DATA-Nam-Tran.png"
29
29
  name="Nam Tran"
30
- size="large"
30
+ size="xl"
31
31
  status={<AvatarStatusDot variant="error" label="Online" />}
32
32
  />
33
33
  </Stack>
@@ -35,7 +35,7 @@ export default function AvatarUserCard() {
35
35
  <Avatar
36
36
  src={user.src}
37
37
  name={user.name}
38
- size="medium"
38
+ size="lg"
39
39
  status={
40
40
  <AvatarStatusDot variant={user.variant} label={user.variant} />
41
41
  }
@@ -11,22 +11,22 @@ export default function AvatarWithImage() {
11
11
  <Avatar
12
12
  src="https://lookaside.facebook.com/assets/astryx/DATA-Ami-Pena.png"
13
13
  name="Ami Pena"
14
- size="tiny"
14
+ size="xsm"
15
15
  />
16
16
  <Avatar
17
17
  src="https://lookaside.facebook.com/assets/astryx/DATA-Ana-Thomas.png"
18
18
  name="Ana Thomas"
19
- size="small"
19
+ size="md"
20
20
  />
21
21
  <Avatar
22
22
  src="https://lookaside.facebook.com/assets/astryx/DATA-Daniela-Gimenez.png"
23
23
  name="Daniela Gimenez"
24
- size="medium"
24
+ size="lg"
25
25
  />
26
26
  <Avatar
27
27
  src="https://lookaside.facebook.com/assets/astryx/DATA-Gabriela-Fernandez.png"
28
28
  name="Gabriela Fernandez"
29
- size="large"
29
+ size="xl"
30
30
  />
31
31
  </Stack>
32
32
  );
@@ -11,19 +11,19 @@ export default function AvatarWithStatus() {
11
11
  <Avatar
12
12
  src="https://lookaside.facebook.com/assets/astryx/DATA-Itai-Jordaan.png"
13
13
  name="Itai Jordaan"
14
- size="large"
14
+ size="xl"
15
15
  status={<AvatarStatusDot variant="success" label="Online" />}
16
16
  />
17
17
  <Avatar
18
18
  src="https://lookaside.facebook.com/assets/astryx/DATA-Margot-Schroder.png"
19
19
  name="Margot Schroder"
20
- size="large"
20
+ size="xl"
21
21
  status={<AvatarStatusDot variant="neutral" label="Offline" />}
22
22
  />
23
23
  <Avatar
24
24
  src="https://lookaside.facebook.com/assets/astryx/DATA-Pablo-Morales.png"
25
25
  name="Pablo Morales"
26
- size="large"
26
+ size="xl"
27
27
  status={<AvatarStatusDot variant="error" label="Busy" />}
28
28
  />
29
29
  </Stack>
@@ -36,7 +36,7 @@ export default function AvatarGroupShowcase() {
36
36
  <Text type="supporting" color="secondary">
37
37
  Team members
38
38
  </Text>
39
- <AvatarGroup size="medium">
39
+ <AvatarGroup size="lg">
40
40
  {USERS.map(u => (
41
41
  <Avatar key={u.key} name={u.name} />
42
42
  ))}
@@ -46,7 +46,7 @@ export default function AvatarGroupShowcase() {
46
46
  <Text type="supporting" color="secondary">
47
47
  With overflow
48
48
  </Text>
49
- <AvatarGroup size="medium">
49
+ <AvatarGroup size="lg">
50
50
  {USERS.slice(0, 3).map(u => (
51
51
  <Avatar key={u.key} name={u.name} />
52
52
  ))}
@@ -24,7 +24,7 @@ export default function AvatarGroupOverflowCustomText() {
24
24
  <Text type="supporting" color="secondary">
25
25
  Team members
26
26
  </Text>
27
- <AvatarGroup size="medium">
27
+ <AvatarGroup size="lg">
28
28
  {TEAM.map(member => (
29
29
  <Avatar key={member.name} name={member.name} />
30
30
  ))}
@@ -24,7 +24,7 @@ export default function AvatarGroupOverflowDefault() {
24
24
  <Text type="supporting" color="secondary">
25
25
  Reviewers
26
26
  </Text>
27
- <AvatarGroup size="medium">
27
+ <AvatarGroup size="lg">
28
28
  {REVIEWERS.map(reviewer => (
29
29
  <Avatar key={reviewer.name} name={reviewer.name} />
30
30
  ))}
@@ -25,7 +25,7 @@ export default function AvatarGroupOverflowShowcase() {
25
25
  <Text type="supporting" color="secondary">
26
26
  Default overflow
27
27
  </Text>
28
- <AvatarGroup size="medium">
28
+ <AvatarGroup size="lg">
29
29
  {USERS.map(user => (
30
30
  <Avatar key={user.name} name={user.name} />
31
31
  ))}
@@ -36,7 +36,7 @@ export default function AvatarGroupOverflowShowcase() {
36
36
  <Text type="supporting" color="secondary">
37
37
  Custom count text
38
38
  </Text>
39
- <AvatarGroup size="medium">
39
+ <AvatarGroup size="lg">
40
40
  {USERS.slice(0, 2).map(user => (
41
41
  <Avatar key={user.name} name={user.name} />
42
42
  ))}
@@ -10,17 +10,17 @@ export default function AvatarStatusDotShowcase() {
10
10
  <HStack gap={4} vAlign="center">
11
11
  <Avatar
12
12
  name="Online User"
13
- size="large"
13
+ size="xl"
14
14
  status={<AvatarStatusDot variant="success" label="Online" />}
15
15
  />
16
16
  <Avatar
17
17
  name="Away User"
18
- size="large"
18
+ size="xl"
19
19
  status={<AvatarStatusDot variant="neutral" label="Away" />}
20
20
  />
21
21
  <Avatar
22
22
  name="Busy User"
23
- size="large"
23
+ size="xl"
24
24
  status={<AvatarStatusDot variant="error" label="Busy" />}
25
25
  />
26
26
  </HStack>
@@ -10,17 +10,17 @@ export default function AvatarStatusDotVariants() {
10
10
  <HStack gap={4} vAlign="center">
11
11
  <Avatar
12
12
  name="Ana Silva"
13
- size="large"
13
+ size="xl"
14
14
  status={<AvatarStatusDot variant="success" label="Online" />}
15
15
  />
16
16
  <Avatar
17
17
  name="Ben Okafor"
18
- size="large"
18
+ size="xl"
19
19
  status={<AvatarStatusDot variant="neutral" label="Away" />}
20
20
  />
21
21
  <Avatar
22
22
  name="Cleo Marsh"
23
- size="large"
23
+ size="xl"
24
24
  status={<AvatarStatusDot variant="error" label="Do not disturb" />}
25
25
  />
26
26
  </HStack>
@@ -27,7 +27,7 @@ export default function CarouselSnap() {
27
27
  {TEAM.map(person => (
28
28
  <Card key={person.name} width={180} minHeight={140}>
29
29
  <Stack direction="vertical" gap={3} hAlign="center">
30
- <Avatar name={person.name} size="medium" />
30
+ <Avatar name={person.name} size="lg" />
31
31
  <Stack direction="vertical" gap={1} hAlign="center">
32
32
  <Text type="body" weight="bold">
33
33
  {person.name}
@@ -17,7 +17,7 @@ export default function ChatMessageAvatarName() {
17
17
  <ChatMessageList style={{maxWidth: 500}}>
18
18
  <ChatMessage
19
19
  sender="assistant"
20
- avatar={<Avatar name="Agent" size="small" />}>
20
+ avatar={<Avatar name="Agent" size="md" />}>
21
21
  <ChatMessageBubble
22
22
  name={
23
23
  <Text type="supporting" weight="semibold" color="secondary">
@@ -50,7 +50,7 @@ export default function ChatMessageAvatarName() {
50
50
  </ChatMessage>
51
51
  <ChatMessage
52
52
  sender="assistant"
53
- avatar={<Avatar name="Agent" size="small" />}>
53
+ avatar={<Avatar name="Agent" size="md" />}>
54
54
  <ChatMessageBubble
55
55
  name={
56
56
  <Text type="supporting" weight="semibold" color="secondary">
@@ -37,7 +37,7 @@ export default function ChatMessageMultiBubble() {
37
37
  </ChatMessage>
38
38
  <ChatMessage
39
39
  sender="assistant"
40
- avatar={<Avatar name="Agent" size="small" />}>
40
+ avatar={<Avatar name="Agent" size="md" />}>
41
41
  <ChatMessageBubble
42
42
  group="first"
43
43
  name={
@@ -17,7 +17,7 @@ export default function ChatMessageBubbleGrouping() {
17
17
  <ChatMessageList style={{maxWidth: 500}}>
18
18
  <ChatMessage
19
19
  sender="assistant"
20
- avatar={<Avatar name="Agent" size="small" />}>
20
+ avatar={<Avatar name="Agent" size="md" />}>
21
21
  <ChatMessageBubble
22
22
  group="first"
23
23
  name={
@@ -20,7 +20,7 @@ export default function ChatMessageBubbleMetadata() {
20
20
  <ChatMessageList style={{maxWidth: 500}}>
21
21
  <ChatMessage
22
22
  sender="assistant"
23
- avatar={<Avatar name="Agent" size="small" />}>
23
+ avatar={<Avatar name="Agent" size="md" />}>
24
24
  <ChatMessageBubble
25
25
  name={
26
26
  <Text type="supporting" weight="semibold" color="secondary">
@@ -16,9 +16,9 @@ import {Fragment} from 'react';
16
16
  const DENSITIES = ['compact', 'balanced', 'spacious'] as const;
17
17
 
18
18
  const AVATAR_SIZE = {
19
- compact: 'xsmall' as const,
20
- balanced: 'small' as const,
21
- spacious: 'small' as const,
19
+ compact: 'sm' as const,
20
+ balanced: 'md' as const,
21
+ spacious: 'md' as const,
22
22
  };
23
23
 
24
24
  export default function ChatMessageListDensity() {
@@ -34,15 +34,11 @@ export default function ChatMessageListDensity() {
34
34
  <VStack style={{flex: 1, minHeight: 0}}>
35
35
  <ChatMessageList density={density}>
36
36
  <ChatMessage sender="user">
37
- <ChatMessageBubble>
38
- How does density work?
39
- </ChatMessageBubble>
37
+ <ChatMessageBubble>How does density work?</ChatMessageBubble>
40
38
  </ChatMessage>
41
39
  <ChatMessage
42
40
  sender="assistant"
43
- avatar={
44
- <Avatar name="Agent" size={AVATAR_SIZE[density]} />
45
- }>
41
+ avatar={<Avatar name="Agent" size={AVATAR_SIZE[density]} />}>
46
42
  <ChatMessageBubble>
47
43
  Density provides default spacing at every level — message
48
44
  gap, bubble padding, and gap between child elements. Use gap
@@ -42,7 +42,7 @@ export default function ChatMessageListFullFeatured() {
42
42
 
43
43
  <ChatMessage
44
44
  sender="assistant"
45
- avatar={<Avatar name="Agent" size="small" />}>
45
+ avatar={<Avatar name="Agent" size="md" />}>
46
46
  <ChatMessageBubble group="first">
47
47
  <Markdown density="compact">
48
48
  {`Sure! Here's the key pattern from **useReducer.ts**:`}
@@ -15,7 +15,7 @@ export default function HoverCardShowcase() {
15
15
  content={
16
16
  <Stack direction="vertical" gap={2} style={{width: 240}}>
17
17
  <Stack direction="horizontal" gap={2} vAlign="center">
18
- <Avatar name="Jane Doe" size="medium" />
18
+ <Avatar name="Jane Doe" size="lg" />
19
19
  <Stack direction="vertical" gap={0}>
20
20
  <Heading level={5}>Jane Doe</Heading>
21
21
  <Text type="supporting" color="secondary">
@@ -13,14 +13,14 @@ export default function ItemWithMedia() {
13
13
  return (
14
14
  <Stack gap={0}>
15
15
  <Item
16
- startContent={<Avatar name="Ada Lovelace" size="xsmall" />}
16
+ startContent={<Avatar name="Ada Lovelace" size="sm" />}
17
17
  label="Ada Lovelace"
18
18
  description="Design systems engineer"
19
19
  endContent={<Badge label="Owner" variant="purple" />}
20
20
  onClick={() => {}}
21
21
  />
22
22
  <Item
23
- startContent={<Avatar name="Grace Hopper" size="xsmall" />}
23
+ startContent={<Avatar name="Grace Hopper" size="sm" />}
24
24
  label="Grace Hopper"
25
25
  description="Compiler platform"
26
26
  endContent={<Text color="secondary">Online</Text>}
@@ -13,14 +13,14 @@ export default function ListItemWithMedia() {
13
13
  <ListItem
14
14
  label="Ada Lovelace"
15
15
  description="Design systems engineer"
16
- startContent={<Avatar name="Ada Lovelace" size="xsmall" />}
16
+ startContent={<Avatar name="Ada Lovelace" size="sm" />}
17
17
  endContent={<Badge label="Owner" variant="purple" />}
18
18
  onClick={() => {}}
19
19
  />
20
20
  <ListItem
21
21
  label="Grace Hopper"
22
22
  description="Platform infrastructure"
23
- startContent={<Avatar name="Grace Hopper" size="xsmall" />}
23
+ startContent={<Avatar name="Grace Hopper" size="sm" />}
24
24
  endContent={<Badge label="On call" variant="blue" />}
25
25
  onClick={() => {}}
26
26
  />