40760aa884
- server:Go 网关(WS 流式识别中继/计费配额/微信登录支付 mock/反馈/埋点),gummy provider 已真实联调 - desktop:Tauri 2(全局快捷键 push-to-talk/浮层/托盘/设置/登录购买/反馈/首启引导) - android:Compose 主 App + IME(键盘内录音直传) - ios:App + 键盘扩展(1A spike 实证键盘内不可录音,走 deep link 听写) - design/design-pipeline:设计系统 + token 导出 iOS/Android 主题 - doc:前后端设计文档(HTML);web:官网宣传页;todo:任务看板 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
387 lines
12 KiB
JSON
387 lines
12 KiB
JSON
{
|
|
"plugins": [
|
|
"react",
|
|
"import"
|
|
],
|
|
"rules": {
|
|
"react/forbid-elements": [
|
|
"warn",
|
|
{
|
|
"forbid": []
|
|
}
|
|
],
|
|
"no-restricted-imports": [
|
|
"warn",
|
|
{
|
|
"patterns": [
|
|
{
|
|
"group": [
|
|
"components/core/**",
|
|
"components/forms/**",
|
|
"components/voice/**",
|
|
"ui_kits/desktop/**",
|
|
"ui_kits/mobile/**"
|
|
],
|
|
"message": "Import design-system components from 'index.js', not component internals."
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"no-restricted-syntax": [
|
|
"warn",
|
|
{
|
|
"selector": "Literal[value=/#[0-9a-fA-F]{3,8}\\b/]",
|
|
"message": "Raw hex color — use a design-system color token via var()."
|
|
},
|
|
{
|
|
"selector": "Literal[value=/\\b\\d+px\\b/]",
|
|
"message": "Raw px value — use a design-system spacing token via var()."
|
|
},
|
|
{
|
|
"selector": "Literal[value=/font-family\\s*:\\s*(?!['\\\"]?(?:Outfit))/i]",
|
|
"message": "Font not provided by the design system. Available: Outfit."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Badge'] > JSXAttribute > JSXIdentifier[name!=/^(?:tone|children|key|ref|className|style|children)$/]",
|
|
"message": "<Badge> doesn't accept that prop. Declared props: tone, children."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Badge'] > JSXAttribute[name.name='tone'] > Literal[value!=/^(?:neutral|blue|green|orange|red)$/]",
|
|
"message": "<Badge> tone must be one of 'neutral' | 'blue' | 'green' | 'orange' | 'red'."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute > JSXIdentifier[name!=/^(?:variant|size|block|disabled|onClick|children|key|ref|className|style|children)$/]",
|
|
"message": "<Button> doesn't accept that prop. Declared props: variant, size, block, disabled, onClick, children."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:primary|secondary|ghost|danger)$/]",
|
|
"message": "<Button> variant must be one of 'primary' | 'secondary' | 'ghost' | 'danger'."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Button'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:sm|md|lg)$/]",
|
|
"message": "<Button> size must be one of 'sm' | 'md' | 'lg'."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Card'] > JSXAttribute > JSXIdentifier[name!=/^(?:padding|style|children|key|ref|className|style|children)$/]",
|
|
"message": "<Card> doesn't accept that prop. Declared props: padding, style, children."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='IconButton'] > JSXAttribute > JSXIdentifier[name!=/^(?:size|label|disabled|onClick|children|key|ref|className|style|children)$/]",
|
|
"message": "<IconButton> doesn't accept that prop. Declared props: size, label, disabled, onClick, children."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Input'] > JSXAttribute > JSXIdentifier[name!=/^(?:size|placeholder|value|disabled|onChange|style|key|ref|className|style|children)$/]",
|
|
"message": "<Input> doesn't accept that prop. Declared props: size, placeholder, value, disabled, onChange, style."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Input'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:md|lg)$/]",
|
|
"message": "<Input> size must be one of 'md' | 'lg'."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Kbd'] > JSXAttribute > JSXIdentifier[name!=/^(?:children|key|ref|className|style|children)$/]",
|
|
"message": "<Kbd> doesn't accept that prop. Declared props: children."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='MicBar'] > JSXAttribute > JSXIdentifier[name!=/^(?:state|label|onPointerDown|onPointerUp|key|ref|className|style|children)$/]",
|
|
"message": "<MicBar> doesn't accept that prop. Declared props: state, label, onPointerDown, onPointerUp."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='MicBar'] > JSXAttribute[name.name='state'] > Literal[value!=/^(?:idle|recording|disabled|quota)$/]",
|
|
"message": "<MicBar> state must be one of 'idle' | 'recording' | 'disabled' | 'quota'."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='ProgressBar'] > JSXAttribute > JSXIdentifier[name!=/^(?:value|max|height|warnAt|style|key|ref|className|style|children)$/]",
|
|
"message": "<ProgressBar> doesn't accept that prop. Declared props: value, max, height, warnAt, style."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='RecognitionOverlay'] > JSXAttribute > JSXIdentifier[name!=/^(?:state|finalText|partialText|hint|width|style|key|ref|className|style|children)$/]",
|
|
"message": "<RecognitionOverlay> doesn't accept that prop. Declared props: state, finalText, partialText, hint, width, style."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='RecognitionOverlay'] > JSXAttribute[name.name='state'] > Literal[value!=/^(?:listening|streaming)$/]",
|
|
"message": "<RecognitionOverlay> state must be one of 'listening' | 'streaming'."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='SettingRow'] > JSXAttribute > JSXIdentifier[name!=/^(?:label|description|children|key|ref|className|style|children)$/]",
|
|
"message": "<SettingRow> doesn't accept that prop. Declared props: label, description, children."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Switch'] > JSXAttribute > JSXIdentifier[name!=/^(?:checked|onChange|disabled|key|ref|className|style|children)$/]",
|
|
"message": "<Switch> doesn't accept that prop. Declared props: checked, onChange, disabled."
|
|
},
|
|
{
|
|
"selector": "JSXOpeningElement[name.name='Waveform'] > JSXAttribute > JSXIdentifier[name!=/^(?:bars|active|height|color|style|key|ref|className|style|children)$/]",
|
|
"message": "<Waveform> doesn't accept that prop. Declared props: bars, active, height, color, style."
|
|
}
|
|
]
|
|
},
|
|
"overrides": [
|
|
{
|
|
"files": [
|
|
"**/index.js"
|
|
],
|
|
"rules": {
|
|
"no-restricted-imports": "off"
|
|
}
|
|
}
|
|
],
|
|
"x-omelette": {
|
|
"components": {
|
|
"Badge": {
|
|
"replaces": []
|
|
},
|
|
"Button": {
|
|
"replaces": []
|
|
},
|
|
"Card": {
|
|
"replaces": []
|
|
},
|
|
"IconButton": {
|
|
"replaces": []
|
|
},
|
|
"Input": {
|
|
"replaces": []
|
|
},
|
|
"Kbd": {
|
|
"replaces": []
|
|
},
|
|
"MicBar": {
|
|
"replaces": []
|
|
},
|
|
"ProgressBar": {
|
|
"replaces": []
|
|
},
|
|
"RecognitionOverlay": {
|
|
"replaces": []
|
|
},
|
|
"SettingRow": {
|
|
"replaces": []
|
|
},
|
|
"Switch": {
|
|
"replaces": []
|
|
},
|
|
"Waveform": {
|
|
"replaces": []
|
|
}
|
|
},
|
|
"tokens": [
|
|
"--accent",
|
|
"--accent-hover",
|
|
"--accent-press",
|
|
"--accent-soft",
|
|
"--accent-soft-2",
|
|
"--accent-text",
|
|
"--amber-100",
|
|
"--amber-500",
|
|
"--bg-app",
|
|
"--blue-100",
|
|
"--blue-200",
|
|
"--blue-300",
|
|
"--blue-400",
|
|
"--blue-50",
|
|
"--blue-500",
|
|
"--blue-600",
|
|
"--blue-700",
|
|
"--blue-800",
|
|
"--blue-900",
|
|
"--border-1",
|
|
"--border-2",
|
|
"--control-lg",
|
|
"--control-md",
|
|
"--control-sm",
|
|
"--control-xl",
|
|
"--danger",
|
|
"--danger-soft",
|
|
"--dur-base",
|
|
"--dur-fast",
|
|
"--dur-slow",
|
|
"--ease-in-out",
|
|
"--ease-out",
|
|
"--focus-ring",
|
|
"--font-mono",
|
|
"--font-sans",
|
|
"--gray-0",
|
|
"--gray-100",
|
|
"--gray-200",
|
|
"--gray-25",
|
|
"--gray-300",
|
|
"--gray-400",
|
|
"--gray-50",
|
|
"--gray-500",
|
|
"--gray-600",
|
|
"--gray-700",
|
|
"--gray-800",
|
|
"--gray-900",
|
|
"--gray-950",
|
|
"--green-100",
|
|
"--green-500",
|
|
"--leading-loose",
|
|
"--leading-normal",
|
|
"--leading-tight",
|
|
"--overlay-bg",
|
|
"--overlay-text",
|
|
"--overlay-text-2",
|
|
"--overlay-text-3",
|
|
"--positive",
|
|
"--positive-soft",
|
|
"--radius-full",
|
|
"--radius-lg",
|
|
"--radius-md",
|
|
"--radius-sm",
|
|
"--radius-xl",
|
|
"--radius-xs",
|
|
"--red-100",
|
|
"--red-500",
|
|
"--shadow-card",
|
|
"--shadow-key",
|
|
"--shadow-menu",
|
|
"--shadow-overlay",
|
|
"--shadow-window",
|
|
"--space-1",
|
|
"--space-10",
|
|
"--space-12",
|
|
"--space-16",
|
|
"--space-2",
|
|
"--space-3",
|
|
"--space-4",
|
|
"--space-5",
|
|
"--space-6",
|
|
"--space-8",
|
|
"--surface-2",
|
|
"--surface-3",
|
|
"--surface-card",
|
|
"--text-1",
|
|
"--text-2",
|
|
"--text-2xl",
|
|
"--text-3",
|
|
"--text-3xl",
|
|
"--text-4xl",
|
|
"--text-base",
|
|
"--text-lg",
|
|
"--text-md",
|
|
"--text-on-accent",
|
|
"--text-sm",
|
|
"--text-xl",
|
|
"--text-xs",
|
|
"--tracking-normal",
|
|
"--tracking-wide",
|
|
"--warning",
|
|
"--warning-soft",
|
|
"--weight-bold",
|
|
"--weight-medium",
|
|
"--weight-regular",
|
|
"--weight-semibold"
|
|
],
|
|
"tokenKinds": {
|
|
"--blue-50": "color",
|
|
"--blue-100": "color",
|
|
"--blue-200": "color",
|
|
"--blue-300": "color",
|
|
"--blue-400": "color",
|
|
"--blue-500": "color",
|
|
"--blue-600": "color",
|
|
"--blue-700": "color",
|
|
"--blue-800": "color",
|
|
"--blue-900": "color",
|
|
"--gray-0": "color",
|
|
"--gray-25": "color",
|
|
"--gray-50": "color",
|
|
"--gray-100": "color",
|
|
"--gray-200": "color",
|
|
"--gray-300": "color",
|
|
"--gray-400": "color",
|
|
"--gray-500": "color",
|
|
"--gray-600": "color",
|
|
"--gray-700": "color",
|
|
"--gray-800": "color",
|
|
"--gray-900": "color",
|
|
"--gray-950": "color",
|
|
"--green-500": "color",
|
|
"--green-100": "color",
|
|
"--amber-500": "color",
|
|
"--amber-100": "color",
|
|
"--red-500": "color",
|
|
"--red-100": "color",
|
|
"--bg-app": "color",
|
|
"--surface-card": "color",
|
|
"--surface-2": "color",
|
|
"--surface-3": "color",
|
|
"--border-1": "color",
|
|
"--border-2": "color",
|
|
"--text-1": "font",
|
|
"--text-2": "font",
|
|
"--text-3": "font",
|
|
"--text-on-accent": "font",
|
|
"--accent": "color",
|
|
"--accent-hover": "color",
|
|
"--accent-press": "color",
|
|
"--accent-soft": "color",
|
|
"--accent-soft-2": "color",
|
|
"--accent-text": "font",
|
|
"--positive": "color",
|
|
"--positive-soft": "color",
|
|
"--warning": "color",
|
|
"--warning-soft": "color",
|
|
"--danger": "color",
|
|
"--danger-soft": "color",
|
|
"--overlay-bg": "color",
|
|
"--overlay-text": "font",
|
|
"--overlay-text-2": "font",
|
|
"--overlay-text-3": "font",
|
|
"--focus-ring": "color",
|
|
"--font-sans": "font",
|
|
"--font-mono": "font",
|
|
"--text-xs": "font",
|
|
"--text-sm": "font",
|
|
"--text-base": "font",
|
|
"--text-md": "font",
|
|
"--text-lg": "font",
|
|
"--text-xl": "font",
|
|
"--text-2xl": "font",
|
|
"--text-3xl": "font",
|
|
"--text-4xl": "font",
|
|
"--weight-regular": "font",
|
|
"--weight-medium": "font",
|
|
"--weight-semibold": "font",
|
|
"--weight-bold": "font",
|
|
"--leading-tight": "font",
|
|
"--leading-normal": "font",
|
|
"--leading-loose": "font",
|
|
"--tracking-normal": "font",
|
|
"--tracking-wide": "font",
|
|
"--space-1": "spacing",
|
|
"--space-2": "spacing",
|
|
"--space-3": "spacing",
|
|
"--space-4": "spacing",
|
|
"--space-5": "spacing",
|
|
"--space-6": "spacing",
|
|
"--space-8": "spacing",
|
|
"--space-10": "spacing",
|
|
"--space-12": "spacing",
|
|
"--space-16": "spacing",
|
|
"--radius-xs": "radius",
|
|
"--radius-sm": "radius",
|
|
"--radius-md": "radius",
|
|
"--radius-lg": "radius",
|
|
"--radius-xl": "radius",
|
|
"--radius-full": "radius",
|
|
"--control-sm": "spacing",
|
|
"--control-md": "spacing",
|
|
"--control-lg": "spacing",
|
|
"--control-xl": "spacing",
|
|
"--shadow-card": "shadow",
|
|
"--shadow-menu": "shadow",
|
|
"--shadow-window": "shadow",
|
|
"--shadow-overlay": "shadow",
|
|
"--shadow-key": "shadow",
|
|
"--ease-out": "other",
|
|
"--ease-in-out": "other",
|
|
"--dur-fast": "other",
|
|
"--dur-base": "other",
|
|
"--dur-slow": "other"
|
|
},
|
|
"fontFamilies": [
|
|
"Outfit"
|
|
]
|
|
}
|
|
} |