Skip to content

feat: hooks-plugin migration — replace HookRegistry with typed plugin system#6

Merged
haliphax merged 15 commits intomainfrom
plugin-system
Apr 22, 2026
Merged

feat: hooks-plugin migration — replace HookRegistry with typed plugin system#6
haliphax merged 15 commits intomainfrom
plugin-system

Conversation

@haliphax
Copy link
Copy Markdown
Contributor

@haliphax haliphax commented Apr 21, 2026

Replace the hand-rolled HookRegistry (2 untyped hooks) with a typed ShoggothPluginSystem built on hooks-plugin. Extract Discord platform wiring from daemon/src/index.ts into a fully self-contained plugin loaded via standard plugin discovery.

What changed

Plugin system (@shoggoth/plugins)

  • 14 typed lifecycle hooks across daemon, platform, messaging, session, and health categories
  • ShoggothPluginSystem class wrapping hooks-plugin primitives (sync, async, waterfall)
  • MessagingPlatformPlugin interface + defineMessagingPlatformPlugin validator
  • PlatformDeliveryRegistry — platform-agnostic operator delivery resolution; plugins register resolvers for their URN segment
  • Plugin discovery via package.json shoggothPlugin property bag
  • freezeConfig utility for post-waterfall config immutability
  • Deleted HookRegistry
  • All hook context types use real imports from @shoggoth/shared and @shoggoth/messaging (no placeholder any types)

Shared plugin interfaces (@shoggoth/shared)

  • plugin-interfaces.ts defines HitlPendingStack, HitlAutoApproveGate, PolicyEngine, SubagentRuntimeExtension, MessageToolContext, PlatformAdapter, etc.
  • Proper type contracts for cross-package plugin boundaries

Daemon hook orchestration

  • fireDaemonHooks helper fires hooks in boot sequence order: configure → register → health → start → startup → lock → ready
  • Returns drain functions for platform.stop and daemon.shutdown
  • Singleton init ordering: procman, TurnQueue, ModelResilienceGate all init before fireDaemonHooks()
  • Zero imports from @shoggoth/platform-discord in daemon — no platform-specific code leaks
  • Daemon uses deliveryRegistry.resolveOperatorDelivery() for workflow notifications

Discord plugin (@shoggoth/platform-discord)

  • Loaded via standard loadAllPluginsFromConfig (same path as 3rd-party plugins)
  • Default config.plugins includes { package: "@shoggoth/platform-discord" }
  • Plugin owns: bot token resolution, session-for-channel resolution, operator delivery, HITL notice registry
  • Registers PlatformDeliveryResolver for the "discord" URN segment
  • platform.start handles gateway connection, interaction handler, HITL reactions, reaction passthrough, subagent extension, message tool context, platform adapter

MCP transport hardening

  • mcp-jsonrpc-transport.ts direct spawn fallback now merges process.env with config env (prevents PATH loss)

Tests: 2169 passing, 220 test files, no regressions

haliphax and others added 3 commits April 21, 2026 05:03
- Add hooks-plugin dependency, define 14 typed hook contexts
- Implement ShoggothPluginSystem wrapping PluginSystem, freezeConfig utility
- Add MessagingPlatformPlugin interface + defineMessagingPlatformPlugin validator
- Replace HookRegistry with ShoggothPluginSystem throughout
- Rewrite plugin loader to read package.json shoggothPlugin bag (not shoggoth.json)
- Add fireDaemonHooks helper for boot sequence hook orchestration
- Create Discord plugin (createDiscordPlugin factory) with 4 required hooks
- Update daemon bootstrap to use new plugin system
- Add plugin system documentation
- Delete hook-registry.ts, add 27 new tests (2169 total, all passing)
Extract Discord-specific wiring from daemon/index.ts into the
platform-discord plugin. The plugin implements MessagingPlatformPlugin
and receives all dependencies through PlatformStartCtx.

- plugin.ts: Fill in platform.start with Discord gateway startup,
  interaction handler, HITL reaction wiring, reaction passthrough,
  subagent extension, message tool context, and platform adapter
- hook-types.ts: Expand PlatformDeps with daemon-provided callbacks
- daemon-hooks.ts: Pass expanded context when firing platform.start
- daemon/index.ts: Refactor to use ShoggothPluginSystem + fireDaemonHooks
…d plugin self-containment

- Remove plan references and rename internal functions
- Init procman before fireDaemonHooks so MCP stdio uses procman env merge
- Harden direct spawn fallback to merge process.env
- Move TurnQueue and ModelResilienceGate init before fireDaemonHooks
- Remove placeholder messageToolContext so Discord plugin builds real context
- Plugin owns its own HitlDiscordNoticeRegistry, remove from daemon/PlatformDeps
…iveryRegistry

- Remove all @shoggoth/platform-discord imports from daemon/src/index.ts
- Discord plugin loaded via config.plugins + loadAllPluginsFromConfig (same as 3rd party)
- Add PlatformDeliveryRegistry: plugins register resolvers for their platform segment
- Daemon uses deliveryRegistry.resolveOperatorDelivery() instead of Discord-specific config reads
- Plugin owns bot token resolution, session-for-channel resolution, owner user ID
- Remove resolveSessionForChannel/getBotToken from PlatformDeps
- Add deliveryRegistry to PlatformStartCtx
- Default config.plugins includes @shoggoth/platform-discord
…shared and @shoggoth/messaging

- Add plugin-interfaces.ts to @shoggoth/shared with proper interfaces
- hook-types.ts imports ShoggothConfig, Logger from @shoggoth/shared
- hook-types.ts imports PlatformRegistration, PlatformRuntime, InternalMessage from @shoggoth/messaging
- HitlPendingStack, HitlAutoApproveGate, PolicyEngine, etc. defined in @shoggoth/shared
- Add @shoggoth/messaging as dependency of @shoggoth/plugins
- Zero placeholder `type X = any` remaining
@haliphax haliphax merged commit fb473e6 into main Apr 22, 2026
2 checks passed
@haliphax haliphax deleted the plugin-system branch April 22, 2026 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant