Skip to content

Conversation

@davewaring
Copy link
Contributor

@davewaring davewaring commented Jan 19, 2026

Summary

  • Implements core infrastructure for backend plugins that can register REST API endpoints dynamically without modifying core code
  • Adds @plugin_endpoint decorator and PluginRouteLoader for dynamic route management
  • Extends Plugin database model with plugin_type, endpoints_file, route_prefix, and backend_dependencies fields
  • Adds Library API endpoints for plugin file access

Changes

Phase 1 - Core Infrastructure (Backend Plugin System)

  • decorators.py: @plugin_endpoint() decorator with path validation, methods, and admin_only flag
  • route_loader.py: PluginRouteLoader class with async lock, atomic swap pattern, and module cleanup
  • admin.py: Admin router with /plugins/reload-routes and /plugins/routes endpoints
  • main.py: Initialize route loader on startup, load enabled backend plugins

Phase 2.1 - Plugin Database Model

  • plugin.py: Add PluginType enum and 4 new fields for backend plugin metadata
  • migration: Alembic migration to add columns with safe existence checks

Library API Endpoints

  • GET /api/v1/library/projects - List projects from active/archived/ideas folders
  • POST /api/v1/library/read-file - Read a specific file from Library
  • GET /api/v1/library/project/{slug}/context - Get aggregated project context
  • POST /api/v1/library/append-file - Append content to project documentation files

Security

  • All endpoints require authentication
  • Path validation prevents directory traversal attacks
  • Admin endpoints require admin authentication
  • Library write operations restricted to specific files (research-findings.md, ideas.md)

Test plan

  • Verify migration runs without errors on fresh database
  • Verify existing plugins still work (no regression)
  • Test admin reload endpoint with admin user (should succeed)
  • Test admin reload endpoint with non-admin user (should 403)
  • Verify route loader initializes on startup without errors
  • Test Library list projects endpoint returns expected projects
  • Test Library read-file endpoint with valid and invalid paths
  • Test path traversal prevention (e.g., ../ in paths)
  • Test unauthenticated requests are rejected

🤖 Generated with Claude Code

Adds new API endpoints for plugins to access BrainDrive-Library content:

- GET /api/v1/library/projects - List projects in Library
- POST /api/v1/library/read-file - Read a specific file from a project
- GET /api/v1/library/project/{slug}/context - Get all context files at once

Security:
- Path validation prevents directory traversal attacks
- Restricted to ~/BrainDrive-Library/ only
- Requires authenticated user
- Allowed file types: .md, .txt, .json, .yaml, .yml

This enables plugins like Research Assistant to load project context
for AI-powered analysis without needing direct filesystem access.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@davewaring
Copy link
Contributor Author

@DJJones66 my goal here is to give BrainDrive-Owners the ability to have a BrainDrive-Library file on their computer that their braindrive can access but without accessign any other files on the system. I want this for the plugin we talked about building so when I put an article in the AI can review our projects for relevant context from the article. But I think this functionality could be very useful beyond just this. It's basically another way to get at chat with documents when you have a structured file system like we are building.

Implements core infrastructure for backend plugins that can register
REST API endpoints dynamically without modifying core code.

Phase 1 - Core Infrastructure:
- Add @plugin_endpoint decorator for marking endpoint functions
- Add PluginRouteLoader for dynamic route loading/unloading
- Add admin endpoint POST /admin/plugins/reload-routes
- Integrate route loader with app startup

Phase 2.1 - Plugin Database Model:
- Add plugin_type field (frontend/backend/fullstack)
- Add endpoints_file field for Python endpoint file
- Add route_prefix field for URL prefix
- Add backend_dependencies field (JSON list of slugs)
- Add Alembic migration for new fields

Also includes:
- Library API append-file endpoint for writing to project docs
- CORS config property helpers

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@davewaring davewaring changed the title Add Library API endpoint for plugin file access Add backend plugin architecture (Phase 1 + 2.1) and Library API Jan 21, 2026
davewaring and others added 4 commits January 21, 2026 15:37
… 2.2-2.3)

Phase 2.2 - Extend BaseLifecycleManager:
- Add module documentation for backend plugin support
- Add VALID_PLUGIN_TYPES constant (frontend, backend, fullstack)
- Update validate_plugin_metadata() with backend field validation
- Require endpoints_file for backend/fullstack plugins
- Validate backend_dependencies is a list, route_prefix starts with /
- Add is_backend_plugin() and get_backend_metadata() helper methods

Phase 2.3 - Update Plugin Repository:
- Add get_backend_plugins(user_id) - returns backend/fullstack plugins
- Add get_enabled_backend_plugins(user_id) - enabled backend plugins only
- Add get_plugins_depending_on(backend_slug, user_id) - for cascade disable
- Add get_all_enabled_backend_plugins() - for route loader startup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 3.1 - Route Reload Triggers:
- Add _trigger_route_reload_if_backend() helper for route reloads
- Trigger reload after install/uninstall/update of backend plugins
- Support all install methods: local, GitHub, file upload, remote URL

Phase 3.2 - Cascade Disable:
- Update PATCH /plugins/{plugin_id} to cascade-disable dependent plugins
- When disabling backend plugin, find and disable dependents first
- Return cascade_disabled list in response for transparency
- Trigger route reload after enable/disable of backend plugins

Phase 3.3 - Auto-Install Backend Dependencies:
- Add _auto_install_backend_dependencies() to check plugin metadata
- Auto-install missing backend dependencies before main plugin
- Return auto_installed_dependencies in response
- Fail with clear error if required dependency cannot be installed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Frontend:
- Add PluginTypeTabs component (All/Frontend/Backend/Fullstack)
- Add BackendPluginWarningDialog for security warnings
- Add backend/fullstack badges to ModuleCard
- Add dependency relationships display in ModuleDetailHeader
- Add cascade disable confirmation dialog
- Add pluginType filter support to useModules hook and moduleService
- Add plugin_type to installer types and InstallationResult

Backend:
- Fix route_loader.py: Change prefix from /api/v1/plugins to /api/v1/plugin-api
  to avoid removing core plugin management routes
- Add plugin_type filter parameter to /plugins/manager endpoint
- Add pluginType field to module response from parent plugin

Co-Authored-By: Claude <noreply@anthropic.com>
Previously the Library path was hardcoded to ~/BrainDrive-Library.
Now users can set LIBRARY_PATH in their .env file to configure
a custom location for their BrainDrive-Library folder.

- Add LIBRARY_PATH setting to config.py (default: ~/BrainDrive-Library)
- Update library.py to use settings.LIBRARY_PATH instead of hardcoded path
- Support ~ expansion for home directory paths
- Update docstring to document the new configuration option

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@davewaring davewaring marked this pull request as ready for review January 27, 2026 00:34
@davewaring
Copy link
Contributor Author

Closing this PR as part of the planned split (see library-integration decisions.md from 2026-01-25).

What happened:
This PR bundled two separate concerns:

  1. Backend plugin infrastructure (modularizing-backend project)
  2. Library API endpoints (library-integration project)

The split:

Why:

  • Clean separation of concerns
  • Each PR maps to exactly one project
  • Hybrid architecture decision: core provides primitives, Library plugin provides conventions

The useful code from this PR (path validation, auth patterns) has been incorporated into PR #217.

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.

2 participants