ActionMenu
Related: ActionMenuProps
ActionMenuItem
ActionMenuProps
Related: ActionMenuItem
AgentListQuery
AgentPicker
Related: AgentPickerProps
AgentPickerProps
Related: AgentListQuery
AgentsIcon
AlertTriangleIcon
ArrowDownIcon
ArrowLeftIcon
ArrowUpIcon
BADGES_NOTE
Badge
Related: BadgeProps
BadgeProps
Button
Related: LinkButtonProps
ButtonProps
Button: button attributes, no anchor ones.
This stays an INTERFACE extending ButtonHTMLAttributes<HTMLButtonElement>
because it is published plugin API: a plugin may write
interface MyButton extends ButtonProps {} (a union cannot be extended —
TS2312) and may hand a ButtonProps value to a slot typed as plain
ButtonHTMLAttributes<HTMLButtonElement> (a union including anchor attributes
is not assignable — TS2322). The link form is the ADDITIVE LinkButtonProps,
and Button accepts either.
It declares NO href member. href?: undefined here would make
interface MyButton extends ButtonProps { href: string } a TS2430
(“incorrectly extends”), which is a narrowing of a surface that is additive
only. The discriminant Button narrows on lives on ButtonActionProps.
Properties
Related: ButtonVariant
ButtonVariant
Card
Related: CardProps
CardProps
ChannelListQuery
ChannelPicker
Related: ChannelPickerProps
ChannelPickerProps
Related: ChannelListQuery
CheckCircleIcon
CheckIcon
Checkbox
Related: CheckboxProps
CheckboxProps
ChevronDownIcon
ChevronRightIcon
ChipGroup
Related: ChipGroupProps
ChipGroupProps
ChipOption
value and the visible label.
Properties
CloseIcon
CodeBlock
Related: CodeBlockProps
CodeBlockProps
CompletionInput
Related: CompletionInputProps
CompletionInputProps
ConfirmDialog
Related: ConfirmDialogProps
ConfirmDialogProps
ConnectorsIcon
ConversationsIcon
CopyField
Related: CopyFieldProps
CopyFieldProps
CopyIcon
CreateFolder
parentId and resolve with its id.
DEFAULT_DATE_RANGE_PRESETS
DashboardIcon
DatabaseIcon
DateRangePicker
datetime-local inputs and
an Apply action, with the active window echoed as text below.
Controlled: the caller owns value and receives the next window through
onValueChange — a preset click emits its token immediately, while the custom
inputs hold a working draft until Apply commits the normalized absolute range.
The drafts track the controlled value, re-seeded on a NEW absolute value (keyed
on from/to), so edits against an unchanged value are preserved but a genuinely
different value replaces an in-progress draft.
Props
Related: DateRangePickerProps
DateRangePickerProps
Related: DateRangePreset, DateRangeValue
DateRangePreset
\d+[hdw] token the backend resolves, plus its chip label.
Properties
DateRangeValue
Dialog
Related: DialogProps
DialogProps
DirtyGuardBoundary
useRegisterDirty; while any is dirty a route
navigation (a route-token/plugin navigate, an AppLink, or a browser
back/forward) confirms through the shared discard dialog, and a full-page unload
raises the native prompt. Use this directly to guard a dirty editor that is a plain
page section (no tabs); GuardedTabs wraps this same boundary to additionally
guard tab switches.
Parameters
Drawer
Related: DrawerProps
DrawerProps
EditIcon
EmptyState
Related: EmptyStateProps
EmptyStateProps
EntityCardGrid
Related: EntityCardGridProps
EntityCardGridProps
ErrorBoundary
ErrorBoundaryProps
ErrorState
Related: ErrorStateProps
ErrorStateProps
ExecutionKeyPicker
Related: ExecutionKeyPickerProps
ExecutionKeyPickerProps
Related: ExecutionKeyBinding, ExecutionKeyQuery
ExecutionKeyQuery
UseQueryResult<TokensPayload> satisfies it structurally, so the SDK names no
query library.
Properties
ExplorerColumn
renderRow must emit exactly this many
<TD>s per item; folder rows span all of them.
Properties
ExplorerEmptyState
ExplorerEmptyStates
Related: ExplorerEmptyState
ExplorerSearch
matchesSearch).
Properties
ExplorerTags
ExplorerView
Related: ExplorerViewProps
ExplorerViewProps
Related: ExplorerColumn, ExplorerEmptyStates, ExplorerSearch, ExplorerTags, Folder
ExtensionComboBuilder
Related: ExtensionComboBuilderProps
ExtensionComboBuilderProps
ExtensionKindGroup
kind and every catalog entry of that kind.
Properties
ExtensionPicker
Related: ExtensionPickerProps
ExtensionPickerProps
ExternalLinkButton
Related: ExternalLinkButtonProps
ExternalLinkButtonProps
ExternalLinkIcon
EyeIcon
EyeOffIcon
FailedReplyOutcome
Related: FailedReplyOutcomeProps
FailedReplyOutcomeProps
Field
Related: FieldProps
FieldControlProps
FieldProps
FilterIcon
FleetOutcomeReport
Related: FleetOutcomeReportProps
FleetOutcomeReportProps
FleetReloadReport
Related: FleetReloadReportProps
FleetReloadReportProps
FleetReport
null for an absent report or a converged one with no
unreleased span and no worker awaiting a respawn (nothing to warn about), so callers can
always mount it unconditionally beside their own success line.
Props
Related: FleetReportProps
FleetReportProps
Folder
parentId, null = root).
Properties
FolderActionsMenu
renderFolderActions slot. Each button shows only
where the caller may make that write; a dialog already open stays open after its
button is withdrawn, so its outcome is still shown. Renders nothing for a caller
who may make none of the three writes.
Props
Related: FolderActionsMenuProps
FolderActionsMenuProps
FolderActionsMenu.
Properties
Related: Folder, FoldersChanged
FolderBreadcrumb
Related: FolderBreadcrumbProps
FolderBreadcrumbProps
Related: Folder
FolderIcon
FolderPicker
Related: FolderPickerProps
FolderPickerProps
Related: Folder
FolderRow
Related: FolderRowProps
FolderRowProps
Related: Folder
FoldersChanged
FormDialog
Related: FormDialogProps
FormDialogProps
GridIcon
GuardedTabs
Tabs that guards a switch away from a dirty
editor. Wraps the tabs in a DirtyGuardBoundary, so an editor rendered in
any panel can arm the guard through useRegisterDirty.
Parameters
Related: TabItem
HeadingLevel
# through ######.
HolderHref
href and the client-side transition to it.
Properties
HolderList
Related: HolderListProps
HolderListProps
HolderPreview
Related: HolderPreviewProps
HolderPreviewProps
Related: HolderListProps, HolderPreviewState
HolderPreviewState
HooksIcon
IconComponent
IconProps
style, events and ARIA pass
through. className is APPENDED to the tai-icon sizing class rather than
replacing it — the same merge every other design-system primitive does.
InteractionsIcon
JsonDiff
Related: JsonDiffProps
JsonDiffProps
JsonDiffRow
JsonTree
Related: JsonTreeProps
JsonTreeProps
LinkButtonProps
Button: an href, so it carries anchor attributes and no
button ones.
target and rel are inherited from AnchorHTMLAttributes and are settable,
but on the EXTERNAL branch they are not the caller’s to choose: an absolute
http(s) URL always renders target="_blank" with
rel="noopener noreferrer external", whatever the caller passed. On the
in-app branch target is the caller’s and rel is pinned only when they ask
for _blank.
It declares NO ref, and that is a REFUSAL rather than an omission: a blocked
href renders a NeutralizedLink span and no anchor at all, so a
Ref<HTMLAnchorElement> would be filled on two of the three renderings and
left null on the third — a ref that silently does nothing for exactly the
input the check exists to catch. A caller that needs the element wraps the
button.
Properties
Related: ButtonVariant
ManifestIcon
Markdown
Related: MarkdownProps
MarkdownBlock
text is resolved at render time.
Related: HeadingLevel
MarkdownProps
MarketplaceIcon
McpListingRefusal
Related: McpListingRefusalProps
McpListingRefusalProps
Related: McpListingRefusalReason
McpListingRefusalReason
MediaDocument
Content-Disposition: attachment for documents, so the anchor download-hints and
opens in a new tab; rel="noreferrer" stops the Studio URL leaking to the media
host. A url that fails isRenderableMediaSrc is the caller’s notice, never a
live href.
Props
Related: MediaDocumentProps
MediaDocumentProps
MediaImage
.map body) because the
load-failure flag is per-image useState, which the rules of hooks forbid inside a
.map callback. referrerPolicy="no-referrer" is REQUIRED: it stops the Studio URL
(which can encode the interaction/operator context) from leaking to the image host
on a remote-image load. altFallback supplies the alt when the item has no caption;
a caller overrides it for its own content and can supply renderNotice to render the
blocked/failed states in its own presentation.
Props
Related: MediaImageProps
MediaImageProps
MediaPlayer
<audio>/<video controls> player. referrerPolicy is not a valid
attribute on <audio>/<video>, so a remote load has no per-element referrer
control; the player therefore admits ONLY the platform’s own served-media reference
(isServedMediaUrl: same-origin, leaking no page URL to a media host), and any
other url, a bare https: one included, is the caller’s notice. The load-failure
flag keys on the url that failed so a new url at the same position gets a fresh load.
Props
Related: MediaPlayerProps
MediaPlayerProps
MembersIcon
MenuIcon
MinusIcon
MonitorIcon
MoonIcon
MoveToFolderDialog
Related: MoveToFolderDialogProps
MoveToFolderDialogProps
MoveToFolderDialog.
Properties
Related: Folder, FoldersChanged
NAV_ICONS
login is excluded: it is
not a destination the navigation surfaces list. Keyed by the token type, so
adding a route to RouteToken fails the build here until it gets a mark.
Related: IconComponent, RouteToken
NotificationsIcon
NumberInput
Related: NumberInputProps
NumberInputProps
NumericColumnProps
OpenTargetOptions
OpenTargetProps
openTargetProps yields — spread onto the entry
element (<TR>, card <div>). Every field is optional so the disabled case
is the empty object.
Properties
OverflowAxis
horizontal, the default); a bounded, capped-height list scrolls
DOWN (vertical). Both wear the same conditional region attributes — only the
dimension read to decide whether they overflow differs.
OverflowRegionAttributes
OverlayDetails
OverlayDetailsFields
Related: OverlayDetailsFieldsProps
OverlayDetailsFieldsProps
Related: OverlayDetails
Page
Related: PageLayoutProps
PageFillProvider
useFillViewport) and the active
flag (for usePageFillActive). Renders no DOM of its own.
Parameters
PageHeader
Related: PageHeaderProps
PageHeaderProps
PageLayoutProps
PendingIcon
PluginIcon
PlusIcon
PresetsIcon
ProgressBar
total, value/total fills the track
and the percentage is announced via aria-valuenow; without one, the bar is
indeterminate (no aria-valuenow, per ARIA).
Props
Related: ProgressBarProps
ProgressBarProps
ProseScrollLabels
RadioGroup
Related: RadioGroupProps
RadioGroupProps
Related: RadioOption
RadioOption
RecycleRollSection
Related: RecycleRollSectionProps
RecycleRollSectionProps
RevealInput
Related: RevealInputProps
RevealInputProps
SUBJECT_INCOMPLETE_MESSAGE
SchedulingIcon
ScrollRegion
Related: ScrollRegionProps
ScrollRegionProps
Related: OverflowAxis
SearchIcon
SearchableSelect
SearchableSelectGroup
SearchableSelectOptions.
Properties
Related: SearchableSelectOption
SearchableSelectGroupsProps
Related: SearchableSelectGroup
SearchableSelectOption
SearchableSelect: a SelectOption that may carry a description,
a line of text drawn under its label and searched alongside it.
Properties
Related: SelectOption
SearchableSelectProps
Related: SearchableSelectOption
Select
SelectGroup
Related: SelectOption
SelectGroupsProps
Related: SelectGroup
SelectOption
SelectProps
Related: SelectOption
ServedEndpointsIcon
ServedMediaGrammar
useApi().constants): the served route prefix and the stored-media id pattern. Media is
stored by reference and served from the API origin at MEDIA_ROUTE_PREFIX + <id>; a record
carries it as a RELATIVE url of exactly that shape, resolved to the API base at render time
(resolveMediaSrc), not assumed same-origin as the SPA page.
SettingsIcon
SignOutIcon
Skeleton
Related: SkeletonProps
SkeletonProps
SortAscIcon
SortDescIcon
Spinner
Related: SpinnerProps
SpinnerProps
Stack
Related: StackProps
StackProps
Stepper
Related: StepperProps
StepperProps
Related: StepperStep
StepperStatus
StepperStep
Related: StepperStatus
StorageIcon
SubjectSection
Related: SubjectSectionProps
SubjectSectionKeyFieldProps
keyField where the key goes, labelled by the host.
Properties
Related: SubjectSectionSharedProps, SubjectTargetOption
SubjectSectionProps
SubjectSection accepts: exactly one of the two key shapes.
Related: SubjectSectionKeyFieldProps, SubjectSectionTextKeyProps
SubjectSectionSharedProps
Related: SubjectTargetOption
SubjectSectionTextKeyProps
subjectKey.
Properties
Related: SubjectSectionSharedProps, SubjectTargetOption
SubjectTargetOption
target_kind:target_name value, kind · name label.
Properties
SunIcon
SystemIcon
TBody
Related: TableSectionProps
TD
Related: TDProps
TDProps
Related: NumericColumnProps
TH
Related: THProps
THProps
scope defaults to col because that is what a <th> in the
header row IS, and without it nothing associates the cell with the column
below it: a screen reader announcing a data cell has no header to name it.
A row header — the leading cell of a body row — passes scope="row".
Properties
Related: NumericColumnProps
THead
Related: TableSectionProps
TOKEN_NAMES
--tai-dark-* half of each themed pair is deliberately NOT here. Those
names are the theming mechanism’s own storage — the two blocks in tokens.css
that apply the dark theme are the only readers, and the scanner test holds
them to that. A plugin styles against the name WITHOUT the dark segment and
gets whichever half the viewer’s theme resolves to.
TOOL_SEARCH_NAMES_ONLY_NOTE
TR
Related: TableRowProps
TabItem
Table
Related: TableProps
TableProps
TableRowProps
TableSectionProps
<thead> and <tbody> take the same surface: the native one.
Properties
Tabs
Related: TabsProps
TabsProps
Related: TabItem
TagChips
Related: TagChipsProps
TagChipsProps
TagVocabularyEntry
TagsInput
value list; onChange receives the
next list on every add/remove. A blank or duplicate entry is ignored (never a
silent duplicate chip). Enter or comma commits the draft chip.
The draft input is a NATIVE-ATTRIBUTE PASS-THROUGH (the family inputs.tsx
documents): inside a Field it renders the SDK’s TextInput, which spreads
useFieldControl() and so claims the Field’s control id, taking the Field’s
visible label as its name; mounted OUTSIDE a Field it is named by a caller
aria-label, which the editor forwards to that same input. Without one a bare
editor is unnamed — the published component owns the naming route rather than
assuming a Field is always present. When a Field DOES name it, a caller
aria-label still has to CONTAIN that visible label (WCAG 2.5.3, Label in
Name); components/field-group.test.ts enforces that at every call site.
Props
Related: TagsInputProps
TagsInputProps
TemplatedTextField
Related: TemplatedTextFieldProps
TemplatedTextFieldProps
Related: TemplatedTextInlineProps, TemplatedTextTemplateOption
TemplatedTextInlineProps
renderInline receives to draw the inline-content editor.
Properties
TemplatedTextTemplateOption
TextInput
Related: TextInputProps
TextInputProps
Textarea
Related: TextareaProps
TextareaProps
TokenName
ToolListQuery
data is the names the host
offers. A caller’s TanStack UseQueryResult<readonly string[]> satisfies it
structurally, so the SDK names no query library.
Properties
ToolMetaWriteAccess
ToolMetaWriteError
ToolPicker
Related: ToolPickerProps
ToolPickerProps
Related: ToolListQuery
ToolsIcon
Tooltip
Related: TooltipProps
TooltipProps
UNTAGGED_TOKEN
UnplugIcon
VersionHistoryEntry
VersionHistoryPanel
Related: VersionHistoryPanelProps
VersionHistoryPanelProps
Related: VersionHistoryEntry
ViewMode
ViewToggle
useViewMode.
Props
Related: ViewToggleProps
ViewToggleProps
Related: ViewMode
WriteFailure
Related: WriteFailureProps
WriteFailureProps
XCircleIcon
buildSubject
StateSubject from the sub-form values: null when untouched (no
subject), a subject when target, kind and key are all set, or a loud failure when only
some are — never a silently dropped partial subject. The target splits on its FIRST
colon, so a target name may itself contain one.
Parameters
buildTagVocabulary
items, name-sorted, plus an untagged pseudo-tag
(labelled untaggedLabel) when any item is untagged; a selected token whose
items vanished still appears (count 0) so it can be cleared.
Parameters
Related: TagVocabularyEntry
canHoldExecutionKey
Select
exactly while the list read is pending or this holds.
Parameters
Related: ExecutionKeyBinding, ExecutionKeyQuery
channelIdentityHint
null for a
listed channel that declares none, undefined when the name is not listed.
Parameters
childFolders
parentId (null = the root directory), name-sorted.
Parameters
Related: Folder
diffJson
before and after.
Parameters
Related: JsonDiffRow
folderPathTo
folderId, for a
breadcrumb. null is the root (an empty path). The walk is bounded by the folder
count, so a cyclic or dangling chain truncates instead of looping.
Parameters
Related: Folder
foldersForView
rows are the overlay rows (each tool’s folder_id), population the tool names
the screen lists. Linear in folders + rows; the subtree walk is cycle-guarded, so a
malformed parent chain yields a bounded result rather than looping.
Parameters
Related: Folder
formatRangeLabel
Related: DateRangePreset, DateRangeValue
groupByKind
kind. Groups are ordered by
kind and each group’s members by name, so the render order is stable regardless
of the server’s list order. Each group carries its kind’s served multiple; a kind
whose entries disagree is a catalog fault and throws.
Parameters
Related: ExtensionKindGroup
isExecutionKeyListEmpty
Related: ExecutionKeyQuery
isRenderableMediaSrc
https: URL, the
platform’s own served-media reference (a relative MEDIA_ROUTE_PREFIX + <id>),
or — when the caller opts in with allowDataImage — an inline data:image/* URI.
isSafeHttpUrl is TIGHTENED to https-only here (it alone also admits http:,
which the Studio CSP img-src/media-src blocks and the contract never emits);
the served-media branch pins a well-formed platform media id (a relative url
isSafeHttpUrl cannot parse). allowDataImage defaults OFF: only a sink that
stores media RAW (never substituted to a served reference) opts in, and even then
ONLY data:image/* is admitted — a data: of any other type (data:text/html,
an SVG document, …) is ALWAYS blocked. http:, javascript:, a non-image
data:, and any other-shaped relative url fail every branch → a loud blocked
item. The gate keys on the reference form; resolveMediaSrc joins an
admitted reference to the API base for the actual load.
Parameters
Related: ServedMediaGrammar
isSafeHttpUrl
http:///https:// URL. Everything else is unsafe.
Parameters
isServedMediaUrl
url is the platform’s own served-media reference: a relative
MEDIA_ROUTE_PREFIX + <id> whose id matches MEDIA_ID_PATTERN whole. A served
reference is same-origin to the API base (resolveMediaSrc) and leaks no page
context on load, so a sink with no per-element referrer control (<audio>/<video>,
where referrerPolicy is not a valid attribute) admits ONLY this form.
Parameters
Related: ServedMediaGrammar
matchesSelectedTags
mcpListingRefusalOf
error is, read through the client that raised it, or null when it
is not one: a read of a server’s tools or a selection-changing write, refused because the
worker that answered holds no listing for the server.
Parameters
Related: McpListingRefusalReason
normalizeCustomRange
now —
capping first can leave a future instant on the post-swap end. The end is
INCLUSIVE of its minute, extended to :59.999, so 23:59 reaches the day’s end.
Parameters
openTargetProps
onOpen: undefined to get an inert entry (empty props).
Props
Related: OpenTargetOptions, OpenTargetProps
overlayDetailsPatch
Related: OverlayDetails
parseMarkdown
Related: MarkdownBlock
previewHolders
Related: HolderPreviewState
resolveMediaSrc
https: url is already
absolute and is returned unchanged. A served-media reference is RELATIVE and is
joined to the API origin (baseUrl) — NOT the SPA page origin: in a cross-origin
deployment the two differ, and a page-relative src would resolve against Studio
and 404. An empty baseUrl (same-origin deployment) leaves the reference
relative, which is correct; a configured base’s trailing slash is stripped so the
join never double-slashes.
Parameters
Related: ServedMediaGrammar
safeHttpUrl
href denotes, or undefined when it denotes none.
The // is required rather than inferred from a successful new URL(),
because for a scheme that matches the document’s own, the authority-less
spelling is a PATH: an anchor with href="https:/settings" on an https page
navigates to /settings on the CURRENT origin, while new URL() with no base
reads the same string as the host settings. Only the // form means the same
thing to both.
An absolute http(s) URL carrying user:pass@ userinfo is rejected too: .href
re-serialization preserves the userinfo (unlike host tricks), so
https://trusted.com@evil.com would render as trusted.com yet navigate to
evil.com.
Callers render the returned string rather than their input, so the URL that was
judged is always the URL that is navigated. isSafeHttpUrl gives the yes/no
answer for a caller that does not need the URL itself.
Parameters
templatedTextSummary
toFolders
Folder shape.
Parameters
Related: Folder
toSubjectTargetOptions
Related: SubjectTargetOption
toolSearchShown
ToolPicker given these props draws its search: the list is loaded, the
select offers an option (a listed tool, or a flagged stored value) and the picker is
enabled. A pending, failed, refused or empty read, or a disabled picker, draws none. A
host reads it to say what the search matches only while the search is there.
Parameters
Related: ToolPickerProps
useCreateFolder
FolderPicker’s onCreateFolder
takes. undefined when the caller may not create a folder, so the picker offers
no create. A rejection propagates to the picker, which shows it; a not-configured
refusal is also reported, withdrawing every overlay write.
Parameters
Related: CreateFolder, FoldersChanged
useFieldControl
id and aria-describedby are undefined both when there is no Field AND
inside a group Field: a group has no single element to carry them, and the
group container itself already carries the name and the description. Only
aria-invalid still crosses that boundary, because role="group" does not
support it (ARIA 1.2), so the control is the sole place an errored group can
expose its invalid state.
Related: FieldControlProps
useFillViewport
<main> to the viewport and lets the page’s own root flex or
height: 100% down the chain. Must be called under a PageFillProvider
(the shell mounts one); outside it there is no wrapper to modify, so it throws
rather than silently do nothing.
useHolderHref
null for a count holder and for a kind neither the
core table nor any registered plugin resolves.
Related: HolderHref
useOverflowRegion
<pre>, a JSON
pane, or the div ScrollRegion renders. Use the hook when wrapping the
content in a ScrollRegion would give the surface a second scroller.
The box is measured as it is attached, whenever it or any child resizes, and
whenever its content changes — replaced, appended, or edited in place. A
replaced child is a NEW element, so the registration is re-pointed at the
current children before each measurement, adding and dropping only the ones
that actually changed; both sides of that are registrations on the shared
observers, not observers of this mount’s own. The only DOM change a
measurement can cause is the region ATTRIBUTES this hook returns, and
attributes are deliberately left unobserved — that, not an absence of
mutation, is what stops the pair from re-triggering each other.
Parameters
Related: OverflowAxis, OverflowRegionAttributes
usePageFillActive
<main> and the page wrapper.
useProseScrollRegions
<table> and every <pre> — as scroll regions. React
cannot wrap markup it did not create, so this walks the DOM instead. A table
is moved into a div.tai-scroll-region (once — the pass is idempotent)
because the table itself is not the scrolling box; a <pre> already IS its
own scrolling box, so it is instrumented in place. Either way the scrolling
element carries the same conditional tabindex/role/aria-label as
ScrollRegion.
The name is the nearest heading preceding the surface — read for all of them
in one document-order pass — so a reader landing on the region hears which
section it belongs to; labels covers a surface with no heading above it, and
a name shared by several surfaces is numbered so no two regions answer to the
same one.
The pass runs from the ref callback rather than an effect, which puts it in
the commit phase, BEFORE the browser paints: .tai-prose table is
width: 100% with no overflow of its own — the scroller exists only on the
wrapper this builds — so a pass that ran after paint would show one frame at
320/360 px with the table overflowing the document, then jolt sideways. A
passive-effect probe measured exactly that: at first paint wrappers=0 and the
table’s parent was .tai-prose.
Injected HTML is replaced wholesale when its source changes, so the pass is
re-run from a MutationObserver on the subtree rather than on attachment
alone.
Props
Related: ProseScrollLabels
useRegisterDirty
DirtyGuardBoundary (which
GuardedTabs also provides). A no-op outside a boundary (an editor rendered
standalone, e.g. in isolation tests) so the hook is always safe to call.
Parameters
useReportToolMetaRefusal
tool-meta-not-configured) is recorded so every screen withdraws its overlay
writes; any other failure is left to the caller, which shows it.
useSubjectFields
targetOptions from it.
useToolMetaWriteAccess
useViewMode
surface (a stable key like 'tools'). Returns
the stored choice or fallback when none is set, and a setter that writes through
to localStorage. Storage failures degrade to in-memory only — never a thrown
boot, matching the theme preference’s defensive reads/writes.
Parameters
Related: ViewMode

