What
Plugins can ship hook modules, small pieces of code Claude Code runs at set moments, including to draw plugin UI. These modules now have a shared key/value store.
$.state.getand$.state.settake a reference{ plugin, key, id? }. A write can passifVersionso it only succeeds if the value has not changed since it was read.- Values must be JSON and stay under the same size limit as
store.set. - Only the plugin that owns a key may write it, and writes are refused while
ui.renderis running. - Readers set up during rendering are refreshed when a value changes, and each write marks "steady" and "live" timestamps.
- A handler cannot change the reference,
ifVersionor the previous value. state.getandstate.setjoin the host's list of allowed calls, next tostore.*andclock.*.- A static check (one that reads the code without running it) requires
pluginandkeyto be string literals or file-level constants, reports an object literal there, and lists each module's state reads and writes. - At run time the host refuses a call whose plugin and key pair was not found by that scan.
- Plugin validation reads
interface PluginStatefrom the plugin's types contract, reports modules that write another plugin's state and keys missing from the contract, and lists state owned by plugins that are not enabled as not checked.
Why
Plugin UI modules can share state that updates across render hooks. Plugin authors who build state keys at run time will get a refusal and need to write them as fixed strings.