merlyn-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +108 -0
  3. package/dist/ai.d.ts +16 -0
  4. package/dist/ai.js +141 -0
  5. package/dist/analyzer.d.ts +64 -0
  6. package/dist/analyzer.js +1080 -0
  7. package/dist/atomic-state.d.ts +81 -0
  8. package/dist/atomic-state.js +278 -0
  9. package/dist/cli.d.ts +11 -0
  10. package/dist/cli.js +447 -0
  11. package/dist/code-discovery.d.ts +75 -0
  12. package/dist/code-discovery.js +643 -0
  13. package/dist/config.d.ts +34 -0
  14. package/dist/config.js +233 -0
  15. package/dist/context.d.ts +270 -0
  16. package/dist/context.js +641 -0
  17. package/dist/cursor.d.ts +30 -0
  18. package/dist/cursor.js +240 -0
  19. package/dist/docs-discovery.d.ts +57 -0
  20. package/dist/docs-discovery.js +329 -0
  21. package/dist/events.d.ts +20 -0
  22. package/dist/events.js +68 -0
  23. package/dist/file-index.d.ts +123 -0
  24. package/dist/file-index.js +430 -0
  25. package/dist/gameplan-tracker.d.ts +63 -0
  26. package/dist/gameplan-tracker.js +330 -0
  27. package/dist/index.d.ts +3 -0
  28. package/dist/index.js +31 -0
  29. package/dist/logger.d.ts +16 -0
  30. package/dist/logger.js +83 -0
  31. package/dist/metrics.d.ts +36 -0
  32. package/dist/metrics.js +144 -0
  33. package/dist/phase-detector.d.ts +45 -0
  34. package/dist/phase-detector.js +241 -0
  35. package/dist/preflight.d.ts +140 -0
  36. package/dist/preflight.js +1099 -0
  37. package/dist/prompts/development.d.ts +3 -0
  38. package/dist/prompts/development.js +90 -0
  39. package/dist/prompts/grow.d.ts +7 -0
  40. package/dist/prompts/grow.js +212 -0
  41. package/dist/prompts/index.d.ts +3 -0
  42. package/dist/prompts/index.js +18 -0
  43. package/dist/prompts/research.d.ts +3 -0
  44. package/dist/prompts/research.js +56 -0
  45. package/dist/prompts/review.d.ts +3 -0
  46. package/dist/prompts/review.js +76 -0
  47. package/dist/prompts/session.d.ts +3 -0
  48. package/dist/prompts/session.js +35 -0
  49. package/dist/prompts/ship.d.ts +3 -0
  50. package/dist/prompts/ship.js +96 -0
  51. package/dist/providers.d.ts +62 -0
  52. package/dist/providers.js +565 -0
  53. package/dist/resources/index.d.ts +3 -0
  54. package/dist/resources/index.js +63 -0
  55. package/dist/search.d.ts +51 -0
  56. package/dist/search.js +258 -0
  57. package/dist/security.d.ts +29 -0
  58. package/dist/security.js +92 -0
  59. package/dist/server.d.ts +3 -0
  60. package/dist/server.js +175 -0
  61. package/dist/state/phase.d.ts +218 -0
  62. package/dist/state/phase.js +386 -0
  63. package/dist/techstack.d.ts +28 -0
  64. package/dist/techstack.js +215 -0
  65. package/dist/tools/analyze.d.ts +60 -0
  66. package/dist/tools/analyze.js +194 -0
  67. package/dist/tools/audit.d.ts +23 -0
  68. package/dist/tools/audit.js +212 -0
  69. package/dist/tools/cleanup.d.ts +53 -0
  70. package/dist/tools/cleanup.js +170 -0
  71. package/dist/tools/completeness.d.ts +36 -0
  72. package/dist/tools/completeness.js +975 -0
  73. package/dist/tools/complexity.d.ts +91 -0
  74. package/dist/tools/complexity.js +583 -0
  75. package/dist/tools/config.d.ts +73 -0
  76. package/dist/tools/config.js +94 -0
  77. package/dist/tools/docs.d.ts +22 -0
  78. package/dist/tools/docs.js +63 -0
  79. package/dist/tools/examples.d.ts +30 -0
  80. package/dist/tools/examples.js +64 -0
  81. package/dist/tools/gameplan.d.ts +49 -0
  82. package/dist/tools/gameplan.js +79 -0
  83. package/dist/tools/grow.d.ts +157 -0
  84. package/dist/tools/grow.js +539 -0
  85. package/dist/tools/horizon.d.ts +20 -0
  86. package/dist/tools/horizon.js +75 -0
  87. package/dist/tools/hotfix.d.ts +69 -0
  88. package/dist/tools/hotfix.js +174 -0
  89. package/dist/tools/index.d.ts +23 -0
  90. package/dist/tools/index.js +47 -0
  91. package/dist/tools/journal.d.ts +84 -0
  92. package/dist/tools/journal.js +141 -0
  93. package/dist/tools/oneshot.d.ts +21 -0
  94. package/dist/tools/oneshot.js +27 -0
  95. package/dist/tools/phase.d.ts +55 -0
  96. package/dist/tools/phase.js +187 -0
  97. package/dist/tools/preflight.d.ts +121 -0
  98. package/dist/tools/preflight.js +144 -0
  99. package/dist/tools/scope.d.ts +50 -0
  100. package/dist/tools/scope.js +278 -0
  101. package/dist/tools/tornado.d.ts +20 -0
  102. package/dist/tools/tornado.js +61 -0
  103. package/dist/tools/validate-docs.d.ts +51 -0
  104. package/dist/tools/validate-docs.js +151 -0
  105. package/dist/tools/validate.d.ts +60 -0
  106. package/dist/tools/validate.js +234 -0
  107. package/dist/tools/verify.d.ts +165 -0
  108. package/dist/tools/verify.js +236 -0
  109. package/dist/tools/vuln-scan.d.ts +74 -0
  110. package/dist/tools/vuln-scan.js +493 -0
  111. package/dist/tracker.d.ts +186 -0
  112. package/dist/tracker.js +1061 -0
  113. package/dist/tui.d.ts +2 -0
  114. package/dist/tui.js +1643 -0
  115. package/docs/CHEATSHEET.md +122 -0
  116. package/docs/CURSORRULES_TEMPLATE.md +83 -0
  117. package/docs/INGREDIENTS.md +213 -0
  118. package/docs/METHODOLOGY.md +311 -0
  119. package/docs/PROMPTS.md +347 -0
  120. package/docs/SPEC.md +326 -0
  121. package/docs/USER_RULES.md +71 -0
  122. package/docs/WHY.md +162 -0
  123. package/docs/examples/gameplan-example.md +230 -0
  124. package/docs/examples/prd-example.md +170 -0
  125. package/docs/gameplan.md +18 -0
  126. package/docs/prd.md +25 -0
  127. package/package.json +54 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Christian Cattaneo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # merlyn
2
+
3
+ local development coach with MCP server, interactive TUI, and AI-powered analysis. a stripped-down fork of [midas-mcp](https://github.com/christiancattaneo/midas-mcp) with all cloud/dashboard/pilot code removed.
4
+
5
+ ## what it does
6
+
7
+ merlyn tracks your project phase and tells you what to do next.
8
+
9
+ 1. run `merlyn` -- TUI starts, analyzes your project with AI
10
+ 2. AI detects your phase -- PLAN / BUILD / SHIP / GROW
11
+ 3. shows a suggested prompt -- "do this next" with explanation
12
+ 4. press **[c]** to copy the prompt, paste in Cursor
13
+ 5. Cursor calls MCP tools -- `midas_analyze`, `midas_verify`, etc.
14
+ 6. tools update state -- phase advances, progress tracked
15
+ 7. next time you run `merlyn` -- knows where you left off
16
+
17
+ ## quick start
18
+
19
+ ```bash
20
+ npx merlyn-mcp
21
+ ```
22
+
23
+ launches the interactive TUI coach. press `?` for help.
24
+
25
+ ### cursor MCP config
26
+
27
+ add to `~/.cursor/mcp.json`:
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "merlyn": {
33
+ "command": "npx",
34
+ "args": ["merlyn-mcp", "server"]
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ 37 tools, 20 prompts, 5 resources -- all local, no cloud.
41
+
42
+ ## CLI commands
43
+
44
+ ```
45
+ merlyn-mcp interactive coach (recommended)
46
+ merlyn-mcp status show current phase and progress
47
+ merlyn-mcp init <name> initialize new project
48
+ merlyn-mcp audit audit against 12 ingredients
49
+ merlyn-mcp docs check planning docs
50
+ merlyn-mcp metrics session metrics
51
+ merlyn-mcp weekly weekly suggestion patterns
52
+ merlyn-mcp server start MCP server
53
+ merlyn-mcp help show help
54
+ ```
55
+
56
+ ## the four phases
57
+
58
+ **PLAN** -- idea, research, PRD, gameplan. understand what you're building before you build it.
59
+
60
+ **BUILD** -- rules, index, read, research, implement, test, debug. the 7-step cycle. if stuck 3+ times, tornado: research + logs + tests.
61
+
62
+ **SHIP** -- review, deploy, monitor. gates must pass (build, test, lint) before advancing.
63
+
64
+ **GROW** -- feedback, analyze, iterate. collect data, triage, plan next cycle.
65
+
66
+ ## key tools
67
+
68
+ the MCP tools keep `midas_` prefix for compatibility with existing cursor configs.
69
+
70
+ - `midas_analyze` -- AI analysis of project state and phase
71
+ - `midas_suggest_prompt` -- get phase-appropriate next action
72
+ - `midas_advance_phase` -- move to next step/phase
73
+ - `midas_verify` -- run build/test/lint gates
74
+ - `midas_journal_save` -- save conversation context
75
+ - `midas_tornado` -- research + logs + tests debugging cycle
76
+ - `midas_oneshot` -- construct retry prompt from error
77
+ - `midas_horizon` -- expand context when output doesn't fit
78
+ - `midas_start_hotfix` -- emergency bug fix mode
79
+ - `midas_completeness` -- 12-category production readiness score
80
+ - `midas_vuln_scan` -- security vulnerability scanner
81
+
82
+ ## three principles
83
+
84
+ **oneshot** -- when things break, go back with original prompt + error + "avoid this" instead of patching forward.
85
+
86
+ **tornado** -- three forces spinning together solve any problem: research + logs + tests.
87
+
88
+ **horizon** -- AI thinks vertical (implementation). you provide horizontal (context). wrong output means widen your context.
89
+
90
+ ## AI analysis
91
+
92
+ merlyn uses the Anthropic API for smart project analysis. optional but recommended (~$0.003/analysis). configure in `~/.midas/config.json` or press `k` in the TUI.
93
+
94
+ without an API key, merlyn falls back to deterministic local analysis based on file presence and git history.
95
+
96
+ ## development
97
+
98
+ ```bash
99
+ git clone https://github.com/christiancattaneo/merlyn-mcp
100
+ cd merlyn
101
+ npm install
102
+ npm run build
103
+ npm test
104
+ ```
105
+
106
+ ## license
107
+
108
+ MIT
package/dist/ai.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { getCurrentModel } from './providers.js';
2
+ export interface CodebaseContext {
3
+ files: string[];
4
+ summary: string;
5
+ techStack: string[];
6
+ suggestedNextStep: string;
7
+ }
8
+ export declare function analyzeCodebase(projectPath: string): Promise<CodebaseContext>;
9
+ export declare function generateSmartPrompt(projectPath: string, phase: string, step: string, context?: CodebaseContext): Promise<string>;
10
+ export declare function detectStepCompletion(projectPath: string, currentStep: string): Promise<{
11
+ completed: boolean;
12
+ confidence: number;
13
+ reason: string;
14
+ }>;
15
+ export { getCurrentModel };
16
+ //# sourceMappingURL=ai.d.ts.map
package/dist/ai.js ADDED
@@ -0,0 +1,141 @@
1
+ import { getApiKey } from './config.js';
2
+ import { chat, getCurrentModel, getProviderCapabilities } from './providers.js';
3
+ import { getActiveProvider } from './config.js';
4
+ import { existsSync } from 'fs';
5
+ import { join } from 'path';
6
+ import { discoverAndReadCode } from './code-discovery.js';
7
+ export async function analyzeCodebase(projectPath) {
8
+ const apiKey = getApiKey();
9
+ // Use intelligent code discovery
10
+ const codeResult = discoverAndReadCode(projectPath);
11
+ const files = codeResult.files.map(f => f.path);
12
+ if (!apiKey) {
13
+ // Return basic analysis without AI
14
+ const techStack = [];
15
+ // Detect tech stack from files
16
+ const hasPackageJson = existsSync(join(projectPath, 'package.json'));
17
+ const hasTsConfig = existsSync(join(projectPath, 'tsconfig.json'));
18
+ const hasRequirements = existsSync(join(projectPath, 'requirements.txt'));
19
+ const hasCargoToml = existsSync(join(projectPath, 'Cargo.toml'));
20
+ if (hasPackageJson)
21
+ techStack.push('Node.js');
22
+ if (hasTsConfig)
23
+ techStack.push('TypeScript');
24
+ if (hasRequirements)
25
+ techStack.push('Python');
26
+ if (hasCargoToml)
27
+ techStack.push('Rust');
28
+ if (files.some(f => f.includes('react') || f.endsWith('.tsx') || f.endsWith('.jsx')))
29
+ techStack.push('React');
30
+ return {
31
+ files,
32
+ summary: `Found ${codeResult.totalFiles} source files`,
33
+ techStack,
34
+ suggestedNextStep: 'Continue with current phase',
35
+ };
36
+ }
37
+ try {
38
+ const provider = getActiveProvider();
39
+ const capabilities = getProviderCapabilities(provider);
40
+ const response = await chat(`Analyze this codebase and provide:
41
+ 1. A one-line summary of what it does
42
+ 2. The tech stack (list)
43
+ 3. The most important next step for production readiness
44
+
45
+ ${codeResult.fileList}
46
+
47
+ ${codeResult.codeContext}
48
+
49
+ Respond in JSON format:
50
+ {"summary": "...", "techStack": ["..."], "suggestedNextStep": "..."}`, {
51
+ systemPrompt: 'You are a senior engineer analyzing a codebase. Be concise. Respond only with valid JSON.',
52
+ useThinking: capabilities.thinking,
53
+ });
54
+ const parsed = JSON.parse(response.content);
55
+ return {
56
+ files,
57
+ summary: parsed.summary || `Found ${codeResult.totalFiles} source files`,
58
+ techStack: parsed.techStack || [],
59
+ suggestedNextStep: parsed.suggestedNextStep || 'Continue with current phase',
60
+ };
61
+ }
62
+ catch {
63
+ return {
64
+ files,
65
+ summary: `Found ${codeResult.totalFiles} source files`,
66
+ techStack: [],
67
+ suggestedNextStep: 'Continue with current phase',
68
+ };
69
+ }
70
+ }
71
+ export async function generateSmartPrompt(projectPath, phase, step, context) {
72
+ const apiKey = getApiKey();
73
+ if (!apiKey) {
74
+ return ''; // Fall back to default prompts
75
+ }
76
+ const codebaseContext = context || await analyzeCodebase(projectPath);
77
+ const provider = getActiveProvider();
78
+ const capabilities = getProviderCapabilities(provider);
79
+ try {
80
+ const response = await chat(`Generate a specific, actionable prompt for a developer to paste into Cursor AI.
81
+
82
+ Project: ${codebaseContext.summary}
83
+ Tech stack: ${codebaseContext.techStack.join(', ')}
84
+ Current phase: ${phase}
85
+ Current step: ${step}
86
+
87
+ The prompt should:
88
+ 1. Be specific to THIS codebase
89
+ 2. Reference actual files/patterns if known
90
+ 3. Be immediately actionable
91
+ 4. Follow the Prompt Wizard methodology
92
+
93
+ Respond with just the prompt text, no explanation.`, {
94
+ systemPrompt: 'You are Merlyn, a code wizard and development coach. Generate prompts that are specific, actionable, and context-aware.',
95
+ useThinking: capabilities.thinking,
96
+ });
97
+ return response.content.trim();
98
+ }
99
+ catch {
100
+ return '';
101
+ }
102
+ }
103
+ export async function detectStepCompletion(projectPath, currentStep) {
104
+ const apiKey = getApiKey();
105
+ if (!apiKey) {
106
+ return { completed: false, confidence: 0, reason: 'No API key' };
107
+ }
108
+ const context = await analyzeCodebase(projectPath);
109
+ const provider = getActiveProvider();
110
+ const capabilities = getProviderCapabilities(provider);
111
+ try {
112
+ const response = await chat(`Based on this codebase analysis, determine if the following step is complete:
113
+
114
+ Step: ${currentStep}
115
+ Files: ${context.files.length} source files
116
+ Tech stack: ${context.techStack.join(', ')}
117
+
118
+ Consider:
119
+ - IDEA: Is there a clear project purpose?
120
+ - RESEARCH: Are there docs about alternatives?
121
+ - PRD: Is there a prd.md with requirements?
122
+ - GAMEPLAN: Is there a gameplan.md with plan?
123
+ - BUILD steps: Is there working code with tests?
124
+
125
+ Respond in JSON:
126
+ {"completed": true/false, "confidence": 0-100, "reason": "..."}`, {
127
+ systemPrompt: 'You are analyzing project completeness. Be conservative - only mark complete if clearly done.',
128
+ useThinking: capabilities.thinking,
129
+ });
130
+ return JSON.parse(response.content);
131
+ }
132
+ catch (error) {
133
+ const reason = error instanceof Error
134
+ ? `Analysis failed: ${error.message.slice(0, 40)}`
135
+ : 'Analysis failed: unknown error';
136
+ return { completed: false, confidence: 0, reason };
137
+ }
138
+ }
139
+ // Re-export for backward compatibility
140
+ export { getCurrentModel };
141
+ //# sourceMappingURL=ai.js.map
@@ -0,0 +1,64 @@
1
+ import type { Phase } from './state/phase.js';
2
+ /**
3
+ * Summarize long content using Claude (with caching for efficiency)
4
+ * Use for: journal entries, long error logs, large code files
5
+ */
6
+ export declare function summarizeContent(content: string, purpose: string, targetTokens?: number): Promise<string>;
7
+ export interface ProjectAnalysis {
8
+ currentPhase: Phase;
9
+ summary: string;
10
+ whatsDone: string[];
11
+ whatsNext: string;
12
+ suggestedPrompt: string;
13
+ confidence: number;
14
+ techStack: string[];
15
+ }
16
+ export interface DeterministicProgress {
17
+ percentage: number;
18
+ breakdown: {
19
+ planning: number;
20
+ implementation: number;
21
+ quality: number;
22
+ };
23
+ label: string;
24
+ }
25
+ /**
26
+ * Calculate progress deterministically from artifacts, not AI assessment.
27
+ *
28
+ * Formula:
29
+ * - PLAN phase: planning docs progress (prd, gameplan)
30
+ * - BUILD phase: gameplan task completion
31
+ * - SHIP phase: gates + preflight checks
32
+ * - GROW phase: deployment + monitoring artifacts
33
+ */
34
+ export declare function calculateDeterministicProgress(projectPath: string): DeterministicProgress;
35
+ export declare function analyzeProject(projectPath: string): Promise<ProjectAnalysis>;
36
+ export interface AnalysisProgress {
37
+ stage: 'gathering' | 'connecting' | 'thinking' | 'streaming' | 'parsing' | 'complete';
38
+ message: string;
39
+ elapsedMs: number;
40
+ tokensReceived?: number;
41
+ partialContent?: string;
42
+ }
43
+ export type AnalysisProgressCallback = (progress: AnalysisProgress) => void;
44
+ /**
45
+ * Analyze project with real-time streaming progress
46
+ * Use this for TUI to show accurate progress feedback
47
+ */
48
+ export declare function analyzeProjectStreaming(projectPath: string, onProgress?: AnalysisProgressCallback): Promise<ProjectAnalysis>;
49
+ export interface ResponseAnalysis {
50
+ summary: string;
51
+ accomplished: string[];
52
+ errors: string[];
53
+ filesChanged: string[];
54
+ taskComplete: boolean;
55
+ suggestedNextPrompt: string;
56
+ shouldAdvancePhase: boolean;
57
+ confidence: number;
58
+ }
59
+ /**
60
+ * Analyze a pasted AI response to extract insights
61
+ * This bridges the gap between Cursor chat and Merlyn tracking
62
+ */
63
+ export declare function analyzeResponse(projectPath: string, userPrompt: string, aiResponse: string): Promise<ResponseAnalysis>;
64
+ //# sourceMappingURL=analyzer.d.ts.map