@plumeai/plugin-sdk 0.0.0-stage → 0.1.2
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/LICENSE +21 -0
- package/bin/plume-plugin.mjs +70 -0
- package/dist/client/styles/src/index.d.ts +123 -0
- package/dist/client/ui/src/avatar/AgentAvatar.d.ts +42 -0
- package/dist/client/ui/src/avatar/AvatarPile.d.ts +36 -0
- package/dist/client/ui/src/avatar/AvatarStack.d.ts +26 -0
- package/dist/client/ui/src/avatar/art.d.ts +32 -0
- package/dist/client/ui/src/fileIcon.d.ts +33 -0
- package/dist/client/ui/src/hooks/useCopied.d.ts +16 -0
- package/dist/client/ui/src/hooks/useLiveRefresh.d.ts +22 -0
- package/dist/client/ui/src/hooks/useNarrow.d.ts +16 -0
- package/dist/client/ui/src/i18n/context.d.ts +17 -0
- package/dist/client/ui/src/i18n/index.d.ts +2 -0
- package/dist/client/ui/src/i18n/list.d.ts +20 -0
- package/dist/client/ui/src/i18n/locales.d.ts +10 -0
- package/dist/client/ui/src/i18n/messages/en.d.ts +1418 -0
- package/dist/client/ui/src/i18n/messages/index.d.ts +6 -0
- package/dist/client/ui/src/i18n/messages/zh-CN.d.ts +1263 -0
- package/dist/client/ui/src/i18n/plural.d.ts +16 -0
- package/dist/client/ui/src/i18n/translate.d.ts +43 -0
- package/dist/client/ui/src/icons/index.d.ts +5 -0
- package/dist/client/ui/src/image/AnnotateCanvas.d.ts +29 -0
- package/dist/client/ui/src/image/AnnotateToolbar.d.ts +73 -0
- package/dist/client/ui/src/image/Annotator.d.ts +154 -0
- package/dist/client/ui/src/image/annotate.d.ts +227 -0
- package/dist/client/ui/src/image/paint.d.ts +35 -0
- package/dist/client/ui/src/image/screenshot-geometry.d.ts +112 -0
- package/dist/client/ui/src/image/useBarDrag.d.ts +31 -0
- package/dist/client/ui/src/image/useMovableBar.d.ts +26 -0
- package/dist/client/ui/src/image/useToolbarPlacement.d.ts +42 -0
- package/dist/client/ui/src/index.d.ts +140 -0
- package/dist/client/ui/src/inputs/ColorField.d.ts +9 -0
- package/dist/client/ui/src/inputs/ComposerToggle.d.ts +23 -0
- package/dist/client/ui/src/inputs/DateRangeField.d.ts +25 -0
- package/dist/client/ui/src/inputs/NativeField.d.ts +5 -0
- package/dist/client/ui/src/inputs/SearchField.d.ts +21 -0
- package/dist/client/ui/src/inputs/Segmented.d.ts +23 -0
- package/dist/client/ui/src/inputs/Select.d.ts +32 -0
- package/dist/client/ui/src/inputs/ShortcutRecorder.d.ts +8 -0
- package/dist/client/ui/src/inputs/Slider.d.ts +13 -0
- package/dist/client/ui/src/inputs/TextArea.d.ts +30 -0
- package/dist/client/ui/src/inputs/Toggle.d.ts +10 -0
- package/dist/client/ui/src/inputs/WorktreeToggle.d.ts +19 -0
- package/dist/client/ui/src/inputs/day-range.d.ts +57 -0
- package/dist/client/ui/src/inputs/pickers.d.ts +40 -0
- package/dist/client/ui/src/inputs/useFieldFade.d.ts +1 -0
- package/dist/client/ui/src/keyboard.d.ts +21 -0
- package/dist/client/ui/src/layout/ApprovalFrame.d.ts +33 -0
- package/dist/client/ui/src/layout/Collapse.d.ts +9 -0
- package/dist/client/ui/src/layout/CopyMark.d.ts +19 -0
- package/dist/client/ui/src/layout/Disclosure.d.ts +66 -0
- package/dist/client/ui/src/layout/ErrorBoundary.d.ts +26 -0
- package/dist/client/ui/src/layout/PageTopRow.d.ts +19 -0
- package/dist/client/ui/src/layout/PanelEmpty.d.ts +17 -0
- package/dist/client/ui/src/layout/ResizeHandle.d.ts +24 -0
- package/dist/client/ui/src/layout/RetainedViews.d.ts +32 -0
- package/dist/client/ui/src/layout/Settings.d.ts +41 -0
- package/dist/client/ui/src/layout/Splitter.d.ts +25 -0
- package/dist/client/ui/src/lib/agent-avatar.d.ts +58 -0
- package/dist/client/ui/src/lib/code/font-stack.d.ts +12 -0
- package/dist/client/ui/src/lib/code/themes.d.ts +35 -0
- package/dist/client/ui/src/lib/date-format.d.ts +8 -0
- package/dist/client/ui/src/lib/dispatches.d.ts +8 -0
- package/dist/client/ui/src/lib/hour-style.d.ts +13 -0
- package/dist/client/ui/src/lib/number-draft.d.ts +24 -0
- package/dist/client/ui/src/lib/relative-time.d.ts +18 -0
- package/dist/client/ui/src/lib/tiling.d.ts +89 -0
- package/dist/client/ui/src/lib/typing.d.ts +19 -0
- package/dist/client/ui/src/motion/RollWords.d.ts +26 -0
- package/dist/client/ui/src/motion/RollingText.d.ts +43 -0
- package/dist/client/ui/src/motion/TypedText.d.ts +9 -0
- package/dist/client/ui/src/motion/freeze.d.ts +22 -0
- package/dist/client/ui/src/motion/held.d.ts +17 -0
- package/dist/client/ui/src/motion/loaders.d.ts +65 -0
- package/dist/client/ui/src/motion/reduced.d.ts +13 -0
- package/dist/client/ui/src/motion/ticked.d.ts +24 -0
- package/dist/client/ui/src/motion/ticker.d.ts +31 -0
- package/dist/client/ui/src/motion/tokens.d.ts +29 -0
- package/dist/client/ui/src/motion/useNow.d.ts +6 -0
- package/dist/client/ui/src/overlay/Confirm.d.ts +96 -0
- package/dist/client/ui/src/overlay/ContextMenu.d.ts +40 -0
- package/dist/client/ui/src/overlay/Dialog.d.ts +60 -0
- package/dist/client/ui/src/overlay/Menu.d.ts +90 -0
- package/dist/client/ui/src/overlay/Overlay.d.ts +17 -0
- package/dist/client/ui/src/overlay/Popover.d.ts +127 -0
- package/dist/client/ui/src/overlay/Tooltip.d.ts +14 -0
- package/dist/client/ui/src/overlay/afterimage.d.ts +20 -0
- package/dist/client/ui/src/overlay/chrome-top.d.ts +8 -0
- package/dist/client/ui/src/overlay/hover-layers.d.ts +41 -0
- package/dist/client/ui/src/overlay/portal.d.ts +21 -0
- package/dist/client/ui/src/overlay/scrims.d.ts +20 -0
- package/dist/client/ui/src/overlay/tooltip-attribute.d.ts +62 -0
- package/dist/client/ui/src/primitives/Button.d.ts +64 -0
- package/dist/client/ui/src/primitives/Caret.d.ts +25 -0
- package/dist/client/ui/src/primitives/ChoiceMark.d.ts +12 -0
- package/dist/client/ui/src/primitives/ClosableTab.d.ts +23 -0
- package/dist/client/ui/src/primitives/CountUp.d.ts +21 -0
- package/dist/client/ui/src/primitives/GitHubMark.d.ts +12 -0
- package/dist/client/ui/src/primitives/IconButton.d.ts +55 -0
- package/dist/client/ui/src/primitives/MarkNumber.d.ts +12 -0
- package/dist/client/ui/src/primitives/RowDeleteButton.d.ts +6 -0
- package/dist/client/ui/src/primitives/Skeleton.d.ts +36 -0
- package/dist/client/ui/src/primitives/TabStrip.d.ts +29 -0
- package/dist/client/ui/src/primitives/Text.d.ts +341 -0
- package/dist/client/ui/src/primitives/TimeAgo.d.ts +13 -0
- package/dist/client/ui/src/primitives/useCountUp.d.ts +23 -0
- package/dist/client/ui/src/row/FlowRow.d.ts +31 -0
- package/dist/client/ui/src/row/HoverRow.d.ts +28 -0
- package/dist/client/ui/src/scroll/BackToLatest.d.ts +19 -0
- package/dist/client/ui/src/scroll/OverlayScrollbar.d.ts +9 -0
- package/dist/client/ui/src/scroll/ScrollText.d.ts +24 -0
- package/dist/client/ui/src/scroll/Scroller.d.ts +66 -0
- package/dist/client/ui/src/scroll/Sideways.d.ts +30 -0
- package/dist/client/ui/src/scroll/fade.d.ts +2 -0
- package/dist/client/ui/src/scroll/follow.d.ts +157 -0
- package/dist/client/ui/src/scroll/measure-batch.d.ts +13 -0
- package/dist/client/ui/src/scroll/memory.d.ts +22 -0
- package/dist/client/ui/src/scroll/signature.d.ts +24 -0
- package/dist/client/ui/src/scroll/useFollowBottom.d.ts +80 -0
- package/dist/client/ui/src/scroll/useSideways.d.ts +29 -0
- package/dist/contract/src/app.d.ts +16 -0
- package/dist/contract/src/changes.d.ts +50 -0
- package/dist/contract/src/diagnostics.d.ts +86 -0
- package/dist/contract/src/index.d.ts +18 -0
- package/dist/contract/src/plugin.d.ts +1391 -0
- package/dist/contract/src/resources.d.ts +79 -0
- package/dist/contract/src/service.d.ts +806 -0
- package/dist/contract/src/ui.d.ts +1039 -0
- package/dist/contract/src/usage.d.ts +102 -0
- package/dist/core/llm/ai/anthropic-messages-request.d.ts +82 -0
- package/dist/core/llm/ai/anthropic-messages.d.ts +43 -0
- package/dist/core/llm/ai/cache-routing.d.ts +53 -0
- package/dist/core/llm/ai/chat-delta.d.ts +107 -0
- package/dist/core/llm/ai/compat-key.d.ts +19 -0
- package/dist/core/llm/ai/endpoint.d.ts +57 -0
- package/dist/core/llm/ai/failure.d.ts +181 -0
- package/dist/core/llm/ai/index.d.ts +16 -0
- package/dist/core/llm/ai/openai-chat-completions-request.d.ts +49 -0
- package/dist/core/llm/ai/openai-chat-completions.d.ts +37 -0
- package/dist/core/llm/ai/openai-responses-request.d.ts +63 -0
- package/dist/core/llm/ai/openai-responses.d.ts +11 -0
- package/dist/core/llm/ai/prefix-fingerprint.d.ts +20 -0
- package/dist/core/llm/ai/reasoning-compat.d.ts +69 -0
- package/dist/core/llm/ai/request-params-compat.d.ts +39 -0
- package/dist/core/llm/ai/retry.d.ts +130 -0
- package/dist/core/llm/ai/sanitize-history.d.ts +23 -0
- package/dist/core/llm/ai/think-tag.d.ts +37 -0
- package/dist/core/llm/ai/thinking-options.d.ts +35 -0
- package/dist/core/llm/ai/tool-names.d.ts +17 -0
- package/dist/core/llm/ai/tool-pairing-compat.d.ts +53 -0
- package/dist/core/llm/ai/tool-result-images-compat.d.ts +24 -0
- package/dist/core/llm/ai/tool-schema.d.ts +20 -0
- package/dist/core/llm/ai/usage-fields.d.ts +30 -0
- package/dist/core/llm/ai/vendors/index.d.ts +20 -0
- package/dist/core/llm/ai/vendors/thinking.d.ts +39 -0
- package/dist/core/llm/ai/vendors/types.d.ts +47 -0
- package/dist/core/llm/config/image-models.d.ts +34 -0
- package/dist/core/llm/config/retry-policy.d.ts +35 -0
- package/dist/core/llm/images/chat-images.d.ts +11 -0
- package/dist/core/llm/images/dimensions.d.ts +15 -0
- package/dist/core/llm/images/generate.d.ts +15 -0
- package/dist/core/llm/images/openai-images.d.ts +11 -0
- package/dist/core/llm/images/quota.d.ts +9 -0
- package/dist/core/llm/images/shape.d.ts +44 -0
- package/dist/core/llm/images/types.d.ts +118 -0
- package/dist/core/llm/model-catalog-format.d.ts +50 -0
- package/dist/core/llm/model-catalog.d.ts +51 -0
- package/dist/core/llm/types/message.d.ts +450 -0
- package/dist/core/llm/types/provider.d.ts +169 -0
- package/dist/core/llm/types/tool.d.ts +23 -0
- package/dist/core/llm/types.d.ts +10 -0
- package/dist/core/llm/utils/pricing.d.ts +18 -0
- package/dist/core/llm/utils/record.d.ts +2 -0
- package/dist/core/llm/utils/sse.d.ts +69 -0
- package/dist/infra/rpc/src/endpoint.d.ts +36 -0
- package/dist/infra/rpc/src/index.d.ts +2 -0
- package/dist/infra/rpc/src/rpc.d.ts +54 -0
- package/dist/theme.css +336 -0
- package/dist/ui.d.ts +2 -0
- package/lib/build.mjs +143 -0
- package/lib/check.mjs +23 -0
- package/lib/dev.mjs +52 -0
- package/lib/icons.mjs +2 -0
- package/lib/init.mjs +109 -0
- package/lib/install.mjs +80 -0
- package/lib/link.mjs +44 -0
- package/lib/lint/i18n.mjs +149 -0
- package/lib/lint/imports.mjs +83 -0
- package/lib/lint/index.mjs +54 -0
- package/lib/lint/styles.mjs +160 -0
- package/lib/manifest.d.mts +9 -0
- package/lib/manifest.mjs +99 -0
- package/lib/targets.mjs +60 -0
- package/package.json +34 -4
- package/skill/SKILL.md +150 -0
- package/skill/references/components.md +2830 -0
- package/skill/references/logic.md +526 -0
- package/skill/references/style-i18n.md +70 -0
- package/skill/references/ui.md +532 -0
- package/template/AGENTS.md +17 -0
- package/template/CLAUDE.md +1 -0
- package/template/README.md +12 -0
- package/template/gitignore +2 -0
- package/template/src/index.ts +28 -0
- package/template/src/messages.ts +16 -0
- package/template/src/types.ts +8 -0
- package/template/src/ui.tsx +30 -0
- package/template/tsconfig.json +7 -0
- package/tsconfig.json +25 -0
- package/README.md +0 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wJiaaa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* plume-plugin:新建、检查、构建、安装 Plume 插件。随 Plume 应用发,应用启动时生成 `~/.plume/bin/plume-plugin`,
|
|
4
|
+
* 用 Plume 自己的运行时跑这个文件,插件作者的机器上不用装 Node 和 npm。
|
|
5
|
+
*
|
|
6
|
+
* plume-plugin init <目录> [--name 插件名] [--display 市场里的名字]
|
|
7
|
+
* plume-plugin check [目录] 类型检查和插件规则(公开接口、样式、文案),缺省当前目录
|
|
8
|
+
* plume-plugin build [目录]
|
|
9
|
+
* plume-plugin install [目录] [--to 目录] 装进 ~/.plume/plugins,Plume 开着就当场加载
|
|
10
|
+
* plume-plugin dev [目录] [--to 目录] 构建、装上,之后一改源码就重新来一遍
|
|
11
|
+
* plume-plugin link [目录] 重新链到这份 SDK(Plume 挪了位置、npm 删了链接时)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { buildPlugin } from "../lib/build.mjs";
|
|
15
|
+
import { checkPlugin } from "../lib/check.mjs";
|
|
16
|
+
import { devPlugin } from "../lib/dev.mjs";
|
|
17
|
+
import { initPlugin } from "../lib/init.mjs";
|
|
18
|
+
import { installPlugin } from "../lib/install.mjs";
|
|
19
|
+
import { linkSdk } from "../lib/link.mjs";
|
|
20
|
+
|
|
21
|
+
const USAGE = `用法:
|
|
22
|
+
plume-plugin init <目录> [--name 插件名] [--display 市场里的名字]
|
|
23
|
+
plume-plugin check [目录]
|
|
24
|
+
plume-plugin build [目录]
|
|
25
|
+
plume-plugin install [目录] [--to 目录]
|
|
26
|
+
plume-plugin dev [目录] [--to 目录]
|
|
27
|
+
plume-plugin link [目录]`;
|
|
28
|
+
|
|
29
|
+
const [command, ...rest] = process.argv.slice(2);
|
|
30
|
+
const positional = [];
|
|
31
|
+
const flags = {};
|
|
32
|
+
for (let index = 0; index < rest.length; index++) {
|
|
33
|
+
const arg = rest[index];
|
|
34
|
+
if (arg.startsWith("--")) flags[arg.slice(2)] = rest[++index];
|
|
35
|
+
else positional.push(arg);
|
|
36
|
+
}
|
|
37
|
+
const dir = positional[0] ?? process.cwd();
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
if (command === "init") {
|
|
41
|
+
if (!positional[0]) throw new Error(USAGE);
|
|
42
|
+
const created = initPlugin(positional[0], { name: flags.name, displayName: flags.display });
|
|
43
|
+
console.log(`✓ ${created.name} → ${created.dir}`);
|
|
44
|
+
console.log(
|
|
45
|
+
created.workspace
|
|
46
|
+
? " 在仓库根目录跑 pnpm install,再 pnpm build:plugins"
|
|
47
|
+
: " 写法见 .claude/skills/plume-plugin/SKILL.md;写完 plume-plugin check、plume-plugin dev",
|
|
48
|
+
);
|
|
49
|
+
} else if (command === "check") {
|
|
50
|
+
if (!(await checkPlugin(dir))) process.exitCode = 1;
|
|
51
|
+
else console.log("✓ 检查通过");
|
|
52
|
+
} else if (command === "build") {
|
|
53
|
+
console.log(`✓ ${await buildPlugin(dir)}`);
|
|
54
|
+
} else if (command === "install") {
|
|
55
|
+
console.log(`✓ 装到 ${installPlugin(dir, flags.to)};Plume 开着的话已经加载`);
|
|
56
|
+
} else if (command === "dev") {
|
|
57
|
+
devPlugin(dir, { root: flags.to });
|
|
58
|
+
console.log("盯着 src/、package.json、README.md,改了就重新构建、装上;Ctrl+C 结束");
|
|
59
|
+
} else if (command === "link") {
|
|
60
|
+
linkSdk(dir);
|
|
61
|
+
console.log("✓ 已链到这份 SDK");
|
|
62
|
+
} else {
|
|
63
|
+
console.log(USAGE);
|
|
64
|
+
if (command && command !== "help" && command !== "--help") process.exitCode = 1;
|
|
65
|
+
}
|
|
66
|
+
} catch (error) {
|
|
67
|
+
// esbuild 的报错它自己已经打过了。
|
|
68
|
+
if (!error?.errors) console.error(`✗ ${error instanceof Error ? error.message : String(error)}`);
|
|
69
|
+
process.exitCode = 1;
|
|
70
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 共用的 Tailwind 类名组合:控件、卡片、代码、几种文字。产品界面、@plume/ui 的组件、插件的界面入口都从这里取,
|
|
3
|
+
* 改一处外观各处一起变。只用 theme.css 里的 token。
|
|
4
|
+
*
|
|
5
|
+
* 产品的 Tailwind 扫描这个包,这里写到的类一定会生成:第三方插件自己写的 Tailwind 类扫不到,用这里导出的组合可以。
|
|
6
|
+
* 只在一个页面用一次的布局(栅格、窗口顶行、页面边距)写在用的地方,不放进来。
|
|
7
|
+
*/
|
|
8
|
+
export declare const text: {
|
|
9
|
+
/** 次要说明:路径、状态、空状态。 */
|
|
10
|
+
faint: string;
|
|
11
|
+
error: string;
|
|
12
|
+
link: string;
|
|
13
|
+
};
|
|
14
|
+
/** 单行输入框和下拉框:无描边的一块 card 底,悬停、聚焦时深一档。高度只有 control 这一档。 */
|
|
15
|
+
export declare const field = "h-control min-w-0 rounded-field bg-card px-4 text-label text-ink outline-none transition-colors placeholder:text-ink-faint hover:bg-card-hover focus:bg-card-hover";
|
|
16
|
+
/** 包住输入框的 label:上面一行小字,下面是控件。 */
|
|
17
|
+
export declare const fieldLabel = "flex flex-col gap-1.5 text-caption font-medium text-ink-muted";
|
|
18
|
+
/** 多行输入框:没有框,放进自己画框的容器里(主输入框那种),外观由容器出。 */
|
|
19
|
+
export declare const textarea = "min-w-0 resize-none bg-transparent text-body text-ink outline-none placeholder:text-ink-faint";
|
|
20
|
+
type ButtonVariant = "primary" | "ghost" | "subtle" | "soft" | "danger";
|
|
21
|
+
/**
|
|
22
|
+
* 按钮:五种外观、三档高度。焦点环是全局的(见渲染进程的 styles.css);按下不缩放,底色深一档。
|
|
23
|
+
* 组件见 @plume/ui 的 Button,一般不直接拼这些。
|
|
24
|
+
*/
|
|
25
|
+
export declare const button: {
|
|
26
|
+
/** 禁用时不关掉指针事件:悬停提示要能解释它为什么不能按。 */
|
|
27
|
+
base: string;
|
|
28
|
+
/** md 32 是默认,对话框和表单底部的按钮;sm 26 给面板里的行;xs 20 给跟在一行小字后面的动作,圆角随之降到 6px。 */
|
|
29
|
+
size: {
|
|
30
|
+
md: string;
|
|
31
|
+
sm: string;
|
|
32
|
+
xs: string;
|
|
33
|
+
};
|
|
34
|
+
/** 只有图标时是正方形,图标居中;有字时字从左边起。 */
|
|
35
|
+
square: {
|
|
36
|
+
md: string;
|
|
37
|
+
sm: string;
|
|
38
|
+
xs: string;
|
|
39
|
+
};
|
|
40
|
+
pad: {
|
|
41
|
+
md: string;
|
|
42
|
+
sm: string;
|
|
43
|
+
xs: string;
|
|
44
|
+
};
|
|
45
|
+
variant: {
|
|
46
|
+
/** 一处只有一个,要按的那个:前景色压在底色上,不引入新的颜色也读得出是实心的。 */
|
|
47
|
+
primary: string;
|
|
48
|
+
/** 描边,平常的按钮,放在 primary 旁边。 */
|
|
49
|
+
ghost: string;
|
|
50
|
+
/** 没有描边,一排动作不想在面板上画出格子时用。 */
|
|
51
|
+
subtle: string;
|
|
52
|
+
/** 有底没描边:放在 primary 旁边、指针没过来之前就要读得出是按钮的一排选择。 */
|
|
53
|
+
soft: string;
|
|
54
|
+
/** 破坏性操作。只在悬停时上色:一排红按钮没人会读。 */
|
|
55
|
+
danger: string;
|
|
56
|
+
};
|
|
57
|
+
/** 一组选择里选中的那个:悬停态一直保持。只有 ghost 和 subtle 有。 */
|
|
58
|
+
pressed: Partial<Record<ButtonVariant, string>>;
|
|
59
|
+
/** 忙碌:和 disabled 分开,读起来是“在做”,不是“不能按”。宽度不变。 */
|
|
60
|
+
loading: string;
|
|
61
|
+
};
|
|
62
|
+
/** 图标按钮:平时是淡的字色,悬停才有底。按下底色深一档,不缩放。组件见 @plume/ui 的 IconButton。 */
|
|
63
|
+
export declare const iconButton: {
|
|
64
|
+
/** 禁用时不关掉指针事件:`explainDisabled` 要靠悬停提示说明为什么不能按。 */
|
|
65
|
+
base: string;
|
|
66
|
+
/**
|
|
67
|
+
* xs 20 是标题行和一行小字的高度,圆角随之降到 6px。composer 跟着主输入框工具栏的控件边长走,
|
|
68
|
+
* 那个尺寸变了,这一排仍然是一行。
|
|
69
|
+
*/
|
|
70
|
+
size: {
|
|
71
|
+
xs: string;
|
|
72
|
+
sm: string;
|
|
73
|
+
md: string;
|
|
74
|
+
composer: string;
|
|
75
|
+
};
|
|
76
|
+
tone: {
|
|
77
|
+
default: string;
|
|
78
|
+
danger: string;
|
|
79
|
+
};
|
|
80
|
+
/** 开着的开关,比如“区分大小写”。 */
|
|
81
|
+
active: string;
|
|
82
|
+
/** 一排里现在值得按的那个:满色的字,不是实心按钮。 */
|
|
83
|
+
emphasis: string;
|
|
84
|
+
};
|
|
85
|
+
export declare const card: {
|
|
86
|
+
frame: string;
|
|
87
|
+
head: string;
|
|
88
|
+
title: string;
|
|
89
|
+
subtitle: string;
|
|
90
|
+
status: string;
|
|
91
|
+
body: string;
|
|
92
|
+
/** 按语气换边框和标题行的底色。 */
|
|
93
|
+
tone: {
|
|
94
|
+
default: {
|
|
95
|
+
frame: string;
|
|
96
|
+
head: string;
|
|
97
|
+
};
|
|
98
|
+
error: {
|
|
99
|
+
frame: string;
|
|
100
|
+
head: string;
|
|
101
|
+
};
|
|
102
|
+
warning: {
|
|
103
|
+
frame: string;
|
|
104
|
+
head: string;
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
/** 卡片底部一行:左边是说明,右边是按钮。 */
|
|
109
|
+
export declare const actions: {
|
|
110
|
+
row: string;
|
|
111
|
+
note: string;
|
|
112
|
+
};
|
|
113
|
+
export declare const code: {
|
|
114
|
+
block: string;
|
|
115
|
+
diff: string;
|
|
116
|
+
diffLine: string;
|
|
117
|
+
diffKind: {
|
|
118
|
+
same: string;
|
|
119
|
+
add: string;
|
|
120
|
+
remove: string;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 一个智能体的脸:一块有颜色的形状,一双会眨的眼睛。
|
|
3
|
+
*
|
|
4
|
+
* 表情就是状态。面板里一排子智能体,谁在干活、谁在排队、谁做完了、谁出了事,从眼睛就读得
|
|
5
|
+
* 出来,不用每张脸旁边再挂一个字:
|
|
6
|
+
*
|
|
7
|
+
* idle 睁着眼,时不时眨一下
|
|
8
|
+
* working 上下轻轻颠着,眼睛左右扫——像在翻东西
|
|
9
|
+
* waiting 眯着眼、褪了色,还没轮到它
|
|
10
|
+
* done 眯成两道弯,满意了
|
|
11
|
+
* failed 叉叉眼
|
|
12
|
+
* stopped 闭着眼,被人叫停了
|
|
13
|
+
*
|
|
14
|
+
* 眨眼不用 CSS 的无限循环:那样哪怕一屏二十张脸都在屏幕外,动画时钟也一直在走。这里每张脸
|
|
15
|
+
* 自己排下一次眨眼的时间,看不见就跳过——两次眨眼之间什么都不跑。
|
|
16
|
+
*/
|
|
17
|
+
import { type Avatar } from "../lib/agent-avatar.ts";
|
|
18
|
+
import type { DispatchState } from "../lib/dispatches.ts";
|
|
19
|
+
export type AvatarMood = "idle" | DispatchState;
|
|
20
|
+
export interface AgentAvatarProps {
|
|
21
|
+
avatar: Avatar;
|
|
22
|
+
/** 像素边长。 */
|
|
23
|
+
size?: number;
|
|
24
|
+
mood?: AvatarMood;
|
|
25
|
+
/** 右下角的小圆点:在跑是强调色、会一圈圈往外扩;出错是红的。 */
|
|
26
|
+
badge?: "running" | "failed" | null;
|
|
27
|
+
/**
|
|
28
|
+
* 悬停时眼睛跟着指针、身子弹一下。默认开。
|
|
29
|
+
*
|
|
30
|
+
* `host` 是往上找的那个容器:一整行的任何地方悬停都算,而不是非得对准这 20 像素。
|
|
31
|
+
*/
|
|
32
|
+
interactive?: boolean;
|
|
33
|
+
host?: string;
|
|
34
|
+
/** 名字,决定眨眼的节奏——七张脸不该踩着同一个拍子。 */
|
|
35
|
+
seed?: string;
|
|
36
|
+
/** 默认是装饰:名字总在旁边写着。单独出现、没有字陪着的时候才给它一个名字。 */
|
|
37
|
+
label?: string;
|
|
38
|
+
/** 换一个值就蹦一下——刚保存好、刚换了脸,给它一个「是我」的回应。 */
|
|
39
|
+
cheer?: string | number | null;
|
|
40
|
+
className?: string;
|
|
41
|
+
}
|
|
42
|
+
export declare function AgentAvatar({ avatar, size, mood, badge, interactive, host, seed, label, cheer, className, }: AgentAvatarProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 一摞脸:派出去不止一个时,叠在一起说「有好几个」。
|
|
3
|
+
*
|
|
4
|
+
* 和 `AvatarStack` 是两件事。那一排并排摆开,每张脸都看得清表情,适合「这一批都是谁」的场合;
|
|
5
|
+
* 这一摞叠着放,占地方小,说的是「这里有好几个,点开看」——放在一行字旁边、一个切换器上这类挤的地方。
|
|
6
|
+
* 表情仍然在:在跑的还在颠,只是被邻居盖住半张脸。
|
|
7
|
+
*
|
|
8
|
+
* 叠放有先后:后一张压在前一张上面,像一张一张往右放下去的牌,最后放下的那张完整露出来,「+N」
|
|
9
|
+
* 是最后一张。反过来(前一张压后一张)时,「+2」的加号被它左边那张盖住,读出来像「-2」,一摞
|
|
10
|
+
* 牌也像是从右往左倒着放的。
|
|
11
|
+
*
|
|
12
|
+
* 每张脸垫一枚圆底,叠起来才分得清谁是谁:形状各不相同的脸直接叠,三角压着云朵,读起来是一团
|
|
13
|
+
* 色块。被压住的那枚在上一枚的位置被挖掉,不是被涂盖,所以无论底下是什么,都透不出下面那张脸
|
|
14
|
+
* (`@plume/styles` 的 `ui/motion.css`)。指针进来的时候这一摞往右松开一点,像一叠牌被拨开。
|
|
15
|
+
*/
|
|
16
|
+
import type { Avatar } from "../lib/agent-avatar.ts";
|
|
17
|
+
import { type AvatarMood } from "./AgentAvatar.tsx";
|
|
18
|
+
export interface PileFace {
|
|
19
|
+
key: string;
|
|
20
|
+
avatar: Avatar;
|
|
21
|
+
mood?: AvatarMood;
|
|
22
|
+
seed: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function AvatarPile({ faces, size, max, focus, className, }: {
|
|
25
|
+
faces: PileFace[];
|
|
26
|
+
size?: number;
|
|
27
|
+
max?: number;
|
|
28
|
+
/**
|
|
29
|
+
* 要完整露出来的那一张(面板顶上:正在看的那个)。
|
|
30
|
+
*
|
|
31
|
+
* 它排在露出来的那几张的最后——也就是最上面,紧挨着旁边写它名字的标题。放不下的时候先让出别人的
|
|
32
|
+
* 位置,它自己一定在。
|
|
33
|
+
*/
|
|
34
|
+
focus?: string;
|
|
35
|
+
className?: string;
|
|
36
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 一排小脸:这一批派出去的是谁、各自在干什么。
|
|
3
|
+
*
|
|
4
|
+
* 并排而不是叠着:叠起来的头像组说的是「有这么些人」,而这里每张脸自己有话说——谁在颠着干活、
|
|
5
|
+
* 谁眯着眼在排队、谁已经交差——被邻居盖住半张脸,表情就读不出来了。
|
|
6
|
+
*
|
|
7
|
+
* 放不下的收成一个「+N」,数字本身就是提示:想看全的点开面板。
|
|
8
|
+
*/
|
|
9
|
+
import type { Avatar } from "../lib/agent-avatar.ts";
|
|
10
|
+
import { type AvatarMood } from "./AgentAvatar.tsx";
|
|
11
|
+
export interface StackFace {
|
|
12
|
+
key: string;
|
|
13
|
+
avatar: Avatar;
|
|
14
|
+
mood?: AvatarMood;
|
|
15
|
+
/** 名字,决定眨眼的节奏。 */
|
|
16
|
+
seed: string;
|
|
17
|
+
/** 悬停时的那句话,同时是读屏念的名字。 */
|
|
18
|
+
tip: string;
|
|
19
|
+
onClick?: () => void;
|
|
20
|
+
}
|
|
21
|
+
export declare function AvatarStack({ faces, size, max, className }: {
|
|
22
|
+
faces: StackFace[];
|
|
23
|
+
size?: number;
|
|
24
|
+
max?: number;
|
|
25
|
+
className?: string;
|
|
26
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 每种形状的轮廓、脸在哪,和每种颜色的色值。
|
|
3
|
+
*
|
|
4
|
+
* 都画在 100×100 的格子里,身体大致占 10–90:留出边是给悬停时那一下「果冻」——压扁时会横着
|
|
5
|
+
* 胀出去一截,贴边画的话那一截会被裁掉。
|
|
6
|
+
*
|
|
7
|
+
* `face` 是两只眼睛的中点。不是每个形状都在正中:三角形的肚子在下半截,云的上沿全是鼓包,
|
|
8
|
+
* 眼睛放在几何中心会挤到边上去。整体都往右上偏一点,这张脸就是在「看着」右边的名字。
|
|
9
|
+
*/
|
|
10
|
+
import type { AvatarColor, AvatarShape } from "../lib/agent-avatar.ts";
|
|
11
|
+
export interface ShapeArt {
|
|
12
|
+
d: string;
|
|
13
|
+
/** 只有水滴用:它是歪着的,歪在路径外面比把每个坐标都转一遍好改。 */
|
|
14
|
+
transform?: string;
|
|
15
|
+
face: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
gap: number;
|
|
19
|
+
scale: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare const SHAPE_ART: Record<AvatarShape, ShapeArt>;
|
|
23
|
+
/**
|
|
24
|
+
* 眼睛的颜色,亮暗主题都是它:眼睛长在身体上,不长在窗口上,窗口底色换了它也不该跟着换。
|
|
25
|
+
* 和身体的颜色一样是这幅画自己的颜料,不是界面的 token,所以写在这里而不是样式表里。
|
|
26
|
+
*/
|
|
27
|
+
export declare const EYE_ART = "#141417";
|
|
28
|
+
/**
|
|
29
|
+
* 色值是亮暗两种主题共用的一套中等明度:眼睛是深色的,身体太暗眼睛就看不见,太浅在白底上
|
|
30
|
+
* 就化开了。所以没有黑、没有灰、也没有嫩黄。
|
|
31
|
+
*/
|
|
32
|
+
export declare const COLOR_ART: Record<AvatarColor, string>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type LucideIcon } from "./icons/index.ts";
|
|
2
|
+
/**
|
|
3
|
+
* 一个文件在列表里长什么样。
|
|
4
|
+
*
|
|
5
|
+
* 颜色是重点。四十行一样灰的树得一行一行读;同一棵树有了 TypeScript 的蓝、JSON 的琥珀、Markdown 的
|
|
6
|
+
* 石板灰,一眼就读完了,因为眼睛先找到一组,再读名字。
|
|
7
|
+
*
|
|
8
|
+
* 色相跟着人们在编辑器里已经习惯的约定走——TS 蓝、JS 黄、Rust 锈色——而不是这里另起一套。没人认得
|
|
9
|
+
* 的配色只是装饰。
|
|
10
|
+
*
|
|
11
|
+
* 每种颜色都给两套主题各一个值:在白底上读得清的中间调,放到近黑的底上是浑的,反过来也一样。
|
|
12
|
+
*/
|
|
13
|
+
export interface FileLook {
|
|
14
|
+
Icon: LucideIcon;
|
|
15
|
+
/** 不走 Tailwind:行内设上,因为这些颜色不在主题推导的色阶里。 */
|
|
16
|
+
light: string;
|
|
17
|
+
dark: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function lookFor(name: string, isDirectory: boolean, expanded?: boolean): FileLook;
|
|
20
|
+
/** 取在当前主题下读得清的那个色值。深浅色跟随系统,和 theme.css 的 `prefers-color-scheme` 一致。 */
|
|
21
|
+
export declare function iconColour(look: FileLook): string;
|
|
22
|
+
/**
|
|
23
|
+
* 附件标记前面那枚图标该是什么:和文件树、回复里的文件链接同一张表。
|
|
24
|
+
*
|
|
25
|
+
* 只按门类画的话(`.plume-attachment-token[data-kind]` 那十几枚),`starship.toml`、`a.ts`、`x.json`
|
|
26
|
+
* 都落在「文本」那一档,是同一张灰纸,文件夹也只是另一种灰。表里认不出的(Word、表格、压缩包……)
|
|
27
|
+
* 返回 `null`,由门类图标接着画——那些本来就按常见配色挑过,比通用的灰纸强。
|
|
28
|
+
*/
|
|
29
|
+
export declare function tokenLook(name: string | undefined, kind?: string): FileLook | null;
|
|
30
|
+
/** 画出来的那一枚。大小和位置由 `.plume-token-glyph` 定,和门类图标住同一个位置。 */
|
|
31
|
+
export declare function TokenGlyph({ look }: {
|
|
32
|
+
look: FileLook;
|
|
33
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 复制键按下之后那个对钩:亮一会儿,自己变回去。
|
|
3
|
+
*
|
|
4
|
+
* 没有这一下,复制和没复制在屏幕上长得一模一样——剪贴板是个看不见的地方,人会忍不住再按一次。
|
|
5
|
+
* 各处各写一份的话,停留时长各不相同,有的卸载时不清定时器、有的压根不变回去。
|
|
6
|
+
*
|
|
7
|
+
* 只管对钩,不管怎么写剪贴板:渲染进程里有的走 `navigator.clipboard`,有的走主进程,而 `ui/`
|
|
8
|
+
* 不调 service。写成功了再 `mark`,写失败就别亮。
|
|
9
|
+
*
|
|
10
|
+
* `T` 是「亮的是哪一个」:同一页上有两枚复制键(链接和口令)时,亮的只该是按下的那枚。
|
|
11
|
+
*/
|
|
12
|
+
export declare function useCopied<T = true>(): {
|
|
13
|
+
copied: T | null;
|
|
14
|
+
mark: (which: T) => void;
|
|
15
|
+
reset: () => void;
|
|
16
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 让某样东西跟着正在干活的 agent 走,而不是等它这一轮结束。
|
|
3
|
+
*
|
|
4
|
+
* 每个汇报工作区状态的界面原本都是同一个形状——`running` 变回 false 时重读一次——也都有同一个毛病:
|
|
5
|
+
* 一轮花四分钟改文件,git 面板和改动计数显示的是四分钟前的样子。说明「积了多少没看过」的那个数,
|
|
6
|
+
* 反倒是窗口里最后一个知道的。
|
|
7
|
+
*
|
|
8
|
+
* 轮询,而不是从工具结果驱动,这是有意的。写文件的不只是工具:跑格式化的 `bash`、agent 写完又执行的
|
|
9
|
+
* 脚本、窗口旁边开着的编辑器。问一次 git 很便宜,而且对所有这些都对;一张「会写文件的工具」清单是
|
|
10
|
+
* 猜测,下次加一个工具它就过时了。
|
|
11
|
+
*
|
|
12
|
+
* 挂载时刷新一次,一轮结束时再刷新一次,所以最终状态不会落后一个轮询间隔;`touchWorkingTree` 时也刷新,
|
|
13
|
+
* 管两轮之间改动工作区的事。窗口回到前台时也刷新:在旁边终端里切分支、改文件时没有东西在轮询,而回来
|
|
14
|
+
* 正是人要看的时候。
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* 工作区刚被不是一轮对话的东西改过——比如撤销把文件放了回去。
|
|
18
|
+
*
|
|
19
|
+
* 空闲时没有东西轮询,没有这个的话,改动计数会一直停在文件放回去之前的数,直到下一轮结束。
|
|
20
|
+
*/
|
|
21
|
+
export declare function touchWorkingTree(): void;
|
|
22
|
+
export declare function useLiveRefresh(refresh: () => void | Promise<void>, running: boolean, ms?: number): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 一个元素是不是窄到放不下两栏,按元素自己量。
|
|
3
|
+
*
|
|
4
|
+
* 面板里的内容没法问窗口自己有多宽——同一个组件既跑在 368px 的面板里,也跑在整列宽的正文里。
|
|
5
|
+
* 这里看的是它实际拿到的那个盒子。
|
|
6
|
+
*
|
|
7
|
+
* 第一次测量在节点一到就做,而不是留给 observer 的首次回调。那次回调在绘制之后才到,一个从 `false`
|
|
8
|
+
* 起步的组件会先画一帧错的布局——更糟的是,挂在这次翻转上的东西(比如列表/详情的重置)会在用户已经
|
|
9
|
+
* 动手之后晚一拍才触发,把刚做的操作撤掉。
|
|
10
|
+
*
|
|
11
|
+
* 用回调 ref,不用 ref 对象。这不是风格问题:`useRef` + `useLayoutEffect` 只在 effect 第一次运行时
|
|
12
|
+
* 挂 observer,一个先渲染了*别的*东西的组件——比如项目加载时的空状态——要么根本没挂上,要么挂到一个
|
|
13
|
+
* 随后被换掉的节点上。两种情况下 observer 都在看一个不存在的东西,标记停在碰巧的那个值上,一个开到
|
|
14
|
+
* 全屏的面板在一千像素宽时还在画堆叠布局。React 每次节点变化都会调用回调 ref,而节点变化正是要紧的那件事。
|
|
15
|
+
*/
|
|
16
|
+
export declare function useNarrow(threshold: number): [boolean, (node: HTMLDivElement | null) => void];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type UiLocale } from "./locales.ts";
|
|
2
|
+
import type { MessageKey, ResolvedUiLocale } from "./messages/index.ts";
|
|
3
|
+
import { type MessageVariables } from "./translate.ts";
|
|
4
|
+
interface I18nValue {
|
|
5
|
+
locale: UiLocale;
|
|
6
|
+
resolvedLocale: ResolvedUiLocale;
|
|
7
|
+
t: (key: MessageKey, variables?: MessageVariables) => string;
|
|
8
|
+
formatNumber: (value: number, options?: Intl.NumberFormatOptions) => string;
|
|
9
|
+
formatDate: (value: Date | number, options?: Intl.DateTimeFormatOptions) => string;
|
|
10
|
+
}
|
|
11
|
+
export declare function I18nProvider({ locale, children }: {
|
|
12
|
+
locale: UiLocale;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
}): import("react").JSX.Element;
|
|
15
|
+
/** 当前界面语言和产品的文案目录。插件只用 `resolvedLocale` 选自己 `messages.ts` 里的那一份;`t()` 查的是产品的目录,插件的文字不在里面。 */
|
|
16
|
+
export declare function useI18n(): I18nValue;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A list of things, punctuated the way the interface language punctuates one.
|
|
3
|
+
*
|
|
4
|
+
* Lists used to be joined with a hardcoded 「、」, so the English interface summed up a run of tool
|
|
5
|
+
* calls as "Read files merge.ts、Created files merge.test.ts". The separator belongs to the language,
|
|
6
|
+
* not to the sentence it sits in, which is why it is looked up here instead of written at each call.
|
|
7
|
+
*
|
|
8
|
+
* It comes from `Intl.ListFormat`, but not from `format()`: a conjunction style closes a list with
|
|
9
|
+
* "and" — "and" in English at `long` — and a summary line is a tally, not a sentence. `type: "unit"`
|
|
10
|
+
* has no conjunction, but CLDR joins Chinese units with nothing at all (the pattern behind
|
|
11
|
+
* 「3小时20分钟」), which would run the parts together. What is left is the literal between two middle
|
|
12
|
+
* items: the language's own list comma, which never carries a conjunction — 「、」 in Chinese,
|
|
13
|
+
* ", " in English.
|
|
14
|
+
*
|
|
15
|
+
* For items of one kind. Fields or clauses — a name and its description — take `common.comma`
|
|
16
|
+
* instead, because Chinese separates those with 「,」 rather than 「、」.
|
|
17
|
+
*/
|
|
18
|
+
import type { ResolvedUiLocale } from "./messages/index.ts";
|
|
19
|
+
/** `items`, joined for the language the window is set to — or for `locale`, when a caller has one. */
|
|
20
|
+
export declare function formatList(items: readonly string[], locale?: ResolvedUiLocale): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MessageKey, ResolvedUiLocale } from "./messages/index.ts";
|
|
2
|
+
/** 界面语言的设置值:跟随系统,或者指定一种。 */
|
|
3
|
+
export type UiLocale = "system" | ResolvedUiLocale;
|
|
4
|
+
export interface LocaleOption {
|
|
5
|
+
value: UiLocale;
|
|
6
|
+
mark: string;
|
|
7
|
+
label: MessageKey;
|
|
8
|
+
}
|
|
9
|
+
export declare const LOCALE_OPTIONS: readonly LocaleOption[];
|
|
10
|
+
export declare function resolveUiLocale(locale: UiLocale, languages: readonly string[]): ResolvedUiLocale;
|