Builtin commands & slots

Catalog of SDK builtin command ids, keybindings, and slot ids hosts contribute against.

Generated from packages/sdk/src/registry/builtins/commands.tsx. Regenerate when adding or removing commands.

This catalog enumerates every command the SDK ships with at boot — id, title, default keybinding (if any), menu locations where it appears in builtin menus, and the when predicate that gates visibility. Hosts can layer additional commands, override existing run bodies, or unregister builtins entirely; see host-configuration.md → Extending the editor for the recipes.

Columns:

  • Id — stable command identifier. SDK builtins are namespaced ph.*; hosts should use their own prefix (acme.*, myapp.*).
  • Title — palette label / default menu label. When a menu contribution sets titleOverride, that wins for that location only.
  • Keybinding — registered chord, in mod+x syntax (mod = ⌘ on macOS, Ctrl on Win/Linux). "—" = no default chord.
  • Menus — builtin menu locations contributing this command. Host menus are not listed.
  • When — short description of the gate. See the source for the exact predicate.

Stubbed commands (run body is a no-op console.warn) are flagged with (stub). The keybinding dispatcher skips preventDefault() for stubs so existing inline handlers (if any) keep owning the chord during incremental migration. See STILL_STUB_IDS for the current set + per-id TODO notes.


ph.editor.* — editor lifecycle

IdTitleKeybindingMenusWhen
ph.editor.insertInserttopbaralways
ph.editor.undoUndomod+ztopbarenablement: canUndo, when: !tiptap.active
ph.editor.redoRedomod+y, shift+mod+ztopbarenablement: canRedo, when: !tiptap.active
ph.editor.saveSavemod+stopbarfeatures.saveButton !== false && !tiptap.active
ph.editor.togglePreviewToggle previewtopbaralways
ph.editor.exitPreviewExit previewescape(keybinding only)mode === "preview"
ph.editor.clearSelectionClear selectionescape(keybinding only)selection.id != null && !tiptap.active && mode !== "preview"
ph.editor.openMoreMoretopbaralways
ph.editor.openCommandPaletteCommand palettemod+k(keybinding only; paletteHide)!isInsideTextEditingSurface
ph.editor.openBlocksPanelBrowse blockssidebar/tabsfeatures.blocksPanel.enabled !== false
ph.editor.openComponentsPanelComponentssidebar/tabsalways
ph.editor.openComponentsTabOpen components tabalways
ph.editor.closeSidebarClose sidebarwhen: sidebar open

ph.canvas.* — viewport / device / zoom

IdTitleKeybindingMenusWhen
ph.canvas.setViewSet viewalways
ph.canvas.toggleDeviceToggle devicealways
ph.canvas.toggleResponsiveToggle responsivefeatures.responsivePreview !== false
ph.canvas.toggleViewModeToggle view modetopbaralways
ph.canvas.toggleGridLinesToggle grid linesshift+mod+gnavmenu/view!tiptap.active
ph.canvas.toggleBreakpointMarkersToggle breakpoint linesnavmenu/viewalways
ph.canvas.toggleDeviceGuidesToggle device guidesnavmenu/viewalways
ph.canvas.toggleHiddenToggle hiddenshift+mod+hnavmenu/view!tiptap.active
ph.canvas.zoomInZoom inmod++, mod+=always
ph.canvas.zoomOutZoom outmod+-always
ph.canvas.zoomResetReset zoommod+0always

ph.site.* / ph.theme.* / ph.media.* / ph.layers.* / ph.modifiers.* / ph.importExport.*

IdTitleKeybindingMenusWhen
ph.site.selectBackgroundSelect backgroundnavmenu/settingsfeatures.directSave === true
ph.theme.openThemenavmenu/settingsalways
ph.media.openMedia libraryshift+mod+mnavmenu/settings!tiptap.active
ph.media.selectAll (stub)Select all mediamod+amedia.modalOpen && !media.selectionMode
ph.media.deleteSelected (stub)Delete selected mediabackspace, deletemedia.modalOpen && media.selectedCount > 0
ph.layers.popOutPop out layersshift+mod+lnavmenu/view!tiptap.active
ph.layers.toggleDockToggle layers docknavmenu/viewalways
ph.modifiers.openModifiersshift+mod+onavmenu/tools!tiptap.active
ph.importExport.openImport / Exportshift+mod+enavmenu/toolsfeatures.importExport !== false && !tiptap.active

ph.ui.* — preferences

IdTitleKeybindingMenusWhen
ph.ui.toggleSidebarSideToggle sidebar sidenavmenu/preferencesalways
ph.ui.toggleDarkModeToggle dark modenavmenu/preferencesfeatures.darkModeSwitcher !== false

ph.sidebar.* / ph.ai.*

IdTitleKeybindingMenusWhen
ph.sidebar.search (stub)Search sidebarmod+f`mouseOver === "sidebar"
ph.ai.openAssistantAI assistantisAiEnabled
ph.ai.includeTextInChatInclude text in AI chattiptap/inline/context-menutiptap.active && isAiEnabled

ph.node.* — node-scoped actions

IdTitleKeybindingMenusWhen
ph.node.deleteDeletebackspace, deletecanvas/contextselection.id && selection.id !== ROOT && selection.canDelete && !tiptap.active
ph.node.duplicateDuplicatemod+dcanvas/contextselection.id && selection.canDelete (proxy for has-parent)
ph.node.copyCopymod+ccanvas/contextselection.id && !ROOT
ph.node.pastePastemod+vcanvas/contextclipboard.hasNode && selection.id
ph.node.copyClassesCopy classescanvas/contextselection.id
ph.node.pasteClassesPaste classescanvas/contextclipboard.hasClasses && selection.id
ph.node.selectParentSelect parentcanvas/contextparent.id
ph.node.selectPageSelect pagehasPageIsolation
ph.node.selectAncestorSelect ancestornode/breadcrumb (data-driven rows)breadcrumbLength > 1
ph.node.deselectDeselectcanvas/contextselection.id != null
ph.node.moveUpMove upcanvas/contextselection.id && parent.id && siblingMove.canMoveUp
ph.node.moveDownMove downcanvas/contextselection.id && parent.id && siblingMove.canMoveDown
ph.node.isolateIsolate componentcanvas/chipselection.type === "component" && !disableIsolate
ph.node.renameDisplayNameRenamenode/breadcrumb (rename trigger)selection.id
ph.node.addBlockAboveAdd block abovecanvas/contextselection.id
ph.node.addBlockBelowAdd block belowcanvas/contextselection.id
ph.node.addEmptySectionAdd empty sectioncanvas/contextselection.id
ph.node.addContainerAdd containercanvas/contextselection.id
ph.node.insertComponentInsert componentcanvas/contextselection.id
ph.node.convertToComponentConvert to componentcanvas/contextselection.id, enablement: canMakeSavedComponent
ph.node.aiContextInclude node in AI chatcanvas/contextselection.id && !ROOT && isAiEnabled
ph.node.cycleNextSiblingNext siblingtab(keybinding only)selection.id && !tiptap.active
ph.node.cyclePrevSiblingPrevious siblingshift+tab(keybinding only)selection.id && !tiptap.active

ph.text.* — rich-text marks, blocks, panels

IdTitleKeybindingMenusWhen
ph.text.boldBold(Tiptap-owned)tiptap/inlinetiptap.active
ph.text.italicItalic(Tiptap-owned)tiptap/inlinetiptap.active
ph.text.underlineUnderline(Tiptap-owned)tiptap/inlinetiptap.active
ph.text.toggleStrikeStrikethroughtiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.toggleSuperscriptSuperscripttiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.toggleSubscriptSubscripttiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.setBlockTypeSet block typetiptap.active && richTextMode === "full"
ph.text.setFontFamilySet font familytiptap.active
ph.text.setFontSizeSet font sizetiptap.active
ph.text.applyTypographyPresetApply typography presettiptap.active
ph.text.setAlignAlign texttiptap/inline/more-panel (left/center/right)tiptap.active && richTextMode === "full"
ph.text.toggleBulletListBullet listtiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.toggleOrderedListNumbered listtiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.indentListItemIndent list itemtiptap/inline/more-paneltiptap.active && in-list
ph.text.outdentListItemOutdent list itemtiptap/inline/more-paneltiptap.active && in-list
ph.text.openLinkPanelOpen link paneltiptap/inlinetiptap.active
ph.text.setLinkSet linktiptap.active
ph.text.unsetLinkUnset linktiptap.active && isActive("link")
ph.text.openFontPanelOpen font paneltiptap/inlinetiptap.active
ph.text.openTextColorPanelOpen text color paneltiptap/inlinetiptap.active
ph.text.openHighlightPanelOpen highlight paneltiptap/inlinetiptap.active
ph.text.openMorePanelOpen more paneltiptap/inlinetiptap.active && richTextMode === "full"
ph.text.setColorSet text colortiptap.active
ph.text.unsetColorUnset text colortiptap.active
ph.text.setHighlightSet highlighttiptap.active
ph.text.unsetHighlightUnset highlighttiptap.active && isActive("highlight")
ph.text.insertImageInsert imagetiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.insertHorizontalRuleInsert horizontal ruletiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.clearFormattingClear formattingtiptap/inline/more-paneltiptap.active
ph.text.openVariablePickerInsert variabletiptap/inline/context-menutiptap.active
ph.text.insertVariableInsert variable (parameterized)tiptap.active
ph.text.closeActivePanelClose active paneltiptap.activePanel != null

Overlay / annotation / sections / component

IdTitleKeybindingMenusWhen
ph.overlay.dismissTop (stub)Closeescapeoverlay.stackDepth > 0
ph.annotation.delete (stub)Delete annotationbackspace, deleteannotation.selectedId && !annotation.editingId && !tiptap.active
ph.sections.toggleQuickLook (stub)Toggle section quick lookspacesections.modalOpen && sections.hoveredBlock != null
ph.component.createReusableSave as reusable componentalways