@astryxdesign/cli 0.4.1 → 0.4.2-canary.464a445
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 +34 -0
- package/README.md +1 -0
- package/api/init/init.doc.mjs +2 -2
- package/api/init/init.test.mjs +19 -2
- package/api/init/init.type.d.mts +9 -1
- package/api/init/init.type.mjs +3 -1
- package/api/init/run/run.mjs +36 -6
- package/api/theme/add/add.mjs +2 -13
- package/api/theme/build/build.font-warning.test.mjs +161 -0
- package/api/theme/build/build.mjs +19 -12
- package/api/theme/build/build.test.mjs +53 -0
- package/api/theme/build/font-warning.d.mts +26 -0
- package/api/theme/build/font-warning.mjs +214 -0
- package/api/theme/build/font-warning.test.mjs +242 -0
- package/api/theme/template/template.d.mts +21 -0
- package/api/theme/template/template.mjs +69 -0
- package/api/theme/template/template.test.mjs +82 -0
- package/api/theme/theme.d.mts +1 -0
- package/api/theme/theme.mjs +1 -0
- package/api/theme/theme.type.d.mts +13 -0
- package/api/theme/theme.type.mjs +11 -1
- package/api/theme/themeTemplate.doc.d.mts +11 -0
- package/api/theme/themeTemplate.doc.mjs +64 -0
- package/assets/docs/getting-started.doc.mjs +11 -1
- package/assets/docs/theme.doc.dense.mjs +2 -2
- package/assets/docs/theme.doc.mjs +20 -9
- package/assets/docs/theme.doc.zh.mjs +1 -1
- package/assets/docs/typography.doc.mjs +38 -0
- package/assets/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleCustomContent.doc.mjs +13 -0
- package/assets/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleCustomContent.tsx +55 -0
- package/assets/templates/pages/ai-chat/page.tsx +18 -13
- package/assets/templates/themes/butter/butterTheme.ts +4 -1
- package/assets/templates/themes/chocolate/chocolateTheme.ts +4 -1
- package/assets/templates/themes/gothic/gothicTheme.ts +4 -1
- package/assets/templates/themes/stone/stoneTheme.ts +4 -1
- package/assets/theme.template.ts +322 -0
- package/authoring/doctypes/base/type.ts +9 -1
- package/authoring/doctypes/component/component.doc.mjs +1 -1
- package/clients/cli/commands/build-theme.font-warning.test.mjs +138 -0
- package/clients/cli/commands/build-theme.mjs +50 -0
- package/clients/cli/commands/init.behavior.test.mjs +13 -2
- package/clients/cli/commands/theme-template.behavior.test.mjs +85 -0
- package/clients/cli/commands/theme-template.doc.mjs +42 -0
- package/clients/cli/commands/theme.doc.mjs +2 -2
- package/clients/cli/index.mjs +1 -0
- package/clients/cli/lib/manifest.mjs +2 -0
- package/foundation/agent-docs/agent-docs.mjs +1 -1
- package/foundation/response/response-types.doc.mjs +5 -0
- package/foundation/text/copyright-header.d.mts +11 -0
- package/foundation/text/copyright-header.mjs +35 -0
- package/foundation/text/copyright-header.test.mjs +58 -0
- package/package.json +9 -9
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file FunctionDoc for `themeTemplate()` / `astryx theme template`. Colocated with the
|
|
6
|
+
* API function it documents; the response-shape source of truth stays in
|
|
7
|
+
* `theme.type.mjs`.
|
|
8
|
+
* @position packages/cli/api/theme — function documentation
|
|
9
|
+
*/
|
|
10
|
+
/** @type {import('@astryxdesign/cli/authoring').FunctionDoc} */
|
|
11
|
+
export const doc: import("@astryxdesign/cli/authoring").FunctionDoc;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file FunctionDoc for `themeTemplate()` / `astryx theme template`. Colocated with the
|
|
5
|
+
* API function it documents; the response-shape source of truth stays in
|
|
6
|
+
* `theme.type.mjs`.
|
|
7
|
+
* @position packages/cli/api/theme — function documentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** @type {import('@astryxdesign/cli/authoring').FunctionDoc} */
|
|
11
|
+
export const doc = {
|
|
12
|
+
type: 'function',
|
|
13
|
+
kind: 'api',
|
|
14
|
+
name: 'themeTemplate',
|
|
15
|
+
displayName: 'themeTemplate()',
|
|
16
|
+
summary: 'Write the annotated theme template into a project.',
|
|
17
|
+
description:
|
|
18
|
+
'Writes theme.template.ts: the annotated reference for the whole theme surface — every ' +
|
|
19
|
+
'defineTheme field, the token families, the component override syntax, and how a theme is ' +
|
|
20
|
+
'consumed — with the CLI command that prints the authoritative reference for each section. ' +
|
|
21
|
+
'Read it, copy what you need into your own theme file, delete it. Where `theme add` starts ' +
|
|
22
|
+
'you from a theme we ship, this starts you from a blank one. Refuses to overwrite without ' +
|
|
23
|
+
'`overwrite`, so it is safe to re-run.',
|
|
24
|
+
importPath: '@astryxdesign/cli/api',
|
|
25
|
+
signature:
|
|
26
|
+
'themeTemplate(options?: {targetPath?: string, overwrite?: boolean, cwd?: string}): ThemeNewResponse',
|
|
27
|
+
keywords: ['theme', 'template', 'starter', 'defineTheme', 'scaffold', 'reference', 'tokens'],
|
|
28
|
+
params: [
|
|
29
|
+
{
|
|
30
|
+
name: 'options.targetPath',
|
|
31
|
+
type: 'string',
|
|
32
|
+
description: 'Destination file. Must resolve within cwd.',
|
|
33
|
+
default: "'theme.template.ts'",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'options.overwrite',
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
description: 'Replace an existing file instead of reporting it untouched.',
|
|
39
|
+
default: 'false',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'options.cwd',
|
|
43
|
+
type: 'string',
|
|
44
|
+
description: 'Directory the target path resolves against.',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
returns: [
|
|
48
|
+
{
|
|
49
|
+
type: 'theme.template',
|
|
50
|
+
description:
|
|
51
|
+
'Receipt: the path (relative to cwd), whether it was written, and the reason it was not — `exists` when a file was already there, which is a success, not a failure.',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
throws: [{code: 'ERR_PATH_TRAVERSAL', when: 'the target path escapes cwd'}],
|
|
55
|
+
examples: [
|
|
56
|
+
{label: 'Write it at the project root', code: 'themeTemplate();'},
|
|
57
|
+
{
|
|
58
|
+
label: 'Somewhere else, replacing what is there',
|
|
59
|
+
code: "themeTemplate({targetPath: 'src/themes/template.ts', overwrite: true});",
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
command: 'theme template',
|
|
63
|
+
related: ['themeAdd', 'themeBuild', 'themeList'],
|
|
64
|
+
};
|
|
@@ -20,9 +20,19 @@ export const docs = {
|
|
|
20
20
|
{
|
|
21
21
|
type: 'code',
|
|
22
22
|
lang: 'text',
|
|
23
|
-
label: '
|
|
23
|
+
label: 'Set up the design system',
|
|
24
24
|
code: 'Install @astryxdesign/core, @stylexjs/stylex, @astryxdesign/theme-neutral, and @astryxdesign/cli in this project, then run `npx @astryxdesign/cli init` to set up agent docs. Read the generated files to learn the conventions.',
|
|
25
25
|
},
|
|
26
|
+
{
|
|
27
|
+
type: 'prose',
|
|
28
|
+
text: 'Then give it a look. Every app gets a theme whether or not anyone picks one, so it is worth one question at setup rather than revisiting screens later that were built around the wrong look:',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: 'code',
|
|
32
|
+
lang: 'text',
|
|
33
|
+
label: 'Give it a look',
|
|
34
|
+
code: "Ask me what look and feel this app should have. Run `npx @astryxdesign/cli theme list` and start from the closest shipped theme with `theme add <slug>`, which copies it in as editable source; if none of them fit, run `npx @astryxdesign/cli theme template` and fill in the annotated template it writes. Default to neutral if I have no preference, and show me the result before moving on.",
|
|
35
|
+
},
|
|
26
36
|
],
|
|
27
37
|
},
|
|
28
38
|
{
|
|
@@ -8,9 +8,9 @@ export const docsDense = {
|
|
|
8
8
|
{ section: 'Quick Start', title: 'Quick Start', content: [null, null, null, null, { type: 'prose', text: 'default import = runtime injection. /built import = pre-compiled CSS (pair with theme.css).' }] },
|
|
9
9
|
{ section: 'Available Themes', title: 'Themes', content: [null, null, { type: 'prose', text: 'published: neutral (start here), butter, chocolate, gothic (dark-only), matcha, stone, y2k. @astryxdesign/theme-{name} = source (runtime). @astryxdesign/theme-{name}/built = optimized (+ theme.css).' }] },
|
|
10
10
|
{ section: 'Theme Props', title: 'Props', content: [null] },
|
|
11
|
-
{ section: 'Creating a Custom Theme', title: 'Custom Theme', content: [{ type: 'prose', text: '
|
|
11
|
+
{ section: 'Creating a Custom Theme', title: 'Custom Theme', content: [{ type: 'prose', text: '`theme list` + `theme add <slug>` to start from a shipped theme, or defineTheme from scratch. only override tokens that differ.' }, null, { type: 'prose', text: '`astryx theme template` writes theme.template.ts: every defineTheme field + token families + override syntax, annotated, with the CLI command that prints each reference.' }] },
|
|
12
12
|
{ section: 'defineTheme', title: 'defineTheme', content: [{ type: 'prose', text: 'scale configs (color, typography, radius, motion) + explicit token overrides + component overrides. color derives full palette from accent hex via HCT.' }, null, null] },
|
|
13
|
-
{ section: 'Component Style Overrides', title: 'Component Overrides', content: [{ type: 'prose', text: 'components field uses semantic component keys + style keys (base, variant:value, stateName), not raw selectors. for external CSS, prefer data-* selectors from `astryx docs styling`. write standard CSS (borderRadius, padding) — pipeline expands to internal vars. public vars (--button-
|
|
13
|
+
{ section: 'Component Style Overrides', title: 'Component Overrides', content: [{ type: 'prose', text: 'components field uses semantic component keys + style keys (base, variant:value, stateName), not raw selectors. for external CSS, prefer data-* selectors from `astryx docs styling`. write standard CSS (borderRadius, padding) — pipeline expands to internal vars. public vars (--button-focus-offset etc) set directly. private vars (--_*) cannot be set — use CSS properties. run `astryx component <Name>` for details.' }, null, null, null, null] },
|
|
14
14
|
{ section: 'Custom Variants', title: 'Custom Variants', content: [{ type: 'prose', text: 'any unknown prop:value in components becomes a new variant. astryx theme build generates TS augmentations. works on any extensible prop axis (variant, status, etc).' }, null, null, null, null] },
|
|
15
15
|
{ section: 'Building Themes for Production', title: 'Build for Production', content: [{ type: 'prose', text: 'astryx theme build compiles defineTheme to static CSS. outputs .css + .js (__built:true) + .d.ts.' }, null, null, null, null] },
|
|
16
16
|
{ section: 'Runtime vs Built Themes', title: 'Runtime vs Built', content: [{ type: 'prose', text: 'runtime: useInsertionEffect injects styles client-side. built: static CSS on first paint. USE /built + theme.css FOR SSR.' }, null, null, null] },
|
|
@@ -142,13 +142,17 @@ function App() {
|
|
|
142
142
|
content: [
|
|
143
143
|
{
|
|
144
144
|
type: 'prose',
|
|
145
|
-
text: '
|
|
145
|
+
text: 'Start from a theme we ship, or write one from scratch with defineTheme. Only override tokens that differ from defaults; omitted tokens use the design system defaults.',
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
148
|
type: 'code',
|
|
149
149
|
lang: 'bash',
|
|
150
|
-
label: '
|
|
151
|
-
code: 'astryx theme',
|
|
150
|
+
label: 'Browse, then copy a theme in as editable source',
|
|
151
|
+
code: 'astryx theme list\nastryx theme add stone',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: 'prose',
|
|
155
|
+
text: 'For an annotated map of the whole surface — every defineTheme field, the token families, and the component override syntax, each with the CLI command that prints its reference — run `astryx theme template`. It writes `theme.template.ts` into your project to read and copy from (`astryx init --features theme` writes it as part of project setup).',
|
|
152
156
|
},
|
|
153
157
|
],
|
|
154
158
|
},
|
|
@@ -275,14 +279,17 @@ const brandTheme = defineTheme({
|
|
|
275
279
|
base: { borderRadius: '20px', padding: '24px' },
|
|
276
280
|
},
|
|
277
281
|
button: {
|
|
278
|
-
base: {
|
|
282
|
+
base: {
|
|
283
|
+
borderRadius: '9999px',
|
|
284
|
+
textTransform: 'uppercase',
|
|
285
|
+
// Some components have public CSS vars for properties that don't map
|
|
286
|
+
// to standard CSS. Set these directly. Take the name from
|
|
287
|
+
// \`astryx component <Name>\` — a var the component does not define
|
|
288
|
+
// compiles to CSS that never applies.
|
|
289
|
+
'--button-focus-offset': '3px',
|
|
290
|
+
},
|
|
279
291
|
'variant:ghost': { borderWidth: '2px', borderStyle: 'solid' },
|
|
280
292
|
},
|
|
281
|
-
// Some components have public CSS vars for properties that don't map
|
|
282
|
-
// to standard CSS. Set these directly.
|
|
283
|
-
button: {
|
|
284
|
-
base: { '--button-press-scale': 'scale(0.95)' },
|
|
285
|
-
},
|
|
286
293
|
}`,
|
|
287
294
|
},
|
|
288
295
|
{
|
|
@@ -410,6 +417,10 @@ import './themes/ocean.css';
|
|
|
410
417
|
<App />
|
|
411
418
|
</Theme>`,
|
|
412
419
|
},
|
|
420
|
+
{
|
|
421
|
+
type: 'prose',
|
|
422
|
+
text: 'The build also warns when the theme names font families it does not load (webfonts like Fraunces) and prints the `<link>`/`@font-face` to add — the built CSS only sets font-family, so loading the font files stays the app\'s job. See `astryx docs typography` for the full recipe.',
|
|
423
|
+
},
|
|
413
424
|
],
|
|
414
425
|
},
|
|
415
426
|
{
|
|
@@ -8,7 +8,7 @@ export const docsZh = {
|
|
|
8
8
|
{ section: 'Quick Start', title: '快速开始', content: [null, null, null, null, { type: 'prose', text: '默认导入使用运行时样式注入。/built 导入使用预编译 CSS(需配合 theme.css)。' }] },
|
|
9
9
|
{ section: 'Available Themes', title: '可用主题', content: [null, null, { type: 'prose', text: '已发布主题:neutral(推荐起点)、butter、chocolate、gothic(仅暗色)、matcha、stone、y2k。@astryxdesign/theme-{name} = 源码版(运行时注入)。@astryxdesign/theme-{name}/built = 优化版(配合 theme.css)。' }] },
|
|
10
10
|
{ section: 'Theme Props', title: 'Theme 属性', content: [null] },
|
|
11
|
-
{ section: 'Creating a Custom Theme', title: '创建自定义主题', content: [{ type: 'prose', text: '
|
|
11
|
+
{ section: 'Creating a Custom Theme', title: '创建自定义主题', content: [{ type: 'prose', text: '用 `theme list` + `theme add <slug>` 从内置主题开始,或用 defineTheme 从零编写。只覆盖与默认值不同的令牌。' }, null, { type: 'prose', text: '`astryx theme template` 会写入 theme.template.ts:带注释的完整参考,涵盖每个 defineTheme 字段、令牌族和覆盖语法,并标明打印各自参考的 CLI 命令。' }] },
|
|
12
12
|
{ section: 'defineTheme', title: 'defineTheme', content: [{ type: 'prose', text: '支持比例配置(typography、radius、motion)+ 显式令牌覆盖 + 组件覆盖。' }, null, null] },
|
|
13
13
|
{ section: 'Building Themes for Production', title: '生产构建', content: [{ type: 'prose', text: 'astryx theme build 将 defineTheme 编译为静态 CSS。输出 .css + .js(__built:true)+ .d.ts。' }, null, null, null, null] },
|
|
14
14
|
{ section: 'Runtime vs Built Themes', title: '运行时 vs 构建', content: [{ type: 'prose', text: '运行时:useInsertionEffect 在客户端注入样式。构建:静态 CSS 在首次渲染时就存在。SSR 应用请使用 /built + theme.css。' }, null, null, null] },
|
|
@@ -44,6 +44,44 @@ export const docs = {
|
|
|
44
44
|
],
|
|
45
45
|
},
|
|
46
46
|
|
|
47
|
+
// ── Loading Custom Fonts ────────────────────────────────────────────────
|
|
48
|
+
{
|
|
49
|
+
title: 'Loading Custom Fonts',
|
|
50
|
+
category: 'foundations',
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: 'prose',
|
|
54
|
+
text: 'Astryx never loads font files. defineTheme and the built CSS only set font-family — naming a webfont (Fraunces, JetBrains Mono, …) makes every browser look for it, and quietly fall back when the app has not loaded it. `astryx theme build` warns when a theme names families that are neither CSS generics nor common system fonts and prints the snippet to add; loading the font is always the app\'s job.',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: 'code',
|
|
58
|
+
lang: 'html',
|
|
59
|
+
label: 'Google Fonts — add to your document <head>',
|
|
60
|
+
code: `<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
61
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
62
|
+
<link
|
|
63
|
+
rel="stylesheet"
|
|
64
|
+
href="https://fonts.googleapis.com/css2?family=Fraunces:wght@400;600;700&family=JetBrains+Mono&display=swap"
|
|
65
|
+
/>`,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'code',
|
|
69
|
+
lang: 'css',
|
|
70
|
+
label: 'Self-hosted — one @font-face per family and weight',
|
|
71
|
+
code: `@font-face {
|
|
72
|
+
font-family: 'Fraunces';
|
|
73
|
+
src: url('/fonts/fraunces.woff2') format('woff2');
|
|
74
|
+
font-weight: 400 700; /* variable-font range, or one weight per file */
|
|
75
|
+
font-display: swap; /* fallback text stays visible while the font loads */
|
|
76
|
+
}`,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: 'prose',
|
|
80
|
+
text: "Always pair a webfont with a real fallback stack — metric-similar system fonts plus a generic — so text stays readable before the font loads and wherever it never does: defineTheme({typography: {heading: {family: 'Fraunces', fallbacks: 'Georgia, serif'}}}).",
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
|
|
47
85
|
// ── Font Sizes ──────────────────────────────────────────────────────────
|
|
48
86
|
{
|
|
49
87
|
title: 'Font Sizes',
|
package/assets/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleCustomContent.doc.mjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/** @type {import('@astryxdesign/cli/authoring').TemplateDoc} */
|
|
4
|
+
export const doc = {
|
|
5
|
+
type: 'block',
|
|
6
|
+
exampleFor: 'ChatMessageBubble',
|
|
7
|
+
name: 'ChatMessageBubble — Custom Content',
|
|
8
|
+
displayName: 'ChatMessageBubble — Custom Content',
|
|
9
|
+
description: 'Custom in-message content aligned to the bubble text column. An artifact card is wrapped in a ghost bubble with width="100%", so its left edge matches the bubble text and it spans the full message column instead of the default bubble width cap; the timestamp rides the bubble metadata slot.',
|
|
10
|
+
isReady: true,
|
|
11
|
+
aspectRatio: 4 / 3,
|
|
12
|
+
componentsUsed: ['Chat', 'ChatMessage', 'ChatMessageBubble', 'ChatMessageMetadata', 'ClickableCard', 'Text', 'Timestamp'],
|
|
13
|
+
};
|
package/assets/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleCustomContent.tsx
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
ChatMessageList,
|
|
7
|
+
ChatMessage,
|
|
8
|
+
ChatMessageBubble,
|
|
9
|
+
ChatMessageMetadata,
|
|
10
|
+
} from '@astryxdesign/core/Chat';
|
|
11
|
+
import {ClickableCard} from '@astryxdesign/core/ClickableCard';
|
|
12
|
+
import {Text} from '@astryxdesign/core/Text';
|
|
13
|
+
import {Timestamp} from '@astryxdesign/core/Timestamp';
|
|
14
|
+
|
|
15
|
+
export default function ChatMessageBubbleCustomContent() {
|
|
16
|
+
return (
|
|
17
|
+
<ChatMessageList style={{maxWidth: 520}}>
|
|
18
|
+
<ChatMessage sender="user">
|
|
19
|
+
<ChatMessageBubble>Can you pull up the Q3 report?</ChatMessageBubble>
|
|
20
|
+
</ChatMessage>
|
|
21
|
+
<ChatMessage sender="assistant">
|
|
22
|
+
<ChatMessageBubble name="Navi">
|
|
23
|
+
Sure, here is the artifact from last quarter.
|
|
24
|
+
</ChatMessageBubble>
|
|
25
|
+
{/* A ghost bubble aligns custom content with the bubble text column;
|
|
26
|
+
width="100%" spans the full message column instead of the default
|
|
27
|
+
bubble width cap. Metadata rides the bubble's metadata slot. */}
|
|
28
|
+
<ChatMessageBubble
|
|
29
|
+
variant="ghost"
|
|
30
|
+
width="100%"
|
|
31
|
+
metadata={
|
|
32
|
+
<ChatMessageMetadata
|
|
33
|
+
timestamp={
|
|
34
|
+
<Timestamp value="2026-04-28T09:45:00" format="time" />
|
|
35
|
+
}
|
|
36
|
+
footer={
|
|
37
|
+
<Text type="supporting" color="secondary">
|
|
38
|
+
Claude Opus 4.6
|
|
39
|
+
</Text>
|
|
40
|
+
}
|
|
41
|
+
/>
|
|
42
|
+
}>
|
|
43
|
+
<ClickableCard label="Open Q3 performance report" onClick={() => {}}>
|
|
44
|
+
<Text type="body" weight="semibold" display="block">
|
|
45
|
+
Q3 Performance Report
|
|
46
|
+
</Text>
|
|
47
|
+
<Text type="supporting" color="secondary" display="block">
|
|
48
|
+
12 pages · updated 2 days ago
|
|
49
|
+
</Text>
|
|
50
|
+
</ClickableCard>
|
|
51
|
+
</ChatMessageBubble>
|
|
52
|
+
</ChatMessage>
|
|
53
|
+
</ChatMessageList>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -70,9 +70,6 @@ const chatLayout: CSSProperties = {
|
|
|
70
70
|
flex: 1,
|
|
71
71
|
minHeight: 0,
|
|
72
72
|
};
|
|
73
|
-
const artifactCard: CSSProperties = {
|
|
74
|
-
marginBlockStart: 'var(--spacing-2)',
|
|
75
|
-
};
|
|
76
73
|
const artifactScroll: CSSProperties = {
|
|
77
74
|
flex: 1,
|
|
78
75
|
overflowY: 'auto',
|
|
@@ -250,8 +247,7 @@ function ArtifactCard({onOpen}: {onOpen: () => void}) {
|
|
|
250
247
|
onClick={onOpen}
|
|
251
248
|
variant="muted"
|
|
252
249
|
padding={3}
|
|
253
|
-
maxWidth={360}
|
|
254
|
-
style={artifactCard}>
|
|
250
|
+
maxWidth={360}>
|
|
255
251
|
<HStack gap={3} vAlign="center" width="100%">
|
|
256
252
|
<Icon icon={DocumentTextIcon} size="md" color="secondary" />
|
|
257
253
|
<StackItem size="fill">
|
|
@@ -614,15 +610,24 @@ The fix is to catch \`TokenExpiredError\` specifically and attempt a refresh bef
|
|
|
614
610
|
{`I've drafted a design doc covering the problem, the fix, and the test matrix — pulling straight from the changes we just made.\n\nOpen the document below to review it. Want me to expand any section?`}
|
|
615
611
|
</Markdown>
|
|
616
612
|
</ChatMessageBubble>
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
613
|
+
{/* Ghost + width="100%" aligns the card with the
|
|
614
|
+
bubble text column and spans the full message
|
|
615
|
+
column; metadata rides the bubble slot. */}
|
|
616
|
+
<ChatMessageBubble
|
|
617
|
+
variant="ghost"
|
|
618
|
+
width="100%"
|
|
619
|
+
metadata={
|
|
620
|
+
<ChatMessageMetadata
|
|
621
|
+
timestamp={
|
|
622
|
+
<Timestamp
|
|
623
|
+
value="2026-04-29T10:18:40"
|
|
624
|
+
format="time"
|
|
625
|
+
/>
|
|
626
|
+
}
|
|
623
627
|
/>
|
|
624
|
-
}
|
|
625
|
-
|
|
628
|
+
}>
|
|
629
|
+
<ArtifactCard onOpen={openArtifact} />
|
|
630
|
+
</ChatMessageBubble>
|
|
626
631
|
</ChatMessage>
|
|
627
632
|
|
|
628
633
|
{/* User follow-up */}
|
|
@@ -202,8 +202,11 @@ export const butterTheme = defineTheme({
|
|
|
202
202
|
// Radius
|
|
203
203
|
// --radius-element drives buttons, badges, inputs — 8px per design
|
|
204
204
|
// --radius-container drives cards, banners, popovers — 12px per design
|
|
205
|
+
// --radius-none and --radius-full are always fixed and must never be
|
|
206
|
+
// scaled by a theme (see defineTheme's radius config docs) — 0 and
|
|
207
|
+
// 9999px respectively, matching @astryxdesign/core's own defaults.
|
|
205
208
|
// =========================================================================
|
|
206
|
-
'--radius-none': '
|
|
209
|
+
'--radius-none': '0px',
|
|
207
210
|
'--radius-inner': '0.375rem',
|
|
208
211
|
'--radius-element': '0.5rem', // 8px
|
|
209
212
|
'--radius-container': '0.75rem', // 12px
|
|
@@ -176,8 +176,11 @@ export const chocolateTheme = defineTheme({
|
|
|
176
176
|
|
|
177
177
|
// =========================================================================
|
|
178
178
|
// Radius — soft and rounded
|
|
179
|
+
// --radius-none and --radius-full are always fixed and must never be
|
|
180
|
+
// scaled by a theme (see defineTheme's radius config docs) — 0 and
|
|
181
|
+
// 9999px respectively, matching @astryxdesign/core's own defaults.
|
|
179
182
|
// =========================================================================
|
|
180
|
-
'--radius-none': '
|
|
183
|
+
'--radius-none': '0px',
|
|
181
184
|
'--radius-inner': '0.375rem',
|
|
182
185
|
'--radius-element': '0.625rem',
|
|
183
186
|
'--radius-container': '0.75rem',
|
|
@@ -201,8 +201,11 @@ export const gothicTheme = defineTheme({
|
|
|
201
201
|
|
|
202
202
|
// =========================================================================
|
|
203
203
|
// Radius — subtle rounding (original gothic)
|
|
204
|
+
// --radius-none and --radius-full are always fixed and must never be
|
|
205
|
+
// scaled by a theme (see defineTheme's radius config docs) — 0 and
|
|
206
|
+
// 9999px respectively, matching @astryxdesign/core's own defaults.
|
|
204
207
|
// =========================================================================
|
|
205
|
-
'--radius-none': '
|
|
208
|
+
'--radius-none': '0px',
|
|
206
209
|
'--radius-inner': '0.25rem',
|
|
207
210
|
'--radius-element': '0.5rem',
|
|
208
211
|
'--radius-container': '0.75rem',
|
|
@@ -219,8 +219,11 @@ export const stoneTheme = defineTheme({
|
|
|
219
219
|
|
|
220
220
|
// =========================================================================
|
|
221
221
|
// Radius — clean and subtle
|
|
222
|
+
// --radius-none and --radius-full are always fixed and must never be
|
|
223
|
+
// scaled by a theme (see defineTheme's radius config docs) — 0 and
|
|
224
|
+
// 9999px respectively, matching @astryxdesign/core's own defaults.
|
|
222
225
|
// =========================================================================
|
|
223
|
-
'--radius-none': '
|
|
226
|
+
'--radius-none': '0px',
|
|
224
227
|
'--radius-inner': '0.25rem',
|
|
225
228
|
'--radius-element': '0.5rem',
|
|
226
229
|
'--radius-container': '0.75rem',
|