Follow Discord
Sweep 22 Sep 2026 · 17:19Z Build v2.1.280 501 read Stable v2.1.267 Latest v2.1.280 Next v2.1.280 Feeds RSS JSON llms.txt Unofficial
Claude Code v2.1.269 ·

Plugin hooks.json surface field replaced by per-module surfaceModules

Plugin hooks.json no longer has a top-level surface field; each Client element now names its own module, and multiple surfaceModules can load at once

TierYou'll noticehow much it should matter to you
Useful2my rating, 1 to 5
Signal2worth watching, 1 to 5
AreaPlugin Hookswhat it touches
KindImprovementsin v2.1.269,
Group of 2 You'll notice No documentation found

Plugin hooks.json no longer has a top-level surface field; each Client element now names its own module, and multiple surfaceModules can load at once

What

  • The hooks.json schema for plugins no longer accepts a top-level surface key. Instead, each Client element in the config must name its own module. Using the old surface field now produces a hard schema error.
  • The runtime error shown when a plugin has no drawable Client now checks surfaceModules from the hooks module's own exports, instead of looking for a surface entry in hooks.json.
  • The code that resolves a plugin's hooks module used to also resolve and validate a separate surface path (checking for path traversal and that the file exists) and store it as surfacePath; that check is now removed, and the code just sets modulePath.
  • Elsewhere, the surface-environment loader was changed from loading a single surface module to loading an array of surfaceModules, and its logging now lists all the loaded module names instead of just one.

Why

This lets a plugin provide multiple UI-drawing ('surface') modules instead of just one, with each Client referencing its own module directly rather than all of them sharing a single top-level surface path.

Read from
Names in the bundlesurfaceModules

See this entry in the whole of v2.1.269 →

Feedback