Skip to content

Latest commit

 

History

History
93 lines (80 loc) · 12.9 KB

File metadata and controls

93 lines (80 loc) · 12.9 KB

Distribution API

This is a guide, not the contract. What the platform guarantees is specified under openspec/specs/. For this page: host-services · gesture-configuration · platform-composition. Where this page and a specification disagree, the specification is right, and that is a defect in this page: change the behaviour there, then explain it here.

Everything a user does in the workbench by hand, your product's own code can do too. This area is the lookup for it: what a distribution may inject and call, the rules behind it, and one page per area.

A plugin never injects these. A weaver gets a brokered subset through ctx (ctx.ui.confirm(), ctx.registerSettingsSection(), ctx.session), and the broker checks a capability first (default-deny). That indirection is the whole isolation story: it is what lets the same weaver run sandboxed in an iframe, where a direct injection would be impossible.

Your distribution does inject them. Your composition root, your login page and your own components are the application, not a guest in it. Every service below is providedIn: 'root', so inject(TheService) is all it takes.

Shell renders the dialog and toast outlets, so there is nothing to place in a template. DialogOutlet and ToastOutlet exist for a distribution that builds its own root component instead.

The rules behind every page

  • A switch moves the control, it does not remove the capability. provideShellFeatures and FeatureSwitches take a gesture away from the user; the service that performs it keeps working for you.
  • The twin is the same code. Every action on these pages is the one the built-in control runs, with the same guards. Closing a pane from code asks about unsaved work exactly as the × does.
  • Facts are signals. What you can read re-evaluates where you read it; there is no separate event saying the same thing.
  • Prevention belongs to the owner. The surface that holds unsaved work decides whether it may be closed; a service asks it, and answers whether it ran where a caller needs to know.

I want to …

I want to … Call Page
decide what the product is made of the providers, indexed by intent Composition
add chrome without a plugin provideViews, provideBarItems, provideRailItems Composition
read a capability switch switches.content.splitRight() Switches
change a switch while the app runs switches.update({ content: { splitRight: false } }) Switches
open a document as a tab tabs.open({ path, title }), tabs.navigateTo(path) Tabs
pin, keep or close a tab tabs.pin(path), tabs.keep(path), tabs.close(path) Tabs
bring a tab to the front where it already lives tabs.revealContentTab(path) Tabs
know which tab is active tabs.activeContent(), tabs.tabs() Tabs
split the content area panes.splitRight(), panes.splitDown(handle) Panes
close a pane or undo the split panes.closePane(handle), panes.unsplit() Panes
fill the area with one pane, or collapse one panes.maximize(handle), panes.minimize(handle), panes.restore() Panes
move the address to a pane, move a tab into one panes.focus(handle), panes.moveTab(path, handle) Panes
read the arrangement panes.panes(), panes.isSplit(), panes.activePane() Panes
switch to a workspace workspaces.switchTo(id) Workspaces
save the arrangement as a workspace, or as the baseline workspaces.saveCurrent(name), workspaces.saveBaseline() Workspaces
reset one workspace, or all await workspaces.reset(id?), await workspaces.resetAll() Workspaces
rename or remove a saved workspace workspaces.rename(id, name), await workspaces.remove(id) Workspaces
know which workspace is active, and which changed workspaces.activeId(), workspaces.hasChanges(), workspaces.changedIds() Workspaces
collapse or expand a sidebar sidebars.collapse(regionId), sidebars.expand(regionId), sidebars.toggle(regionId) Sidebars
set a sidebar's width sidebars.setWidth(regionId, px) Sidebars
hide a view, or show it again sidebars.hideView(viewId), sidebars.showView(viewId) Sidebars
read the sidebars sidebars.regions(), sidebars.hiddenViews() Sidebars
put the whole arrangement back await appReset.reset({ workspaces: true }) Resetting the application
ask the user something dialogs.confirm(…), dialogs.prompt(…), dialogs.open(MyDialog) Dialogs and toasts
show progress while a promise runs await dialogs.withProgress({ message }, work) Dialogs and toasts
show a toast, or take it down again toasts.show({ message, kind }), toasts.dismiss(id) Dialogs and toasts
add or open a settings section settings.register(…), settings.open(sectionId) Settings
remove a settings section again handle.dispose() on what register returned Settings
run a command from code commands.execute(id), await commands.run(command) Commands
show a shortcut the way the shell does formatChord('mod+k') Commands
know who is signed in auth.authenticated(), auth.roles(), auth.meets(access) Session
follow light and dark in my own UI theme.resolvedTheme(), theme.setMode(mode) Appearance
set the text size textSize.setScale('lg') Appearance
open the plugin store store.open() Plugins at runtime
turn a plugin off, revoke a capability, uninstall enablement.setEnabled(plugin, false), grants.setGranted(plugin, capability, false), install.uninstall(plugin) Plugins at runtime
open a surface in its own window popout.open(target) Windows, sync and updates
make my own state follow across windows sync.register(…), sync.announce(key) Windows, sync and updates
apply a change my backend pushed from another device sync.notifyRemoteChange(key) Windows, sync and updates
point the version at my own build info version.version.set(v) Windows, sync and updates
react to a new version updates.updateAvailable(), await updates.activateUpdate() Windows, sync and updates
check for a new version by hand await updates.checkForUpdate() Windows, sync and updates

The pages

The per-symbol reference is the package itself: @loomweaver/shell ships typed declarations with JSDoc on every public member, which your editor shows in place. A plugin never injects any of this; it goes through ctx, which is described in Authoring a weaver.