12 KiB
Project Restructuring Plan
Based on discussion in https://github.com/danielmiessler/fabric/issues/1127
This plan synthesizes the proposal by ksylvan with key clarifications and additions from jaredmontoya, eugeis, and others in the thread. The goal is to reorganize the project to align with standard Go conventions, reduce root-level clutter, and improve overall clarity for developers.
Revision 2 Changes: Added support for additional binary tools (code_helper and to_pdf) in the cmd/ directory structure.
Rationale for Restructuring
The current project structure mixes application code, web assets, scripts, and configuration files at the top level. This creates several challenges:
- Top-Level Clutter: A large number of files and directories in the root makes it difficult to quickly understand the project's structure and entry points.
- Non-Idiomatic Go Structure: Go source code is spread across multiple top-level directories. Standard Go practice places main application code in
cmd/and private, non-reusable package code ininternal/. - Mixed Concerns: Application code (Go), web frontend code (Svelte), data processing scripts (Python), and infrastructure configuration (
nix,Dockerfile) are intermingled, obscuring the separation of concerns.
The proposed restructure addresses these issues by organizing the project by function, adhering to community best practices.
Proposed Final Directory Structure
This is the high-level view of the proposed structure. It incorporates the core plan and ensures that technically required files like flake.nix remain in the root directory.
.
├── cmd
│ ├── fabric
│ │ └── main.go # Main application entrypoint
│ ├── code_helper
│ │ ├── main.go # Code analysis helper tool
│ │ └── code.go # Supporting code for code_helper
│ └── to_pdf
│ └── main.go # LaTeX to PDF conversion tool (renamed from to_pdf.go)
├── internal
│ ├── cli # All CLI-related code
│ ├── core # Core application logic (e.g., chatter)
│ ├── domain # Domain types, moved from 'common'
│ ├── patterns # Logic for loading/managing patterns
│ ├── plugins # All plugin logic (ai, db, etc.)
│ ├── server # The 'restapi' code, renamed for clarity
│ ├── tools # Non-binary tool utilities (converter, jina, youtube, etc.)
│ └── util # Specific, shared utilities (to be used sparingly)
├── data
│ ├── patterns/ # All pattern markdown files
│ └── strategies/ # All strategy json files
├── scripts
│ ├── docker
│ │ ├── Dockerfile
│ │ ├── docker-compose.yml
│ │ ├── start-docker.sh # Helper script to start docker-compose stack
│ │ └── README.md # Docker deployment documentation
│ ├── python_ui
│ │ ├── streamlit.py
│ │ └── requirements.txt
│ ├── pattern_generation
│ │ ├── extract_patterns.py
│ │ └── ...
│ └── setup_fabric.bat # Windows setup script
├── docs
│ ├── images/
│ ├── NOTES.md
│ └── Pattern_Descriptions/ # Documentation about patterns
├── web/ # (Svelte frontend, unchanged)
├── completions/ # (Shell completions, unchanged)
├── nix/ # (Nix environment, unchanged)
├── go.mod
├── go.sum
├── LICENSE
├── README.md
├── .gitignore
├── .envrc # (Must remain in root for direnv)
├── flake.nix # (Must remain in root for Nix)
└── flake.lock # (Must remain in root for Nix)
Key Changes Explained
-
✅ Introduction of
cmd/Directory- What: All executable entry points are moved to
cmd/subdirectories:- ✅
cmd/fabric/main.go- Main application entrypoint - ✅
cmd/code_helper/- Code analysis helper tool (moved fromplugins/tools/code_helper/) - ✅
cmd/to_pdf/- LaTeX to PDF conversion tool (moved fromplugins/tools/to_pdf/)
- ✅
- Why: This is a standard Go convention that clearly separates executable code from library code. It immediately shows new developers where all application entry points are and allows for additional binaries to be added cleanly in the future.
- What: All executable entry points are moved to
-
✅ Introduction of
internal/Directory- What: The majority of the Go packages (
cli,core,plugins,restapi,common) are moved underinternal/. - Why: The Go toolchain enforces that code within an
internaldirectory can only be imported by code within the same repository. This makes the application's core logic private and prevents other projects from creating unintended dependencies on it, clarifying that the project is an application, not a public library.
- What: The majority of the Go packages (
-
✅ Reorganizing and Renaming Packages
- ✅
restapi->internal/server: The package is renamed to describe its function (providing an HTTP server) rather than its implementation detail (REST). - ✅ Dissolving
common: Thecommonpackage has been broken up. Core data structures moved to a dedicatedinternal/domainpackage. Utility functions moved closer to the packages that use them, with truly shared utilities placed ininternal/util. - ✅
patternslogic: Code for loading and managing patterns consolidated intointernal/patterns. - ✅
plugins/tools->internal/tools: Non-binary tool utilities (converter, jina, youtube, etc.) moved tointernal/toolswhile binary tools moved tocmd/.
- ✅
-
✅ Consolidating Data, Scripts, and Docs
- ✅
data/: Thepatterns/andstrategies/directories, which are data assets consumed by the application, moved into adata/directory to distinguish them from source code. - ✅
scripts/: Helper scripts (Python, shell, batch files, Docker, etc.) grouped underscripts/to clarify their role as auxiliary tools:- ✅
scripts/docker/- Docker deployment files and helper scripts - ✅
scripts/python_ui/- Streamlit UI and Python dependencies - ✅
scripts/pattern_generation/- Pattern extraction and generation tools
- ✅
- ✅
docs/: Miscellaneous markdown files (NOTES.md, etc.) and related assets like images moved todocs/for better organization.
- ✅
Step-by-Step Migration Plan
-
✅ Create New Directories: Create the new top-level directories:
cmd/fabric,cmd/code_helper,cmd/to_pdf,internal,data,scripts, anddocs. -
✅ Move Binary Tools:
- ✅ Move
plugins/tools/code_helper/tocmd/code_helper/ - ✅ Move
plugins/tools/to_pdf/to_pdf.gotocmd/to_pdf/main.go(rename file) - ✅ Move remaining non-binary tools from
plugins/tools/tointernal/tools/
- ✅ Move
-
✅ Move Go Packages: Move the existing Go package directories (
cli,core,plugins,restapi) into the newinternal/directory. -
✅ Refactor and Rename Go Packages:
- ✅ Rename
internal/restapitointernal/server. - ✅ Break apart the
commonpackage, moving its contents into appropriate new locations likeinternal/domainandinternal/util.
- ✅ Rename
-
✅ Move Main Entry Point: Move
main.gotocmd/fabric/main.go. -
✅ Update Go Imports: This is a critical step. Use an IDE or tools like
goimportsto update all import paths in all.gofiles to reflect the new structure:- ✅
.../fabric/clibecomes.../fabric/internal/cli - ✅
.../fabric/plugins/tools/...becomes.../fabric/internal/tools/... - ✅ Update imports in all three binary tools (
fabric,code_helper,to_pdf)
- ✅
-
✅ Move Data Assets: Move the
patterns/andstrategies/directories into thedata/directory. Update the application code to read from these new paths. -
✅ Move Scripts and Docs:
- ✅ Move Docker files (
Dockerfile,docker-compose.yml) toscripts/docker/and create helper scripts and documentation - ✅ Move Python UI (
streamlit.pyandrequirements.txt) toscripts/python_ui/ - ✅ Move pattern generation scripts (
extract_patterns.py, etc.) toscripts/pattern_generation/ - ✅ Move batch files (
setup_fabric.bat) and other helper scripts intoscripts/ - ✅ Move documentation files like
NOTES.mdand theimagesdirectory intodocs/
- ✅ Move Docker files (
-
✅ Update Build and CI/CD Processes:
- ✅ Review and update any build scripts, Makefiles, or CI/CD workflows that reference old paths
- ✅ Update Dockerfile paths in
scripts/docker/Dockerfileto reference new locations - ✅ Update GitHub Actions to build all three binaries:
./cmd/fabric,./cmd/code_helper,./cmd/to_pdf - ✅ Update installation instructions in README.md to reflect new binary locations and Docker setup
- ✅ Specifically, update the "Update Version File and Create Tag" GitHub Action to work with the new file structure
-
✅ Test and Validate:
- ✅ Run
go build ./cmd/fabricto ensure the main application compiles correctly. - ✅ Run
go build ./cmd/code_helperto ensure the code helper tool compiles correctly. - ✅ Run
go build ./cmd/to_pdfto ensure the PDF tool compiles correctly. - ✅ Execute the full test suite with
go test ./.... - ✅ Run all applications and manually test the CLI, API, pattern loading, and helper tools to confirm all functionality is intact.
- ⚠️ Verify that external packaging and distribution methods, such as the Homebrew package, continue to build correctly after the reorganization. Note: The Homebrew formula will need to be updated to build from
./cmd/fabricinstead of the root directory. - ⚠️ Test that
go install github.com/danielmiessler/fabric/cmd/fabric@latestworks for all three tools.
- ✅ Run
✅ RESTRUCTURING COMPLETE
Status: All major restructuring tasks have been completed successfully as of the current PR.
Summary of Achievements:
- ✅ All 10 migration steps completed
- ✅ All 4 key structural changes implemented
- ✅ All binaries (
fabric,code_helper,to_pdf) compile successfully - ✅ Full test suite passes (all packages)
- ✅ Standard Go project layout achieved
- ✅
internal/commonpackage successfully dissolved intointernal/domainandinternal/util - ✅ All import paths updated to reflect new structure
- ✅ GitHub Actions workflows updated for new structure
Remaining Tasks (⚠️):
- External packaging verification (Homebrew, etc.) - requires separate testing
go installcommand verification - requires publishing/tagging
Required Homebrew Formula Update
I have a draft PR ready here: https://github.com/Homebrew/homebrew-core/pull/229472
The current Homebrew formula at https://raw.githubusercontent.com/ksylvan/homebrew-core/refs/heads/main/Formula/f/fabric-ai.rb will need to be updated to work with the new project structure:
Current formula build command:
def install
system "go", "build", *std_go_args(ldflags: "-s -w")
end
Required update for new structure:
def install
system "go", "build", *std_go_args(ldflags: "-s -w"), "./cmd/fabric"
end
Additional considerations:
- The formula currently builds from the root
main.go(which no longer exists) - After restructuring, it needs to build from
./cmd/fabric - The binary name and test commands should remain the same
- All three tools (
fabric,code_helper,to_pdf) could potentially be packaged, but the mainfabricbinary is the primary target
go install commands for new structure:
# Main fabric tool
go install github.com/danielmiessler/fabric/cmd/fabric@latest
# Additional tools (if desired)
go install github.com/danielmiessler/fabric/cmd/code_helper@latest
go install github.com/danielmiessler/fabric/cmd/to_pdf@latest
The project now follows standard Go conventions and is ready for review and merge.