/**
 * Generated by scripts/gen-client-catalog.ts — do not edit by hand; run
 * `pnpm run gen-client-catalog` to regenerate (freshness-gated by
 * `pnpm run verify-client-catalog` in doc-sync).
 *
 * The compile-time contract of the shipped web bundle's slot surface, as
 * `cordis_inspect what:"client"` serves it to the model: every SlotMap key a
 * browser half can register into, what that register call must pass, what the
 * component receives, who already occupies the seat, and which owner has to be
 * mounted for the seat to exist. Data only — this module is the one legitimate
 * meeting point of the two planes, so it carries strings, never client imports.
 *
 * @module @deepseek-ai/dsh-cordis-client-runner/client/slot-catalog
 */

/* jscpd:ignore-start */
/** One option a register call passes for a given slot cardinality. */
export interface ClientSlotOption {
  /** Option name as written in the register options object. */
  name: string
  /** Whether the cardinality requires it. */
  requirement: string
  /** Accepted type, in source spelling. */
  type: string
  /** What it does, from the registrant's side. */
  doc: string
}

/** One browser-half slot a dynamic package can contribute UI into. */
export interface ClientSlotEntry {
  /** SlotMap key passed as the register call's `name`. */
  key: string
  /** Cardinality: `single`, `list`, `keyed`, or `chain`. */
  kind: string
  /** Data scope: `root`, `session`, or `session-maybe`. */
  scope: string
  /** First sentence of the contract prose. */
  summary: string
  /** Full contract prose from the SlotMap declaration. */
  doc: string
  /** Options this cardinality accepts (beyond `name`). */
  registerOptions: readonly ClientSlotOption[]
  /** Declarations of the props the owner passes down, with their own documentation. */
  ownerProps: readonly string[]
  /** Names of the shapes those props reference; deliberately not expanded here. */
  ownerPropsReferences: readonly string[]
  /** Framework-supplied component props for this scope. */
  standardProps: readonly string[]
  /** For keyed slots: how the key set is constrained and which keys are taken. */
  keyDomain: string
  /** Opaque per-render-site context passed to slot-level hooks, when the slot declares one. */
  hookContext: string
  /** Slot-level inject face every entry receives, when the slot declares one. */
  slotInject: string
  /** Which mounted entry makes this slot exist. */
  declaredBy: string
  /** Entries the shipped composition already registered here. */
  occupants: readonly string[]
  /** `shadows-shipped-ui` when registering here replaces shipped UI; `none` when additive. */
  replaceRisk: string
  /** A minimal browser half that registers into this slot. */
  example: string
  /** Source pointer of the contract declaration. */
  source: string
}

/** Rules that apply to every browser-half contribution, in reading order. */
export const CLIENT_NOTES: readonly string[] = [
  'Contribute UI only through `ctx.slots.register(options, Component)`; declare `inject: [\'slots\']` in your returned plugin (object form) or the seat is withheld.',
  'Wrap every registration in `ctx.slots.inject(key, () => ctx.slots.register(...))`. A slot exists only while the entry that declared it is mounted, and registering into an undeclared slot throws; `inject` runs your registration when the declaration is (or becomes) live and re-runs it if the owner remounts.',
  'Do NOT pass `priority`: the browser-half facade assigns one automatically, and it is LOWER than every shipped entry — in a single or keyed cell that means your entry is the one that renders.',
  'You cannot `import` anything, so the design-system components are out of reach: build markup with `React.createElement` and ship CSS through `styles.insert(css)`. Use the theme CSS variables (`var(--dsw-alias-bg-layer-1)`, `var(--dsw-alias-label-primary)`, …) instead of literal colors, or your contribution breaks in the other color scheme.',
  'Every component receives the framework hook seats listed under `framework props` for its scope; a selector hook is called with a selector, e.g. `useSessions(state => state.current)`.',
  'This catalog is the COMPILE-TIME contract of the shipped web bundle, not a snapshot of one page: a key is registrable only where the owner that declares it is mounted. A failed registration surfaces in the browser-half load report — read it back with `cordis_inspect what:"temporary"`.',
]

/** Every slot the shipped web bundle declares, sorted by key. */
// Seats of one cardinality repeat their register options and framework props
// verbatim; that sameness IS the contract a registrant reads, so clone
// detection is told to skip the data rather than the file.
export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
  {
    key: 'conversation',
    kind: 'single',
    scope: 'session-maybe',
    summary: 'The whole center column, across both the no-session hero and a live conversation.',
    doc: 'The whole center column, across both the no-session hero and a live\nconversation. OCCUPIED by ui-conversation\'s ConversationRoot, which\ndeclares the session body, composer, and input seats inside it —\nregistering here replaces the entire conversation surface (and removes\nevery seat it declares) rather than adding to it.\n\nCurrent-session-optional: the occupant owns both states without\nchanging its React identity, so it keeps its own state across a session\nswitch. It receives no owner props; session facts arrive through the\nframework hooks of the `session-maybe` scope.',
    registerOptions: [],
    ownerProps: [
      '/** Conversation owner share: business state and actions belong to the registrant. */\nexport interface ConvOwnerProps {}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: MaybeSnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId | undefined',
      'useProjection: UseProjection',
      'useInput: MaybeSnapshotSelectorHook<InputState>',
      'inputActions: InputActions | undefined',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'root\' (client-ui-layout), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation ConversationRoot',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation\', () => ctx.slots.register(\n      { name: \'conversation\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-layout/src/client/index.ts:62',
  },
  {
    key: 'conversation.chat.assistant-actions',
    kind: 'list',
    scope: 'session',
    summary: 'Action strip attached to one finalized assistant message, rendered inside that message\'s IconActions row.',
    doc: 'Action strip attached to one finalized assistant message, rendered\ninside that message\'s IconActions row. The chat entry owns the render\nsite and passes the addressed message identity; contributors add\nper-message actions without importing the conversation implementation.\nEntries render by ascending `order`.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/**\n * Owner currency of the assistant-message action strip: the durable identity\n * of the one finalized message the contributed actions address. Only finalized\n * messages reach this slot, so the id is always present.\n */\nexport interface AssistantActionOwnerProps {\n  /** Stable identity carried from the `assistant/message` event. */\n  messageId: MessageId\n}',
    ],
    ownerPropsReferences: [
      'MessageId',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.chat.node\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-message-feedback MessageFeedbackActions id \'feedback\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.chat.assistant-actions\', () => ctx.slots.register(\n      { name: \'conversation.chat.assistant-actions\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:109',
  },
  {
    key: 'conversation.chat.commandview',
    kind: 'keyed',
    scope: 'session',
    summary: 'The chat view\'s per-command row hole: keyed dispatch on the command name (`command/run.name`; a run-less cross-window node has none and always lands on the fallback).',
    doc: 'The chat view\'s per-command row hole: keyed dispatch on the command\nname (`command/run.name`; a run-less cross-window node has none and\nalways lands on the fallback). Declared by the chat view entry; the\nrender site dispatches via `entryKey: name` with GenericCommandCard as\nthe `fallback` — a slash command renders durably with zero\nregistration, and a domain upgrades by registering one row component.',
    registerOptions: [
      {
        name: 'key',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key: the entry renders where the owner dispatches this exact key. Registering an already-occupied key replaces that occupant.',
      },
    ],
    ownerProps: [
      '/**\n * Owner share of the per-command row slot: the frozen {@link CommandNode}\n * slice off the snapshot (cache-stable reference — memo premise). The node\n * carries the whole lifecycle (structured name/args, pairing id, and\n * outcome-or-executing). A successful domain command may also carry the\n * explicitly linked projection node needed to fold two log records into one\n * presentation row.\n */\nexport interface CommandRowOwnerProps {\n  /** Folded command lifecycle node (run + optional done). */\n  node: CommandNode\n  /** Explicitly linked compaction checkpoint for the settled `/compact` presentation. */\n  compaction?: CompactionSummaryNode\n}',
    ],
    ownerPropsReferences: [
      'CommandNode',
      'CompactionSummaryNode',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: 'open: any string the owner dispatches (no compile-time key set), none are taken yet',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.chat.node\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.chat.commandview\', () => ctx.slots.register(\n      { name: \'conversation.chat.commandview\', key: \'<one key the owner dispatches>\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:94',
  },
  {
    key: 'conversation.chat.node',
    kind: 'keyed',
    scope: 'session',
    summary: 'Final business node renderer, dispatched by `ChatConversationViewNode.kind`.',
    doc: 'Final business node renderer, dispatched by `ChatConversationViewNode.kind`.',
    registerOptions: [
      {
        name: 'key',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key: the entry renders where the owner dispatches this exact key. Registering an already-occupied key replaces that occupant.',
      },
    ],
    ownerProps: [
      '/** Stable owner currency delivered to one keyed Chat business renderer. */\nexport interface ChatNodeOwnerProps {\n  /** Selected Tool call, when the shared details store names one. */\n  selectedCallId?: CallId | undefined\n  /** Session workspace root; Tool summaries display paths relative to it. */\n  cwd?: string | undefined\n  openFile: (path: string) => void\n  inspectCall: (callId: CallId) => void\n  forkAt: (seq: number) => void\n  /** Resolve a session-authorized historical image for inline display. */\n  loadImage: (attachment: ImageAttachmentRef) => Promise<string>\n  fileMentions: (owner: TurnTailOwnerProps) => MarkdownFileMentions | undefined\n}',
    ],
    ownerPropsReferences: [
      'ImageAttachmentRef',
      'MarkdownFileMentions',
      'TurnTailOwnerProps',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: 'fixed by the owner\'s key table { [Kind in ChatNodeKind]: { node: ChatNode<Kind> } }, already taken: assistant-step, command, command-input, compaction, context, manual-compaction, model-retry, steering, tool-call, turn-error, turn-max-tokens, turn-tail, unknown, user, workflow-run',
    hookContext: 'string',
    slotInject: 'ChatNodeTurnDataInjected',
    declaredBy: 'an entry in \'conversation.view\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation UserMessageNodeView key \'user\'',
      'client-ui-conversation UserMessageNodeView key \'steering\'',
      'client-ui-conversation ContextMessageNodeView key \'context\'',
      'client-ui-conversation AssistantNodeView key \'assistant-step\'',
      'client-ui-conversation CommandNodeView key \'command\'',
      'client-ui-conversation ManualCompactionNodeView key \'manual-compaction\'',
      'client-ui-conversation CompactionNodeView key \'compaction\'',
      'client-ui-conversation RetryNodeView key \'model-retry\'',
      'client-ui-conversation TurnErrorNodeView key \'turn-error\'',
      'client-ui-conversation TurnMaxTokensNodeView key \'turn-max-tokens\'',
      'client-ui-conversation TurnTailNodeView key \'turn-tail\'',
      'client-ui-conversation UnknownNodeView key \'unknown\'',
      'client-ui-goal GoalCommandInputView key \'command-input\'',
      'client-ui-tool ToolCallTree key \'tool-call\'',
      'client-ui-workflow-run WorkflowRunPanel key \'workflow-run\'',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.chat.node\', () => ctx.slots.register(\n      { name: \'conversation.chat.node\', key: \'<one key the owner dispatches>\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:78',
  },
  {
    key: 'conversation.chat.turnTail',
    kind: 'chain',
    scope: 'session',
    summary: 'The completed Turn Node\'s extension chain, rendered before that Node\'s IconActions.',
    doc: 'The completed Turn Node\'s extension chain, rendered before that Node\'s\nIconActions. Entries derive a match from the engine-owned Turn and\nclosing seq before mounting, so presentation components never mount\nonly to return null; an all-declined chain renders nothing.',
    registerOptions: [
      {
        name: 'select',
        requirement: 'required',
        type: '(owner) => unknown | null',
        doc: 'Pure routing selector. Entries are tried in ascending order; the first non-null result wins and arrives as the component\'s `matched` prop. All-null falls through to the owner\'s fallback.',
      },
    ],
    ownerProps: [
      '/**\n * Owner currency of the chat view\'s turn-tail hole: the engine-owned Turn and\n * the closing assistant\'s anchor. Registrants read their own typed Turn data\n * and open files through the same opener the tool rows use.\n */\nexport interface TurnTailOwnerProps {\n  /** Engine-owned closing Turn boundary. */\n  turn: TurnLocation\n  /** The closing assistant\'s seq — the anchor the tail renders under. */\n  seq: number\n  /**\n   * Open a filesystem path through the Host (tool-row semantics; the chat\n   * view resolves relative paths against the session cwd).\n   */\n  openFile: (path: string) => void\n}',
    ],
    ownerPropsReferences: [
      'TurnLocation',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.chat.node\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-deliverables ProducedFiles',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.chat.turnTail\', () => ctx.slots.register(\n      { name: \'conversation.chat.turnTail\', select: owner => null },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:101',
  },
  {
    key: 'conversation.composer',
    kind: 'chain',
    scope: 'session',
    summary: 'The composer takeover chain: entries are selector-routed replacements of the default InputBar.',
    doc: 'The composer takeover chain: entries are selector-routed replacements\nof the default InputBar. Declared by this package\'s \'conversation\'\nentry; the owner dispatches the ComposerChainProps currency and\nrouting lives in entry selectors — new takeover kinds register with\nzero owner changes.',
    registerOptions: [
      {
        name: 'select',
        requirement: 'required',
        type: '(owner) => unknown | null',
        doc: 'Pure routing selector. Entries are tried in ascending order; the first non-null result wins and arrives as the component\'s `matched` prop. All-null falls through to the owner\'s fallback.',
      },
    ],
    ownerProps: [
      '/**\n * Composer chain currency: what ConversationRoot dispatches at its\n * renderSlotChain site. The owner declares the currency only — never a\n * per-entry contract; takeover packages narrow it in their own selectors\n * (`interactions.find(i => i.kind === ...)`), so new takeover kinds register\n * with zero owner changes.\n */\nexport interface ComposerChainProps {\n  interactions: readonly PendingInteraction[]\n  /** Current conversation facts for feature-owned takeover selectors. */\n  session: ConversationSnapshot | undefined\n}',
    ],
    ownerPropsReferences: [
      'ConversationSnapshot',
      'PendingInteraction',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation ApprovalPanel',
      'client-ui-subagent SubagentReadOnlyComposer',
      'client-ui-user-questions QuestionComposer',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.composer\', () => ctx.slots.register(\n      { name: \'conversation.composer\', select: owner => null },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:132',
  },
  {
    key: 'conversation.composer.bar',
    kind: 'single',
    scope: 'session-maybe',
    summary: 'The default composer body: a single slot rendered as the composer chain\'s fallback (a real entry, not a chain rider, so a takeover election hides rather than unmounts it and the textarea DOM survives).',
    doc: 'The default composer body: a single slot rendered as the composer\nchain\'s fallback (a real entry, not a chain rider, so a\ntakeover election hides rather than unmounts it and the textarea DOM\nsurvives). Session-maybe: the bar stays mounted across the\nno-session/session transition — the no-workspace hero renders the SAME\ntextarea DOM as a read-only Workspace-picker trigger instead of a\nparallel inert tree — with the machine hooks absent until a session is\ncurrent. InputBar registers\nhere from this package\'s apply; its machine state arrives through the\nstandard provide channel (useInput + inputActions), the keyboard\ncommand face through its own inject.',
    registerOptions: [],
    ownerProps: [
      '/**\n * Owner share of the composer-bar slot: ConversationRoot\'s layout-phase\n * inputs plus the input-region child-slot content it renders (the region\n * slots stay declared/rendered by the conversation entry; the bar hosts the\n * results as chrome).\n */\nexport interface ComposerBarOwnerProps {\n  /** Hero = empty-state centered card; composer = resident bottom bar. */\n  variant: \'hero\' | \'composer\'\n  /**\n   * A block another plugin raised for this session: the bar refuses input and\n   * shows the blocker\'s reason as the placeholder, but — unlike `disabled` —\n   * keeps the model seat live. Every block this contract has is one the user\n   * clears by choosing a model, so locking that seat too would leave the\n   * composer telling them to do the one thing it prevents.\n   */\n  blocked?: { readonly reason: string }\n  /**\n   * Inert no-workspace state: the bar locks message actions while preserving\n   * its normal DOM so the Workspace pick transitions in place.\n   */\n  disabled?: boolean\n  /** Whether the shared Workspace picker menu is expanded, regardless of which trigger opened it. */\n  workspacePickerOpen?: boolean\n  /** Open the existing Workspace picker from the inert textarea. */ /* …truncated — full shape in source */',
    ],
    ownerPropsReferences: [
      'Workspace',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: MaybeSnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId | undefined',
      'useProjection: UseProjection',
      'useInput: MaybeSnapshotSelectorHook<InputState>',
      'inputActions: InputActions | undefined',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation InputBar',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.composer.bar\', () => ctx.slots.register(\n      { name: \'conversation.composer.bar\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:201',
  },
  {
    key: 'conversation.composer.dock',
    kind: 'list',
    scope: 'session',
    summary: 'The band under the composer card, inside the bar\'s width column — the seat for an ambient readout about the conversation (the shipped stats line lives here).',
    doc: 'The band under the composer card, inside the bar\'s width column — the\nseat for an ambient readout about the conversation (the shipped stats\nline lives here). Same InputZone owner share as the other\nregions. Anything the user must click belongs in the tool row instead\n(`conversation.input.left` / `.right`); anything needing its own line\nabove the card belongs in `conversation.input.dock`.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/**\n * The input-region slot currency: dock/left/right entries read\n * the conversation snapshot and the live input state as owner props (both\n * are point-in-time snapshots — the dispatching skeleton re-renders on\n * either store\'s change, so entries stay current without subscribing).\n */\nexport interface InputZone {\n  readonly session: ConversationSnapshot\n  readonly input: InputState\n}',
    ],
    ownerPropsReferences: [
      'ConversationSnapshot',
      'InputState',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation StatsLine id \'stats\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.composer.dock\', () => ctx.slots.register(\n      { name: \'conversation.composer.dock\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:170',
  },
  {
    key: 'conversation.details.tool',
    kind: 'single',
    scope: 'session',
    summary: 'The body of the details panel for the tool call the user selected — one occupant, so taking it means rendering every tool\'s output, not just the ones you know.',
    doc: 'The body of the details panel for the tool call the user selected —\none occupant, so taking it means rendering every tool\'s output, not just\nthe ones you know. The owner passes a frozen `block` whose two lifecycle\nforms must both be handled: branch on `\'kind\' in block` (a settled\n`ToolResultNode` has it, a still-running call does not), and treat\n`cwd` as display-only, for shortening workspace-rooted paths.\nA per-tool renderer belongs in the keyed `tool.call.toolview` seat\ninstead; this one is the whole panel.',
    registerOptions: [],
    ownerProps: [
      '/** Owner currency of the details panel\'s Tool output renderer. */\nexport interface DetailsToolOwnerProps {\n  /** Frozen selected call slice. */\n  block: ToolCallBlock\n  /** Session workspace root for card cwd and relative-path display. */\n  cwd?: string | undefined\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'details\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-tool ToolDetails',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.details.tool\', () => ctx.slots.register(\n      { name: \'conversation.details.tool\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:124',
  },
  {
    key: 'conversation.hero.agentPreset',
    kind: 'single',
    scope: 'root',
    summary: 'The agent-preset chip beside the workspace picker on the new-session screen.',
    doc: 'The agent-preset chip beside the workspace picker on the new-session\nscreen. Root scope: no session exists yet, so the choice is staged for\nthe next one rather than applied to a current one.',
    registerOptions: [],
    ownerProps: [
      '/** Owner share of the hero agent-preset chip: the shell supplies nothing. */\nexport interface HeroAgentPresetOwnerProps {\n  /** Marker field: the chip owns its own roster, staging, and menu state. */\n  children?: never\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-agent-preset AgentPresetSeat',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.hero.agentPreset\', () => ctx.slots.register(\n      { name: \'conversation.hero.agentPreset\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:145',
  },
  {
    key: 'conversation.hero.workspace',
    kind: 'single',
    scope: 'root',
    summary: 'The hero-phase Workspace picker hole: rendered by ConversationRoot while the session is blank (picking another workspace switches to that workspace\'s blank session, draft carried).',
    doc: 'The hero-phase Workspace picker hole: rendered by ConversationRoot\nwhile the session is blank (picking another workspace switches to that\nworkspace\'s blank session, draft carried). Root scope: the picker\nreads the global workspace list.',
    registerOptions: [],
    ownerProps: [
      '/** Owner share common to the hero / New-Session Workspace pickers. */\nexport interface EmptyWorkspaceOwnerProps {\n  open: boolean\n  anchorRef?: RefObject<HTMLElement>\n  /** Currently active workspace (renders a trailing check in the picker list). */\n  selectedId?: WorkspaceId | undefined\n  onPick: (workspaceId: WorkspaceId) => void\n  onClose: () => void\n}',
    ],
    ownerPropsReferences: [
      'Workspace',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-workspace WorkspacePicker',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.hero.workspace\', () => ctx.slots.register(\n      { name: \'conversation.hero.workspace\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:139',
  },
  {
    key: 'conversation.hero.workspace.directoryFlow',
    kind: 'single',
    scope: 'root',
    summary: 'Directory-flow hole under the conversation empty-state picker (declared by the WorkspacePicker entry).',
    doc: 'Directory-flow hole under the conversation empty-state picker (declared by the WorkspacePicker entry).',
    registerOptions: [],
    ownerProps: [
      '/**\n * Owner share of the directory-flow holes: the complete conversation between\n * the trigger surface and the picking interaction. The occupant reads `open`\n * to run/render its interaction and reports exactly one outcome per open.\n */\nexport interface DirectoryFlowOwnerProps {\n  /** True while a picking interaction is requested; flipping back to false withdraws the request. */\n  open: boolean\n  /** True while the owner adopts a picked path (`createWorkspace` in flight); occupants disable their commit affordances. */\n  busy: boolean\n  /** The operator picked a directory (absolute host path); the owner adopts it. */\n  onPicked: (path: string) => void\n  /** The operator dismissed the interaction; the owner just closes the flow. */\n  onCancel: () => void\n  /** The interaction itself failed (chooser missing, listing denied); the owner shows its error surface. */\n  onError: (message: string) => void\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.hero.workspace\' (client-ui-workspace), so it exists while that entry is mounted',
    occupants: [
      'client-ui-directory-picker-browse BrowseDirectoryFlow',
      'client-ui-directory-picker-native NativeDirectoryFlow',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.hero.workspace.directoryFlow\', () => ctx.slots.register(\n      { name: \'conversation.hero.workspace.directoryFlow\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-workspace/src/client/contract/slots.ts:56',
  },
  {
    key: 'conversation.input.dock',
    kind: 'list',
    scope: 'session',
    summary: 'A full-width row of its own, stacked above the composer card — the seat for anything that needs a line to itself (queue rows, a todo strip, a goal bar).',
    doc: 'A full-width row of its own, stacked above the composer card — the seat\nfor anything that needs a line to itself (queue rows, a todo strip, a\ngoal bar). Pick this over the three seats below when your content wraps\nor carries prose; pick `conversation.composer.dock` for an ambient\nreadout under the card, and `conversation.input.left` /\n`.right` for a small control INSIDE the card\'s tool row.\nRead only `session`/`input` off the owner share (InputZone) —\nboth are point-in-time snapshots re-rendered for you, never subscribe.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/**\n * The input-region slot currency: dock/left/right entries read\n * the conversation snapshot and the live input state as owner props (both\n * are point-in-time snapshots — the dispatching skeleton re-renders on\n * either store\'s change, so entries stay current without subscribing).\n */\nexport interface InputZone {\n  readonly session: ConversationSnapshot\n  readonly input: InputState\n}',
    ],
    ownerPropsReferences: [
      'ConversationSnapshot',
      'InputState',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation QueueDock id \'queue\'',
      'client-ui-conversation TodoDock id \'todo\'',
      'client-ui-goal GoalDock id \'goal\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.input.dock\', () => ctx.slots.register(\n      { name: \'conversation.input.dock\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:161',
  },
  {
    key: 'conversation.input.left',
    kind: 'list',
    scope: 'session',
    summary: 'The left end of the tool row INSIDE the composer card, after the resident chrome (access mode, plan, attach) — the seat for a small always-visible control.',
    doc: 'The left end of the tool row INSIDE the composer card, after the\nresident chrome (access mode, plan, attach) — the seat for a small\nalways-visible control. Entries sit beside that chrome, never replace\nit. Same InputZone owner share; use `.right` for a control that\nbelongs next to the send button, and the docks for anything taller than\none row.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/**\n * The input-region slot currency: dock/left/right entries read\n * the conversation snapshot and the live input state as owner props (both\n * are point-in-time snapshots — the dispatching skeleton re-renders on\n * either store\'s change, so entries stay current without subscribing).\n */\nexport interface InputZone {\n  readonly session: ConversationSnapshot\n  readonly input: InputState\n}',
    ],
    ownerPropsReferences: [
      'ConversationSnapshot',
      'InputState',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.input.left\', () => ctx.slots.register(\n      { name: \'conversation.input.left\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:179',
  },
  {
    key: 'conversation.input.model',
    kind: 'single',
    scope: 'session',
    summary: 'The named model-select seat at the right end of the composer tool row, left of the send button — one occupant, so taking it means rendering the whole model affordance yourself.',
    doc: 'The named model-select seat at the right end of the composer tool row,\nleft of the send button — one occupant, so taking it means rendering the\nwhole model affordance yourself. Same `locked`-only owner share and same\nrenders-nothing-while-empty contract as the plan seat. Note the composer\ndeliberately keeps this seat LIVE while it refuses text for a\nmodel-related block: every such block is one the user clears by picking\na model here.',
    registerOptions: [],
    ownerProps: [
      '/**\n * Owner share of the two named composer control seats (plan / model): the\n * bar passes its disable state; the filling entry owns everything else.\n */\nexport interface InputControlOwnerProps {\n  /** Session-removed lock (the bar\'s chrome disable state). */\n  locked: boolean\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.composer.bar\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-model-selection ModelSelect',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.input.model\', () => ctx.slots.register(\n      { name: \'conversation.input.model\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:221',
  },
  {
    key: 'conversation.input.overlay',
    kind: 'list',
    scope: 'session',
    summary: 'The InputBar floating overlay anchor: MenuView (this package) and the popupSelect shell (ui-commands) contribute list entries; each reads its own store and renders null while closed.',
    doc: 'The InputBar floating overlay anchor: MenuView (this package) and the\npopupSelect shell (ui-commands) contribute list entries; each reads its\nown store and renders null while closed. Declared (children table) by\nui-conversation\'s composer entry; the anchor hides with the input\nunder a takeover.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-commands PopupSelectView id \'command-popup\'',
      'client-ui-input-trigger MenuView id \'slash-menu\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.input.overlay\', () => ctx.slots.register(\n      { name: \'conversation.input.overlay\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-input-trigger/src/client/slots.ts:24',
  },
  {
    key: 'conversation.input.plan',
    kind: 'single',
    scope: 'session',
    summary: 'The named plan-status seat in the composer tool row, immediately right of the access-mode control — one occupant, so taking it means rendering the plan affordance yourself.',
    doc: 'The named plan-status seat in the composer tool row, immediately right\nof the access-mode control — one occupant, so taking it means rendering\nthe plan affordance yourself. The owner passes only `locked` (see\nInputControlOwnerProps): honour it by refusing interaction, and\ntake everything else from the framework session kit or your own inject.\nUnoccupied, the seat renders nothing at all — the bar paints no\nplaceholder, so an absent plan plugin costs no layout.',
    registerOptions: [],
    ownerProps: [
      '/**\n * Owner share of the two named composer control seats (plan / model): the\n * bar passes its disable state; the filling entry owns everything else.\n */\nexport interface InputControlOwnerProps {\n  /** Session-removed lock (the bar\'s chrome disable state). */\n  locked: boolean\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.composer.bar\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-plan PlanChip',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.input.plan\', () => ctx.slots.register(\n      { name: \'conversation.input.plan\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:211',
  },
  {
    key: 'conversation.input.right',
    kind: 'list',
    scope: 'session',
    summary: 'The right end of the same tool row, before the primary send button — the seat for a control the user reaches on the way to sending (the model select sits in its own named seat just left of here).',
    doc: 'The right end of the same tool row, before the primary send button —\nthe seat for a control the user reaches on the way to sending (the\nmodel select sits in its own named seat just left of here). Same\nInputZone owner share and the same one-row height budget as\n`conversation.input.left`.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/**\n * The input-region slot currency: dock/left/right entries read\n * the conversation snapshot and the live input state as owner props (both\n * are point-in-time snapshots — the dispatching skeleton re-renders on\n * either store\'s change, so entries stay current without subscribing).\n */\nexport interface InputZone {\n  readonly session: ConversationSnapshot\n  readonly input: InputState\n}',
    ],
    ownerPropsReferences: [
      'ConversationSnapshot',
      'InputState',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.input.right\', () => ctx.slots.register(\n      { name: \'conversation.input.right\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:187',
  },
  {
    key: 'conversation.session',
    kind: 'single',
    scope: 'session',
    summary: 'The entire body of one session: taking this seat means rendering that session\'s conversation yourself.',
    doc: 'The entire body of one session: taking this seat means rendering that\nsession\'s conversation yourself. The occupant also owns the per-session\ndraft mirror and the active view ring, so a replacement inherits both\nduties and an empty one leaves a blank session pane — nothing here\ndegrades gracefully. To ADD rather than replace, take a seat inside the\nflow instead: `conversation.view` for a whole tab, the input regions for\ncomposer chrome.',
    registerOptions: [],
    ownerProps: [],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation ConversationSession',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.session\', () => ctx.slots.register(\n      { name: \'conversation.session\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:44',
  },
  {
    key: 'conversation.session.header',
    kind: 'single',
    scope: 'session',
    summary: 'The strip above the session\'s scrollport: title, view tabs, and the action row.',
    doc: 'The strip above the session\'s scrollport: title, view tabs, and the\naction row. Taking this seat means rendering all three yourself, and it\nalso collapses `conversation.session.header.actions` — that additive\nseat is declared by whoever occupies this one, so replacing the header\ntakes every action entry down with it.',
    registerOptions: [],
    ownerProps: [],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation ConversationSessionHeader',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.session.header\', () => ctx.slots.register(\n      { name: \'conversation.session.header\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:52',
  },
  {
    key: 'conversation.session.header.actions',
    kind: 'list',
    scope: 'session',
    summary: 'One button in the session header\'s action row — the additive way to put a per-session control beside the title without replacing the header.',
    doc: 'One button in the session header\'s action row — the additive way to put\na per-session control beside the title without replacing the header.\nEntries render by ascending `order`; negative values are reserved for\nstatic session context that precedes interactive actions. The owner\npasses nothing: everything a control needs comes from the framework\nsession kit (`sessionId`, `useSession`, `useInput`, `inputActions`) and\nfrom the registrant\'s own inject face, so an empty owner share means\nself-sufficient, not starved.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/** Header actions derive their state from the standard session/global kit. */\nexport interface ConversationHeaderActionOwnerProps {}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.session.header\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-agent-preset AgentPresetLabel id \'agent-preset\'',
      'client-ui-jobs JobListAction id \'job-list\'',
      'client-ui-subagent SubagentCatalogAction id \'subagent-catalog\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.session.header.actions\', () => ctx.slots.register(\n      { name: \'conversation.session.header.actions\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:63',
  },
  {
    key: 'conversation.session.header.utilities',
    kind: 'list',
    scope: 'session',
    summary: 'Right-aligned Session utilities kept outside the title-adjacent action group, so an optional utility cannot reorder session context or lineage.',
    doc: 'Right-aligned Session utilities kept outside the title-adjacent action\ngroup, so an optional utility cannot reorder session context or lineage.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/** Header actions derive their state from the standard session/global kit. */\nexport interface ConversationHeaderActionOwnerProps {}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.session.header\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'session-log-export SessionLogDownloadHeaderAction id \'session-log-download\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.session.header.utilities\', () => ctx.slots.register(\n      { name: \'conversation.session.header.utilities\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:68',
  },
  {
    key: 'conversation.view',
    kind: 'list',
    scope: 'session',
    summary: 'The conversation view ring: one list entry per view tab (chat here; trajectory/waterfall from ui-trajectory), rendered one-at-a-time by the session body via `only: <active id>`.',
    doc: 'The conversation view ring: one list entry per view tab (chat here;\ntrajectory/waterfall from ui-trajectory), rendered one-at-a-time by\nthe session body via `only: <active id>`. Declared by this package\'s\nbody entry (declaring is claiming). Session scope: views read the\nconversation snapshot through the standard kit.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/**\n * View-slot owner share: the cross-view inspect handoff (otherwise views need\n * nothing from the render site — sessionId and the snapshot hook arrive as\n * framework-standard props; tool rows go through each view\'s own declared\n * toolview hole).\n */\nexport interface ConvViewOwnerProps {\n  /** One-shot inspect request from another view (chat\'s Inspect button); null when idle. */\n  inspect?: { callId: CallId } | null\n  /** Acknowledge the inspect request once applied (clears the store field). */\n  onInspectDone?: () => void\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.session\' (client-ui-conversation), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation ChatView id \'chat\'',
      'client-ui-trajectory TrajectoryView id \'trajectory\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'conversation.view\', () => ctx.slots.register(\n      { name: \'conversation.view\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-conversation/src/client/contract/slots.ts:76',
  },
  {
    key: 'details',
    kind: 'single',
    scope: 'session',
    summary: 'The right details column, shown when the layout opens it.',
    doc: 'The right details column, shown when the layout opens it. OCCUPIED by\nui-conversation\'s DetailsPanel, which declares the tool-details seat\ninside it — registering here replaces the column and takes that seat\nwith it. Absent an occupant the column renders nothing.\n\nNo owner props: the framework injects the session id and hooks for the\n`session` scope, and `ctx.layout` owns whether the column is open.',
    registerOptions: [],
    ownerProps: [
      '/** Details owner share: empty — sessionId arrives as a framework-standard prop. */\nexport interface DetailsOwnerProps {}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'root\' (client-ui-layout), so it exists while that entry is mounted',
    occupants: [
      'client-ui-conversation DetailsPanel',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'details\', () => ctx.slots.register(\n      { name: \'details\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-layout/src/client/index.ts:72',
  },
  {
    key: 'root',
    kind: 'single',
    scope: 'root',
    summary: 'The built-in render-tree root hole (seeded by SlotCore): the one slot the shell itself renders, and the ancestor of every other seat.',
    doc: 'The built-in render-tree root hole (seeded by SlotCore): the one slot the\nshell itself renders, and the ancestor of every other seat. OCCUPIED by\nui-layout\'s AppFrame, which declares the sidebar, conversation, details,\nand shell.overlay seats inside it.\n\nDO NOT register here. This is a single slot, so a second entry does not\nsit beside the frame — it shadows it, and a dynamically registered entry\nis assigned a lower priority than the shipped one, which makes it the\nwinner: the page would render your component alone, with every seat the\nframe declares gone. For a surface of your own that floats over the whole\napp, register into `shell.overlay` instead (a list slot: additive, and\nclick-through until your entry opts into pointer events).',
    registerOptions: [],
    ownerProps: [
      '/** Root owner share: the shell supplies nothing — the frame is inject-assembled. */\nexport interface RootOwnerProps { children?: never }',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'the runtime itself (built in; always present)',
    occupants: [
      'client-ui-layout AppFrame',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'root\', () => ctx.slots.register(\n      { name: \'root\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/runtime/src/client/slots.ts:41',
  },
  {
    key: 'settings.action',
    kind: 'list',
    scope: 'root',
    summary: 'Optional actions rendered in the content-column header before Close.',
    doc: 'Optional actions rendered in the content-column header before Close.\nRegistrants own visibility, behavior, copy, and failure presentation;\nthe shell supplies only the ordered render site.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/** Owner share of the header title seat (the shell supplies nothing). */\nexport interface SettingsHeaderOwnerProps {\n  /** Marker field: header owner props are intentionally empty. */\n  children?: never\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar.settings\' (client-ui-settings-general), so it exists while that entry is mounted',
    occupants: [
      'client-ui-settings-general SettingsDocumentAction id \'open-document\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.action\', () => ctx.slots.register(\n      { name: \'settings.action\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings/src/client/contract/slots.ts:35',
  },
  {
    key: 'settings.close',
    kind: 'single',
    scope: 'root',
    summary: 'The close button\'s visually-hidden label text (the button itself — icon, geometry, focus — is shell chrome).',
    doc: 'The close button\'s visually-hidden label text (the button itself —\nicon, geometry, focus — is shell chrome). Absent contribution leaves\nthe button without an accessible name (broken-composition state).',
    registerOptions: [],
    ownerProps: [
      '/** Owner share of the header title seat (the shell supplies nothing). */\nexport interface SettingsHeaderOwnerProps {\n  /** Marker field: header owner props are intentionally empty. */\n  children?: never\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar.settings\' (client-ui-settings-general), so it exists while that entry is mounted',
    occupants: [
      'client-ui-settings-general CloseLabel',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.close\', () => ctx.slots.register(\n      { name: \'settings.close\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings/src/client/contract/slots.ts:41',
  },
  {
    key: 'settings.general.item',
    kind: 'list',
    scope: 'root',
    summary: 'One preference row inside the General section — the additive seat for a single setting that needs no page of its own (a whole page is `settings.section`), contributed by the feature plugin that owns the preference (locale → Language, ui-theme → Appearance, ui-conversation → Composer Enter).',
    doc: 'One preference row inside the General section — the additive seat for a\nsingle setting that needs no page of its own (a whole page is\n`settings.section`), contributed by the feature plugin that owns the\npreference (locale → Language, ui-theme → Appearance, ui-conversation →\nComposer Enter). Options: `id` (row key), `order` (row position). The\nsection column only stacks rows, so a row draws its own internals,\nincluding its label: nothing projects a `label` here and the owner passes\nno props at all — copy, current value, and the write path are all yours,\nthrough your own inject face and `host.call`. Declared at runtime by\nui-settings-general\'s General entry; the type lives here with every other\nsettings slot type, because this package is the settings domain\'s base\nlayer and every registrant already depends on it for `ctx.settingsScope`.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/** Owner share of a General preference row (the section supplies nothing). */\nexport interface SettingsGeneralItemOwnerProps {\n  /** Marker field: item owner props are intentionally empty. */\n  children?: never\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'settings.section\' (client-ui-settings-general), so it exists while that entry is mounted',
    occupants: [
      'client-locale LanguageRow id \'language\'',
      'client-ui-agent-preset AgentPresetRow id \'agent-preset\'',
      'client-ui-conversation EnterBehaviorRow id \'composer-enter\'',
      'client-ui-permission-presets PermissionRow id \'permission\'',
      'client-ui-theme AppearanceRow id \'appearance\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.general.item\', () => ctx.slots.register(\n      { name: \'settings.general.item\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings/src/client/contract/slots.ts:88',
  },
  {
    key: 'settings.header',
    kind: 'single',
    scope: 'root',
    summary: 'The panel title text seat.',
    doc: 'The panel title text seat. Content renders inside the nav heading row;\nthe dialog\'s accessible name points at that node via aria-labelledby.\nAbsent contribution leaves the heading empty.',
    registerOptions: [],
    ownerProps: [
      '/** Owner share of the header title seat (the shell supplies nothing). */\nexport interface SettingsHeaderOwnerProps {\n  /** Marker field: header owner props are intentionally empty. */\n  children?: never\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar.settings\' (client-ui-settings-general), so it exists while that entry is mounted',
    occupants: [
      'client-ui-settings-general HeaderContent',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.header\', () => ctx.slots.register(\n      { name: \'settings.header\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings/src/client/contract/slots.ts:29',
  },
  {
    key: 'settings.onboarding',
    kind: 'list',
    scope: 'root',
    summary: 'Root-scoped onboarding steps contributed by settings features.',
    doc: 'Root-scoped onboarding steps contributed by settings features. The\nshell mounts one ordered step at a time; the active registrant either\ncompletes itself or keeps ownership until the user completes its sole\npath. Registrants own readiness, copy, dialog behavior, AND visible\nchrome: a step wraps its visible content in its modal surface (including\n`#root` inert ownership) and renders null while private facts are still\nloading. The shell paints no chrome of its own, so a mounted-but-deciding\nstep shows and blocks nothing.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/** Owner share of the currently active settings-backed onboarding step. */\nexport interface SettingsOnboardingOwnerProps {\n  /** Stable id of the step currently selected by the coordinator. */\n  stepId: string\n  /** Complete or skip this step and transfer ownership to the next entry. */\n  complete: () => void\n  /** Open the settings panel directly on one registered section. */\n  openSection: (id: string) => void\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar.settings\' (client-ui-settings-general), so it exists while that entry is mounted',
    occupants: [
      'client-ui-settings-models WelcomeNotice id \'welcome-notice\'',
      'client-ui-settings-models DeepSeekOnboardingDialog id \'deepseek-official\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.onboarding\', () => ctx.slots.register(\n      { name: \'settings.onboarding\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings/src/client/contract/slots.ts:73',
  },
  {
    key: 'settings.plugin.item',
    kind: 'list',
    scope: 'root',
    summary: 'One plugin\'s card inside the plugin configuration section (see module JSDoc).',
    doc: 'One plugin\'s card inside the plugin configuration section (see module JSDoc).',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/** Owner share of a plugin card (the section supplies nothing). */\nexport interface SettingsPluginItemOwnerProps {\n  /** Marker field: card owner props are intentionally empty. */\n  children?: never\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'settings.plugins.tab\' (client-ui-settings-plugins), so it exists while that entry is mounted',
    occupants: [
      'client-ui-settings-plugins BashCard id \'bash\'',
      'client-ui-settings-plugins AgentLoopCard id \'agent-loop\'',
      'client-ui-settings-plugins WebSearchCard id \'web-search\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.plugin.item\', () => ctx.slots.register(\n      { name: \'settings.plugin.item\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings-plugins/src/client/slot-contract.ts:16',
  },
  {
    key: 'settings.plugins.tab',
    kind: 'list',
    scope: 'root',
    summary: 'One page inside the Plugins settings section.',
    doc: 'One page inside the Plugins settings section. The section owner renders\nlocalized entry labels as tabs and mounts each contribution inside its\ncorresponding tab panel. Options: `id` (tab key), `order` (tab order),\nand `label` (registrant-localized tab text). Declared at runtime by the\nfeature that owns the Plugins section; the type lives here so inventory\nand configuration plugins collaborate without depending on one another.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/** Owner share of a Plugins tab (the section supplies nothing). */\nexport interface SettingsPluginsTabOwnerProps {\n  /** Marker field: tab owner props are intentionally empty. */\n  children?: never\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'settings.section\' (client-ui-settings-plugins), so it exists while that entry is mounted',
    occupants: [
      'client-ui-settings-plugin-inventory PluginInventorySettingsTab id \'all\'',
      'client-ui-settings-plugins ConfigurablePluginsTab id \'configurable\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.plugins.tab\', () => ctx.slots.register(\n      { name: \'settings.plugins.tab\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings/src/client/contract/slots.ts:62',
  },
  {
    key: 'settings.section',
    kind: 'list',
    scope: 'root',
    summary: 'One settings page per list entry.',
    doc: 'One settings page per list entry. Registrant options carry the nav\nidentity: `id` (section key, drives `only` filtering), `order` (nav\nposition), `label` (registrant-localized display text — the registrant\nre-registers with fresh text on locale change, so the shell never\nsubscribes locale state; the ledger bump doubles as the shell\'s\nre-render trigger). Sections render inside the panel content column.\n(`settings.general.item`, declared by ui-settings-general\'s General\nentry, is typed in the locale package — the common dependency of every\nitem registrant; the shell neither declares nor renders it.)',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/**\n * Owner share of a settings section entry. The shell owns modal visibility\n * and navigation; a section\'s data arrives through its own inject faces and\n * stores. `close` is the one shell affordance a section receives, for flows\n * that leave settings altogether (starting a session from a section) — the\n * onboarding coordinator\'s `openSection`/`complete` precedent, inverted.\n */\nexport interface SettingsSectionOwnerProps {\n  /** Close the settings panel (the shell owns the open state). */\n  close: () => void\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar.settings\' (client-ui-settings-general), so it exists while that entry is mounted',
    occupants: [
      'client-ui-agent-preset AgentPresetSection id \'agent-presets\'',
      'client-ui-settings-general GeneralSection id \'general\'',
      'client-ui-settings-models ModelsSection id \'models\'',
      'client-ui-settings-plugins PluginsSettingsSection id \'plugins\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.section\', () => ctx.slots.register(\n      { name: \'settings.section\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings/src/client/contract/slots.ts:53',
  },
  {
    key: 'settings.trigger',
    kind: 'single',
    scope: 'root',
    summary: 'The sidebar-foot trigger row content: icon + label, supplied as slot content (the accessible name comes from the content — rail state renders the label visually hidden).',
    doc: 'The sidebar-foot trigger row content: icon + label, supplied as slot\ncontent (the accessible name comes from the content — rail state\nrenders the label visually hidden). The shell renders the button\nchrome and owns open state. Absent contribution degrades to an\nicon-only button without an accessible name (broken-composition state;\nthe shipped composition always registers the seat).',
    registerOptions: [],
    ownerProps: [
      '/** Owner share of the trigger content seat: the sidebar column state. */\nexport interface SettingsTriggerOwnerProps {\n  /** Whether the sidebar renders wide content (false = 56px rail, icon only). */\n  wide: boolean\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar.settings\' (client-ui-settings-general), so it exists while that entry is mounted',
    occupants: [
      'client-ui-settings-general TriggerContent',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'settings.trigger\', () => ctx.slots.register(\n      { name: \'settings.trigger\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-settings/src/client/contract/slots.ts:23',
  },
  {
    key: 'shell.overlay',
    kind: 'list',
    scope: 'root',
    summary: 'Frame-wide floating layer, above every column and outside their scroll containers.',
    doc: 'Frame-wide floating layer, above every column and outside their scroll\ncontainers. Deliberately generic and unowned by any feature: a badge, a\ntoast stack or a status pill all belong here, and entries order among\nthemselves. The layer itself is click-through — entries opt back into\npointer events — so an occupant never blocks the app underneath.\n\nThis is the additive seat for a frame-wide surface of your own: a fresh\n`id` is added beside the shipped entries instead of replacing them.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'root\' (client-ui-layout), so it exists while that entry is mounted',
    occupants: [],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'shell.overlay\', () => ctx.slots.register(\n      { name: \'shell.overlay\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-layout/src/client/index.ts:83',
  },
  {
    key: 'sidebar',
    kind: 'single',
    scope: 'root',
    summary: 'The whole left column.',
    doc: 'The whole left column. OCCUPIED by ui-sidebar\'s SidebarRoot, which\ndeclares the workspace and settings seats inside it — registering here\nreplaces the navigation column outright rather than adding to it, and\nthe seats it declares disappear with it. To add something to the\nsidebar, register into one of those inner seats instead.\n\nThe occupant receives the frame\'s live column state (collapsed, width)\nand is expected to render the compact control rail while collapsed.',
    registerOptions: [],
    ownerProps: [
      '/** Sidebar owner share: live column state from the frame\'s concession solve. */\nexport interface SidebarOwnerProps {\n  /** True when the sidebar is closed (the column renders the compact control rail). */\n  collapsed: boolean\n  /** Rendered column width in px (SIDEBAR_COLLAPSED when collapsed). */\n  width: number\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'root\' (client-ui-layout), so it exists while that entry is mounted',
    occupants: [
      'client-ui-sidebar SidebarRoot',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'sidebar\', () => ctx.slots.register(\n      { name: \'sidebar\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-layout/src/client/index.ts:49',
  },
  {
    key: 'sidebar.footer.action',
    kind: 'list',
    scope: 'root',
    summary: 'Optional actions beside Settings at the sidebar foot.',
    doc: 'Optional actions beside Settings at the sidebar foot. Declared by this\npackage\'s \'sidebar\' entry; each action receives only the column state.',
    registerOptions: [
      {
        name: 'id',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
      },
      {
        name: 'order',
        requirement: 'optional',
        type: 'number',
        doc: 'Position among the entries, ascending (default 0).',
      },
      {
        name: 'label',
        requirement: 'optional',
        type: 'string | (() => string)',
        doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
      },
    ],
    ownerProps: [
      '/** Owner share of an action rendered beside Settings at the sidebar foot. */\nexport interface SidebarFooterActionOwnerProps {\n  /** Whether the sidebar renders wide content (false = 56px rail). */\n  wide: boolean\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar\' (client-ui-sidebar), so it exists while that entry is mounted',
    occupants: [
      'client-ui-cordis CordisPanel id \'cordis-panel\'',
    ],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'sidebar.footer.action\', () => ctx.slots.register(\n      { name: \'sidebar.footer.action\', id: \'my-entry\', order: 100, label: \'My entry\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-sidebar/src/client/contract/slots.ts:35',
  },
  {
    key: 'sidebar.settings',
    kind: 'single',
    scope: 'root',
    summary: 'The settings seat at the sidebar foot.',
    doc: 'The settings seat at the sidebar foot. Declared by this package\'s\n\'sidebar\' entry; ui-settings registers its trigger row + modal panel.\nThe sidebar passes only its column state — it holds no settings state.',
    registerOptions: [],
    ownerProps: [
      '/**\n * Owner share of the sidebar settings seat: the column display state the\n * occupant\'s trigger row must render against (wide row vs rail icon).\n */\nexport interface SidebarSettingsOwnerProps {\n  /** Whether the sidebar renders wide content (false = 56px rail). */\n  wide: boolean\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar\' (client-ui-sidebar), so it exists while that entry is mounted',
    occupants: [
      'client-ui-settings-general SettingsRoot',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'sidebar.settings\', () => ctx.slots.register(\n      { name: \'sidebar.settings\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-sidebar/src/client/contract/slots.ts:30',
  },
  {
    key: 'sidebar.workspaces',
    kind: 'single',
    scope: 'root',
    summary: 'The workspace/session browsing region: section header, search, the grouped/flat session list, and every workspace dialog.',
    doc: 'The workspace/session browsing region: section header, search, the\ngrouped/flat session list, and every workspace dialog. Declared by this\npackage\'s \'sidebar\' entry (declaring is claiming); ui-workspace\nregisters the browser.',
    registerOptions: [],
    ownerProps: [
      '/**\n * Owner share of the browser hole — the only facts crossing the shell/region\n * boundary. Business data and actions arrive through the region\'s own inject.\n */\nexport interface SidebarSectionOwnerProps {\n  /** Shell fold-state output: wide renders the full browser, rail the icon column. */\n  wide: boolean\n  /** Rail icons request expansion; the browser rides the wide flip for focus. */\n  expandSidebar: () => void\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar\' (client-ui-sidebar), so it exists while that entry is mounted',
    occupants: [
      'client-ui-workspace WorkspaceBrowser',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'sidebar.workspaces\', () => ctx.slots.register(\n      { name: \'sidebar.workspaces\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-sidebar/src/client/contract/slots.ts:24',
  },
  {
    key: 'sidebar.workspaces.directoryFlow',
    kind: 'single',
    scope: 'root',
    summary: 'Directory-flow hole under the sidebar browsing region (declared by the WorkspaceBrowser entry).',
    doc: 'Directory-flow hole under the sidebar browsing region (declared by the WorkspaceBrowser entry).',
    registerOptions: [],
    ownerProps: [
      '/**\n * Owner share of the directory-flow holes: the complete conversation between\n * the trigger surface and the picking interaction. The occupant reads `open`\n * to run/render its interaction and reports exactly one outcome per open.\n */\nexport interface DirectoryFlowOwnerProps {\n  /** True while a picking interaction is requested; flipping back to false withdraws the request. */\n  open: boolean\n  /** True while the owner adopts a picked path (`createWorkspace` in flight); occupants disable their commit affordances. */\n  busy: boolean\n  /** The operator picked a directory (absolute host path); the owner adopts it. */\n  onPicked: (path: string) => void\n  /** The operator dismissed the interaction; the owner just closes the flow. */\n  onCancel: () => void\n  /** The interaction itself failed (chooser missing, listing denied); the owner shows its error surface. */\n  onError: (message: string) => void\n}',
    ],
    ownerPropsReferences: [],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
    ],
    keyDomain: '',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'sidebar.workspaces\' (client-ui-workspace), so it exists while that entry is mounted',
    occupants: [
      'client-ui-directory-picker-browse BrowseDirectoryFlow',
      'client-ui-directory-picker-native NativeDirectoryFlow',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'sidebar.workspaces.directoryFlow\', () => ctx.slots.register(\n      { name: \'sidebar.workspaces.directoryFlow\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-workspace/src/client/contract/slots.ts:58',
  },
  {
    key: 'tool.call.toolview',
    kind: 'keyed',
    scope: 'session',
    summary: 'Keyed atomic Tool call view, dispatched by the wire Tool name.',
    doc: 'Keyed atomic Tool call view, dispatched by the wire Tool name. Register\nwith `key: \'<tool name>\'` to own how one tool\'s calls render inside a\nturn — the key domain is open (any wire tool name, including a tool your\nown package registered), so there is no compile-time key set to pick\nfrom and a typo simply never renders.\n\nA key the shipped composition already covers is replaced, not shared;\nan unclaimed key falls back to the generic tool row, so registering is\nadditive for your own tool and a takeover for a shipped one. The owner\npasses the call\'s identity, its frozen running-or-settled node, and the\nexpansion state (see ToolCallOwnerProps), so the view stays a pure\nfunction of what the turn already knows.',
    registerOptions: [
      {
        name: 'key',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key: the entry renders where the owner dispatches this exact key. Registering an already-occupied key replaces that occupant.',
      },
    ],
    ownerProps: [
      '/** Standard owner currency supplied to every atomic Tool view. */\nexport interface ToolCallOwnerProps {\n  /** Tool call identity, stable across running and settled forms. */\n  callId: string\n  /** Wire Tool name and keyed dispatch value. */\n  toolName: string\n  /** Frozen running call or settled result node. */\n  block: ToolCallBlock\n  /** Session workspace root for relative summaries. */\n  cwd?: string | undefined\n  /** Open a Tool argument path through the Host. */\n  openFile: (path: string) => void\n  /** Inspect this call in the trajectory view when available. */\n  inspect?: (() => void) | undefined\n}',
    ],
    ownerPropsReferences: [
      'Wire',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: 'open: any string the owner dispatches (no compile-time key set), already taken: ask_user_question, bash, cordis_define, cordis_run, cordis_stop, cordis_undefine, edit, glob, grep, read, skill, todo_write, web_fetch, web_search, write',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'conversation.chat.node\' (client-ui-tool), so it exists while that entry is mounted',
    occupants: [
      'client-ui-skill SkillRow key \'skill\'',
      'client-ui-tool AskQuestionRow key \'ask_user_question\'',
      'client-ui-tool BashRow key \'bash\'',
      'client-ui-tool FileMutationRow key \'edit\'',
      'client-ui-tool FileMutationRow key \'write\'',
      'client-ui-tool ReadRow key \'read\'',
      'client-ui-tool SearchRow key \'grep\'',
      'client-ui-tool SearchRow key \'glob\'',
      'client-ui-tool TodoRow key \'todo_write\'',
      'client-ui-tool WebRow key \'web_search\'',
      'client-ui-tool WebRow key \'web_fetch\'',
      'client-ui-cordis CordisDefineRow key \'cordis_define\'',
      'client-ui-cordis CordisRunRow key \'cordis_run\'',
      'client-ui-cordis CordisActionRow key \'cordis_stop\'',
      'client-ui-cordis CordisActionRow key \'cordis_undefine\'',
    ],
    replaceRisk: 'shadows-shipped-ui',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'tool.call.toolview\', () => ctx.slots.register(\n      { name: \'tool.call.toolview\', key: \'<one key the owner dispatches>\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/client/ui-tool/src/client/contract/slots.ts:23',
  },
  {
    key: 'tool.view.cordis',
    kind: 'keyed',
    scope: 'session',
    summary: 'Interactive Package-owned region rendered inside the latest eligible `cordis_run` card in the conversation flow.',
    doc: 'Interactive Package-owned region rendered inside the latest eligible\n`cordis_run` card in the conversation flow. Use it for controls and other\nUI the user can interact with. Dynamic Client code registers with\n`key: \'self\'`; the Guard binds that key to the current Plugin and Package.',
    registerOptions: [
      {
        name: 'key',
        requirement: 'required',
        type: 'string',
        doc: 'Your cell key: the entry renders where the owner dispatches this exact key. Registering an already-occupied key replaces that occupant.',
      },
    ],
    ownerProps: [
      '/** Owner currency delivered to a dynamic Package\'s business view. */\nexport interface CordisToolViewOwnerProps {\n  readonly pluginId: CordisDynamicPluginId\n  readonly packageId: CordisDynamicPackageId\n  readonly pluginRunId: CordisDynamicPluginRunId\n}',
    ],
    ownerPropsReferences: [
      'CordisDynamicPackageId',
      'CordisDynamicPluginId',
      'CordisDynamicPluginRunId',
    ],
    standardProps: [
      'useSessions: SnapshotSelectorHook<SessionListState>',
      'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
      'useSession: SnapshotSelectorHook<ConversationSnapshot>',
      'sessionId: SessionId',
      'useProjection: UseProjection',
      'useInput: SnapshotSelectorHook<InputState>',
      'inputActions: InputActions',
    ],
    keyDomain: 'open: any string the owner dispatches (no compile-time key set), none are taken yet',
    hookContext: '',
    slotInject: '',
    declaredBy: 'an entry in \'tool.call.toolview\' (client-ui-cordis), so it exists while that entry is mounted',
    occupants: [],
    replaceRisk: 'none',
    example: 'return {\n  inject: [\'slots\'],\n  apply(ctx) {\n    ctx.slots.inject(\'tool.view.cordis\', () => ctx.slots.register(\n      { name: \'tool.view.cordis\', key: \'<one key the owner dispatches>\' },\n      () => React.createElement(\'div\', null, \'hello\'),\n    ))\n  },\n}',
    source: 'packages/extensions/ui-cordis/src/client/slots.ts:31',
  },
]
/* jscpd:ignore-end */
