Skip to content

Instantly share code, notes, and snippets.

@bossjones
Created April 17, 2025 21:14
Show Gist options
  • Save bossjones/ca546a0c44a902d8a7edf6d29ae93d19 to your computer and use it in GitHub Desktop.
Save bossjones/ca546a0c44a902d8a7edf6d29ae93d19 to your computer and use it in GitHub Desktop.

Okay, let's break down prompt_library.py into a more modular structure within the promptlib directory.

The core idea is to separate concerns:

  1. Data Structures (Types): Definitions of how cursor rules look.
  2. Constants: Configuration like paths and patterns.
  3. Core Rule Logic: Functions for reading, parsing, and generating rule files.
  4. MCP Endpoints: Separate files for Resources, Prompts, and Tools.
  5. Complex Workflows: Isolate the multi-phase workflow logic.
  6. Server Setup: Initialize the FastMCP server and register all endpoints.

Proposed Tree Structure

Here's a simplified, modular structure within src/codegen_lab/promptlib:

src/codegen_lab
├── __init__.py
├── __main__.py
├── __version__.py
├── cli.py
└── promptlib           # <--- All new logic goes here
    ├── __init__.py
    ├── constants.py    # <--- CURSOR_RULES_DIR, TECHNOLOGY_PATTERNS
    ├── types.py        # <--- TypedDict definitions (CursorRule, etc.)
    ├── rules.py        # <--- Core rule file handling (read, parse, generate)
    ├── resources.py    # <--- @mcp.resource functions
    ├── prompts.py      # <--- @mcp.prompt functions
    ├── tools.py        # <--- Most @mcp.tool functions
    ├── workflow.py     # <--- plan_and_execute_... workflow tool + helpers
    └── server.py       # <--- FastMCP instance creation & registration of all endpoints

Explanation:

  • constants.py: Holds CURSOR_RULES_DIR and TECHNOLOGY_PATTERNS.
  • types.py: Contains all the TypedDict definitions (CursorRuleMetadata, CursorRule, etc.).
  • rules.py: Houses the functions that directly interact with rule files: get_cursor_rule_files, get_cursor_rule_names, read_cursor_rule, parse_cursor_rule, generate_cursor_rule.
  • resources.py: Contains the functions decorated with @mcp.resource (list_cursor_rules, get_cursor_rule, get_cursor_rule_raw).
  • prompts.py: Contains the functions decorated with @mcp.prompt (repo_analysis_prompt, generate_cursor_rule_prompt).
  • tools.py: Contains most functions decorated with @mcp.tool (e.g., instruct_repo_analysis, get_static_cursor_rule, save_cursor_rule, prep_workspace, etc.).
  • workflow.py: Specifically isolates the complex plan_and_execute_prompt_library_workflow tool and its helper functions (execute_phase_1 to execute_phase_5). This keeps the most complex logic separate.
  • server.py:
    • Initializes the FastMCP instance (mcp = FastMCP(...)).
    • Imports the functions from resources.py, prompts.py, tools.py, and workflow.py.
    • Crucially, it applies the @mcp.resource, @mcp.prompt, and @mcp.tool decorators here to register the imported functions with the mcp instance. This avoids circular dependencies.
    • Defines a function like run_server() which calls mcp.run().
  • prompt_library.py: This original file can now be deleted or significantly reduced. Its responsibilities are moved into the promptlib modules.
  • __main__.py: This file should now import run_server from promptlib.server and call it in its if __name__ == "__main__": block to start the server.

Checklist for Moving Logic

Here's what should be moved from the original prompt_library.py to the new modules:

1. Move to promptlib/constants.py: * [ ] CURSOR_RULES_DIR = Path(...) * [ ] TECHNOLOGY_PATTERNS = {...}

2. Move to promptlib/types.py: * [ ] CursorRuleMetadata(TypedDict, total=False) * [ ] CursorRuleExample(TypedDict) * [ ] CursorRuleFilter(TypedDict) * [ ] CursorRuleAction(TypedDict) * [ ] CursorRule(TypedDict)

3. Move to promptlib/rules.py: * [ ] get_cursor_rule_files() -> list[Path] * [ ] get_cursor_rule_names() -> list[str] * [ ] read_cursor_rule(rule_name: str) -> str | None * [ ] parse_cursor_rule(content: str) -> dict[str, Any] * [ ] generate_cursor_rule(...) -> str * [ ] Ensure necessary imports (glob, json, re, Path, os, typing, constants, types) are added here.

4. Move Functions to promptlib/resources.py (Implementations Only): * [ ] Define list_cursor_rules_impl() -> list[dict[str, str]] | dict[str, Any] (function body of list_cursor_rules) * [ ] Define get_cursor_rule_impl(name: str) -> dict[str, Any] (function body of get_cursor_rule) * [ ] Define get_cursor_rule_raw_impl(name: str) -> str (function body of get_cursor_rule_raw) * [ ] Add necessary imports (rules, typing, Any). Do not add @mcp.resource decorators here.

5. Move Functions to promptlib/prompts.py (Implementations Only): * [ ] Define repo_analysis_prompt_impl(...) -> list[dict[str, Any]] (function body of repo_analysis_prompt) * [ ] Define generate_cursor_rule_prompt_impl(...) -> list[dict[str, Any]] (function body of generate_cursor_rule_prompt) * [ ] Add necessary imports (json, typing, rules, Context). Do not add @mcp.prompt decorators here.

6. Move Functions to promptlib/tools.py (Implementations Only): * [ ] Define instruct_repo_analysis_impl() -> dict[str, Any] * [ ] Define instruct_custom_repo_rules_generation_impl(...) -> dict[str, Any] * [ ] Define get_static_cursor_rule_impl(...) -> dict[str, str | bool | list[dict[str, str]]] * [ ] Define get_static_cursor_rules_impl(...) -> dict[str, list[dict[str, str | bool | list[dict[str, str]]]]] * [ ] Define save_cursor_rule_impl(...) -> dict[str, list[dict[str, str | dict[str, bool | str]]] | str] * [ ] Define recommend_cursor_rules_impl(...) -> list[dict[str, str | list[str]]] | dict[str, bool | list[dict[str, str]]] * [ ] Define prep_workspace_impl() -> dict[str, str] * [ ] Define create_cursor_rule_files_impl(...) -> dict[str, Any] * [ ] Define ensure_makefile_task_impl(...) -> dict[str, Any] * [ ] Define ensure_ai_report_impl(...) -> dict[str, Any] * [ ] Define run_update_cursor_rules_impl() -> dict[str, Any] * [ ] Define update_dockerignore_impl() -> dict[str, Any] * [ ] Define cursor_rules_workflow_impl(...) -> dict[str, Any] (Note: This calls other tools directly, ensure imports are correct) * [ ] Add necessary imports (Field, Path, os, re, json, typing, constants, rules). Do not add @mcp.tool decorators here.

7. Move Functions to promptlib/workflow.py (Implementations Only): * [ ] Define plan_and_execute_prompt_library_workflow_impl(...) -> dict[str, Any] * [ ] Define execute_phase_1_impl(...) -> dict[str, Any] * [ ] Define execute_phase_2_impl(...) -> dict[str, Any] * [ ] Define execute_phase_3_impl(...) -> dict[str, Any] * [ ] Define execute_phase_4_impl(...) -> dict[str, Any] * [ ] Define execute_phase_5_impl(...) -> dict[str, Any] * [ ] Add necessary imports (Field, typing, Any, prompts, tools). Do not add @mcp.tool decorators here.

8. Create promptlib/server.py: * [ ] Add imports: FastMCP from mcp.server.fastmcp, resources, prompts, tools, workflow. * [ ] Define mcp = FastMCP("prompt_library", debug=True, log_level="DEBUG"). * [ ] Register resources: ```python @mcp.resource("cursor-rules://list", ...) def list_cursor_rules(): return resources.list_cursor_rules_impl()

    @mcp.resource("cursor-rule://{name}", ...)
    def get_cursor_rule(name: str):
        return resources.get_cursor_rule_impl(name)

    @mcp.resource("cursor-rule-raw://{name}", ...)
    def get_cursor_rule_raw(name: str):
        return resources.get_cursor_rule_raw_impl(name)
    ```
*   [ ] Register prompts (similarly, calling `prompts.<func_name>_impl`).
*   [ ] Register tools (similarly, calling `tools.<func_name>_impl` and `workflow.<func_name>_impl`). Remember to copy the `Field` definitions for arguments into the registration function signatures here.
*   [ ] Define `def run_server(): mcp.run()`.

9. Update src/codegen_lab/__main__.py: * [ ] Remove old prompt_library logic if any. * [ ] Add from .promptlib.server import run_server. * [ ] In if __name__ == "__main__":, call run_server().

10. Delete src/codegen_lab/prompt_library.py: * [ ] Remove the original file once all logic is migrated.

11. Add __init__.py files: * [ ] Ensure src/codegen_lab/promptlib/__init__.py exists (can be empty).

This structure separates concerns effectively, makes the codebase easier to navigate, and isolates the core server setup and registration logic in server.py. Remember to adjust imports within the new modules as needed.

I want to break out this prompt_library.py file into smaller modules. Please look at the constants defined, models, etc and think about the most simplified version of what this might look like. Show me a tree structure and check list of what should get moved to the new modules.

here's what I have so far:

tree -L 7 -I "*.pyc|__pycache__|.git|.pytest_cache|.ruff_cache|.mypy_cache|.coverage|htmlcov|.venv|.env|*.egg-info|build|dist|node_modules|.DS_Store|images" src/codegen_lab
src/codegen_lab
├── __init__.py
├── __main__.py
├── __version__.py
├── cli.py
├── prompt_library.py
└── promptlib
    ├── __init__.py

i think we can move all logic inside the new promptlib module?

here is prompt_library.py:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment