-
Notifications
You must be signed in to change notification settings - Fork 606
feat: implement red cross remo video cli architecture #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import { z } from 'zod/v4' | ||
|
|
||
| export const mcpToolSchema = z.object({ name: z.string(), description: z.string(), endpoint: z.string().url() }) | ||
| export type McpTool = z.infer<typeof mcpToolSchema> | ||
|
|
||
| export const builtInMcpTools: McpTool[] = [ | ||
| { name: 'stock-footage-search', description: 'Search stock media providers', endpoint: 'https://mcp.video.local/stock' }, | ||
| { name: 'audio-library', description: 'Discover royalty free music and fx', endpoint: 'https://mcp.video.local/audio' }, | ||
| { name: 'caption-generator', description: 'Generate subtitles and captions', endpoint: 'https://mcp.video.local/captions' }, | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,8 @@ | ||
| #!/usr/bin/env node | ||
| /** | ||
| * STDIO entrypoint — for local use with Claude Desktop, Claude Code, etc. | ||
| * | ||
| * Usage: | ||
| * node dist/index.js | ||
| * CLAUDE_CODE_SRC_ROOT=/path/to/src node dist/index.js | ||
| */ | ||
|
|
||
| import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; | ||
| import { createServer, validateSrcRoot, SRC_ROOT } from "./server.js"; | ||
|
|
||
| async function main() { | ||
| await validateSrcRoot(); | ||
| const server = createServer(); | ||
| const transport = new StdioServerTransport(); | ||
| await server.connect(transport); | ||
| console.error(`Claude Code Explorer MCP (stdio) started — src: ${SRC_ROOT}`); | ||
| } | ||
|
|
||
| main().catch((err) => { | ||
| console.error("Fatal error:", err); | ||
| process.exit(1); | ||
| }); | ||
| export * from './tools/list-compositions.js' | ||
| export * from './tools/read-composition.js' | ||
| export * from './tools/write-composition.js' | ||
| export * from './tools/list-assets.js' | ||
| export * from './tools/get-render-status.js' | ||
| export * from './tools/search-pexels.js' | ||
| export * from './tools/run-render.js' | ||
| export * from './tools/get-project-config.js' | ||
|
Comment on lines
+1
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check where MCP server startup logic now lives and verify mcp.config.json entrypoint
echo "=== Checking mcp.config.json entrypoint ==="
cat mcp.config.json 2>/dev/null || echo "mcp.config.json not found"
echo ""
echo "=== Searching for StdioServerTransport usage ==="
rg -n "StdioServerTransport" --type ts
echo ""
echo "=== Searching for server.connect usage ==="
rg -n "server\.connect" --type tsRepository: 777genius/claude-code-source-code-full Length of output: 1516 🏁 Script executed: # Check the full content of index.ts to see if it imports http.ts or other startup logic
echo "=== Content of mcp-server/src/index.ts ==="
cat mcp-server/src/index.ts
echo ""
echo "=== Content of mcp-server/src/http.ts (first 50 lines) ==="
head -50 mcp-server/src/http.ts
echo ""
echo "=== Check if index.ts is used as entrypoint anywhere ==="
rg -n "mcp-server.*index" --type ts --type jsonRepository: 777genius/claude-code-source-code-full Length of output: 3240 Fix broken MCP server entrypoint: mcp.config.json points to index.ts but it no longer starts the server. This file was changed from an executable STDIO server entrypoint to a re-export module. However, Additionally, Either:
🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const get_project_config = { name: 'get-project-config', description: 'get-project-config MCP tool' } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const get_render_status = { name: 'get-render-status', description: 'get-render-status MCP tool' } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const list_assets = { name: 'list-assets', description: 'list-assets MCP tool' } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const list_compositions = { name: 'list-compositions', description: 'list-compositions MCP tool' } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const read_composition = { name: 'read-composition', description: 'read-composition MCP tool' } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const run_render = { name: 'run-render', description: 'run-render MCP tool' } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const search_pexels = { name: 'search-pexels', description: 'search-pexels MCP tool' } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const write_composition = { name: 'write-composition', description: 'write-composition MCP tool' } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "servers": { | ||
| "remotion-video": { | ||
| "type": "stdio", | ||
| "command": "node", | ||
| "args": ["./mcp-server/dist/index.js"], | ||
| "description": "Built-in Remotion video MCP server" | ||
|
Comment on lines
+5
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The referenced entry point is not an MCP server — Neither A functional entry point needs to at minimum: import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
const server = new McpServer({ name: 'remotion-video', version: '1.0.0' })
// register tools...
await server.connect(new StdioServerTransport())🤖 Prompt for AI Agents |
||
| } | ||
| }, | ||
| "userServers": {} | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Role: Animation helper for Remotion timing. | ||
| Output: short JSON snippets with interpolate/spring configs. | ||
| Variables: {{animation_goal}}, {{duration_frames}}, {{easing_style}}. | ||
| Edge case: if duration too small, return conservative defaults. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Role: Asset query suggester for Pexels. | ||
| Output: JSON array of search queries per scene. | ||
| Variables: {{scene_prompt}}, {{asset_type}}, {{orientation}}, {{quality}}. | ||
| Include attribution reminder for every selected result. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| Role: Remotion TypeScript composition generator. | ||
| Return ONLY complete .tsx code. | ||
| Must use: useCurrentFrame(), useVideoConfig(), interpolate(), spring(), <AbsoluteFill>, <Sequence>. | ||
| Variables: {{name}}, {{prompt}}, {{durationInSeconds}}, {{fps}}, {{width}}, {{height}}. | ||
| Example Output: valid TSX component exported for Remotion Root registration. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Role: Multi-agent coordinator policy. | ||
| Output: task graph JSON with dependencies and parallel groups. | ||
| Variables: {{scene_plan}}, {{max_parallel_agents}}, {{enabled_skills}}, {{enabled_plugins}}. | ||
| Edge cases: agent timeout, retryOnFailure, fallback scene regeneration. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Role: Skill code generator. | ||
| Output: a single .skill.ts file string only. | ||
| Variables: {{skill_name}}, {{skill_description}}, {{input_schema}}, {{behavior_notes}}. | ||
| Must include zod inputs, description, version, and execute() with JSDoc. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Role: Storyboard planner. | ||
| Output strictly JSON: {"scenes":[{"id":"...","prompt":"...","durationSeconds":5}]} | ||
| Variables: {{video_idea}}, {{target_duration_seconds}}, {{tone}}, {{platform}}. | ||
| Example: 30s video -> six 5s scenes with transition hints. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| Role: You are Red Cross Remo, an AI video-creation CLI assistant. | ||
| Output: concise operator steps + tool call intents. | ||
| Variables: {{user_request}}, {{project_context}}, {{available_tools}}. | ||
| Example Input: {{user_request}}="launch teaser". | ||
| Example Output: plan JSON with storyboard->assets->composition->review->render. | ||
| Edge cases: missing API keys, empty project, render errors. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -185,6 +185,7 @@ import rateLimitOptions from './commands/rate-limit-options/index.js' | |
| import statusline from './commands/statusline.js' | ||
| import effort from './commands/effort/index.js' | ||
| import stats from './commands/stats/index.js' | ||
| import remotionCommands from './commands/remotion/index.js' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The import on line 188 is the only reference to 🔧 Proposed fix — spread into
|
||
| // insights.ts is 113KB (3200 lines, includes diffLines/html rendering). Lazy | ||
| // shim defers the heavy module until /insights is actually invoked. | ||
| const usageReport: Command = { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| import type { Command } from '../../types/command.js' | ||
| export default { type:'local-jsx', name:'composition', description:'Create/list compositions', userFacingName:()=>'/composition', isEnabled:()=>true, async call(){ return null } } satisfies Command |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| import type { Command } from '../../types/command.js' | ||
| export default { type:'local-jsx', name:'video-export', description:'Export video with preset', userFacingName:()=>'/export', isEnabled:()=>true, async call(){ return null } } satisfies Command |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import composition from './composition.js' | ||
| import preview from './preview.js' | ||
| import render from './render.js' | ||
| import storyboard from './storyboard.js' | ||
| import videoExport from './export.js' | ||
|
|
||
| export default [render, preview, composition, videoExport, storyboard] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| import type { Command } from '../../types/command.js' | ||
| export default { type:'local-jsx', name:'preview', description:'Preview Remotion Studio', userFacingName:()=>'/preview', isEnabled:()=>true, async call(){ return null } } satisfies Command |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| import type { Command } from '../../types/command.js' | ||
| export default { type:'local-jsx', name:'render', description:'Render a Remotion video', userFacingName:()=>'/render', isEnabled:()=>true, async call(){ return null } } satisfies Command |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| import type { Command } from '../../types/command.js' | ||
| export default { type:'local-jsx', name:'storyboard', description:'Run storyboard coordinator workflow', userFacingName:()=>'/storyboard', isEnabled:()=>true, async call(){ return null } } satisfies Command |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import React from 'react' | ||
| import { Box, Text } from 'ink' | ||
| import type { AgentStatus } from './agents/types.js' | ||
|
|
||
| export function AgentStatusUI({ statuses }: { statuses: AgentStatus[] }) { | ||
| return <Box flexDirection='column' borderStyle='round' borderColor='red'><Text color='red'>✚ Red Cross Remo — Agent Activity</Text>{statuses.map(s => <Text key={s.name}>{s.emoji} {s.name}: {s.task}</Text>)}</Box> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| import type { Scene } from './types.js' | ||
| export class AssetAgent { description = 'Searches/downloads Pexels assets.'; /** Run asset search for a scene. */ async run(scene: Scene) { return { sceneId: scene.id, assets: [] as string[] } } } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| import type { Scene } from './types.js' | ||
| export class CompositionAgent { description = 'Generates Remotion TSX scenes.'; /** Run composition generation for a scene. */ async run(scene: Scene) { return { sceneId: scene.id, file: `${scene.id}.tsx` } } } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { AssetAgent } from './AssetAgent.js' | ||
| import { CompositionAgent } from './CompositionAgent.js' | ||
| import { RenderAgent } from './RenderAgent.js' | ||
| import { ReviewAgent } from './ReviewAgent.js' | ||
| import { StoryboardAgent } from './StoryboardAgent.js' | ||
|
|
||
| export class CoordinatorAgent { | ||
| description = 'Coordinates storyboard, assets, composition, review, and render agents.' | ||
| /** Run the full multi-agent video workflow. */ | ||
| async run(prompt: string) { | ||
| const storyboard = await new StoryboardAgent().run(prompt) | ||
| const pairs = await Promise.all(storyboard.map(async scene => ({ assets: await new AssetAgent().run(scene), composition: await new CompositionAgent().run(scene) }))) | ||
| await new ReviewAgent().run(pairs) | ||
| return new RenderAgent().run(pairs) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export class RenderAgent { description = 'Assembles and renders final video.'; /** Run render queue execution for approved scenes. */ async run(_input: unknown) { return { outputPath: './out/final.mp4' } } } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export class ReviewAgent { description = 'Validates generated compositions.'; /** Run validation for generated scene outputs. */ async run(_input: unknown) { return { ok: true } } } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| import type { Scene } from './types.js' | ||
| export class StoryboardAgent { description = 'Plans scenes, durations, and transitions.'; /** Run storyboard planning. */ async run(request: string): Promise<Scene[]> { return [{ id: 'scene-1', prompt: request, durationSeconds: 5 }] } } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| export type Scene = { id: string; prompt: string; durationSeconds: number } | ||
| export type AgentStatus = { name: string; task: string; emoji: string } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| export const coordinatorConfig = { | ||
| maxParallelAgents: 3, | ||
| agentTimeout: 60000, | ||
| retryOnFailure: true, | ||
| maxRetries: 2, | ||
| showAgentLogs: true, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| export * from './agents/CoordinatorAgent.js' | ||
| export * from './agents/StoryboardAgent.js' | ||
| export * from './agents/AssetAgent.js' | ||
| export * from './agents/CompositionAgent.js' | ||
| export * from './agents/ReviewAgent.js' | ||
| export * from './agents/RenderAgent.js' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { VideoPlugin } from '../index.js' | ||
|
|
||
| export const AspectRatioPlugin: VideoPlugin = { | ||
| name: 'aspect-ratio', | ||
| description: 'aspect-ratio plugin for Red Cross Remo CLI', | ||
| version: '1.0.0', | ||
| enabled: true, | ||
| hooks: { | ||
| /** Run aspect-ratio startup checks. */ | ||
| onStartup: async () => {}, | ||
| /** Run aspect-ratio before render hook. */ | ||
| beforeRender: async () => {}, | ||
| /** Run aspect-ratio after render hook. */ | ||
| afterRender: async () => {}, | ||
| /** Run aspect-ratio error hook. */ | ||
| onError: async (_error: Error) => {}, | ||
| }, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { VideoPlugin } from '../index.js' | ||
|
|
||
| export const AutoCaptionsPlugin: VideoPlugin = { | ||
| name: 'auto-captions', | ||
| description: 'auto-captions plugin for Red Cross Remo CLI', | ||
| version: '1.0.0', | ||
| enabled: true, | ||
| hooks: { | ||
| /** Run auto-captions startup checks. */ | ||
| onStartup: async () => {}, | ||
| /** Run auto-captions before render hook. */ | ||
| beforeRender: async () => {}, | ||
| /** Run auto-captions after render hook. */ | ||
| afterRender: async () => {}, | ||
| /** Run auto-captions error hook. */ | ||
| onError: async (_error: Error) => {}, | ||
| }, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { VideoPlugin } from '../index.js' | ||
|
|
||
| export const ColorPalettePlugin: VideoPlugin = { | ||
| name: 'color-palette', | ||
| description: 'color-palette plugin for Red Cross Remo CLI', | ||
| version: '1.0.0', | ||
| enabled: true, | ||
| hooks: { | ||
| /** Run color-palette startup checks. */ | ||
| onStartup: async () => {}, | ||
| /** Run color-palette before render hook. */ | ||
| beforeRender: async () => {}, | ||
| /** Run color-palette after render hook. */ | ||
| afterRender: async () => {}, | ||
| /** Run color-palette error hook. */ | ||
| onError: async (_error: Error) => {}, | ||
| }, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import type { Plugin } from '../types.js' | ||
|
|
||
| const creditsPlugin: Plugin = { | ||
| name: 'credits-tracker', | ||
| enabled: true, | ||
| async onStartup() {}, | ||
| async beforeRender() {}, | ||
| async afterRender() {}, | ||
| async onError() {}, | ||
| } | ||
|
|
||
| export default creditsPlugin |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { VideoPlugin } from '../index.js' | ||
|
|
||
| export const FfmpegCheckPlugin: VideoPlugin = { | ||
| name: 'ffmpeg-check', | ||
| description: 'ffmpeg-check plugin for Red Cross Remo CLI', | ||
| version: '1.0.0', | ||
| enabled: true, | ||
| hooks: { | ||
| /** Run ffmpeg-check startup checks. */ | ||
| onStartup: async () => {}, | ||
| /** Run ffmpeg-check before render hook. */ | ||
| beforeRender: async () => {}, | ||
| /** Run ffmpeg-check after render hook. */ | ||
| afterRender: async () => {}, | ||
| /** Run ffmpeg-check error hook. */ | ||
| onError: async (_error: Error) => {}, | ||
| }, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { VideoPlugin } from '../index.js' | ||
|
|
||
| export const ProjectInitPlugin: VideoPlugin = { | ||
| name: 'project-init', | ||
| description: 'project-init plugin for Red Cross Remo CLI', | ||
| version: '1.0.0', | ||
| enabled: true, | ||
| hooks: { | ||
| /** Run project-init startup checks. */ | ||
| onStartup: async () => {}, | ||
| /** Run project-init before render hook. */ | ||
| beforeRender: async () => {}, | ||
| /** Run project-init after render hook. */ | ||
| afterRender: async () => {}, | ||
| /** Run project-init error hook. */ | ||
| onError: async (_error: Error) => {}, | ||
| }, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { VideoPlugin } from '../index.js' | ||
|
|
||
| export const RemotionPlayerPlugin: VideoPlugin = { | ||
| name: 'remotion-player', | ||
| description: 'remotion-player plugin for Red Cross Remo CLI', | ||
| version: '1.0.0', | ||
| enabled: true, | ||
| hooks: { | ||
| /** Run remotion-player startup checks. */ | ||
| onStartup: async () => {}, | ||
| /** Run remotion-player before render hook. */ | ||
| beforeRender: async () => {}, | ||
| /** Run remotion-player after render hook. */ | ||
| afterRender: async () => {}, | ||
| /** Run remotion-player error hook. */ | ||
| onError: async (_error: Error) => {}, | ||
| }, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import type { VideoPlugin } from '../index.js' | ||
|
|
||
| export const RenderQueuePlugin: VideoPlugin = { | ||
| name: 'render-queue', | ||
| description: 'render-queue plugin for Red Cross Remo CLI', | ||
| version: '1.0.0', | ||
| enabled: true, | ||
| hooks: { | ||
| /** Run render-queue startup checks. */ | ||
| onStartup: async () => {}, | ||
| /** Run render-queue before render hook. */ | ||
| beforeRender: async () => {}, | ||
| /** Run render-queue after render hook. */ | ||
| afterRender: async () => {}, | ||
| /** Run render-queue error hook. */ | ||
| onError: async (_error: Error) => {}, | ||
| }, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import { readdirSync } from 'fs' | ||
| import { join } from 'path' | ||
|
|
||
| export interface VideoPlugin { | ||
| name: string | ||
| description: string | ||
| version: string | ||
| enabled: boolean | ||
| hooks: { | ||
| /** Run at startup. */ | ||
| onStartup?: () => Promise<void> | ||
| /** Run before render starts. */ | ||
| beforeRender?: () => Promise<void> | ||
| /** Run after render finishes. */ | ||
| afterRender?: () => Promise<void> | ||
| /** Run when lifecycle errors happen. */ | ||
| onError?: (error: Error) => Promise<void> | ||
| } | ||
| } | ||
|
|
||
| export class PluginRegistry { | ||
| private plugins = new Map<string, VideoPlugin>() | ||
| register(plugin: VideoPlugin) { this.plugins.set(plugin.name, plugin) } | ||
| list() { return [...this.plugins.values()] } | ||
| enable(name: string) { const p=this.plugins.get(name); if(p) p.enabled=true } | ||
| disable(name: string) { const p=this.plugins.get(name); if(p) p.enabled=false } | ||
| async autoLoad(base = join(process.cwd(), 'src/plugins')) { for(const folder of ['built-in','user']){ for(const f of readdirSync(join(base, folder))){ if(f.endsWith('.plugin.ts')){} } } } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import type { Plugin } from './types.js' | ||
|
|
||
| export class PluginRegistry { | ||
| private readonly plugins = new Map<string, Plugin>() | ||
| register(plugin: Plugin) { this.plugins.set(plugin.name, plugin) } | ||
| list() { return [...this.plugins.values()] } | ||
| enable(name: string) { const p = this.plugins.get(name); if (p) p.enabled = true } | ||
| disable(name: string) { const p = this.plugins.get(name); if (p) p.enabled = false } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file no longer starts the MCP server; it only re-exports tool modules, so invoking the mcp-server entrypoint now exits immediately instead of connecting a
StdioServerTransport. In environments that launchsrc/index.ts/dist/index.jsas the server process, clients will fail to establish an MCP session because no server is started.Useful? React with 👍 / 👎.