diff --git a/.athignore b/.athignore index c6fa5b1..02f1e02 100644 --- a/.athignore +++ b/.athignore @@ -340,7 +340,9 @@ docs/_site/ ############################################################################### # ATHANOR PROJECT FILES ############################################################################### +!/.ath_materials/**/* /.ath_materials/project_graph.json +/.ath_materials/project_settings.json ############################################################################### # PROJECT FILES diff --git a/.gitignore b/.gitignore index f9076d8..ea5591f 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,12 @@ Thumbs.db codebase.md # Temporary folder -/temp-folder \ No newline at end of file +/temp-folder + +############################################################################### +# ATHANOR PROJECT FILES +############################################################################### +/.ath_materials/**/* +!/.ath_materials/prompts/ +!/.ath_materials/prompts/**/* +!/.ath_materials/project_settings.json \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 42ddf02..c6b27f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,22 @@ and this project aims to adhere to [Semantic Versioning](https://semver.org/spec _(Future changes will go here)_ +## [0.7.5] - 2025-06-28 + +### Added + +- An option is now available in the project creation dialog to append default Athanor ignore rules to the project's `.gitignore` file. ([81b0a65](https://github.com/lacerbi/athanor/commit/81b0a65)) +- Style matching has been introduced to writing prompts to improve the consistency of AI-generated content. ([456ed28](https://github.com/lacerbi/athanor/commit/456ed28)) + +### Changed + +- Updated and expanded the main `PROJECT.md` documentation. ([1f5ceac](https://github.com/lacerbi/athanor/commit/1f5ceac)) +- Created a new `docs/design` directory to better organize design specification documents. ([bb0d6a4](https://github.com/lacerbi/athanor/commit/bb0d6a4)) + +### Fixed + +- Corrected various style comments in the codebase. ([16a92a8](https://github.com/lacerbi/athanor/commit/16a92a8)) + ## [0.7.4] - 2025-06-24 ### Added diff --git a/PROJECT.md b/PROJECT.md index 3a8e3cf..a714657 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -4,66 +4,96 @@ Athanor is an **Electron-based desktop application** that integrates AI coding assistants into a developer’s workflow. Its primary goal is to streamline two main flows: -1.  **Prompt Creation & Refinement** +1. **Intelligent Prompt Creation & Refinement** -    - The user selects relevant files/folders within a dynamic file explorer. -    - Athanor then generates prompt text (optionally using multiple specialized “prompt templates” or “task templates”). -    - The user copies this prompt into an AI assistant (e.g., ChatGPT, Bard, Claude, etc.). -    - **Tooltips**: Throughout the application, contextual help is provided via tooltips that appear when hovering over buttons, controls, and interface elements. This is the primary method for providing short helper information without cluttering the UI. + - The user describes a task and manually selects a few key "seed" files. + - Athanor's **Relevance Engine** automatically analyzes the project—leveraging dependencies, Git history, file mentions, and user activity—to identify and include other relevant "neighboring" files. + - Athanor then generates a comprehensive, context-rich prompt using specialized templates. + - The user copies this prompt into an AI assistant (e.g., ChatGPT, Claude, Gemini, etc.). + - **Tooltips**: Throughout the application, contextual help is provided via tooltips that appear when hovering over buttons, controls, and interface elements. This is the primary method for providing short helper information without cluttering the UI. -2.  **Applying AI-Generated Changes** -    - The user copies the AI’s response from the assistant back into the clipboard. -    - Athanor parses custom XML-like commands (e.g., `...`) to figure out how to create, modify, or delete specific files. -    - The user can preview diffs, accept or reject each change, and finalize changes to disk. +2. **Applying AI-Generated Changes** + - The user copies the AI’s response from the assistant back into the clipboard. + - Athanor parses custom XML-like commands (e.g., `...`) to figure out how to create, modify, or delete specific files. + - The user can preview diffs, accept or reject each change, and finalize changes to disk. ### Key Features -1.  **Dynamic File Explorer** +1. **Intelligent Context Builder (Relevance Engine)** -    - Displays a tree of the chosen project directory. -    - Tracks file line counts (for text files) and uses `.athignore` rules to hide excluded paths. -    - Allows multi-select of files and folders; selecting a folder auto-selects its descendants unless hidden. -    - Automatically updates when files are added or removed on disk (Chokidar watchers). + - At the core of Athanor is a sophisticated `RelevanceEngineService.ts` that automatically discovers contextually relevant files, going far beyond manual selection. + - It uses a two-phase scoring engine fueled by multiple heuristics: + - **Code Analysis**: Direct dependencies in languages like JavaScript/TypeScript and Python are resolved using `DependencyResolver.ts` and `DependencyScanner.ts`. + - **Git History**: `GitService.ts` analyzes commit history to find files that are frequently changed together. + - **Project Graph**: Identifies "hub files" (highly interconnected) and files that mention each other. + - **User Activity**: `UserActivityService.ts` tracks recently edited files, giving them higher relevance. + - **Task Description**: Natural language analysis of the task description identifies keywords and direct path mentions. + - The engine produces a token-budgeted list of "neighboring files" that are included in the prompt, providing the AI with rich, relevant context. This state is managed in the UI by `contextStore.ts`. -2.  **Ignore Rules Management** +2. **Project-Wide Analysis & Caching** -    - By default, Athanor automatically processes rules from the project's `.gitignore` file. This behavior can be toggled in the project settings. -    - The `.athignore` file is used for Athanor-specific ignore rules or for overriding `.gitignore` rules (e.g., re-including a file with an exception rule like `!path/to/file`). -    - The main process (via `ignoreRulesManager.ts`) uses the `ignore` library to handle advanced wildcard matching, including an 'ignore all by name' option available via the file explorer's context menu. + - On opening a project, Athanor runs a background analysis using a `projectAnalysisWorker.ts` to build a comprehensive dependency and relationship graph of the entire codebase. + - This graph, managed by `ProjectGraphService.ts`, powers the Relevance Engine. + - The resulting graph is cached in the `.ath_materials` folder as `project_graph.json` to ensure fast subsequent loads. The analysis automatically re-runs when file changes are detected after a period of user inactivity. -3.  **Task & Prompt Management** +3. **Direct LLM API Integration (Optional)** + + - While the core workflow is API-key-free, Athanor includes an optional feature for direct communication with LLM providers (OpenAI, Anthropic, Gemini, Mistral). + - API keys are stored securely using Electron's `safeStorage` via the `ApiKeyServiceMain`. + - The `LLMServiceMain`, client adapters, and extensive model configuration (`electron/modules/llm/main/config.ts`) manage these interactions. + +4. **Git Integration** + + - Athanor deeply integrates with Git repositories via `GitService.ts`. + - It uses Git to find recently committed files and identify files that share commit history, which are key signals for the Relevance Engine. + - The service can also retrieve commit history for specific files. + +5. **Dynamic File Explorer** + + - Displays a tree of the chosen project directory. + - Tracks file line counts (for text files) and uses `.athignore` rules to hide excluded paths. + - Allows multi-select of files and folders; selecting a folder auto-selects its descendants unless hidden. + - Automatically updates when files are added or removed on disk (Chokidar watchers). + +6. **Ignore Rules Management** + + - By default, Athanor automatically processes rules from the project's `.gitignore` file. This behavior can be toggled in the project settings. + - The `.athignore` file is used for Athanor-specific ignore rules or for overriding `.gitignore` rules (e.g., re-including a file with an exception rule like `!path/to/file`). + - The main process (via `ignoreRulesManager.ts`) uses the `ignore` library to handle advanced wildcard matching, including an 'ignore all by name' option available via the file explorer's context menu. + +7. **Task & Prompt Management** - Multiple “task tabs,” managed by `workbenchStore.ts`, each containing: - A **task description**: plain-text or markdown instructions. - An **AI output** area: displays the generated prompt for the user to copy. - A **context** field: for ephemeral data (like partial commit messages or specific instructions); includes context suggestions based on task content (`contextDetection.ts`). - - A **selected files list** which lists selected files in order of relevance; note that separate task tabs have distinct selected files lists. + - A **selected files list** which holds the user's explicitly selected files for that task. This list acts as a "seed" for the Relevance Engine to discover additional relevant files. Each task tab maintains its own distinct list of selected files. - Prompt (`prompt_*.xml`) and Task (`task_*.xml`) templates live in `resources/prompts/` and are loaded on application startup via `promptService.ts`. - The user can dynamically switch between prompt/task _variants_ (e.g., different modes like “Query,” “Coder,” “Architect” or task variations like “Default”, “LaTeX”) using context menus in the Action Panel (`PromptContextMenu.tsx`, `TaskContextMenu.tsx`). -4.  **Clipboard & Code Changes** +8. **Clipboard & Code Changes** -    - Code blocks or raw text can be copied with consistent line endings and optional code fences. -    - The “apply changes” flow scans for XML blocks from the AI’s output, extracts file operations, and shows them in a diff panel. + - Code blocks or raw text can be copied with consistent line endings and optional code fences. + - The “apply changes” flow scans for XML blocks from the AI’s output, extracts file operations, and shows them in a diff panel. -5.  **Project Setup & Supplementary Materials** +9. **Project Setup & Supplementary Materials** -    - On folder selection, Athanor can create a `.athignore` file if it does not exist. -    - A hidden `.ath_materials` folder is automatically created to store extra references (like doc fragments). -    - If a `.gitignore` file exists, its rules are automatically applied by default. + - On folder selection, Athanor can create a `.athignore` file if it does not exist. + - A hidden `.ath_materials` folder is automatically created to store extra references (like doc fragments). + - If a `.gitignore` file exists, its rules are automatically applied by default. -6.  **User Interface Layout** +10. **User Interface Layout** -    - **Left Panel**: The file explorer with watchers, expansions, checkboxes, and a context menu (right-click to ignore items). -    - **Right Panel**: Tabs for different tasks, a file viewer, and the “Apply Changes” panel that lists AI-proposed modifications. Action Panel controls prompt generation, preset tasks, and configuration toggles (Smart Preview, Include File Tree, Documentation Format). -    - A bottom **log panel** shows messages and clickable events for debugging or re-inspection (`logStore.ts`). + - **Left Panel**: The file explorer with watchers, expansions, checkboxes, and a context menu (right-click to ignore items). + - **Right Panel**: Tabs for different tasks, a file viewer, and the “Apply Changes” panel that lists AI-proposed modifications. Action Panel controls prompt generation, preset tasks, and configuration toggles (Smart Preview, Include File Tree, Documentation Format). + - A bottom **log panel** shows messages and clickable events for debugging or re-inspection (`logStore.ts`). -7.  **Preset Tasks** +11. **Preset Tasks** -    - Pre-defined tasks (e.g., 'AI Summary', 'Refactor Code') available in the Action Panel, loaded from `task_*.xml` files. + - Pre-defined tasks (e.g., 'AI Summary', 'Refactor Code') available in the Action Panel, loaded from `task_*.xml` files. -8.  **Drag and Drop** -    - File paths can be dragged from the file explorer and dropped into the Task Description or Context text areas (`useFileDrop.ts`). +12. **Drag and Drop** + - File paths can be dragged from the file explorer and dropped into the Task Description or Context text areas (`useFileDrop.ts`). ## Tech Stack @@ -71,58 +101,73 @@ Athanor is an **Electron-based desktop application** that integrates AI coding a Athanor follows Electron's recommended **“secure by default”** pattern, separating logic between **main** and **renderer** processes: -1.  **Main Process (Electron)** - -    - **`main.ts`**: Application startup, window creation, and core event handling. It creates singleton instances of services like `FileService` and `SettingsService`. -    - **IPC Handlers**: -      - `ipcHandlers.ts` collects all handlers from `handlers/` (e.g., `coreHandlers.ts`, `fileOperationHandlers.ts`, `fileWatchHandlers.ts`) into a single registration function. -      - Handlers receive the `FileService` instance and delegate all file system operations to it, ensuring a single point of control. -    - **File Service (`electron/services/FileService.ts`)**: -      - Maintains a global “base directory” to represent the open project folder. -      - Performs all file reads/writes, folder creation, and error handling using Node's `fs/promises` and Chokidar for watching. -      - Integrates with `ignoreRulesManager.ts` to handle file exclusion logic. -      - Cleans up watchers on application exit or directory change. -      - Delegates pure path manipulation logic to `PathUtils.ts`. -    - **Ignore Rules Manager (`ignoreRulesManager.ts`):** -      - Loads `.athignore` and `.gitignore` files for file exclusion. -      - Provides advanced matching logic using the `ignore` npm library. -    - **Path Utilities (`electron/services/PathUtils.ts`):** -      - Provides a set of pure, static functions for all path normalization (Unix-style internally), conversion, and manipulation logic. - -2.  **Renderer Process (React)** -    - **`src/services/fileSystemService.ts`**: -      - High-level logic for building a file tree from data returned via IPC from the main process's `FileService`. -      - Normalizes line endings and counts file lines for text files. -      - Applies ignoring rules or merges them into the UI structure. -    - **React Components** (`src/components/*`): -      - **`AthanorApp.tsx`** and **`MainLayout.tsx`** define the overall UI layout: -        - File explorer on the left (expanded by `FileExplorer.tsx`). -        - Action tabs (workbench, viewer, apply-changes) on the right. -      - `ApplyChangesPanel.tsx` is the UI for viewing & applying AI-proposed code modifications. -      - `FileContextMenu.tsx` handles ignoring items and possibly other file actions from the explorer. -      - `ActionPanel.tsx` controls prompt generation and preset tasks, hooking into `promptStore.ts`, `workbenchStore.ts`, and `taskStore.ts`. -    - **Global Stores** (Zustand) in `src/stores/*`: -      - `fileSystemStore.ts`: Tracks selected files/folders, previews, and tree data. -      - `promptStore.ts`: Manages loaded prompt definitions & active prompt variants. -      - `workbenchStore.ts`: Maintains multiple “task tabs” used to hold user tasks & AI outputs. -      - `applyChangesStore.ts`: Handles the ephemeral list of file changes returned by AI, letting the user apply or reject them. -      - `taskStore.ts`: Manages loaded task definitions & active task variants. -    - **Utilities** (`src/utils/*`): -      - `fileTree.ts`: Functions for sorting & iterating nested file structures. -      - `constants.ts`: Shared config (e.g., thresholds for large files). -      - `extractTagContent.ts`: Helpers for parsing XML segments. -      - Others (e.g., `buildPrompt.ts`, `tokenCount.ts` (using `js-tiktoken`)) serve specialized tasks like AI prompt assembly or token counting. +1. **Main Process (Electron)** + + - **`main.ts`**: Application startup, window creation, and core event handling. It creates singleton instances of services like `FileService` and `SettingsService`. + - **IPC Handlers**: + - `ipcHandlers.ts` collects all handlers from `handlers/` (e.g., `coreHandlers.ts`, `fileOperationHandlers.ts`, `fileWatchHandlers.ts`) into a single registration function. + - Handlers receive the `FileService` instance and delegate all file system operations to it, ensuring a single point of control. + - **File Service (`electron/services/FileService.ts`)**: + - Maintains a global “base directory” to represent the open project folder. + - Performs all file reads/writes, folder creation, and error handling using Node's `fs/promises` and Chokidar for watching. + - Integrates with `ignoreRulesManager.ts` to handle file exclusion logic. + - Cleans up watchers on application exit or directory change. + - Delegates pure path manipulation logic to `PathUtils.ts`. + - **Ignore Rules Manager (`ignoreRulesManager.ts`):** + - Loads `.athignore` and `.gitignore` files for file exclusion. + - Provides advanced matching logic using the `ignore` npm library. + - **Path Utilities (`electron/services/PathUtils.ts`):** + - Provides a set of pure, static functions for all path normalization (Unix-style internally), conversion, and manipulation logic. + - **Git Service (`electron/services/GitService.ts`)**: + - Executes `git` commands to analyze the repository for the Relevance Engine (e.g., shared commit history, recent changes). It is a core component of the context-building heuristics. + - **Project Graph Service (`electron/services/ProjectGraphService.ts`)**: + - Runs in a background worker thread to analyze the entire project. + - Builds a graph of dependencies, file mentions, and Git-based relationships, which is then cached. This graph is the primary data source for the Relevance Engine. + - **Relevance Engine Service (`electron/services/RelevanceEngineService.ts`)**: + - The central service for intelligent context discovery. It orchestrates `GitService`, `ProjectGraphService`, and other utilities to score all project files based on their relevance to the current task. + - **User Activity Service (`electron/services/UserActivityService.ts`)**: + - A lightweight service that listens for file changes from `FileService` to identify which files are being actively edited, providing a real-time relevance signal. + - **Dependency Resolver/Scanner (`DependencyResolver.ts`, `DependencyScanner.ts`)**: + - Utilities used by the Project Graph Service to perform language-aware dependency analysis for JavaScript/TypeScript and Python. + - **LLM & API Key Services (`electron/modules/`)**: + - A dedicated module for handling optional, direct LLM API calls (`LLMServiceMain`) and secure storage of API keys (`ApiKeyServiceMain`). + +2. **Renderer Process (React)** + - **`src/services/fileSystemService.ts`**: + - High-level logic for building a file tree from data returned via IPC from the main process's `FileService`. + - Normalizes line endings and counts file lines for text files. + - Applies ignoring rules or merges them into the UI structure. + - **React Components** (`src/components/*`): + - **`AthanorApp.tsx`** and **`MainLayout.tsx`** define the overall UI layout: + - File explorer on the left (expanded by `FileExplorer.tsx`). + - Action tabs (workbench, viewer, apply-changes) on the right. + - `ApplyChangesPanel.tsx` is the UI for viewing & applying AI-proposed code modifications. + - `FileContextMenu.tsx` handles ignoring items and possibly other file actions from the explorer. + - `ActionPanel.tsx` controls prompt generation and preset tasks, hooking into `promptStore.ts`, `workbenchStore.ts`, and `taskStore.ts`. + - **Global Stores** (Zustand) in `src/stores/*`: + - `fileSystemStore.ts`: Tracks selected files/folders, previews, and tree data. + - `promptStore.ts`: Manages loaded prompt definitions & active prompt variants. + - `workbenchStore.ts`: Maintains multiple “task tabs” used to hold user tasks & AI outputs. + - `applyChangesStore.ts`: Handles the ephemeral list of file changes returned by AI, letting the user apply or reject them. + - `contextStore.ts`: Manages the state for the intelligent context builder, tracking user-selected "seed" files and the "neighboring" files automatically discovered by the Relevance Engine. + - `taskStore.ts`: Manages loaded task definitions & active task variants. + - **Utilities** (`src/utils/*`): + - `fileTree.ts`: Functions for sorting & iterating nested file structures. + - `constants.ts`: Shared config (e.g., thresholds for large files). + - `extractTagContent.ts`: Helpers for parsing XML segments. + - Others (e.g., `buildPrompt.ts`, `tokenCount.ts` (using `js-tiktoken`)) serve specialized tasks like AI prompt assembly or token counting. ### Technology Stack - **Electron v33+**: Powers the main/renderer separation. The main process is responsible for file system access, watchers, and launching the application. The renderer hosts the React UI. -- **React 18+**: Renders the front-end UI, including file explorer trees, task/prompt panels, and the changes diff viewer. +- **React 19+**: Renders the front-end UI, including file explorer trees, task/prompt panels, and the changes diff viewer. - **TypeScript 5+**: Provides strict typing across main and renderer processes. -- **Node.js** (latest LTS): Provides the backend runtime for the main process. +- **Node.js** (latest LTS): Provides the backend runtime for the main process, including **Worker Threads** for background project analysis. - **Zustand**: Maintains local state in separate stores—e.g., file selection state (`fileSystemStore.ts`), prompt management (`promptStore.ts`), multi-tab workbench (`workbenchStore.ts`), task management (`taskStore.ts`), etc. - **Chokidar**: Watches the local file system for changes in the open folder. - **ignore**: Reads `.athignore` and `.gitignore` to filter out hidden or excluded files in the Explorer. - **js-tiktoken**: Used for accurate token counting in prompts. +- **LLM SDKs**: Optional integration with `@anthropic-ai/sdk`, `@google/genai`, `openai`. - **Webpack & electron-forge**: Build, package, and run the Electron application. - **TailwindCSS 3 + Lucide Icons**: Provides a flexible styling system and icon library for a clean UI. - **Material-UI (MUI) 5**: Partially integrated for certain UI elements (used in some components). @@ -136,42 +181,43 @@ Athanor follows Electron's recommended **“secure by default”** pattern, sepa - **Database or Extended Persistence**: If user data or historical tasks become more complex, a storage layer might be beneficial. - **Refined Prompt Templates**: Additional dynamic placeholders or user-defined placeholders. - **Advanced Visual Diffs**: Implement more advanced color-coded diffs for large or complex changes. +- **Extending the Relevance Engine**: Incorporate more advanced heuristics for context discovery, such as semantic code search or analysis of runtime behavior. - **Security**: Further refine path sanitization and sandboxing, especially if running untrusted AI output. ### Action Points -1.  When working with direct file system operations: +1. When working with direct file system operations: -    - Use **`FileService.ts`** methods in main process code via the singleton instance. -    - Access through IPC handlers defined in `handlers/` directory. -    - Handle errors appropriately at each layer. + - Use **`FileService.ts`** methods in main process code via the singleton instance. + - Access through IPC handlers defined in `handlers/` directory. + - Handle errors appropriately at each layer. -2.  When building UI features: +2. When building UI features: -    - Use `fileSystemService.ts` for file tree operations in the renderer. -    - Access through React hooks and components. -    - Handle loading states and error conditions. + - Use `fileSystemService.ts` for file tree operations in the renderer. + - Access through React hooks and components. + - Handle loading states and error conditions. -3.  For new file system features: +3. For new file system features: -    - Add core functionality to **`FileService.ts`** or **`PathUtils.ts`** as appropriate. -    - Create corresponding IPC handlers in `handlers/`. -    - Add interface methods to `preload.ts`. -    - Implement high-level operations in `fileSystemService.ts` if needed for the UI. + - Add core functionality to **`FileService.ts`** or **`PathUtils.ts`** as appropriate. + - Create corresponding IPC handlers in `handlers/`. + - Add interface methods to `preload.ts`. + - Implement high-level operations in `fileSystemService.ts` if needed for the UI. -4.  TypeScript & Global Types: +4. TypeScript & Global Types: -    - Regularly open and double-check **`src/types/global.d.ts`** to avoid TypeScript mistakes. -    - This file extends the `window` interface to expose `window.fileSystem`, houses core global interfaces (like `FileOperation`), and organizes key application-level types. -    - If an IPC method signature changes in the main process or `preload.ts`, update both the main code **and** `global.d.ts` accordingly. + - Regularly open and double-check **`src/types/global.d.ts`** to avoid TypeScript mistakes. + - This file extends the `window` interface to expose `window.fileSystem`, houses core global interfaces (like `FileOperation`), and organizes key application-level types. + - If an IPC method signature changes in the main process or `preload.ts`, update both the main code **and** `global.d.ts` accordingly. -5.  When debugging: +5. When debugging: -    - Check main process logs for **`FileService.ts`** or **`PathUtils.ts`** issues. -    - Verify IPC communication through preload bridge. -    - Inspect renderer process state using React DevTools, focusing on Zustand stores and `fileSystemService.ts` usage. + - Check main process logs for **`FileService.ts`** or **`PathUtils.ts`** issues. + - Verify IPC communication through preload bridge. + - Inspect renderer process state using React DevTools, focusing on Zustand stores and `fileSystemService.ts` usage. -6.  Security considerations: -    - Never bypass the IPC bridge for file operations from the renderer process. -    - Validate all paths and operations rigorously in the main process handlers. -    - Handle sensitive data appropriately at each layer. +6. Security considerations: + - Never bypass the IPC bridge for file operations from the renderer process. + - Validate all paths and operations rigorously in the main process handlers. + - Handle sensitive data appropriately at each layer. diff --git a/.ath_materials/feature_docs/feature_dynamic_context_builder.md b/docs/design/feature_dynamic_context_builder.md similarity index 100% rename from .ath_materials/feature_docs/feature_dynamic_context_builder.md rename to docs/design/feature_dynamic_context_builder.md diff --git a/package.json b/package.json index 477fa22..d7377c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "athanor", - "version": "0.7.4", + "version": "0.7.5", "bugs": { "url": "https://github.com/lacerbi/athanor/issues" }, diff --git a/resources/files/default_athignore b/resources/files/default_athignore index 271e4d5..c684050 100644 --- a/resources/files/default_athignore +++ b/resources/files/default_athignore @@ -369,7 +369,11 @@ docs/_site/ ############################################################################### # ATHANOR PROJECT FILES ############################################################################### -# Athanor system files +# Athanor materials folder is visible (as a separate node in the file manager) +!/.ath_materials/**/* + +# Athanor configuration files are hidden /.ath_materials/project_graph.json +/.ath_materials/project_settings.json # Put other files or folders below \ No newline at end of file diff --git a/resources/files/default_gitignore_extras b/resources/files/default_gitignore_extras new file mode 100644 index 0000000..66be96b --- /dev/null +++ b/resources/files/default_gitignore_extras @@ -0,0 +1,7 @@ +############################################################################### +# ATHANOR PROJECT FILES +############################################################################### +/.ath_materials/**/* +!/.ath_materials/prompts/ +!/.ath_materials/prompts/**/* +!/.ath_materials/project_settings.json \ No newline at end of file diff --git a/resources/prompts/prompt_writer.xml b/resources/prompts/prompt_writer.xml index 3045332..f13faa1 100644 --- a/resources/prompts/prompt_writer.xml +++ b/resources/prompts/prompt_writer.xml @@ -27,6 +27,44 @@ Use the included project instructions as a general guide. # Instructions +## Writing Style Matching + +When editing existing text or when the user provides a sample/excerpt: + +**Carefully analyze and match the writing style**, including: + +- **Register**: Match the level of formality (casual, conversational, professional, academic) +- **Tone & Voice**: Match perspective (first/second/third person), authorial stance, and emotional coloring +- **Humor & Personality**: + - Preserve any wit, sarcasm, or playfulness + - Match the use of jokes, puns, or cultural references + - Maintain the same level of seriousness or levity +- **Sentence Structure**: Replicate patterns of sentence length, complexity, and rhythm +- **Vocabulary**: Use similar word choices, idioms, colloquialisms, and technical terminology level +- **Paragraph Structure**: Match typical paragraph lengths and organizational patterns +- **Stylistic Elements**: Preserve any distinctive features like: + - Use of rhetorical questions or exclamations + - Metaphors, similes, or analogies + - Lists vs. prose + - Transition phrases and connectives + - Punctuation habits (e.g., em dashes, semicolons, Oxford commas, ellipses) + - Parenthetical asides or footnote style +- **Cultural & Regional Language**: Match any specific dialect, spelling conventions (US/UK), or cultural expressions +- **Formatting Conventions**: Follow existing patterns for headings, emphasis, spacing, capitalization +- **Markup & Environment Usage**: Match the document's formatting approach: + - Plain text (no markup) + - Markdown (and which flavor - CommonMark, GFM, etc.) + - HTML tags and attributes + - reStructuredText + - AsciiDoc + - Wiki markup + - Mixed environments (e.g., Markdown with HTML) + - Code block languages and formatting + +**Note**: The above are examples of stylistic elements to consider. The goal is to **match the writing style holistically** - capturing not just individual elements but the overall feel, flow, and character of the text. Pay attention to subtle patterns and combinations that create the unique voice of the existing content. + +If no sample is provided but you're editing existing text, analyze the surrounding content to maintain consistency throughout the document. + ## Response Formats You will respond with 2 sections: A summary section and one or more XML section(s). @@ -206,6 +244,41 @@ Use the included project instructions as a general guide. # Instructions +## Writing Style Matching + +When editing existing LaTeX documents or when the user provides a sample/excerpt: + +**Carefully analyze and match the writing style**, including: + +- **Register & Academic Tone**: Match the level of formality (conversational academic, formal academic, technical report) +- **Authorial Voice**: + - Preserve any personality or humor in explanations + - Match the use of "we" vs passive voice vs imperative mood + - Maintain pedagogical style (if teaching) or research style (if presenting findings) +- **Mathematical Presentation**: Follow existing patterns for: + - Inline vs. display equations + - Notation conventions and variable naming + - Theorem/proof formatting and numbering + - Definition and example styles + - Level of mathematical rigor and detail +- **Citation Style**: Match existing citation patterns (parenthetical, narrative, etc.) +- **Document Structure**: Preserve sectioning conventions, numbering schemes, and organizational patterns +- **LaTeX-Specific Style**: + - Macro usage patterns + - Spacing commands (e.g., `\,` vs `~` vs `\ `) + - Environment choices (e.g., `align` vs `equation` vs `gather`) + - Label naming conventions + - Comment style, frequency, and language + - Use of packages and custom commands +- **Prose Elements**: + - Match sentence structure and complexity + - Preserve any colloquialisms or field-specific jargon + - Maintain transitions between mathematical and prose sections + - Match explanation depth and pedagogical approach +- **Cultural & Field Conventions**: Respect discipline-specific writing norms (e.g., physics vs pure mathematics vs computer science) + +If no sample is provided but you're editing existing text, analyze the surrounding content to maintain consistency throughout the document. + ## LaTeX formatting ### Math conventions @@ -373,161 +446,4 @@ instructing them to select the files from the Athanor file manager. - - -You are an expert software engineer. - -You are tasked with following my instructions. - -Use the project instructions included below as a general guide. - -# Instructions - -## Tracking File State During Edits - -To prevent errors, you must correctly track the "current state" of each file as it's edited during our conversation. - -Your edits are considered **proposals**. The user's feedback determines if your proposal becomes the new official state. - -- **Implicit Acceptance is the Default:** If the user continues with a new instruction without rejecting your proposal, you MUST assume your changes were accepted. The new official state is now your last proposed version. -- **Handling Rejection:** If the user explicitly rejects your proposal (e.g., "no, that's wrong," "undo that"), you MUST discard your proposal and revert to the state *before* you made the change. -- **User Input is Final:** If the user provides a new file themselves, that version immediately becomes the official state, overriding any of your proposals. - -**In short: Your last edit becomes the new baseline, UNLESS the user rejects it or provides a new version.** - -## Response Formats - -You will respond with 2 sections: A summary section and one or more XML section(s). - -### Summary section - -- Provide a brief overall summary -- Provide a 1-sentence summary for each file changed and why -- Provide a 1-sentence summary for each file deleted and why -- Format this section as markdown - -### XML sections - -- Respond with the XML block(s) and nothing else -- Include all of the changed files -- Specify each file operation with CREATE, UPDATE_FULL, or DELETE -- Each file should include a brief change summary -- Include the full file path -- Put the XML block inside markdown codeblocks -- Make sure to enclose the file content with ![CDATA[__FILE CONTENT HERE__]] -- **Regarding file content within `CDATA` blocks:** - - By default use standard space characters (U+0020) - - Avoid introducing non-breaking spaces (U+00A0) and other non-standard whitespace, unless there is a reason (e.g., within a string literal) -- You can write multiple `file` blocks in the same `ath` command -- Ensure to write valid XML by opening and closing all tags as appropriate - -### File operations - -You will provide changes as follows: - -For CREATE and UPDATE_FULL, report the full file content: -```xml - - -Brief change description -CREATE|UPDATE_FULL -path/to/file - - - -[keep adding files here if any] - -``` - -For DELETE operations, leave the file content empty -``` - -``` - -{{ - include_ai_summaries ? -`## AI Summary - -Brief file-level comments that capture essential purpose and behavior - -Place them at the start of new/updated files and include: - -1. Core purpose -2. Key functions/interfaces (if not obvious from filename) -3. Important dependencies and system interactions -4. Non-obvious behaviors or gotchas - -### Rules - -- Keep to 1-5 lines -- Use file-appropriate comment syntax -- Do not leave empty lines before of after the summary -- Skip for files without comment support -- Update when file content changes meaningfully - -### Example - -\`\`\`typescript -// AI Summary: Handles JWT authentication, session management, and role-based access. -// Requires secret key initialization. Core functions: generateToken(), validateSession(). -\`\`\`` -}} - -## Comments - -For code, add comments as needed to explain parts of the code and make it readable. - -Do NOT remove existing comments, unless they are wrong or misleading. - -## File Contents Availability - -Check that the file contents of ALL files which you are planning to update are -available in the `file_contents` section included below. - -If a file content: -- is not provided below -- is only provided partially with `... (content truncated)` - -then it is NOT fully available. - -If you are missing the contents of a file that you are planning to update, -you may be missing crucial information to write valid code! - -If that is the case, do NOT write any code for any file. - -Instead, STOP and list ALL the additional files that you require from the user, -instructing them to select the files from the Athanor file manager. - - - -# Documentation `{{project_name}}` - -{{project_info}} - -{{file_contents}} - - -{{file_tree}} -{{codebase_legend}} - - - - -{{task_description}} -{{task_context}} - - -- Efficiently implement the feature or change described above according to best writing practices -- Think carefully of ALL the files that would need to be modified -- Only change what necessary -- Carefully follow the writing instructions in `system_prompt` - - - - \ No newline at end of file diff --git a/src/components/AthanorApp.tsx b/src/components/AthanorApp.tsx index dad0967..3be4986 100644 --- a/src/components/AthanorApp.tsx +++ b/src/components/AthanorApp.tsx @@ -63,6 +63,7 @@ const AthanorApp: React.FC = () => { refreshFileSystem, showProjectDialog, pendingDirectory, + pendingGitignoreExists, handleCreateProject, handleProjectDialogClose, } = useFileSystemLifecycle(); @@ -236,6 +237,7 @@ const AthanorApp: React.FC = () => { onClose={handleProjectDialogClose} onCreateProject={handleCreateProject} folderName={pendingDirectory ? getBaseName(pendingDirectory) : ''} + gitignoreExists={pendingGitignoreExists} /> {filesData && currentDirectory && ( void; - onCreateProject: (useStandardIgnore: boolean) => Promise; + onCreateProject: (useStandardIgnore: boolean, augmentGitignore: boolean) => Promise; folderName: string; + gitignoreExists: boolean; } const ProjectCreationDialog: React.FC = ({ @@ -16,8 +17,10 @@ const ProjectCreationDialog: React.FC = ({ isOpen, onClose, onCreateProject, + gitignoreExists, }) => { const [useStandardIgnore, setUseStandardIgnore] = useState(true); + const [augmentGitignore, setAugmentGitignore] = useState(true); const [isLoading, setIsLoading] = useState(false); if (!isOpen) return null; @@ -25,7 +28,7 @@ const ProjectCreationDialog: React.FC = ({ const handleCreate = async () => { setIsLoading(true); try { - await onCreateProject(useStandardIgnore); + await onCreateProject(useStandardIgnore, augmentGitignore); } catch (error) { console.error('Error creating project:', error); } finally { @@ -33,6 +36,15 @@ const ProjectCreationDialog: React.FC = ({ } }; + // Dynamic text based on .gitignore existence + const gitignoreLabel = gitignoreExists + ? 'Append Athanor rules to existing .gitignore' + : 'Create .gitignore with Athanor rules'; + + const gitignoreTooltip = gitignoreExists + ? 'Add Athanor-specific ignore rules to your existing .gitignore file' + : 'Create a new .gitignore file with Athanor-specific ignore rules'; + return (
@@ -70,6 +82,29 @@ const ProjectCreationDialog: React.FC = ({
+ +
+ setAugmentGitignore(e.target.checked)} + className="mt-1 accent-blue-500 dark:accent-blue-400 focus:ring-blue-500 dark:focus:ring-blue-400 dark:focus:ring-offset-gray-800" + /> +
+ + + + +
+
diff --git a/src/hooks/useFileSystemLifecycle.ts b/src/hooks/useFileSystemLifecycle.ts index 12eb83a..7f76aa2 100644 --- a/src/hooks/useFileSystemLifecycle.ts +++ b/src/hooks/useFileSystemLifecycle.ts @@ -3,7 +3,7 @@ import { useState, useCallback, useEffect, useRef } from 'react'; import { FileItem } from '../utils/fileTree'; import { buildFileTree } from '../services/fileSystemService'; -import { createAthignoreFile } from '../services/fileIgnoreService'; +import { initializeProjectFiles } from '../services/fileIgnoreService'; import { useFileSystemStore } from '../stores/fileSystemStore'; import { useWorkbenchStore } from '../stores/workbenchStore'; import { useLogStore } from '../stores/logStore'; @@ -53,6 +53,7 @@ export function useFileSystemLifecycle(): FileSystemLifecycle { const [materialsData, setResourcesData] = useState(null); const [showProjectDialog, setShowProjectDialog] = useState(false); const [pendingDirectory, setPendingDirectory] = useState(null); + const [pendingGitignoreExists, setPendingGitignoreExists] = useState(false); const refreshTimeoutRef = useRef(null); const isInitializedRef = useRef(false); @@ -235,8 +236,10 @@ export function useFileSystemLifecycle(): FileSystemLifecycle { // Existing project - proceed with loading await initializeProject(normalizedDir); } else { - // New project - show creation dialog + // New project - check for .gitignore and show creation dialog + const gitignoreExists = await window.fileService.exists('.gitignore'); setPendingDirectory(normalizedDir); + setPendingGitignoreExists(gitignoreExists); setShowProjectDialog(true); } }, @@ -244,13 +247,14 @@ export function useFileSystemLifecycle(): FileSystemLifecycle { ); const handleCreateProject = useCallback( - async (useStandardIgnore: boolean) => { + async (useStandardIgnore: boolean, augmentGitignore: boolean) => { if (!pendingDirectory) return; try { - // Create .athignore file with selected rules - await createAthignoreFile(pendingDirectory, { + // Initialize project files with selected options + await initializeProjectFiles(pendingDirectory, { useStandardIgnore, + augmentGitignore, }); // Initialize project with new .athignore @@ -442,6 +446,7 @@ export function useFileSystemLifecycle(): FileSystemLifecycle { refreshFileSystem, showProjectDialog, pendingDirectory, + pendingGitignoreExists, handleCreateProject, handleProjectDialogClose, } as FileSystemLifecycle; diff --git a/src/services/fileIgnoreService.ts b/src/services/fileIgnoreService.ts index 9686982..801241b 100644 --- a/src/services/fileIgnoreService.ts +++ b/src/services/fileIgnoreService.ts @@ -3,18 +3,22 @@ // Creates .athignore files with optional standard rules and handles path normalization for ignore patterns. interface AthignoreOptions { useStandardIgnore: boolean; + augmentGitignore?: boolean; } /** - * createAthignoreFile - * ------------------- + * initializeProjectFiles + * ---------------------- + * Initializes project configuration files including .athignore and optionally .gitignore. * Creates or overwrites a .athignore file in the user's project directory. - * Optionally imports .gitignore rules and merges them with the default .athignore template. + * Optionally creates a new .gitignore file or appends Athanor-specific rules to an existing one. * - * @param projectPath - The project directory where .athignore should be placed - * @param options - Controls whether standard ignore rules or .gitignore lines are used + * @param projectPath - The project directory where files should be created + * @param options - Controls file creation behavior: + * - useStandardIgnore: Whether to include standard ignore rules in .athignore + * - augmentGitignore: Whether to create/augment .gitignore with Athanor-specific rules */ -export async function createAthignoreFile( +export async function initializeProjectFiles( projectPath: string, options: AthignoreOptions ): Promise { @@ -52,6 +56,45 @@ export async function createAthignoreFile( // Write the .athignore file await window.fileService.write('.athignore', finalContent); + + // Handle .gitignore augmentation if requested + if (options.augmentGitignore) { + try { + // Get path to the gitignore extras file + const gitignoreExtrasPath = await window.pathUtils.join( + defaultAthignorePath, + 'files/default_gitignore_extras' + ); + + // Read the gitignore extras content + const gitignoreExtrasContent = await window.fileService.read( + await window.pathUtils.relative(gitignoreExtrasPath), + { encoding: 'utf8' } + ) as string; + + // Check if .gitignore already exists + const gitignoreExists = await window.fileService.exists('.gitignore'); + + let gitignoreContent = ''; + + if (gitignoreExists) { + // Read existing .gitignore content + const existingContent = await window.fileService.read('.gitignore', { encoding: 'utf8' }) as string; + // Append new rules with proper spacing + gitignoreContent = existingContent + '\n\n' + gitignoreExtrasContent; + } else { + // Create new .gitignore with just the extras content + gitignoreContent = gitignoreExtrasContent; + } + + // Write the final .gitignore content + await window.fileService.write('.gitignore', gitignoreContent); + + } catch (gitignoreError) { + console.error('Error handling .gitignore:', gitignoreError); + throw new Error(`Failed to create/update .gitignore: ${gitignoreError}`); + } + } } catch (error) { console.error('Error creating .athignore:', error); throw error; diff --git a/src/types/global.d.ts b/src/types/global.d.ts index 129d611..028df0a 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -529,7 +529,8 @@ export interface FileSystemLifecycle { ) => Promise; showProjectDialog: boolean; pendingDirectory: string | null; - handleCreateProject: (useStandardIgnore: boolean) => Promise; + pendingGitignoreExists: boolean; + handleCreateProject: (useStandardIgnore: boolean, augmentGitignore: boolean) => Promise; handleProjectDialogClose: () => void; }