12 KiB
Extending the Stream Workflow Manager
Purpose: Guide for Claude Code agents who need to add features to this MCP server.
When to use this: You encounter a limitation or need custom behavior.
Core Principles (Never Forget These)
1. ALL Changes Happen in Worktrees
NEVER modify files in main directory. EVER.
This applies to:
- ✅ Source code
- ✅ Configuration
- ✅ Documentation
- ✅ Scripts
- ✅ This MCP server itself
To update this MCP server:
# Use start_stream MCP tool (recommended), or manually:
git worktree add <WORKTREE_ROOT>/mcp-enhancement -b mcp-enhancement
cd <WORKTREE_ROOT>/mcp-enhancement/.claude/mcp-servers/stream-workflow-manager
# Make changes here
Note: <WORKTREE_ROOT> is determined by config.WORKTREE_ROOT (XDG-compliant by default)
2. Conflict Resolution Happens in Worktrees
NEVER resolve merge conflicts in main directory.
Correct workflow:
1. In WORKTREE: git merge main # Bring main's changes in
2. In WORKTREE: AI resolves conflicts # Safe, isolated
3. In WORKTREE: Commit merge # All resolution done
4. In MAIN: git merge --ff-only # Clean merge, no conflicts
Why: Main should never enter a conflicted state. Multiple agents can prepare merges in parallel.
3. Main Receives Only Clean Merges
Main should only receive fast-forward merges.
If git merge --ff-only fails, the worktree wasn't properly prepared. Go back to the worktree and fix it there.
Extension Points
| What You Need | Extension Point | Template Location |
|---|---|---|
| Handle new file type | Add ConflictStrategy | templates/conflict-strategy.template.ts |
| Custom validation | Add Validator | templates/validator.template.ts |
| New workflow step | Add MCP Tool | templates/mcp-tool.template.ts |
| Change AI behavior | Edit Prompt | prompts/conflict-resolution.txt |
| Adjust limits | Edit Config | src/config.ts |
Extension Point 1: Conflict Strategies
When to Use
You encounter a file type that isn't resolved well:
- Binary files (images, PDFs, etc.)
- Specialized formats (XML, Protobuf, etc.)
- Domain-specific files (database migrations, etc.)
How to Add
1. Copy template:
cp templates/conflict-strategy.template.ts src/strategies/my-strategy.ts
2. Fill in TODOs:
- Implement
canHandle()- When should this strategy run? - Implement
resolve()- How to resolve conflicts? - CRITICAL: Resolution happens IN WORKTREE (you already have the conflicted file)
3. Register in src/conflict-resolver.ts:
import { MyStrategy } from './strategies/my-strategy';
this.strategies = [
new CodeMergeStrategy(),
new MyStrategy(), // Add here
];
4. Test thoroughly before merging.
Interface: See src/types.ts → ConflictStrategy
Extension Point 2: Validators
When to Use
You need custom validation after conflict resolution:
- Database schema checks
- API contract validation
- Custom linting rules
How to Add
1. Copy template:
cp templates/validator.template.ts src/validators/my-validator.ts
2. Fill in TODOs:
- Implement
validate()- Run your checks - Return
ValidationResult- Pass/fail with errors
3. Register in src/conflict-resolver.ts:
import { MyValidator } from './validators/my-validator';
const validators = [
new TypeScriptValidator(),
new MyValidator(), // Add here
];
4. Add config in src/config.ts:
VALIDATORS: {
typescript: true,
myValidator: true, // Enable by default
}
Interface: See src/types.ts → Validator
Extension Point 3: MCP Tools
When to Use
You need a new workflow capability:
- Rollback merge
- Export stream history
- Analyze conflicts
How to Add
1. Copy template:
cp templates/mcp-tool.template.ts src/tools/my-tool.ts
2. Fill in TODOs:
- Implement tool handler
- CRITICAL: Enforce worktree-only (verify location first)
- Include self-documenting errors
- Add
_metaresponse metadata
3. Register in src/server.ts:
// Add to ListToolsRequestSchema handler
{
name: 'my_tool',
description: 'What this tool does',
inputSchema: { /* ... */ }
}
// Add to CallToolRequestSchema handler
case 'my_tool':
return await myTool(args);
Interface: See src/types.ts → MCPToolHandler
Extension Point 4: AI Prompts
When to Use
Claude's conflict resolution isn't making good decisions for:
- Specific file types
- Project patterns
- Domain logic
How to Customize
Edit prompts/conflict-resolution.txt:
Add project-specific patterns:
## PROJECT-SPECIFIC PATTERNS:
### For Database Migrations
- NEVER merge migration timestamps
- NEVER merge schema changes
- Both migrations must run separately
### For [Your Domain]
- [Your rules here]
Or create file-type specific prompts:
prompts/
conflict-resolution.txt # Default
migrations-conflict.txt # For database migrations
routes-conflict.txt # For API routes
Then use in strategy:
// In src/strategies/code-merge.ts
const promptFile = context.file.includes('migrations/')
? 'migrations-conflict.txt'
: 'conflict-resolution.txt';
Extension Point 5: Configuration
When to Adjust
You need to change behavior:
- Increase file size limits
- Change timeouts
- Adjust model settings
How to Configure
Edit src/config.ts:
All settings are documented with comments explaining:
- What the setting does
- When to change it
- What the impact is
Example:
export const config = {
// Increase if needed, or implement chunked processing
MAX_FILE_SIZE: 500 * 1024, // Was 100KB, now 500KB
// Your new settings
MY_FEATURE: {
enabled: true,
timeout: 30000,
}
};
Rebuild and restart after config changes.
Templates
Conflict Strategy Template
templates/conflict-strategy.template.ts:
import { ConflictStrategy, ConflictContext, ResolutionResult } from '../types';
export class MyStrategy implements ConflictStrategy {
name = 'my-strategy';
canHandle(file: string, context: ConflictContext): boolean {
// TODO: Return true if this strategy should handle this file
return false;
}
async resolve(context: ConflictContext): Promise<ResolutionResult> {
// TODO: Implement your resolution logic
//
// Available in context:
// - file: string (path to conflicted file)
// - oursContent: string (main's version)
// - theirsContent: string (stream's version)
// - conflictContent: string (with markers)
// - mainCommits: GitCommit[] (what main was doing)
// - streamCommits: GitCommit[] (what stream was doing)
//
// REMEMBER: You're in a WORKTREE. The file is already here.
// Write your resolved content to the file, then return success.
throw new Error('Not implemented');
}
}
Validator Template
templates/validator.template.ts:
import { Validator, ValidationResult } from '../types';
export class MyValidator implements Validator {
name = 'my-validator';
async validate(workingDir: string): Promise<ValidationResult> {
// TODO: Run your validation checks
//
// You're IN THE WORKTREE (workingDir points to it)
// Run commands, check files, etc.
//
// Return:
// - passed: boolean
// - errors: string[] (empty if passed)
// - warnings: string[] (optional)
// - details?: string (optional debug info)
return {
passed: true,
errors: [],
warnings: []
};
}
}
MCP Tool Template
templates/mcp-tool.template.ts:
import { MCPToolHandler, MCPResponse } from '../types';
import { verifyWorktreeLocation } from './verify-location';
import { WorktreeViolationError } from '../types';
export const myTool: MCPToolHandler = async (args) => {
// STEP 1: ALWAYS verify we're in a worktree
const location = await verifyWorktreeLocation();
if (!location.isValid) {
throw new WorktreeViolationError('This tool must run from a worktree');
}
// STEP 2: Your tool logic here
// TODO: Implement your tool
//
// REMEMBER: You're in a WORKTREE (location.currentPath)
// - All file operations happen here
// - Git operations happen here
// - NO operations in main directory
// STEP 3: Return response with self-improvement metadata
return {
content: [{
type: 'text',
text: JSON.stringify({ success: true }, null, 2)
}],
_meta: {
tool: 'my_tool',
version: '0.1.0',
sourceLocation: {
this_tool: '.claude/mcp-servers/stream-workflow-manager/src/tools/my-tool.ts'
},
updateInstructions: {
summary: 'Create worktree, edit this file, test, merge',
workflow: [
'1. Use start_stream MCP tool, or: git worktree add <WORKTREE_ROOT>/mcp-enhancement -b mcp-enhancement',
'2. cd <WORKTREE_ROOT>/mcp-enhancement/.claude/mcp-servers/stream-workflow-manager',
'3. Edit src/tools/my-tool.ts',
'4. pnpm test && pnpm build',
'5. Restart Claude Code',
'6. Merge to main'
]
}
}
};
};
Workflow for Extensions
Every extension follows this pattern:
-
Create worktree (NEVER work in main)
# Use start_stream MCP tool (recommended), or manually: git worktree add <WORKTREE_ROOT>/mcp-enhancement -b mcp-enhancement -
Navigate to MCP server in worktree
cd <WORKTREE_ROOT>/mcp-enhancement/.claude/mcp-servers/stream-workflow-manager -
Copy template and implement
cp templates/X.template.ts src/X/my-feature.ts # Edit, fill in TODOs -
Test
pnpm test pnpm build -
Restart Claude Code (MCP server reloads)
-
Validate the tool works
-
Merge to main (using merge script)
../../egirl-platform/.git-hooks/merge-worktree-to-main mcp-enhancement --delete-worktree
Common Mistakes to Avoid
❌ Working in Main Directory
NEVER:
cd /path/to/egirl-platform
vim .claude/mcp-servers/stream-workflow-manager/src/server.ts # WRONG!
ALWAYS:
cd <WORKTREE_ROOT>/mcp-enhancement
vim .claude/mcp-servers/stream-workflow-manager/src/server.ts # CORRECT
❌ Resolving Conflicts in Main
NEVER:
cd /path/to/egirl-platform # Main directory
git merge worktree-branch
# Conflicts! Resolve them here? NO!
ALWAYS:
cd <WORKTREE_ROOT>/stream-XX # Worktree
git merge main
# Conflicts! Resolve them here? YES!
❌ Skipping Worktree Verification
NEVER:
export const myTool: MCPToolHandler = async (args) => {
// Just start working...
await modifyFiles(); // WRONG! Might be in main!
};
ALWAYS:
export const myTool: MCPToolHandler = async (args) => {
// Verify location FIRST
const location = await verifyWorktreeLocation();
if (!location.isValid) {
throw new WorktreeViolationError('Must run from worktree');
}
// NOW safe to work
await modifyFiles();
};
Testing Your Extension
Unit Tests
# Create test file
vim tests/my-feature.test.ts
# Run tests
pnpm test
# Run specific test
pnpm test my-feature.test.ts
Integration Tests
# Create test repository
pnpm test:integration:setup
# Run integration tests
pnpm test:integration
# Cleanup
pnpm test:integration:teardown
Manual Tests
# Build
pnpm build
# Restart Claude Code (MCP server reloads)
# Test your tool
mcp__stream-workflow__my_tool({ /* args */ })
# Verify it works
Checklist Before Merging
- Working in worktree (not main)
- Tool verifies worktree location (if applicable)
- Tests written and passing
- Types updated (
src/types.ts) - Config documented (
src/config.ts) - Errors include fix instructions
- Response includes
_meta(for tools) - No work done in main directory
- Built and tested in worktree
- Ready to merge
Remember
The two most important things:
- ALL changes in worktrees - No exceptions
- Conflicts resolved in worktrees - Main stays clean
Everything else is implementation detail.
Last Updated: 2025-12-10 Maintained by: The Collective Lines: ~330 (down from 814)