From 32cf6866f37ea81e4d80031679f321dc828025cb Mon Sep 17 00:00:00 2001 From: James Brunton Date: Wed, 11 Mar 2026 13:43:30 +0000 Subject: [PATCH] Move AI advice to AGENTS.md and add symlink from CLAUDE.md (#5914) # Description of Changes Inspired by https://github.com/pydantic/pydantic-ai/pull/4169, this PR moves our `CLAUDE.md` advice to the more generic `AGENTS.md` file (which works on Codex, Gemini, etc). It also adds a symlink from `CLAUDE.md` to `AGENTS.md`, which Claude follows properly, so all AIs should get the same advice and we only need to keep one file up-to-date. --- AGENTS.md | 337 ++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 338 +-------------------------------------------- devGuide/AGENTS.md | 24 ---- 3 files changed, 338 insertions(+), 361 deletions(-) create mode 100644 AGENTS.md mode change 100644 => 120000 CLAUDE.md delete mode 100644 devGuide/AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..eb4bf7e827 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,337 @@ +# AGENTS.md + +This file provides guidance to AI Agents when working with code in this repository. + +## Common Development Commands + +### Build and Test +- **Build project**: `./gradlew clean build` +- **Run locally**: `./gradlew bootRun` +- **Full test suite**: `./test.sh` (builds all Docker variants and runs comprehensive tests) +- **Code formatting**: `./gradlew spotlessApply` (runs automatically before compilation) + +### Docker Development +- **Build ultra-lite**: `docker build -t stirlingtools/stirling-pdf:latest-ultra-lite -f ./Dockerfile.ultra-lite .` +- **Build standard**: `docker build -t stirlingtools/stirling-pdf:latest -f ./Dockerfile .` +- **Build fat version**: `docker build -t stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile.fat .` +- **Example compose files**: Located in `exampleYmlFiles/` directory + +### Security Mode Development +Set `DOCKER_ENABLE_SECURITY=true` environment variable to enable security features during development. This is required for testing the full version locally. + +### Frontend Development +- **Frontend dev server**: `cd frontend && npm run dev` (requires backend on localhost:8080) +- **Tech Stack**: Vite + React + TypeScript + Mantine UI + TailwindCSS +- **Proxy Configuration**: Vite proxies `/api/*` calls to backend (localhost:8080) +- **Build Process**: DO NOT run build scripts manually - builds are handled by CI/CD pipelines +- **Package Installation**: DO NOT run npm install commands - package management handled separately +- **Deployment Options**: + - **Desktop App**: `npm run tauri-build` (native desktop application) + - **Web Server**: `npm run build` then serve dist/ folder + - **Development**: `npm run tauri-dev` for desktop dev mode + +#### Import Paths - CRITICAL +**ALWAYS use `@app/*` for imports.** Do not use `@core/*` or `@proprietary/*` unless explicitly wrapping/extending a lower layer implementation. + +```typescript +// ✅ CORRECT - Use @app/* for all imports +import { AppLayout } from "@app/components/AppLayout"; +import { useFileContext } from "@app/contexts/FileContext"; +import { FileContext } from "@app/contexts/FileContext"; + +// ❌ WRONG - Do not use @core/* or @proprietary/* in normal code +import { AppLayout } from "@core/components/AppLayout"; +import { useFileContext } from "@proprietary/contexts/FileContext"; +``` + +**Only use explicit aliases when:** +- Building layer-specific override that wraps a lower layer's component +- Example: `import { AppProviders as CoreAppProviders } from "@core/components/AppProviders"` when creating proprietary/AppProviders.tsx that extends the core version + +The `@app/*` alias automatically resolves to the correct layer based on build target (core/proprietary/desktop) and handles the fallback cascade. + +#### Component Override Pattern (Stub/Shadow) +Use this pattern for desktop-specific or proprietary-specific features WITHOUT runtime checks or conditionals. + +**How it works:** +1. Core defines stub component (returns null or no-op) +2. Desktop/proprietary overrides with same path/name +3. Core imports via `@app/*` - higher layer "shadows" core in those builds +4. No `@ts-ignore`, no `isTauri()` checks, no runtime conditionals! + +**Example - Desktop-specific footer:** + +```typescript +// core/components/rightRail/RightRailFooterExtensions.tsx (stub) +interface RightRailFooterExtensionsProps { + className?: string; +} + +export function RightRailFooterExtensions(_props: RightRailFooterExtensionsProps) { + return null; // Stub - does nothing in web builds +} +``` + +```typescript +// desktop/components/rightRail/RightRailFooterExtensions.tsx (real implementation) +import { Box } from '@mantine/core'; +import { BackendHealthIndicator } from '@app/components/BackendHealthIndicator'; + +interface RightRailFooterExtensionsProps { + className?: string; +} + +export function RightRailFooterExtensions({ className }: RightRailFooterExtensionsProps) { + return ( + + + + ); +} +``` + +```typescript +// core/components/shared/RightRail.tsx (usage - works in ALL builds) +import { RightRailFooterExtensions } from '@app/components/rightRail/RightRailFooterExtensions'; + +export function RightRail() { + return ( +
+ {/* In web builds: renders nothing (stub returns null) */} + {/* In desktop builds: renders BackendHealthIndicator */} + +
+ ); +} +``` + +**Build resolution:** +- **Core build**: `@app/*` → `core/*` → Gets stub (returns null) +- **Desktop build**: `@app/*` → `desktop/*` → Gets real implementation (shadows core) + +**Benefits:** +- No runtime checks or feature flags +- Type-safe across all builds +- Clean, readable code +- Build-time optimization (dead code elimination) + +#### Multi-Tool Workflow Architecture +Frontend designed for **stateful document processing**: +- Users upload PDFs once, then chain tools (split → merge → compress → view) +- File state and processing results persist across tool switches +- No file reloading between tools - performance critical for large PDFs (up to 100GB+) + +#### FileContext - Central State Management +**Location**: `frontend/src/core/contexts/FileContext.tsx` +- **Active files**: Currently loaded PDFs and their variants +- **Tool navigation**: Current mode (viewer/pageEditor/fileEditor/toolName) +- **Memory management**: PDF document cleanup, blob URL lifecycle, Web Worker management +- **IndexedDB persistence**: File storage with thumbnail caching +- **Preview system**: Tools can preview results (e.g., Split → Viewer → back to Split) without context pollution + +**Critical**: All file operations go through FileContext. Don't bypass with direct file handling. + +#### Processing Services +- **enhancedPDFProcessingService**: Background PDF parsing and manipulation +- **thumbnailGenerationService**: Web Worker-based with main-thread fallback +- **fileStorage**: IndexedDB with LRU cache management + +#### Memory Management Strategy +**Why manual cleanup exists**: Large PDFs (up to 100GB+) through multiple tools accumulate: +- PDF.js documents that need explicit .destroy() calls +- Blob URLs from tool outputs that need revocation +- Web Workers that need termination +Without cleanup: browser crashes with memory leaks. + +#### Tool Development + +**Architecture**: Modular hook-based system with clear separation of concerns: + +- **useToolOperation** (`frontend/src/core/hooks/tools/shared/useToolOperation.ts`): Main orchestrator hook + - Coordinates all tool operations with consistent interface + - Integrates with FileContext for operation tracking + - Handles validation, error handling, and UI state management + +- **Supporting Hooks**: + - **useToolState**: UI state management (loading, progress, error, files) + - **useToolApiCalls**: HTTP requests and file processing + - **useToolResources**: Blob URLs, thumbnails, ZIP downloads + +- **Utilities**: + - **toolErrorHandler**: Standardized error extraction and i18n support + - **toolResponseProcessor**: API response handling (single/zip/custom) + - **toolOperationTracker**: FileContext integration utilities + +**Three Tool Patterns**: + +**Pattern 1: Single-File Tools** (Individual processing) +- Backend processes one file per API call +- Set `multiFileEndpoint: false` +- Examples: Compress, Rotate +```typescript +return useToolOperation({ + operationType: 'compress', + endpoint: '/api/v1/misc/compress-pdf', + buildFormData: (params, file: File) => { /* single file */ }, + multiFileEndpoint: false, +}); +``` + +**Pattern 2: Multi-File Tools** (Batch processing) +- Backend accepts `MultipartFile[]` arrays in single API call +- Set `multiFileEndpoint: true` +- Examples: Split, Merge, Overlay +```typescript +return useToolOperation({ + operationType: 'split', + endpoint: '/api/v1/general/split-pages', + buildFormData: (params, files: File[]) => { /* all files */ }, + multiFileEndpoint: true, + filePrefix: 'split_', +}); +``` + +**Pattern 3: Complex Tools** (Custom processing) +- Tools with complex routing logic or non-standard processing +- Provide `customProcessor` for full control +- Examples: Convert, OCR +```typescript +return useToolOperation({ + operationType: 'convert', + customProcessor: async (params, files) => { /* custom logic */ }, +}); +``` + +**Benefits**: +- **No Timeouts**: Operations run until completion (supports 100GB+ files) +- **Consistent**: All tools follow same pattern and interface +- **Maintainable**: Single responsibility hooks, easy to test and modify +- **i18n Ready**: Built-in internationalization support +- **Type Safe**: Full TypeScript support with generic interfaces +- **Memory Safe**: Automatic resource cleanup and blob URL management + +## Architecture Overview + +### Project Structure +- **Backend**: Spring Boot application +- **Frontend**: React-based SPA in `/frontend` directory + - **File Storage**: IndexedDB for client-side file persistence and thumbnails + - **Internationalization**: JSON-based translations (converted from backend .properties) +- **PDF Processing**: PDFBox for core PDF operations, LibreOffice for conversions, PDF.js for client-side rendering +- **Security**: Spring Security with optional authentication (controlled by `DOCKER_ENABLE_SECURITY`) +- **Configuration**: YAML-based configuration with environment variable overrides + +### Controller Architecture +- **API Controllers** (`src/main/java/.../controller/api/`): REST endpoints for PDF operations + - Organized by function: converters, security, misc, pipeline + - Follow pattern: `@RestController` + `@RequestMapping("/api/v1/...")` + +### Key Components +- **SPDFApplication.java**: Main application class with desktop UI and browser launching logic +- **ConfigInitializer**: Handles runtime configuration and settings files +- **Pipeline System**: Automated PDF processing workflows via `PipelineController` +- **Security Layer**: Authentication, authorization, and user management (when enabled) + +### Frontend Directory Structure +The frontend is organized with a clear separation of concerns: + +- **`frontend/src/core/`**: Main application code (shared, production-ready components) + - **`core/components/`**: React components organized by feature + - `core/components/tools/`: Individual PDF tool implementations + - `core/components/viewer/`: PDF viewer components + - `core/components/pageEditor/`: Page manipulation UI + - `core/components/tooltips/`: Help tooltips for tools + - `core/components/shared/`: Reusable UI components + - **`core/contexts/`**: React Context providers + - `FileContext.tsx`: Central file state management + - `file/`: File reducer and selectors + - `toolWorkflow/`: Tool workflow state + - **`core/hooks/`**: Custom React hooks + - `hooks/tools/`: Tool-specific operation hooks (one directory per tool) + - `hooks/tools/shared/`: Shared hook utilities (useToolOperation, etc.) + - **`core/constants/`**: Application constants and configuration + - **`core/data/`**: Static data (tool taxonomy, etc.) + - **`core/services/`**: Business logic services (PDF processing, storage, etc.) + +- **`frontend/src/desktop/`**: Desktop-specific (Tauri) code +- **`frontend/src/proprietary/`**: Proprietary/licensed features +- **`frontend/src-tauri/`**: Tauri (Rust) native desktop application code +- **`frontend/public/`**: Static assets served directly + - `public/locales/`: Translation JSON files + +### Component Architecture +- **Static Assets**: CSS, JS, and resources in `src/main/resources/static/` (legacy) + `frontend/public/` (modern) +- **Internationalization**: + - Backend: `messages_*.properties` files + - Frontend: JSON files in `frontend/public/locales/` (converted from .properties) + - Conversion Script: `scripts/convert_properties_to_json.py` + +### Configuration Modes +- **Ultra-lite**: Basic PDF operations only +- **Standard**: Full feature set +- **Fat**: Pre-downloaded dependencies for air-gapped environments +- **Security Mode**: Adds authentication, user management, and enterprise features + +### Testing Strategy +- **Integration Tests**: Cucumber tests in `testing/cucumber/` +- **Docker Testing**: `test.sh` validates all Docker variants +- **Manual Testing**: No unit tests currently - relies on UI and API testing + +## Development Workflow + +1. **Local Development**: + - Backend: `./gradlew bootRun` (runs on localhost:8080) + - Frontend: `cd frontend && npm run dev` (runs on localhost:5173, proxies to backend) +2. **Docker Testing**: Use `./test.sh` before submitting PRs +3. **Code Style**: Spotless enforces Google Java Format automatically +4. **Translations**: + - Backend: Use helper scripts in `/scripts` for multi-language updates + - Frontend: Update JSON files in `frontend/public/locales/` or use conversion script +5. **Documentation**: API docs auto-generated and available at `/swagger-ui/index.html` + +## Frontend Architecture Status + +- **Core Status**: React SPA architecture complete with multi-tool workflow support +- **State Management**: FileContext handles all file operations and tool navigation +- **File Processing**: Production-ready with memory management for large PDF workflows (up to 100GB+) +- **Tool Integration**: Modular hook architecture with `useToolOperation` orchestrator + - Individual hooks: `useToolState`, `useToolApiCalls`, `useToolResources` + - Utilities: `toolErrorHandler`, `toolResponseProcessor`, `toolOperationTracker` + - Pattern: Each tool creates focused operation hook, UI consumes state/actions +- **Preview System**: Tool results can be previewed without polluting file context (Split tool example) +- **Performance**: Web Worker thumbnails, IndexedDB persistence, background processing + +## Translation Rules + +- **CRITICAL**: Always update translations in `en-GB` only, never `en-US` +- Translation files are located in `frontend/public/locales/` + +## Important Notes + +- **Java Version**: Minimum JDK 21, supports and recommends JDK 25 +- **Lombok**: Used extensively - ensure IDE plugin is installed +- **File Persistence**: + - **Backend**: Designed to be stateless - files are processed in memory/temp locations only + - **Frontend**: Uses IndexedDB for client-side file storage and caching (with thumbnails) +- **Security**: When `DOCKER_ENABLE_SECURITY=false`, security-related classes are excluded from compilation +- **Import Paths**: ALWAYS use `@app/*` for imports - never use `@core/*` or `@proprietary/*` unless explicitly wrapping/extending a lower layer +- **FileContext**: All file operations MUST go through FileContext - never bypass with direct File handling +- **Memory Management**: Manual cleanup required for PDF.js documents and blob URLs - don't remove cleanup code +- **Tool Development**: New tools should follow `useToolOperation` hook pattern (see `useCompressOperation.ts`) +- **Performance Target**: Must handle PDFs up to 100GB+ without browser crashes +- **Preview System**: Tools can preview results without polluting main file context (see Split tool implementation) +- **Adding Tools**: See `ADDING_TOOLS.md` for complete guide to creating new PDF tools + +## Communication Style +- Be direct and to the point +- No apologies or conversational filler +- Answer questions directly without preamble +- Explain reasoning concisely when asked +- Avoid unnecessary elaboration + +## Decision Making +- Ask clarifying questions before making assumptions +- Stop and ask when uncertain about project-specific details +- Confirm approach before making structural changes +- Request guidance on preferences (cross-platform vs specific tools, etc.) +- Verify understanding of requirements before proceeding diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index eeaf5e263e..0000000000 --- a/CLAUDE.md +++ /dev/null @@ -1,337 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Common Development Commands - -### Build and Test -- **Build project**: `./gradlew clean build` -- **Run locally**: `./gradlew bootRun` -- **Full test suite**: `./test.sh` (builds all Docker variants and runs comprehensive tests) -- **Code formatting**: `./gradlew spotlessApply` (runs automatically before compilation) - -### Docker Development -- **Build ultra-lite**: `docker build -t stirlingtools/stirling-pdf:latest-ultra-lite -f ./Dockerfile.ultra-lite .` -- **Build standard**: `docker build -t stirlingtools/stirling-pdf:latest -f ./Dockerfile .` -- **Build fat version**: `docker build -t stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile.fat .` -- **Example compose files**: Located in `exampleYmlFiles/` directory - -### Security Mode Development -Set `DOCKER_ENABLE_SECURITY=true` environment variable to enable security features during development. This is required for testing the full version locally. - -### Frontend Development -- **Frontend dev server**: `cd frontend && npm run dev` (requires backend on localhost:8080) -- **Tech Stack**: Vite + React + TypeScript + Mantine UI + TailwindCSS -- **Proxy Configuration**: Vite proxies `/api/*` calls to backend (localhost:8080) -- **Build Process**: DO NOT run build scripts manually - builds are handled by CI/CD pipelines -- **Package Installation**: DO NOT run npm install commands - package management handled separately -- **Deployment Options**: - - **Desktop App**: `npm run tauri-build` (native desktop application) - - **Web Server**: `npm run build` then serve dist/ folder - - **Development**: `npm run tauri-dev` for desktop dev mode - -#### Import Paths - CRITICAL -**ALWAYS use `@app/*` for imports.** Do not use `@core/*` or `@proprietary/*` unless explicitly wrapping/extending a lower layer implementation. - -```typescript -// ✅ CORRECT - Use @app/* for all imports -import { AppLayout } from "@app/components/AppLayout"; -import { useFileContext } from "@app/contexts/FileContext"; -import { FileContext } from "@app/contexts/FileContext"; - -// ❌ WRONG - Do not use @core/* or @proprietary/* in normal code -import { AppLayout } from "@core/components/AppLayout"; -import { useFileContext } from "@proprietary/contexts/FileContext"; -``` - -**Only use explicit aliases when:** -- Building layer-specific override that wraps a lower layer's component -- Example: `import { AppProviders as CoreAppProviders } from "@core/components/AppProviders"` when creating proprietary/AppProviders.tsx that extends the core version - -The `@app/*` alias automatically resolves to the correct layer based on build target (core/proprietary/desktop) and handles the fallback cascade. - -#### Component Override Pattern (Stub/Shadow) -Use this pattern for desktop-specific or proprietary-specific features WITHOUT runtime checks or conditionals. - -**How it works:** -1. Core defines stub component (returns null or no-op) -2. Desktop/proprietary overrides with same path/name -3. Core imports via `@app/*` - higher layer "shadows" core in those builds -4. No `@ts-ignore`, no `isTauri()` checks, no runtime conditionals! - -**Example - Desktop-specific footer:** - -```typescript -// core/components/rightRail/RightRailFooterExtensions.tsx (stub) -interface RightRailFooterExtensionsProps { - className?: string; -} - -export function RightRailFooterExtensions(_props: RightRailFooterExtensionsProps) { - return null; // Stub - does nothing in web builds -} -``` - -```typescript -// desktop/components/rightRail/RightRailFooterExtensions.tsx (real implementation) -import { Box } from '@mantine/core'; -import { BackendHealthIndicator } from '@app/components/BackendHealthIndicator'; - -interface RightRailFooterExtensionsProps { - className?: string; -} - -export function RightRailFooterExtensions({ className }: RightRailFooterExtensionsProps) { - return ( - - - - ); -} -``` - -```typescript -// core/components/shared/RightRail.tsx (usage - works in ALL builds) -import { RightRailFooterExtensions } from '@app/components/rightRail/RightRailFooterExtensions'; - -export function RightRail() { - return ( -
- {/* In web builds: renders nothing (stub returns null) */} - {/* In desktop builds: renders BackendHealthIndicator */} - -
- ); -} -``` - -**Build resolution:** -- **Core build**: `@app/*` → `core/*` → Gets stub (returns null) -- **Desktop build**: `@app/*` → `desktop/*` → Gets real implementation (shadows core) - -**Benefits:** -- No runtime checks or feature flags -- Type-safe across all builds -- Clean, readable code -- Build-time optimization (dead code elimination) - -#### Multi-Tool Workflow Architecture -Frontend designed for **stateful document processing**: -- Users upload PDFs once, then chain tools (split → merge → compress → view) -- File state and processing results persist across tool switches -- No file reloading between tools - performance critical for large PDFs (up to 100GB+) - -#### FileContext - Central State Management -**Location**: `frontend/src/core/contexts/FileContext.tsx` -- **Active files**: Currently loaded PDFs and their variants -- **Tool navigation**: Current mode (viewer/pageEditor/fileEditor/toolName) -- **Memory management**: PDF document cleanup, blob URL lifecycle, Web Worker management -- **IndexedDB persistence**: File storage with thumbnail caching -- **Preview system**: Tools can preview results (e.g., Split → Viewer → back to Split) without context pollution - -**Critical**: All file operations go through FileContext. Don't bypass with direct file handling. - -#### Processing Services -- **enhancedPDFProcessingService**: Background PDF parsing and manipulation -- **thumbnailGenerationService**: Web Worker-based with main-thread fallback -- **fileStorage**: IndexedDB with LRU cache management - -#### Memory Management Strategy -**Why manual cleanup exists**: Large PDFs (up to 100GB+) through multiple tools accumulate: -- PDF.js documents that need explicit .destroy() calls -- Blob URLs from tool outputs that need revocation -- Web Workers that need termination -Without cleanup: browser crashes with memory leaks. - -#### Tool Development - -**Architecture**: Modular hook-based system with clear separation of concerns: - -- **useToolOperation** (`frontend/src/core/hooks/tools/shared/useToolOperation.ts`): Main orchestrator hook - - Coordinates all tool operations with consistent interface - - Integrates with FileContext for operation tracking - - Handles validation, error handling, and UI state management - -- **Supporting Hooks**: - - **useToolState**: UI state management (loading, progress, error, files) - - **useToolApiCalls**: HTTP requests and file processing - - **useToolResources**: Blob URLs, thumbnails, ZIP downloads - -- **Utilities**: - - **toolErrorHandler**: Standardized error extraction and i18n support - - **toolResponseProcessor**: API response handling (single/zip/custom) - - **toolOperationTracker**: FileContext integration utilities - -**Three Tool Patterns**: - -**Pattern 1: Single-File Tools** (Individual processing) -- Backend processes one file per API call -- Set `multiFileEndpoint: false` -- Examples: Compress, Rotate -```typescript -return useToolOperation({ - operationType: 'compress', - endpoint: '/api/v1/misc/compress-pdf', - buildFormData: (params, file: File) => { /* single file */ }, - multiFileEndpoint: false, -}); -``` - -**Pattern 2: Multi-File Tools** (Batch processing) -- Backend accepts `MultipartFile[]` arrays in single API call -- Set `multiFileEndpoint: true` -- Examples: Split, Merge, Overlay -```typescript -return useToolOperation({ - operationType: 'split', - endpoint: '/api/v1/general/split-pages', - buildFormData: (params, files: File[]) => { /* all files */ }, - multiFileEndpoint: true, - filePrefix: 'split_', -}); -``` - -**Pattern 3: Complex Tools** (Custom processing) -- Tools with complex routing logic or non-standard processing -- Provide `customProcessor` for full control -- Examples: Convert, OCR -```typescript -return useToolOperation({ - operationType: 'convert', - customProcessor: async (params, files) => { /* custom logic */ }, -}); -``` - -**Benefits**: -- **No Timeouts**: Operations run until completion (supports 100GB+ files) -- **Consistent**: All tools follow same pattern and interface -- **Maintainable**: Single responsibility hooks, easy to test and modify -- **i18n Ready**: Built-in internationalization support -- **Type Safe**: Full TypeScript support with generic interfaces -- **Memory Safe**: Automatic resource cleanup and blob URL management - -## Architecture Overview - -### Project Structure -- **Backend**: Spring Boot application -- **Frontend**: React-based SPA in `/frontend` directory - - **File Storage**: IndexedDB for client-side file persistence and thumbnails - - **Internationalization**: JSON-based translations (converted from backend .properties) -- **PDF Processing**: PDFBox for core PDF operations, LibreOffice for conversions, PDF.js for client-side rendering -- **Security**: Spring Security with optional authentication (controlled by `DOCKER_ENABLE_SECURITY`) -- **Configuration**: YAML-based configuration with environment variable overrides - -### Controller Architecture -- **API Controllers** (`src/main/java/.../controller/api/`): REST endpoints for PDF operations - - Organized by function: converters, security, misc, pipeline - - Follow pattern: `@RestController` + `@RequestMapping("/api/v1/...")` - -### Key Components -- **SPDFApplication.java**: Main application class with desktop UI and browser launching logic -- **ConfigInitializer**: Handles runtime configuration and settings files -- **Pipeline System**: Automated PDF processing workflows via `PipelineController` -- **Security Layer**: Authentication, authorization, and user management (when enabled) - -### Frontend Directory Structure -The frontend is organized with a clear separation of concerns: - -- **`frontend/src/core/`**: Main application code (shared, production-ready components) - - **`core/components/`**: React components organized by feature - - `core/components/tools/`: Individual PDF tool implementations - - `core/components/viewer/`: PDF viewer components - - `core/components/pageEditor/`: Page manipulation UI - - `core/components/tooltips/`: Help tooltips for tools - - `core/components/shared/`: Reusable UI components - - **`core/contexts/`**: React Context providers - - `FileContext.tsx`: Central file state management - - `file/`: File reducer and selectors - - `toolWorkflow/`: Tool workflow state - - **`core/hooks/`**: Custom React hooks - - `hooks/tools/`: Tool-specific operation hooks (one directory per tool) - - `hooks/tools/shared/`: Shared hook utilities (useToolOperation, etc.) - - **`core/constants/`**: Application constants and configuration - - **`core/data/`**: Static data (tool taxonomy, etc.) - - **`core/services/`**: Business logic services (PDF processing, storage, etc.) - -- **`frontend/src/desktop/`**: Desktop-specific (Tauri) code -- **`frontend/src/proprietary/`**: Proprietary/licensed features -- **`frontend/src-tauri/`**: Tauri (Rust) native desktop application code -- **`frontend/public/`**: Static assets served directly - - `public/locales/`: Translation JSON files - -### Component Architecture -- **Static Assets**: CSS, JS, and resources in `src/main/resources/static/` (legacy) + `frontend/public/` (modern) -- **Internationalization**: - - Backend: `messages_*.properties` files - - Frontend: JSON files in `frontend/public/locales/` (converted from .properties) - - Conversion Script: `scripts/convert_properties_to_json.py` - -### Configuration Modes -- **Ultra-lite**: Basic PDF operations only -- **Standard**: Full feature set -- **Fat**: Pre-downloaded dependencies for air-gapped environments -- **Security Mode**: Adds authentication, user management, and enterprise features - -### Testing Strategy -- **Integration Tests**: Cucumber tests in `testing/cucumber/` -- **Docker Testing**: `test.sh` validates all Docker variants -- **Manual Testing**: No unit tests currently - relies on UI and API testing - -## Development Workflow - -1. **Local Development**: - - Backend: `./gradlew bootRun` (runs on localhost:8080) - - Frontend: `cd frontend && npm run dev` (runs on localhost:5173, proxies to backend) -2. **Docker Testing**: Use `./test.sh` before submitting PRs -3. **Code Style**: Spotless enforces Google Java Format automatically -4. **Translations**: - - Backend: Use helper scripts in `/scripts` for multi-language updates - - Frontend: Update JSON files in `frontend/public/locales/` or use conversion script -5. **Documentation**: API docs auto-generated and available at `/swagger-ui/index.html` - -## Frontend Architecture Status - -- **Core Status**: React SPA architecture complete with multi-tool workflow support -- **State Management**: FileContext handles all file operations and tool navigation -- **File Processing**: Production-ready with memory management for large PDF workflows (up to 100GB+) -- **Tool Integration**: Modular hook architecture with `useToolOperation` orchestrator - - Individual hooks: `useToolState`, `useToolApiCalls`, `useToolResources` - - Utilities: `toolErrorHandler`, `toolResponseProcessor`, `toolOperationTracker` - - Pattern: Each tool creates focused operation hook, UI consumes state/actions -- **Preview System**: Tool results can be previewed without polluting file context (Split tool example) -- **Performance**: Web Worker thumbnails, IndexedDB persistence, background processing - -## Translation Rules - -- **CRITICAL**: Always update translations in `en-GB` only, never `en-US` -- Translation files are located in `frontend/public/locales/` - -## Important Notes - -- **Java Version**: Minimum JDK 21, supports and recommends JDK 25 -- **Lombok**: Used extensively - ensure IDE plugin is installed -- **File Persistence**: - - **Backend**: Designed to be stateless - files are processed in memory/temp locations only - - **Frontend**: Uses IndexedDB for client-side file storage and caching (with thumbnails) -- **Security**: When `DOCKER_ENABLE_SECURITY=false`, security-related classes are excluded from compilation -- **Import Paths**: ALWAYS use `@app/*` for imports - never use `@core/*` or `@proprietary/*` unless explicitly wrapping/extending a lower layer -- **FileContext**: All file operations MUST go through FileContext - never bypass with direct File handling -- **Memory Management**: Manual cleanup required for PDF.js documents and blob URLs - don't remove cleanup code -- **Tool Development**: New tools should follow `useToolOperation` hook pattern (see `useCompressOperation.ts`) -- **Performance Target**: Must handle PDFs up to 100GB+ without browser crashes -- **Preview System**: Tools can preview results without polluting main file context (see Split tool implementation) -- **Adding Tools**: See `ADDING_TOOLS.md` for complete guide to creating new PDF tools - -## Communication Style -- Be direct and to the point -- No apologies or conversational filler -- Answer questions directly without preamble -- Explain reasoning concisely when asked -- Avoid unnecessary elaboration - -## Decision Making -- Ask clarifying questions before making assumptions -- Stop and ask when uncertain about project-specific details -- Confirm approach before making structural changes -- Request guidance on preferences (cross-platform vs specific tools, etc.) -- Verify understanding of requirements before proceeding diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000000..47dc3e3d86 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/devGuide/AGENTS.md b/devGuide/AGENTS.md deleted file mode 100644 index 461d26c07c..0000000000 --- a/devGuide/AGENTS.md +++ /dev/null @@ -1,24 +0,0 @@ -# Codex Contribution Guidelines for Stirling-PDF - -This file provides high-level instructions for Codex when modifying any files within this repository. Follow these rules to ensure changes remain consistent with the existing project structure. - -## 1. Code Style and Formatting -- Respect the `.editorconfig` settings located in the repository root. Java files use 4 spaces; HTML, JS, and Python generally use 2 spaces. Lines should end with `LF`. -- Format Java code with `./gradlew spotlessApply` before committing. -- Review `DeveloperGuide.md` for project structure and design details before making significant changes. - -## 2. Testing -- Run `./gradlew build` before committing changes to ensure the project compiles. -- If the build cannot complete due to environment restrictions, DO NOT COMMIT THE CHANGE - -## 3. Commits -- Keep commits focused. Group related changes together and provide concise commit messages. -- Ensure the working tree is clean (`git status`) before concluding your work. - -## 4. Pull Requests -- Summarize what was changed and why. Include build results from `./gradlew build` in the PR description. -- Note that the code was generated with the assistance of AI. - -## 5. Translations -- Only modify `messages_en_GB.properties` when adding or updating translations. -