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.insertInsert—topbaralways
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 preview—topbaralways
ph.editor.exitPreviewExit previewescape(keybinding only)mode === "preview"
ph.editor.clearSelectionClear selectionescape(keybinding only)selection.id != null && !tiptap.active && mode !== "preview"
ph.editor.openMoreMore—topbaralways
ph.editor.openCommandPaletteCommand palettemod+k(keybinding only; paletteHide)!isInsideTextEditingSurface
ph.editor.openBlocksPanelBrowse blocks—sidebar/tabsfeatures.blocksPanel.enabled !== false
ph.editor.openComponentsPanelComponents—sidebar/tabsalways
ph.editor.openComponentsTabOpen components tab——always
ph.editor.closeSidebarClose sidebar——when: sidebar open

ph.canvas.* — viewport / device / zoom

IdTitleKeybindingMenusWhen
ph.canvas.setViewSet view——always
ph.canvas.toggleDeviceToggle device——always
ph.canvas.toggleResponsiveToggle responsive——always
ph.canvas.toggleViewModeToggle view mode—topbaralways
ph.canvas.toggleGridLinesToggle grid linesshift+mod+gnavmenu/view!tiptap.active
ph.canvas.toggleBreakpointMarkersToggle breakpoint lines—navmenu/viewalways
ph.canvas.toggleDeviceGuidesToggle device guides—navmenu/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+0—always

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

IdTitleKeybindingMenusWhen
ph.site.selectBackgroundSelect background—navmenu/settingsfeatures.directSave === true
ph.theme.openTheme—navmenu/settingsalways
ph.media.openMedia libraryshift+mod+mnavmenu/settings!tiptap.active
ph.media.selectAll (stub)Select all mediamod+a—media.modalOpen && !media.selectionMode
ph.media.deleteSelected (stub)Delete selected mediabackspace, delete—media.modalOpen && media.selectedCount > 0
ph.layers.popOutPop out layersshift+mod+lnavmenu/view!tiptap.active
ph.layers.toggleDockToggle layers dock—navmenu/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 side—navmenu/preferencesalways
ph.ui.toggleDarkModeToggle dark mode—navmenu/preferencesfeatures.darkModeSwitcher !== false

ph.sidebar.* / ph.ai.*

IdTitleKeybindingMenusWhen
ph.sidebar.search (stub)Search sidebarmod+f—`mouseOver === "sidebar"
ph.ai.openAssistantAI assistant——isAiEnabled
ph.ai.includeTextInChatInclude text in AI chat—tiptap/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 classes—canvas/contextselection.id
ph.node.pasteClassesPaste classes—canvas/contextclipboard.hasClasses && selection.id
ph.node.selectParentSelect parent—canvas/contextparent.id
ph.node.selectPageSelect page——hasPageIsolation
ph.node.selectAncestorSelect ancestor—node/breadcrumb (data-driven rows)breadcrumbLength > 1
ph.node.deselectDeselect—canvas/contextselection.id != null
ph.node.moveUpMove up—canvas/contextselection.id && parent.id && siblingMove.canMoveUp
ph.node.moveDownMove down—canvas/contextselection.id && parent.id && siblingMove.canMoveDown
ph.node.isolateIsolate component—canvas/chipselection.type === "component" && !disableIsolate
ph.node.renameDisplayNameRename—node/breadcrumb (rename trigger)selection.id
ph.node.addBlockAboveAdd block above—canvas/contextselection.id
ph.node.addBlockBelowAdd block below—canvas/contextselection.id
ph.node.addEmptySectionAdd empty section—canvas/contextselection.id
ph.node.addContainerAdd container—canvas/contextselection.id
ph.node.insertComponentInsert component—canvas/contextselection.id
ph.node.convertToComponentConvert to component—canvas/contextselection.id, enablement: canMakeSavedComponent
ph.node.aiContextInclude node in AI chat—canvas/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.toggleStrikeStrikethrough—tiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.toggleSuperscriptSuperscript—tiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.toggleSubscriptSubscript—tiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.setBlockTypeSet block type——tiptap.active && richTextMode === "full"
ph.text.setFontFamilySet font family——tiptap.active
ph.text.setFontSizeSet font size——tiptap.active
ph.text.applyTypographyPresetApply typography preset——tiptap.active
ph.text.setAlignAlign text—tiptap/inline/more-panel (left/center/right)tiptap.active && richTextMode === "full"
ph.text.toggleBulletListBullet list—tiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.toggleOrderedListNumbered list—tiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.indentListItemIndent list item—tiptap/inline/more-paneltiptap.active && in-list
ph.text.outdentListItemOutdent list item—tiptap/inline/more-paneltiptap.active && in-list
ph.text.openLinkPanelOpen link panel—tiptap/inlinetiptap.active
ph.text.setLinkSet link——tiptap.active
ph.text.unsetLinkUnset link——tiptap.active && isActive("link")
ph.text.openFontPanelOpen font panel—tiptap/inlinetiptap.active
ph.text.openTextColorPanelOpen text color panel—tiptap/inlinetiptap.active
ph.text.openHighlightPanelOpen highlight panel—tiptap/inlinetiptap.active
ph.text.openMorePanelOpen more panel—tiptap/inlinetiptap.active && richTextMode === "full"
ph.text.setColorSet text color——tiptap.active
ph.text.unsetColorUnset text color——tiptap.active
ph.text.setHighlightSet highlight——tiptap.active
ph.text.unsetHighlightUnset highlight——tiptap.active && isActive("highlight")
ph.text.insertImageInsert image—tiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.insertHorizontalRuleInsert horizontal rule—tiptap/inline/more-paneltiptap.active && richTextMode === "full"
ph.text.clearFormattingClear formatting—tiptap/inline/more-paneltiptap.active
ph.text.openVariablePickerInsert variable—tiptap/inline/context-menutiptap.active
ph.text.insertVariableInsert variable (parameterized)——tiptap.active
ph.text.closeActivePanelClose active panel——tiptap.activePanel != null

Overlay / annotation / sections / component

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