MCPcopy Create free account
hub / github.com/cortexkit/magic-context / tui

Function tui

packages/plugin/src/tui/index.tsx:727–835  ·  view source on GitHub ↗
(api, _options, meta)

Source from the content-addressed store, hash-verified

725}
726
727const tui: TuiPlugin = async (api, _options, meta) => {
728 // Initialize RPC client for server communication
729 const directory = api.state.path.directory ?? ""
730 initRpcClient(directory)
731 await refreshToastDurationMs()
732
733 // Register sidebar slot
734 api.slots.register(createSidebarContentSlot(api))
735
736 // Register TUI command palette entries (no slash field — slash commands
737 // are registered server-side so there's only one /ctx-* registration).
738 // The server detects TUI mode and sends dialog requests via RPC instead
739 // of sendIgnoredMessage.
740 //
741 // OpenCode 1.14.42 removed `api.command.register` entirely
742 // (anomalyco/opencode#26053). A later patch (1.14.44+) reinstated it as
743 // a deprecated shim that translates to `api.keymap.registerLayer`. To
744 // work across all hosts (1.14.0–1.14.41 with command-only, the broken
745 // 1.14.42–1.14.43, and 1.14.44+ where both exist), we prefer
746 // `api.keymap.registerLayer` and fall back to `api.command.register`
747 // only when keymap is missing.
748 registerCommandPaletteEntries(api)
749
750 // Receive server→TUI notifications (toasts + dialog requests) over a single
751 // persistent WebSocket, pushed the instant the server queues them. This
752 // replaces the old 500ms HTTP poll whose new-connection-per-tick cost was the
753 // source of idle TUI CPU (#200). The socket carries the active session in its
754 // hello so the server scopes delivery; here we re-check the active session per
755 // notification (it can change between queue and delivery) before acting.
756 const handleNotification = async (n: SocketNotification): Promise<boolean> => {
757 const requestedSessionId = getSessionId(api)
758 const generation = getRpcGeneration()
759 // A session-scoped notification only applies while we're viewing that
760 // session; global (session-less) ones always apply. Returning false leaves
761 // it unacked so a TUI on the right session (or a later switch back) still
762 // gets it.
763 if (n.sessionId && requestedSessionId && n.sessionId !== requestedSessionId) {
764 return false
765 }
766 if (n.type === "toast") {
767 const p = n.payload
768 showToast(api, {
769 message: String(p.message ?? ""),
770 variant: (p.variant as "info" | "warning" | "error" | "success") ?? "info",
771 durationOverrideMs:
772 typeof p.duration === "number" && Number.isFinite(p.duration)
773 ? p.duration
774 : undefined,
775 })
776 return true
777 }
778 if (n.type !== "action") return false
779 const action = n.payload?.action
780 const stillActive = () =>
781 getRpcGeneration() === generation && getSessionId(api) === requestedSessionId
782 if (action === "show-status-dialog") {
783 return stillActive() && (await showStatusDialog(api, requestedSessionId))
784 }

Callers

nothing calls this directly

Calls 11

initRpcClientFunction · 0.90
createSidebarContentSlotFunction · 0.90
startNotificationSocketFunction · 0.90
stopNotificationSocketFunction · 0.90
closeRpcFunction · 0.90
detectConflictsFunction · 0.90
refreshToastDurationMsFunction · 0.85
getSessionIdFunction · 0.85
showConflictDialogFunction · 0.85
showStartupAnnouncementFunction · 0.85

Tested by

no test coverage detected