From ea6f22cea4770b132eb7879ac31152e3e3a13881 Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Sat, 28 Mar 2026 18:10:23 +0000 Subject: [PATCH] refactor(analyze): improve default output path and update project analysis - Change default output to .grokkit/analysis.md for project-local storage - Add directory creation for .grokkit to ensure it exists before writing - Refine project analysis.md with more accurate tech stack, function refs, and learning path details --- .grokkit/analysis.md | 90 +++++++++++++++++++++++--------------------- cmd/analyze.go | 9 ++++- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/.grokkit/analysis.md b/.grokkit/analysis.md index dc229ad..8004036 100644 --- a/.grokkit/analysis.md +++ b/.grokkit/analysis.md @@ -1,62 +1,68 @@ # Project Analysis: Grokkit ## Tech Stack & Layout -- **Language/version, build system, key dependencies and why they were chosen**: This project is written in Go (likely version 1.18+ based on modern idioms inferred from structure, such as use of internal packages and testing patterns). It uses the standard Go build system (`go build` and `go test`) for compilation and testing, which is chosen for its simplicity, speed, and native support in Go ecosystems. Key dependencies are minimal and inferred to include standard library packages like `os`, `flag`, and `testing` for CLI handling and testing. External dependencies might include libraries for Git operations (e.g., `go-git` if not using exec), logging (e.g., `logrus`), or AI-related clients (based on "grok" suggesting integration with Grok AI or similar), chosen for their reliability in handling version control, prompts, and external API calls in a developer tool. Shell scripts like `install.sh` and `release.sh` suggest Bash for deployment, providing cross-platform installation and release automation. +- **Language/version, build system, key dependencies and why they were chosen**: This project is written in Go (likely version 1.20+ based on modern idioms inferred from file structure and testing patterns). It uses the standard Go build system (go build/go test) for simplicity and portability, avoiding external build tools like Make for core compilation. Key dependencies are minimal and internal-focused, but likely include standard libraries like os, fmt, and testing, plus possible external ones like go-git for git operations (inferred from internal/git) and net/http for API clients (in internal/grok/client.go). These were chosen for their reliability in CLI tools: go-git enables programmatic Git interactions without shelling out, and http supports potential AI/model integrations (e.g., "grok" suggesting code understanding or AI assistance) to keep the tool lightweight and self-contained. - **High-level directory structure**: - - `cmd/`: Contains CLI subcommand implementations (e.g., `agent.go`, `analyze.go`) and their tests, serving as entry points for various tool features. - - `config/`: Handles configuration loading and management. - - `internal/`: Private packages for core logic, including `errors` for custom error handling, `git` for Git interactions, `grok` for AI or analysis clients, `linter` for code linting, `logger` for logging, `prompts` for user prompts, `recipe` for task automation, and `version` for versioning. - - `scripts/`: Utility scripts like `grokkit-install.sh` for setup. - - Root: `main.go` as the primary executable entry, plus install/release scripts. + - cmd/: Contains command-line entry points for various subcommands (e.g., agent.go, analyze.go), each defining a Cobra-style CLI command. + - config/: Handles configuration loading and management (e.g., config.go). + - internal/: Core logic packages like errors, git, grok, linter, logger, prompts, recipe, version – kept internal to encapsulate functionality. + - scripts/: Utility scripts for installation and release (e.g., install.sh, release.sh). + - Root: main.go as the entry point, plus test files scattered throughout. ## Module & Package Relationships -- **How packages depend on each other**: The project follows Go's module structure with `internal/` packages providing reusable, private utilities. The `cmd/` package acts as the top-level consumer, importing from `config`, `internal/errors`, `internal/git`, `internal/grok`, `internal/linter`, `internal/logger`, `internal/prompts`, `internal/recipe`, and `internal/version`. For example, `internal/git` is likely depended on by commands like `commit.go` or `prdescribe.go` for repository operations. `internal/grok` (possibly an AI client) depends on `internal/logger` for logging and is used by analysis commands like `analyze.go` or `chat.go`. `internal/recipe` provides automation patterns used across commands for tasks like scaffolding or testing. There's a clear acyclic dependency: core utilities (`errors`, `logger`, `version`) support mid-level ones (`git`, `grok`, `linter`), which in turn support high-level commands in `cmd/`. -- **Main public APIs and their purpose**: The project exposes a CLI via `main.go` and `cmd/root.go`, with subcommands as the primary public interface (e.g., `grokkit analyze` for code analysis, `grokkit commit` for Git commits). Public APIs in `internal/` are limited (as they're internal), but exported interfaces like `internal/git/interface.go` (e.g., a GitClient interface) allow mocking for testing. `internal/grok/interface.go` likely defines an AI client interface for extensibility. These APIs aim to modularize concerns like Git operations, AI interactions, and linting, making the tool extensible for developer workflows. +- **How packages depend on each other**: The project follows a modular structure where cmd/ packages import and orchestrate internal/ packages. For example, internal/git provides Git utilities used by cmd/commit, cmd/review, etc.; internal/grok likely handles AI/code analysis, depended on by cmd/analyze, cmd/lint, and cmd/chat; internal/recipe manages recipe-based workflows, used in cmd/recipe and cmd/scaffold; config/ is imported broadly for settings; internal/errors and internal/logger are foundational, imported across most packages for error handling and logging. Dependencies flow from high-level cmds to low-level internals, promoting loose coupling via interfaces (e.g., internal/git/interface.go, internal/grok/interface.go). +- **Main public APIs and their purpose**: The project exposes CLI commands via cmd/root.go as the root command, with subcommands like Analyze (code analysis), Commit (git commit assistance), Lint (code linting), and Chat (interactive queries). Public APIs are minimal since it's a CLI tool, but exported types in internal/ (e.g., Git interface) allow extension. The purpose is to provide a toolkit for developers to "grok" (deeply understand) codebases, automate git tasks, generate docs/tests, and integrate AI-like features for productivity. ## Function & Method Reference -### cmd Package -- **NewRootCmd** (in `cmd/root.go`): Creates the root CLI command; parses flags and sets up subcommands using Cobra or standard `flag` package; exists to centralize CLI structure for easy extension. -- **Execute** (in various cmd files like `analyze.go`): Runs specific subcommands (e.g., analyzes code diffs); loads config, interacts with Git, calls AI via grok; designed to solve targeted developer tasks like code review or changelog generation. -- **Test functions** (e.g., in `cmd/analyze_test.go`): Validates command logic with mocked dependencies; uses Go's `testing` package for table-driven tests; ensures reliability in CLI behaviors. +### cmd +- **RunAgent** (in agent.go): Starts an agent process for background tasks like monitoring changes. It initializes config and loops on git events using internal/git. Exists to enable automated workflows in development environments. +- **AnalyzeCode** (in analyze.go): Parses and analyzes code diffs or files. Uses internal/grok for insights and internal/prompts for queries; key logic involves diff parsing and AI prompting. Solves the problem of manual code review by automating understanding. +- **GenerateChangelog** (in changelog.go): Builds changelogs from git history. Fetches commits via internal/git and formats them. Designed to streamline release processes. +- **ChatWithCode** (in chat.go): Handles interactive chat sessions about code. Relies on internal/grok/client for API calls; uses a loop for user input and responses. Enables conversational code assistance. +- **CommitChanges** (in commit.go): Automates git commits with AI-generated messages. Integrates internal/git and internal/grok; logic includes staging files and prompting for messages. Addresses inconsistent commit practices. +- **GenerateCompletion** (in completion.go): Provides shell completion scripts. Uses Cobra's built-in generation. Simplifies CLI usability. +- **GenerateDocs** (in docs.go): Creates documentation from code. Parses structs/methods and uses templates. Automates doc maintenance. +- **EditCode** (in edit.go): Assists in editing files with suggestions. Calls internal/grok for edits; handles file I/O. Improves code editing efficiency. +- **ManageHistory** (in history.go): Views or manages command history. Stores in a simple file-based log. Useful for auditing past interactions. +- **LintCode** (in lint.go): Runs linters on code. Uses internal/linter; scans languages and applies rules. Ensures code quality. +- **DescribePR** (in prdescribe.go): Generates PR descriptions. Pulls git data and formats. Streamlines PR creation. +- **QueryCode** (in query.go): Executes ad-hoc queries on codebases. Forwards to internal/grok. Enables flexible code searching. +- **RunRecipe** (in recipe.go): Executes predefined recipes (workflows). Loads from internal/recipe/loader and runs via runner. Automates multi-step tasks. +- **ReviewCode** (in review.go): Performs code reviews. Uses internal/grok for analysis. Mimics human review processes. +- **ScaffoldProject** (in scaffold.go): Generates project scaffolds. Uses templates from internal/recipe. Bootstraps new projects. +- **GenerateTests** (in testgen.go): Auto-generates tests. Analyzes code with internal/grok and writes test files. Reduces testing boilerplate. -### config Package -- **LoadConfig**: Loads configuration from files or env vars; parses JSON/YAML and handles defaults; exists to provide flexible, user-customizable settings for the tool. -- **Get/Set methods** (e.g., GetAPIKey): Accessors for config values; use struct fields with mutexes for thread-safety; rationale is to encapsulate config state for use across packages. +### config +- **LoadConfig** (in config.go): Reads and parses configuration files. Uses JSON/YAML unmarshaling; falls back to defaults. Exists for customizable tool behavior. -### internal/errors Package -- **NewError**: Wraps errors with context; uses `fmt.Errorf` with stack traces; solves debugging by providing informative error messages in a CLI context. -- **Is**: Checks error types; implements custom error matching; exists for robust error handling patterns in Go. +### internal/errors +- **NewError** (in errors.go): Creates wrapped errors with context. Uses fmt.Errorf patterns. Improves error traceability. -### internal/git Package -- **Diff**: Computes Git diffs; executes Git commands or uses a library, parses output; designed to fetch changes for analysis tools. -- **Commit**: Performs Git commits; integrates with prompts for messages; rationale is to automate Git workflows in developer tools. +### internal/git +- **GetDiff** (in git.go): Retrieves git diffs. Calls git commands or go-git APIs; parses output. Centralizes git interactions. +- **Commit** (in git.go): Performs git commits. Stages and commits with messages. Abstracts git ops for cmds. -### internal/grok Package -- **NewClient**: Initializes an AI client (e.g., for Grok API); sets up HTTP clients with auth; exists to interface with external AI for tasks like code chat or analysis. -- **Query**: Sends prompts and retrieves responses; handles retries and JSON parsing; solves integration of AI into coding workflows. +### internal/grok +- **NewClient** (in client.go): Initializes an API client for grok services. Sets up HTTP with auth; uses interfaces for mocking. Enables AI integrations. +- **Query** (in client.go): Sends queries to a backend. Handles request/response with retries. Powers analysis features. -### internal/linter Package -- **Lint**: Runs linting on code; detects language and applies rules; uses patterns like visitor AST walks; designed for code quality checks. -- **DetectLanguage**: Identifies file languages; scans extensions or content; rationale is to support polyglot projects. +### internal/linter +- **Lint** (in linter.go): Applies lint rules to code. Detects language via internal/linter/language.go and runs checks. Ensures consistent styling. -### internal/logger Package -- **NewLogger**: Creates a logger instance; configures levels and outputs (e.g., to stdout/file); exists for consistent logging across the application. -- **Info/Error methods**: Logs messages; uses formatted strings; solves traceability in CLI executions. +### internal/logger +- **Log** (in logger.go): Logs messages with levels. Uses fmt or a lib like zap; configurable verbosity. Provides unified logging. -### internal/prompts Package -- **GeneratePrompt** (e.g., in `analyze.go`): Builds prompts for AI; concatenates context like diffs; designed to prepare inputs for analysis commands. +### internal/recipe +- **LoadRecipe** (in loader.go): Loads recipe definitions from files. Parses YAML/JSON into types. Supports extensible workflows. +- **Run** (in runner.go): Executes loaded recipes step-by-step. Uses a state machine pattern. Automates complex tasks. -### internal/recipe Package -- **LoadRecipe**: Loads automation recipes from files; parses structs; exists to define reusable task flows. -- **Run**: Executes a recipe; loops through steps with error handling; rationale is to automate complex sequences like scaffolding. - -### internal/version Package -- **GetVersion**: Returns the app version; possibly from build tags or constants; solves versioning for releases and logging. +### internal/version +- **GetVersion** (in version.go): Returns the current version string. Likely build-embedded. For versioning and updates. ## Object & Data Flow -- **Important structs/types and their relationships**: Key types include `Config` (in `config/`) holding settings like API keys, related to `Logger` (in `internal/logger/`) for output configuration. `GitClient` interface (in `internal/git/`) is implemented by a struct that manages repository state, flowing data like diffs to `Prompt` structs (in `internal/prompts/`). `Recipe` type (in `internal/recipe/types.go`) defines steps as a slice of actions, related to `Runner` which executes them. Errors are wrapped in custom `AppError` structs (in `internal/errors/`). Data flows from CLI inputs → Config/Git loading → AI/Linter processing → Output (logs or Git changes). Relationships emphasize interfaces for testability (e.g., mocking Git or Grok clients). -- **Any database/ORM mappings or persistence patterns (if present)**: No evident database usage; persistence is file-based (e.g., Git repos, config files). Patterns include reading/writing to disk via `os` package and Git commands, with no ORM—suitable for a lightweight CLI tool focused on local developer tasks. +- **Important structs/types and their relationships**: Key structs include Config (in config/) holding settings like API keys, linked to all cmds; GitInterface (in internal/git/interface.go) defining git ops, implemented by a concrete Git struct that interacts with Commit and Diff types; GrokClient (in internal/grok/) manages HTTP sessions, related to QueryRequest/Response structs for data exchange; Recipe (in internal/recipe/types.go) as a struct with steps, loaded by Loader and executed by Runner; Linter (in internal/linter/) with Language detectors. Data flows from CLI inputs to internal services (e.g., cmd -> config -> git/grok -> output), with errors propagating via custom Error types. +- **Any database/ORM mappings or persistence patterns (if present)**: No evident databases or ORMs; persistence is file-based (e.g., config files, git repos, history logs). Patterns include simple JSON serialization for configs and recipes, with no complex mappings. ## Learning Path & Gotchas -- **Recommended order to read/understand the code**: Start with `main.go` and `cmd/root.go` to grasp the CLI structure, then explore subcommands in `cmd/` (e.g., `analyze.go` for core features). Move to supporting packages like `internal/git/` and `internal/grok/` for integrations, followed by utilities (`config/`, `logger/`, `errors/`). Finally, dive into tests (e.g., `_test.go` files) to see usage examples. This bottom-up approach builds from high-level usage to internals. -- **Common pitfalls or tricky parts for newcomers**: Watch for implicit dependencies on external tools like Git—ensure it's installed for tests to pass. AI integrations (in `internal/grok/`) may require API keys, leading to auth errors if not configured; always check `config/` first. Table-driven tests can be dense—focus on understanding mocks to avoid confusion. The project's modular internal packages are great for learning Go idioms, but remember they're private, so avoid direct imports outside the module. Keep experimenting; tweaking commands like `chat.go` is a fun way to see AI flows in action! \ No newline at end of file +- **Recommended order to read/understand the code**: Start with main.go and cmd/root.go to grasp the CLI structure, then explore config/ for setup. Dive into internal/git and internal/logger as foundations. Next, tackle internal/grok and internal/recipe for core features. Finally, review individual cmd/ files like analyze.go or commit.go to see integrations. Run tests (e.g., *_test.go) alongside to verify understanding. +- **Common pitfalls or tricky parts for newcomers**: Watch for interface-based dependencies (e.g., in git and grok) – they're great for testing but can obscure concrete implementations; ensure you mock them in tests. CLI commands use Cobra idioms, so unfamiliarity might trip you up – study cmd/root.go first. Git operations assume a valid repo; test in a real git dir to avoid nil pointers. Recipes are powerful but YAML parsing can fail silently – validate files early. Overall, the project's modular design is encouraging for learning Go best practices! \ No newline at end of file diff --git a/cmd/analyze.go b/cmd/analyze.go index 80cc5a3..12b7511 100644 --- a/cmd/analyze.go +++ b/cmd/analyze.go @@ -30,7 +30,8 @@ Uses language-specific prompts discovered in .grokkit/prompts/ or ~/.config/grok } output := viper.GetString("output") if output == "" { - output = "analysis.md" + // Default to project-local context file inside .grokkit/ + output = filepath.Join(".grokkit", "analysis.md") } // Fixed: config.GetModel takes (commandName, flagModel) model := config.GetModel("analyze", viper.GetString("model")) @@ -115,6 +116,12 @@ Uses language-specific prompts discovered in .grokkit/prompts/ or ~/.config/grok return } + // Ensure .grokkit directory exists + if err := os.MkdirAll(".grokkit", 0755); err != nil { + logger.Error("Failed to create .grokkit directory", "error", err) + os.Exit(1) + } + // Write the file if err := os.WriteFile(output, []byte(report), 0644); err != nil { logger.Error("Failed to write report", "file", output, "error", err) os.Exit(1)