feat: Conversational CMS — Natural Language Admin (#11)#38
Closed
feat: Conversational CMS — Natural Language Admin (#11)#38
Conversation
added 19 commits
March 15, 2026 16:10
…, loader - PluginManifest: value object parsing numen-plugin.json with API version validation - PluginServiceProvider: abstract base with registerHooks(), lifecycle methods (install/activate/deactivate/uninstall), setting() and pluginPath() helpers - HookRegistry: singleton bus with typed registration methods: registerPipelineStage(), registerLLMProvider(), registerImageProvider(), onContentEvent(), addAdminMenuItem(), addAdminWidget(), registerVueComponent() - PluginLoader: discovers plugins from Composer installed.json (type=numen-plugin) and local plugin_paths, validates API version constraint, checks DB active status, boots providers - config/plugins.php: plugin_paths, plugin_api_version, max_plugins settings - AppServiceProvider: registers HookRegistry and PluginLoader as singletons, boots PluginLoader in boot()
- Add PipelineStageContract interface (type/label/configSchema/handle) - Add LLMProviderContract interface (name/generateText/generateChat/supportsStreaming) - Add PluginStageJob: queued job resolving handler from HookRegistry, calls handle(), advances pipeline via PipelineExecutor::advance() - Update PipelineExecutor: minimal change — check HookRegistry for plugin stage types before core match, extract core logic to dispatchCoreStage() - Update HookRegistry: add registerPipelineStageClass/getPipelineStageHandler/ hasPipelineStageHandler/registerLLMProviderInstance/getLLMProviders methods with type validation against respective contracts - Update LLMManager: add registerProvider() to wire plugin LLM providers via anonymous adapter class implementing LLMProvider contract - Update AppServiceProvider: after PluginLoader boots, iterate HookRegistry::getLLMProviders() and wire each into LLMManager
- ChatSidebar: fixed right panel (w-96, z-50), toggle button, localStorage persistence
- ChatConversationList: collapsible list, new chat button, conversation switching
- ChatMessageList: auto-scroll, loading states, empty state
- ChatMessage: user (indigo-600) / assistant (gray-800) styling, markdown via marked
- ChatInputBar: auto-resize textarea, Enter to send, streaming disabled state, cost indicator
- ConfirmActionCard: inline confirm/cancel with POST/DELETE /api/v1/chat/conversations/{id}/confirm
- ActionResultCard: completed action display with optional link
- SSE streaming via fetch + ReadableStream, handles text/confirm/action/cost chunk types
- MainLayout: ChatSidebar component integrated
- Add PluginComponentRegistry (resources/js/plugins/registry.js)
- register/resolve/getSlotComponents methods
- Singleton pluginRegistry export
- PLUGIN_SLOTS constants: admin.sidebar, admin.dashboard.widget,
pipeline.stage.config, content.edit.sidebar
- Add PluginSlot.vue generic slot renderer
- Props: slot (string), slotProps (object)
- Renders all registered components via dynamic <component :is>
- Add Admin/Plugins/Index.vue plugin management page
- Lists all plugins with name, version, status badges
- Status badges: discovered/installed/active/inactive/error
- Actions: Install, Activate, Deactivate, Uninstall, Details
- Settings modal with key/value form + secret masking
- Add Admin/Plugins/Show.vue plugin detail page
- Full manifest info panel
- Dynamic settings editor from manifest.settings schema
- Secret fields rendered as password inputs
- Hook registrations list
- Add PluginWebController (Inertia pages for Index + Show)
- Update MainLayout.vue navigation with Plugins link (puzzle emoji)
- Update HandleInertiaRequests.php to share plugins.components
(active plugin names + component manifests to frontend)
- Add web routes: GET /admin/plugins, GET /admin/plugins/{name}
npm run build: pass
- ChatApiTest: 10 feature tests covering all chat API endpoints - create/list/delete conversations - send message (LLMManager mocked, stream triggered) - message history - confirmation + cancel flow - rate limiting (429) - unauthenticated access (401) - data isolation (users see only own conversations) - IntentRouterTest: 6 unit tests for IntentRouter + IntentPermissionGuard - content.query, content.create, content.delete - pipeline.trigger (PipelineExecutor mocked) - query.generic - permission guard blocks unauthorized users - ConversationContextManagerTest: 3 unit tests - buildContext window - summarizeOlder (LLMManager mocked) - getFullContext with stored summary - ChatConversationFactory + ChatMessageFactory with state helpers
- Add numen:plugin:list — table output (name, version, status, hooks)
- Add numen:plugin:install {name} — delegates to PluginManager::install()
- Add numen:plugin:activate {name} — delegates to PluginManager::activate()
- Add numen:plugin:deactivate {name} — delegates to PluginManager::deactivate()
- Add numen:plugin:uninstall {name} — delegates to PluginManager::uninstall()
- Add numen:plugin:discover — runs PluginManager::discover()
- Add numen:make-plugin {name} — scaffolds full plugin skeleton:
plugins/{name}/numen-plugin.json
plugins/{name}/src/{Name}ServiceProvider.php
plugins/{name}/src/readme.md
plugins/{name}/database/migrations/ (empty)
plugins/{name}/resources/js/ (empty)
plugins/{name}/tests/ (empty)
- Fix PluginLoader memory: add early-exit guard when no paths configured
and expose discoverManifests() public method for CLI context
- Fix phpunit.xml: set PHP memory_limit=256M for test runs
- Fix phpstan.neon: maximumNumberOfProcesses=1 to avoid OOM in parallel workers
- Add tests/Feature/PluginAdminApiTest.php (10 tests covering all admin API endpoints) - Add tests/Unit/PluginManifestTest.php (manifest parsing, API version, required fields) - Add tests/Unit/HookRegistryTest.php (pipeline stages, LLM providers, content events, Vue components) - Add tests/Unit/PluginManagerTest.php (lifecycle transitions, guard clauses, factory smoke tests) - Add database/factories/PluginFactory.php with discovered/installed/active/inactive/errored states - Add database/factories/PluginSettingFactory.php with secret() and forSpace() states - Add HasFactory trait to Plugin and PluginSetting models - Update .env.example with NUMEN_PLUGINS_ENABLED, NUMEN_PLUGINS_PATH, NUMEN_PLUGIN_API_VERSION - Update CHANGELOG.md with v0.9.0 Plugin System entry - Update README.md with Plugin System in feature list - Add docs/plugins.md — developer guide for creating plugins All 31 plugin tests pass. pint --test: PASS. phpstan: no errors.
…nowledge graph merge)
Contributor
Author
|
🚀 Squash merged to dev with commit f58dbe2 Quality Gates Verified:
Post-merge validation completed: Feature branch has been merged to dev and is ready for next phase. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat: Conversational CMS — Natural Language Admin (#11)
Feature Summary
Conversational CMS enables natural language admin interactions through an AI-powered chat interface. Users can manage content, queries, and workflows using natural language commands processed by an intelligent intent router.
Key Components
Features
Test Results
Quality Gates Results (Latest Run - 2026-03-15 18:30 UTC)
Files Changed
Ready for Merge
This PR targets the
devbranch and is ready for integration following PR sequence (#31 ✅ → #33 → #32 → #34 → #11).