Ephemeral-AI-Lab/mayfly--packages-ui ↗★ 22
@ephemeral-ai/mayfly-ui
Renderer-neutral contracts, builders, and UI contribution services for Mayfly
安裝
此插件尚未提供可驗證的 bundle,或相容性檢查未通過。請先閱讀倉庫說明。 閱讀完整 README ↗
說明文件
閱讀完整 README ↗@ephemeral-ai/mayfly-ui
Pure, renderer-neutral builders for Mayfly's public UI wire format. The ui
namespace recursively clones caller data, then creates deeply frozen
MayflyUiNode objects with the same shape a plugin can write by hand. It includes
every content leaf, flex and viewport children, row/column stacks, surfaces,
scrolling, explicit Markdown and Mermaid nodes, structured charts, controlled patterns,
progress, spacers, and dividers. Plain nodes can
enter a stack directly; use ui.child only when child layout metadata is needed.
Caller-owned data is isolated. Snapshots already created by this module may be shared across builders and registry updates without cloning their immutable subtrees again. Arbitrary frozen objects do not receive this optimization. Wire data must not contain cycles or accessor properties; getters are rejected without being executed. Registration identity remains fixed even if the caller later changes the original definition.
import { defineMayflyComponent, ui } from '@ephemeral-ai/mayfly-ui'
export const metric = defineMayflyComponent({
id: '@acme/metric',
render: props => ui.surface({
title: props.label,
child: ui.stack.column([
ui.child(ui.progress({ value: props.value, max: 100 }), {
grow: 1,
when: { minWidth: 40 },
}),
]),
}),
})
Compose
compose is the one layered shell for visible UI:
import { compose, ui } from '@ephemeral-ai/mayfly-ui'
const surface = compose.panel({
title: 'Plugins',
escapeLabel: 'close',
body: compose.browser({
list: ui.list({ id: 'plugins', role: 'browse', selectedIds: [], items: [] }),
detail: ui.text('Select a plugin'),
}),
})
panel is a command Panel (overlay chrome, editor slot). decisionLane is the one lane for agent requests;
decisionStrip is a user-triggered Yes/No lane (y/n, Esc no). tabs, wizard, rail, browser, statusPage, and
completionPalette are body-only compositions. tabs is horizontal tabs over arbitrary pages; rail is the
vertical equivalent with a column rule. Product command panels are keys-only: no visible Save/Cancel/Close
buttons; multi-field forms save with the last field's Enter and Ctrl+S.
defineMayflyComponent records a package-namespaced id, then deeply freezes
each rendered node. It is a pure package-level factory, not a
runtime registry. Core still validates node kinds, values, depth, quotas, and
renderer safety when a plugin contributes the expanded tree.
The root entry is side-effect free. The explicit ./provider entry owns the four
Fiber-scoped snapshot registries; handles publish with set() and remove with
dispose(). A snapshot is frozen before its revision advances. set() is a
data refresh (reason: 'data') or a new instance boundary
(reason: 'replace', the only update that may change scope); callbacks do
not create acknowledgements — action handlers return structured replies that
core admits before a single-use publisher updates the original registration.
The package has no dependency on Harness, core, pi-tui, or a terminal runtime.
ui.markdown(source), ui.diagram(source), and ui.chart({ chart, ...data }) preserve
only renderer-neutral wire data. Mermaid and chart libraries are core-owned;
plugins do not install them or pass library-specific configuration.