Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,4 @@ dist
packages/mcp-server/resources
packages/cli/resources
packages/opencode-plugin/resources
scripts/disable-tests.js
43 changes: 43 additions & 0 deletions .vibe/development-plan-feat-feature-inventory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Development Plan: workflows (feat/feature-inventory branch)

*Generated on 2026-09-21 by Vibe Feature MCP*
*Workflow: [greenfield](https://codemcp.github.io/workflows/workflows/greenfield)*

## Goal
Trim @codemcp/workflows from ~14,900 LOC to ~10,900 LOC by removing dead features (beads, plugin system, MCP resources, crowd, artifact-check, branch-prompt, visualization CLI) while keeping the core MCP loop intact. Also: refactor remaining abstractions, restore docs with inlined visualizer, fix doc injection, fix project_path override.

## Key Decisions
- Keep all workflow YAMLs except 3 crowd variants (sdd-feature-crowd, sdd-bugfix-crowd, sdd-greenfield-crowd)
- Domain filtering (WORKFLOW_DOMAINS + metadata.domain) stays — needed for non-code workflows
- Conditional doc injection via referred_docs: [] on phases, not variable substitution
- project_path param overrides server PROJECT_PATH env var in all tool handlers
- Docs restored as VitePress site with visualizer inlined (no separate packages/visualizer)
- Single-implementation interfaces collapsed (IPlanManager, IInstructionGenerator, ITaskBackendClient)

## Code
### Tasks
- [x] Phase 0: disable all tests (commit bce8dc7)
- [x] Phase 1: delete packages/visualizer and packages/docs (commit 7a8f35b)
- [x] Phase 2: delete dead source files (commit cc263eb)
- [x] Phase 3: trim kept files, re-enable core tests (commit 9432ca4)
- [x] Phase 4: conditional doc injection + instructionSource (commit acd4ac4)
- [x] Phase 5: export/package cleanup (no changes needed)
- [x] Phase 6: YAML cleanup (no changes needed)
- [x] Phase 7: final verification (commit fcea090)
- [x] Refactor: collapse dead abstractions (commit 228ce5d)
- [x] Refactor: remaining cleanup items (commit 2afedf5)
- [x] Restore docs with inlined visualizer (commit e8e8e11)
- [x] Fix referred_docs injection regression (commit 0d7f39b)
- [x] Fix project_path override in all handlers (commit 6d7b2c8)

### Results
- pnpm build: zero errors, zero warnings
- pnpm test: ~430 passing, 0 failing (intentional describe.skip for deleted features)
- CLI: workflow list works, no crowd YAMLs
- MCP server: starts cleanly, 8 tools registered
- Docs: VitePress site builds, visualizer inlined as single SFC
- Doc injection: referred_docs on phases, file-existence checked at runtime
- project_path param: overrides server default in all 6 tool handlers

---
*This plan is maintained by the LLM. Tool responses provide guidance on which section to focus on and what tasks to work on.*
384 changes: 384 additions & 0 deletions .vibe/trim-implementation-plan.md

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"packages/*/dist/**/*",
"packages/*/package.json",
"packages/*/resources/**/*",
"packages/docs/.vitepress/dist/**/*",
"resources/**/*",
"README.md",
"LOGGING.md",
Expand All @@ -33,7 +32,8 @@
},
"scripts": {
"build": "turbo run build && node scripts/generate-skill.js",
"build:visualizer": "cd packages/visualizer && pnpm install && pnpm run build",
"docs:build": "turbo run build --filter=@codemcp/workflows-docs",
"docs:dev": "turbo run dev --filter=@codemcp/workflows-docs",
"pack:dist": "pnpm pack",
"inspector": "npx @modelcontextprotocol/inspector",
"dev": "turbo run dev --filter=@codemcp/workflows-core --filter=@codemcp/workflows-server",
Expand Down Expand Up @@ -73,16 +73,19 @@
"tsx": "4.21.0",
"turbo": "^2.7.6",
"typescript": "^5.9.3",
"vitepress": "^1.6.4",
"vitest": "4.0.18"
},
"lint-staged": {
"*.{ts,js,mts,cts,tsx,jsx}": [
"prettier --write",
"oxlint --fix"
],
"*.{json,md,yml,yaml,vue}": [
"*.{json,md,yml,yaml}": [
"prettier --write"
],
"*.vue": [
"prettier --write",
"oxlint --fix"
]
},
"keywords": [
Expand Down
181 changes: 1 addition & 180 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@

import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import {
existsSync,
mkdirSync,
writeFileSync,
readFileSync,
readdirSync,
} from 'node:fs';
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
import { WorkflowManager } from '@codemcp/workflows-core';

const __filename = fileURLToPath(import.meta.url);
Expand Down Expand Up @@ -44,7 +38,6 @@ if (isLocal) {
StateMachineLoader = coreModule.StateMachineLoader as new () => unknown;
}

import { startVisualizationTool } from './visualization-launcher.js';
import { generateConfig, GeneratorRegistry } from './config-generator.js';
import { generateSkill, SkillGeneratorRegistry } from './skill-generator.js';
import {
Expand Down Expand Up @@ -145,29 +138,6 @@ async function parseCliArgs(): Promise<{ shouldExit: boolean }> {
}
}

// Handle crowd commands (renamed from agents)
if (command === 'crowd') {
const subcommand = args[1];
if (subcommand === 'list') {
handleCrowdList();
return { shouldExit: true };
} else if (subcommand === 'copy') {
const outputDir = parseFlag(args, '--output-dir');
handleCrowdCopy(outputDir);
return { shouldExit: true };
} else {
console.error('❌ Unknown crowd subcommand:', subcommand);
console.error('Available: crowd list, crowd copy [--output-dir DIR]');
process.exit(1);
}
}

// Handle visualize subcommand (also default with no args)
if (command === 'visualize' || args.length === 0) {
startVisualizationTool();
return { shouldExit: true };
}

// Handle validate subcommand
if (command === 'validate') {
const workflowPath = args[1];
Expand Down Expand Up @@ -225,14 +195,6 @@ async function parseCliArgs(): Promise<{ shouldExit: boolean }> {
return { shouldExit: true };
}

// Handle deprecated 'agents' subcommand (renamed to 'crowd')
if (command === 'agents') {
const subcommand = args[1] || '';
console.warn('⚠️ DEPRECATED: "agents" subcommand is renamed to "crowd".');
console.warn(` Use instead: crowd ${subcommand}`);
return { shouldExit: true };
}

// Handle deprecated 'skill' subcommand (merged into 'setup')
if (command === 'skill') {
const subcommand = args[1];
Expand Down Expand Up @@ -595,140 +557,6 @@ function handleSetupList(): void {
console.log(' setup <target> --mode skill Generate skill files only');
}

/**
* Handle crowd list command (renamed from agents list)
*/
function handleCrowdList(): void {
try {
// Find agents directory
const possibleAgentsPaths = [
join(__dirname, '..', '..', '..', 'resources', 'agents'),
join(__dirname, '..', '..', 'core', 'resources', 'agents'),
];

let agentsDir: string | null = null;
for (const path of possibleAgentsPaths) {
if (existsSync(path)) {
agentsDir = path;
break;
}
}

if (!agentsDir) {
console.error('❌ Could not find agents directory');
process.exit(1);
}

const files = readdirSync(agentsDir).filter(
(f: string) => f.endsWith('.yaml') || f.endsWith('.yml')
);

if (files.length === 0) {
console.log('📋 No crowd agent configurations found');
return;
}

console.log('📋 Available crowd agent configurations:\n');
for (const file of files) {
const agentPath = join(agentsDir, file);
const content = readFileSync(agentPath, 'utf8');

// Extract name and displayName from YAML
const nameMatch = content.match(/^name:\s*(.+)$/m);
const displayNameMatch = content.match(/^displayName:\s*(.+)$/m);
const name = nameMatch
? (nameMatch[1]?.trim() ?? file.replace(/\.ya?ml$/, ''))
: file.replace(/\.ya?ml$/, '');
const displayName = displayNameMatch?.[1]?.trim() ?? name;

console.log(` ${name.padEnd(18)} ${displayName}`);
}

console.log(
'\n💡 Use "crowd copy" to copy these configurations to your project'
);
} catch (error) {
console.error('Error listing crowd agents:', error);
process.exit(1);
}
}

/**
* Handle crowd copy command (renamed from agents copy)
*/
function handleCrowdCopy(outputDir?: string): void {
try {
// Find source agents directory
const possibleAgentsPaths = [
join(__dirname, '..', '..', '..', 'resources', 'agents'),
join(__dirname, '..', '..', 'core', 'resources', 'agents'),
];

let sourceAgentsDir: string | null = null;
for (const path of possibleAgentsPaths) {
if (existsSync(path)) {
sourceAgentsDir = path;
break;
}
}

if (!sourceAgentsDir) {
console.error('❌ Could not find source agents directory');
process.exit(1);
}

// Determine target directory
const targetDir = outputDir || join(process.cwd(), '.crowd', 'agents');

// Create target directory if it doesn't exist
if (!existsSync(targetDir)) {
mkdirSync(targetDir, { recursive: true });
}

// Read all agent files
const files = readdirSync(sourceAgentsDir).filter(
(f: string) => f.endsWith('.yaml') || f.endsWith('.yml')
);

if (files.length === 0) {
console.error('❌ No crowd agent configurations found to copy');
process.exit(1);
}

console.log(
`📋 Copying ${files.length} crowd agent configuration(s) to ${targetDir}\n`
);

// Copy each file
let copiedCount = 0;
let skippedCount = 0;

for (const file of files) {
const sourcePath = join(sourceAgentsDir, file);
const targetPath = join(targetDir, file);

if (existsSync(targetPath)) {
console.log(`⏭️ ${file} (already exists, skipping)`);
skippedCount++;
} else {
const content = readFileSync(sourcePath, 'utf8');
writeFileSync(targetPath, content);
console.log(`✅ ${file}`);
copiedCount++;
}
}

console.log(
`\n🎉 Copied ${copiedCount} crowd agent configuration(s)${skippedCount > 0 ? ` (skipped ${skippedCount} existing)` : ''}`
);
console.log(`\n💡 Crowd agent configurations are now in: ${targetDir}`);
console.log('💡 Configure these agents in your crowd-mcp setup');
} catch (error) {
console.error('Error copying crowd agents:', error);
process.exit(1);
}
}

/**
* Show help information
*/
Expand All @@ -742,7 +570,6 @@ Responsible Vibe CLI Tools

USAGE:
npx @codemcp/workflows [COMMAND]
npx @codemcp/workflows Start the interactive visualizer (default)

SETUP COMMANDS:
setup <target> Generate full agent configuration (default mode)
Expand All @@ -755,12 +582,7 @@ WORKFLOW COMMANDS:
workflow list List available workflows
workflow copy <source> <name> Copy a workflow with custom name

CROWD AGENT COMMANDS:
crowd list List available crowd agent configurations
crowd copy [--output-dir DIR] Copy crowd agent configs to project

UTILITY COMMANDS:
visualize Start the interactive workflow visualizer
validate <workflow.yaml> Validate a workflow file
system-prompt Show the system prompt for LLM integration

Expand All @@ -772,7 +594,6 @@ AVAILABLE TARGETS:

DESCRIPTION:
CLI tools for the responsible-vibe development workflow system.
By default, starts the interactive workflow visualizer.

MORE INFO:
GitHub: https://github.com/codemcp/workflows
Expand Down
Loading
Loading