diff --git a/docs/framework/architecture.md b/docs/framework/architecture.md deleted file mode 100644 index a0bd1d00..00000000 --- a/docs/framework/architecture.md +++ /dev/null @@ -1,134 +0,0 @@ -# Architecture - -Core follows a modular, service-based architecture designed for maintainability and testability. - -## Overview - -``` -┌─────────────────────────────────────────────────────────┐ -│ Wails Application │ -├─────────────────────────────────────────────────────────┤ -│ Core │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ Display │ │ WebView │ │ MCP │ │ Config │ │ -│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ Crypt │ │ I18n │ │ IO │ │Workspace │ │ -│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ -├─────────────────────────────────────────────────────────┤ -│ Plugin System │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ -│ │ Plugin A │ │ Plugin B │ │ Plugin C │ │ -│ └──────────┘ └──────────┘ └──────────┘ │ -└─────────────────────────────────────────────────────────┘ -``` - -## Core Container - -The `Core` struct is the central service container: - -```go -type Core struct { - services map[string]any // Service registry - actions []ActionHandler // IPC handlers - Features *Features // Feature flags - servicesLocked bool // Prevent late registration -} -``` - -### Service Registration - -Services are registered using factory functions: - -```go -core.New( - core.WithService(display.NewService), // Auto-discovered name - core.WithName("custom", myFactory), // Explicit name -) -``` - -### Service Retrieval - -Type-safe service retrieval: - -```go -// Returns error if not found -svc, err := core.ServiceFor[*display.Service](c, "display") - -// Panics if not found (use in init code) -svc := core.MustServiceFor[*display.Service](c, "display") -``` - -## Service Lifecycle - -Services can implement lifecycle interfaces: - -```go -// Called when app starts -type Startable interface { - OnStartup(ctx context.Context) error -} - -// Called when app shuts down -type Stoppable interface { - OnShutdown(ctx context.Context) error -} -``` - -## IPC / Actions - -Services communicate via the action system: - -```go -// Register a handler -c.RegisterAction(func(c *core.Core, msg core.Message) error { - if msg.Type == "my-action" { - // Handle message - } - return nil -}) - -// Send a message -c.ACTION(core.Message{ - Type: "my-action", - Data: map[string]any{"key": "value"}, -}) -``` - -## Frontend Bindings - -Wails generates TypeScript bindings automatically: - -```typescript -// Auto-generated from Go service -import { ShowNotification } from '@bindings/display/service'; - -await ShowNotification({ - title: "Hello", - message: "From TypeScript!" -}); -``` - -## Package Structure - -``` -pkg/ -├── core/ # Core container and interfaces -├── display/ # Window, tray, dialogs, clipboard -├── webview/ # JS execution, DOM, screenshots -├── mcp/ # Model Context Protocol server -├── config/ # Configuration persistence -├── crypt/ # Encryption and signing -├── i18n/ # Internationalization -├── io/ # File system helpers -├── workspace/ # Project management -├── plugin/ # Plugin system -└── module/ # Module system -``` - -## Design Principles - -1. **Dependency Injection**: Services receive dependencies via constructor -2. **Interface Segregation**: Small, focused interfaces -3. **Testability**: All services are mockable -4. **No Globals**: State contained in Core instance diff --git a/docs/framework/config.md b/docs/framework/config.md deleted file mode 100644 index c682e852..00000000 --- a/docs/framework/config.md +++ /dev/null @@ -1,122 +0,0 @@ -# Config Service - -The Config service (`pkg/config`) provides unified configuration management with automatic persistence, feature flags, and XDG-compliant directory paths. - -## Features - -- JSON configuration with auto-save -- Feature flag management -- XDG Base Directory support -- Struct serialization helpers -- Type-safe get/set operations - -## Basic Usage - -```go -import "github.com/Snider/Core/pkg/config" - -// Standalone usage -cfg, err := config.New() -if err != nil { - log.Fatal(err) -} - -// With Core framework -c, _ := core.New( - core.WithService(config.Register), -) -cfg := core.MustServiceFor[*config.Service](c, "config") -``` - -## Get & Set Values - -```go -// Set a value (auto-saves) -err := cfg.Set("language", "fr") - -// Get a value -var lang string -err := cfg.Get("language", &lang) -``` - -Available configuration keys: - -| Key | Type | Description | -|-----|------|-------------| -| `language` | string | UI language code | -| `default_route` | string | Default navigation route | -| `configDir` | string | Config files directory | -| `dataDir` | string | Data files directory | -| `cacheDir` | string | Cache directory | -| `workspaceDir` | string | Workspaces directory | - -## Feature Flags - -```go -// Enable a feature -cfg.EnableFeature("dark_mode") - -// Check if enabled -if cfg.IsFeatureEnabled("dark_mode") { - // Apply dark theme -} - -// Disable a feature -cfg.DisableFeature("dark_mode") -``` - -## Struct Serialization - -Store complex data structures in separate JSON files: - -```go -type UserPrefs struct { - Theme string `json:"theme"` - Notifications bool `json:"notifications"` -} - -// Save struct to config/user_prefs.json -prefs := UserPrefs{Theme: "dark", Notifications: true} -err := cfg.SaveStruct("user_prefs", prefs) - -// Load struct from file -var loaded UserPrefs -err := cfg.LoadStruct("user_prefs", &loaded) -``` - -## Directory Paths - -The service automatically creates XDG-compliant directories: - -```go -// Access directory paths -fmt.Println(cfg.ConfigDir) // ~/.config/lethean or ~/lethean/config -fmt.Println(cfg.DataDir) // Data storage -fmt.Println(cfg.CacheDir) // Cache files -fmt.Println(cfg.WorkspaceDir) // User workspaces -``` - -## Manual Save - -Changes are auto-saved, but you can save explicitly: - -```go -err := cfg.Save() -``` - -## Frontend Usage (TypeScript) - -```typescript -import { Get, Set, IsFeatureEnabled } from '@bindings/config/service'; - -// Get configuration -const lang = await Get("language"); - -// Set configuration -await Set("default_route", "/dashboard"); - -// Check feature flag -if (await IsFeatureEnabled("dark_mode")) { - applyDarkTheme(); -} -``` diff --git a/docs/framework/core.md b/docs/framework/core.md deleted file mode 100644 index 3599fd7f..00000000 --- a/docs/framework/core.md +++ /dev/null @@ -1,312 +0,0 @@ -# Core API Reference - -Complete API reference for the Core framework (`pkg/core`). - -## Core Struct - -The central application container. - -### Creation - -```go -func New(opts ...Option) (*Core, error) -``` - -Creates a new Core instance with the specified options. - -### Methods - -#### Service Access - -```go -func ServiceFor[T any](c *Core, name string) (T, error) -``` - -Retrieves a service by name with type safety. - -```go -func MustServiceFor[T any](c *Core, name string) T -``` - -Retrieves a service by name, panics if not found or wrong type. - -#### Actions - -```go -func (c *Core) ACTION(msg Message) error -``` - -Broadcasts a message to all registered action handlers. - -```go -func (c *Core) RegisterAction(handler func(*Core, Message) error) -``` - -Registers an action handler. - -#### Service Registration - -```go -func (c *Core) AddService(name string, svc any) error -``` - -Manually adds a service to the registry. - -#### Config Access - -```go -func (c *Core) Config() *config.Service -``` - -Returns the config service if registered. - -## Options - -### WithService - -```go -func WithService(factory ServiceFactory) Option -``` - -Registers a service using its factory function. - -```go -c, _ := core.New( - core.WithService(config.Register), - core.WithService(display.NewService), -) -``` - -### WithName - -```go -func WithName(name string, factory ServiceFactory) Option -``` - -Registers a service with an explicit name. - -```go -c, _ := core.New( - core.WithName("mydb", database.NewService), -) -``` - -### WithAssets - -```go -func WithAssets(assets embed.FS) Option -``` - -Sets embedded assets for the application. - -### WithServiceLock - -```go -func WithServiceLock() Option -``` - -Prevents late service registration after initialization. - -## ServiceFactory - -```go -type ServiceFactory func(c *Core) (any, error) -``` - -Factory function signature for service creation. - -## Message - -```go -type Message interface{} -``` - -Messages can be any type. Common patterns: - -```go -// Map-based message -c.ACTION(map[string]any{ - "action": "user.created", - "id": "123", -}) - -// Typed message -type UserCreated struct { - ID string - Email string -} -c.ACTION(UserCreated{ID: "123", Email: "user@example.com"}) -``` - -## ServiceRuntime - -Generic helper for services that need Core access. - -```go -type ServiceRuntime[T any] struct { - core *Core - options T -} -``` - -### Creation - -```go -func NewServiceRuntime[T any](c *Core, opts T) *ServiceRuntime[T] -``` - -### Methods - -```go -func (r *ServiceRuntime[T]) Core() *Core -func (r *ServiceRuntime[T]) Options() T -func (r *ServiceRuntime[T]) Config() *config.Service -``` - -### Usage - -```go -type MyOptions struct { - Timeout time.Duration -} - -type MyService struct { - *core.ServiceRuntime[MyOptions] -} - -func NewMyService(c *core.Core) (any, error) { - opts := MyOptions{Timeout: 30 * time.Second} - return &MyService{ - ServiceRuntime: core.NewServiceRuntime(c, opts), - }, nil -} - -func (s *MyService) DoSomething() { - timeout := s.Options().Timeout - cfg := s.Config() - // ... -} -``` - -## Lifecycle Interfaces - -### Startable - -```go -type Startable interface { - OnStartup(ctx context.Context) error -} -``` - -Implement for initialization on app start. - -### Stoppable - -```go -type Stoppable interface { - OnShutdown(ctx context.Context) error -} -``` - -Implement for cleanup on app shutdown. - -### IPC Handler - -```go -type IPCHandler interface { - HandleIPCEvents(c *Core, msg Message) error -} -``` - -Automatically registered when using `WithService`. - -## Built-in Actions - -### ActionServiceStartup - -```go -type ActionServiceStartup struct{} -``` - -Sent to all services when application starts. - -### ActionServiceShutdown - -```go -type ActionServiceShutdown struct{} -``` - -Sent to all services when application shuts down. - -## Error Helpers - -```go -func E(service, operation string, err error) error -``` - -Creates a contextual error with service and operation info. - -```go -if err != nil { - return core.E("myservice", "Connect", err) -} -// Error: myservice.Connect: connection refused -``` - -## Complete Example - -```go -package main - -import ( - "context" - "github.com/Snider/Core/pkg/core" - "github.com/Snider/Core/pkg/config" -) - -type MyService struct { - *core.ServiceRuntime[struct{}] - data string -} - -func NewMyService(c *core.Core) (any, error) { - return &MyService{ - ServiceRuntime: core.NewServiceRuntime(c, struct{}{}), - data: "initialized", - }, nil -} - -func (s *MyService) OnStartup(ctx context.Context) error { - // Startup logic - return nil -} - -func (s *MyService) OnShutdown(ctx context.Context) error { - // Cleanup logic - return nil -} - -func (s *MyService) HandleIPCEvents(c *core.Core, msg core.Message) error { - switch m := msg.(type) { - case map[string]any: - if m["action"] == "myservice.update" { - s.data = m["data"].(string) - } - } - return nil -} - -func main() { - c, err := core.New( - core.WithService(config.Register), - core.WithService(NewMyService), - core.WithServiceLock(), - ) - if err != nil { - panic(err) - } - - svc := core.MustServiceFor[*MyService](c, "main") - _ = svc -} -``` diff --git a/docs/framework/crypt.md b/docs/framework/crypt.md deleted file mode 100644 index 730d7876..00000000 --- a/docs/framework/crypt.md +++ /dev/null @@ -1,133 +0,0 @@ -# Crypt Service - -The Crypt service (`pkg/crypt`) provides cryptographic utilities including hashing, checksums, RSA encryption, and PGP operations. - -## Features - -- Multiple hash algorithms (SHA512, SHA256, SHA1, MD5) -- Checksum functions (Fletcher, Luhn) -- RSA key generation and encryption -- PGP encryption, signing, and verification -- Symmetric PGP encryption - -## Basic Usage - -```go -import "github.com/Snider/Core/pkg/crypt" - -// Standalone usage -crypto, err := crypt.New() - -// With Core framework -c, _ := core.New( - core.WithService(crypt.Register), -) -crypto := core.MustServiceFor[*crypt.Service](c, "crypt") -``` - -## Hashing - -```go -// Available algorithms: SHA512, SHA256, SHA1, MD5, LTHN -hash := crypto.Hash(crypt.SHA256, "hello world") - -// Check if string is valid hash algorithm -isValid := crypto.IsHashAlgo("sha256") -``` - -## Checksums - -```go -// Luhn validation (credit card numbers) -isValid := crypto.Luhn("4532015112830366") - -// Fletcher checksums -f16 := crypto.Fletcher16("data") -f32 := crypto.Fletcher32("data") -f64 := crypto.Fletcher64("data") -``` - -## RSA Encryption - -```go -// Generate key pair (2048 or 4096 bits recommended) -publicKey, privateKey, err := crypto.GenerateRSAKeyPair(2048) - -// Encrypt with public key -ciphertext, err := crypto.EncryptRSA(publicKey, "secret message") - -// Decrypt with private key -plaintext, err := crypto.DecryptRSA(privateKey, ciphertext) -``` - -## PGP Encryption - -### Key Generation - -```go -// Generate PGP key pair -publicKey, privateKey, err := crypto.GeneratePGPKeyPair( - "User Name", - "user@example.com", - "Key comment", -) -``` - -### Asymmetric Encryption - -```go -// Encrypt for recipient -ciphertext, err := crypto.EncryptPGPToString(recipientPublicKey, "secret data") - -// Decrypt with private key -plaintext, err := crypto.DecryptPGP(privateKey, ciphertext) -``` - -### Symmetric Encryption - -```go -var buf bytes.Buffer -err := crypto.SymmetricallyEncryptPGP(&buf, "data", "passphrase") -``` - -### Signing & Verification - -```go -// Sign data -signature, err := crypto.SignPGP(privateKey, "data to sign") - -// Verify signature -err := crypto.VerifyPGP(publicKey, "data to sign", signature) -if err != nil { - // Signature invalid -} -``` - -## Hash Types - -| Constant | Algorithm | -|----------|-----------| -| `crypt.SHA512` | SHA-512 | -| `crypt.SHA256` | SHA-256 | -| `crypt.SHA1` | SHA-1 | -| `crypt.MD5` | MD5 | -| `crypt.LTHN` | Custom LTHN hash | - -## Frontend Usage (TypeScript) - -```typescript -import { - Hash, - GenerateRSAKeyPair, - EncryptRSA, - DecryptRSA -} from '@bindings/crypt/service'; - -// Hash data -const hash = await Hash("SHA256", "hello world"); - -// RSA encryption -const { publicKey, privateKey } = await GenerateRSAKeyPair(2048); -const encrypted = await EncryptRSA(publicKey, "secret"); -const decrypted = await DecryptRSA(privateKey, encrypted); -``` diff --git a/docs/framework/display.md b/docs/framework/display.md deleted file mode 100644 index 96f01b8a..00000000 --- a/docs/framework/display.md +++ /dev/null @@ -1,352 +0,0 @@ -# Display API Reference - -Complete API reference for the Display service (`pkg/display`). - -## Service Creation - -```go -func NewService(c *core.Core) (any, error) -``` - -## Window Management - -### CreateWindow - -```go -func (s *Service) CreateWindow(opts CreateWindowOptions) (*WindowInfo, error) -``` - -Creates a new window with the specified options. - -```go -type CreateWindowOptions struct { - Name string - Title string - URL string - X int - Y int - Width int - Height int -} -``` - -### CloseWindow - -```go -func (s *Service) CloseWindow(name string) error -``` - -### GetWindowInfo - -```go -func (s *Service) GetWindowInfo(name string) (*WindowInfo, error) -``` - -Returns: - -```go -type WindowInfo struct { - Name string - Title string - X int - Y int - Width int - Height int - IsVisible bool - IsFocused bool - IsMaximized bool - IsMinimized bool -} -``` - -### ListWindowInfos - -```go -func (s *Service) ListWindowInfos() []*WindowInfo -``` - -### Window Position & Size - -```go -func (s *Service) SetWindowPosition(name string, x, y int) error -func (s *Service) SetWindowSize(name string, width, height int) error -func (s *Service) SetWindowBounds(name string, x, y, width, height int) error -``` - -### Window State - -```go -func (s *Service) MaximizeWindow(name string) error -func (s *Service) MinimizeWindow(name string) error -func (s *Service) RestoreWindow(name string) error -func (s *Service) FocusWindow(name string) error -func (s *Service) SetWindowFullscreen(name string, fullscreen bool) error -func (s *Service) SetWindowAlwaysOnTop(name string, onTop bool) error -func (s *Service) SetWindowVisibility(name string, visible bool) error -``` - -### Window Title - -```go -func (s *Service) SetWindowTitle(name, title string) error -func (s *Service) GetWindowTitle(name string) (string, error) -``` - -### Window Background - -```go -func (s *Service) SetWindowBackgroundColour(name string, r, g, b, a uint8) error -``` - -### Focus - -```go -func (s *Service) GetFocusedWindow() string -``` - -## Screen Management - -### GetScreens - -```go -func (s *Service) GetScreens() []*Screen -``` - -Returns: - -```go -type Screen struct { - ID string - Name string - X int - Y int - Width int - Height int - ScaleFactor float64 - IsPrimary bool -} -``` - -### GetScreen - -```go -func (s *Service) GetScreen(id string) (*Screen, error) -``` - -### GetPrimaryScreen - -```go -func (s *Service) GetPrimaryScreen() (*Screen, error) -``` - -### GetScreenAtPoint - -```go -func (s *Service) GetScreenAtPoint(x, y int) (*Screen, error) -``` - -### GetScreenForWindow - -```go -func (s *Service) GetScreenForWindow(name string) (*Screen, error) -``` - -### GetWorkAreas - -```go -func (s *Service) GetWorkAreas() []*WorkArea -``` - -Returns usable screen space (excluding dock/taskbar). - -## Layout Management - -### SaveLayout / RestoreLayout - -```go -func (s *Service) SaveLayout(name string) error -func (s *Service) RestoreLayout(name string) error -func (s *Service) ListLayouts() []string -func (s *Service) DeleteLayout(name string) error -func (s *Service) GetLayout(name string) *Layout -``` - -### TileWindows - -```go -func (s *Service) TileWindows(mode TileMode, windows []string) error -``` - -Tile modes: - -```go -const ( - TileModeLeft TileMode = "left" - TileModeRight TileMode = "right" - TileModeGrid TileMode = "grid" - TileModeQuadrants TileMode = "quadrants" -) -``` - -### SnapWindow - -```go -func (s *Service) SnapWindow(name string, position SnapPosition) error -``` - -Snap positions: - -```go -const ( - SnapPositionLeft SnapPosition = "left" - SnapPositionRight SnapPosition = "right" - SnapPositionTop SnapPosition = "top" - SnapPositionBottom SnapPosition = "bottom" - SnapPositionTopLeft SnapPosition = "top-left" - SnapPositionTopRight SnapPosition = "top-right" - SnapPositionBottomLeft SnapPosition = "bottom-left" - SnapPositionBottomRight SnapPosition = "bottom-right" -) -``` - -### StackWindows - -```go -func (s *Service) StackWindows(windows []string, offsetX, offsetY int) error -``` - -### ApplyWorkflowLayout - -```go -func (s *Service) ApplyWorkflowLayout(workflow WorkflowType) error -``` - -Workflow types: - -```go -const ( - WorkflowCoding WorkflowType = "coding" - WorkflowDebugging WorkflowType = "debugging" - WorkflowPresenting WorkflowType = "presenting" -) -``` - -## Dialogs - -### File Dialogs - -```go -func (s *Service) OpenSingleFileDialog(opts OpenFileOptions) (string, error) -func (s *Service) OpenFileDialog(opts OpenFileOptions) ([]string, error) -func (s *Service) SaveFileDialog(opts SaveFileOptions) (string, error) -func (s *Service) OpenDirectoryDialog(opts OpenDirectoryOptions) (string, error) -``` - -Options: - -```go -type OpenFileOptions struct { - Title string - DefaultDirectory string - AllowMultiple bool - Filters []FileFilter -} - -type SaveFileOptions struct { - Title string - DefaultDirectory string - DefaultFilename string - Filters []FileFilter -} - -type FileFilter struct { - DisplayName string - Pattern string // e.g., "*.png;*.jpg" -} -``` - -### ConfirmDialog - -```go -func (s *Service) ConfirmDialog(title, message string) (bool, error) -``` - -### PromptDialog - -```go -func (s *Service) PromptDialog(title, message string) (string, bool, error) -``` - -## System Tray - -```go -func (s *Service) SetTrayIcon(icon []byte) error -func (s *Service) SetTrayTooltip(tooltip string) error -func (s *Service) SetTrayLabel(label string) error -func (s *Service) SetTrayMenu(items []TrayMenuItem) error -func (s *Service) GetTrayInfo() map[string]any -``` - -Menu item: - -```go -type TrayMenuItem struct { - Label string - ActionID string - IsSeparator bool -} -``` - -## Clipboard - -```go -func (s *Service) ReadClipboard() (string, error) -func (s *Service) WriteClipboard(text string) error -func (s *Service) HasClipboard() bool -func (s *Service) ClearClipboard() error -``` - -## Notifications - -```go -func (s *Service) ShowNotification(opts NotificationOptions) error -func (s *Service) ShowInfoNotification(title, message string) error -func (s *Service) ShowWarningNotification(title, message string) error -func (s *Service) ShowErrorNotification(title, message string) error -func (s *Service) RequestNotificationPermission() (bool, error) -func (s *Service) CheckNotificationPermission() (bool, error) -``` - -Options: - -```go -type NotificationOptions struct { - ID string - Title string - Message string - Subtitle string -} -``` - -## Theme - -```go -func (s *Service) GetTheme() *Theme -func (s *Service) GetSystemTheme() string -``` - -Returns: - -```go -type Theme struct { - IsDark bool -} -``` - -## Events - -```go -func (s *Service) GetEventManager() *EventManager -``` - -The EventManager handles WebSocket connections for real-time events. diff --git a/docs/framework/e.md b/docs/framework/e.md deleted file mode 100644 index 6db7114b..00000000 --- a/docs/framework/e.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: e ---- -# Service: `e` - -Package e provides a standardized error handling mechanism for the Core library. -It allows for wrapping errors with contextual information, making it easier to -trace the origin of an error and provide meaningful feedback. - -The design of this package is influenced by the need for a simple, yet powerful -way to handle errors that can occur in different layers of the application, -from low-level file operations to high-level service interactions. - -The key features of this package are: - - Error wrapping: The Op and an optional Msg field provide context about - where and why an error occurred. - - Stack traces: By wrapping errors, we can build a logical stack trace - that is more informative than a raw stack trace. - - Consistent error handling: Encourages a uniform approach to error - handling across the entire codebase. - -## Types - -### `type Error` - -`Error` represents a standardized error with operational context. - -```go -type Error struct { - // Op is the operation being performed, e.g., "config.Load". - Op string - // Msg is a human-readable message explaining the error. - Msg string - // Err is the underlying error that was wrapped. - Err error -} -``` - -#### Methods - -- `Error() string`: Error returns the string representation of the error. -- `Unwrap() error`: Unwrap provides compatibility for Go's errors.Is and errors.As functions. - -## Functions - -- `E(op, msg string, err error) error`: E is a helper function to create a new Error. - -This is the primary way to create errors that will be consumed by the system. For example: - -```go -return e.E("config.Load", "failed to load config file", err) -``` - -The `op` parameter should be in the format of `package.function` or `service.method`. The `msg` parameter should be a human-readable message that can be displayed to the user. The `err` parameter is the underlying error that is being wrapped. diff --git a/docs/framework/help.md b/docs/framework/help.md deleted file mode 100644 index 8f2614fc..00000000 --- a/docs/framework/help.md +++ /dev/null @@ -1,152 +0,0 @@ -# Help Service - -The Help service (`pkg/help`) provides an embeddable documentation system that displays MkDocs-based help content in a dedicated window. - -## Features - -- Embedded help content (MkDocs static site) -- Context-sensitive help navigation -- Works with or without Display service -- Multiple content sources (embedded, filesystem, custom) - -## Basic Usage - -```go -import "github.com/Snider/Core/pkg/help" - -// Create with default embedded content -helpService, err := help.New(help.Options{}) - -// Initialize with core dependencies -helpService.Init(coreInstance, displayService) -``` - -## Showing Help - -```go -// Show main help window -err := helpService.Show() - -// Show specific section -err := helpService.ShowAt("getting-started") -err := helpService.ShowAt("api/config") -``` - -## Options - -```go -type Options struct { - Source string // Path to help content directory - Assets fs.FS // Custom filesystem for assets -} -``` - -### Default Embedded Content - -```go -// Uses embedded MkDocs site -helpService, _ := help.New(help.Options{}) -``` - -### Custom Directory - -```go -// Use local directory -helpService, _ := help.New(help.Options{ - Source: "/path/to/docs/site", -}) -``` - -### Custom Filesystem - -```go -//go:embed docs/* -var docsFS embed.FS - -helpService, _ := help.New(help.Options{ - Assets: docsFS, -}) -``` - -## Integration with Core - -The help service can work standalone or integrated with Core: - -### With Display Service - -When Display service is available, help opens through the IPC action system: - -```go -// Automatically uses display.open_window action -helpService.Init(core, displayService) -helpService.Show() -``` - -### Without Display Service - -Falls back to direct Wails window creation: - -```go -// Creates window directly via Wails -helpService.Init(core, nil) -helpService.Show() -``` - -## Lifecycle - -```go -// Called on application startup -err := helpService.ServiceStartup(ctx) -``` - -## Building Help Content - -Help content is a static MkDocs site. To update: - -1. Edit documentation in `docs/` directory -2. Build with MkDocs: - ```bash - mkdocs build - ``` -3. The built site goes to `pkg/help/public/` -4. Content is embedded at compile time - -## Frontend Usage (TypeScript) - -```typescript -import { Show, ShowAt } from '@bindings/help/service'; - -// Open help window -await Show(); - -// Open specific section -await ShowAt("configuration"); -await ShowAt("api/display"); -``` - -## Help Window Options - -The help window opens with default settings: - -| Property | Value | -|----------|-------| -| Title | "Help" | -| Width | 800px | -| Height | 600px | - -## IPC Action - -When using Display service, help triggers this action: - -```go -{ - "action": "display.open_window", - "name": "help", - "options": { - "Title": "Help", - "Width": 800, - "Height": 600, - "URL": "/#anchor", // When using ShowAt - }, -} -``` diff --git a/docs/framework/i18n.md b/docs/framework/i18n.md deleted file mode 100644 index ce36b851..00000000 --- a/docs/framework/i18n.md +++ /dev/null @@ -1,130 +0,0 @@ -# I18n Service - -The I18n service (`pkg/i18n`) provides internationalization and localization support with automatic language detection and template-based translations. - -## Features - -- JSON-based locale files -- Embedded locale bundles -- Automatic language detection from environment -- Template variable interpolation -- BCP 47 language tag support - -## Basic Usage - -```go -import "github.com/Snider/Core/pkg/i18n" - -// Create service (defaults to English) -i18n, err := i18n.New() -if err != nil { - log.Fatal(err) -} -``` - -## Setting Language - -```go -// Set language using BCP 47 tag -err := i18n.SetLanguage("fr") -err := i18n.SetLanguage("en-US") -err := i18n.SetLanguage("zh-Hans") -``` - -## Translating Messages - -```go -// Simple translation -msg := i18n.Translate("welcome_message") - -// With template data -msg := i18n.Translate("greeting", map[string]string{ - "Name": "John", -}) -// Template: "Hello, {{.Name}}!" -// Result: "Hello, John!" -``` - -## Available Languages - -```go -// Get list of available language codes -langs := i18n.AvailableLanguages() -// Returns: ["en", "es", "fr", "de", ...] -``` - -## Get All Messages - -```go -// Get all translations for a language -messages, err := i18n.GetAllMessages("en") -for key, value := range messages { - fmt.Printf("%s: %s\n", key, value) -} -``` - -## Locale File Format - -Locale files are JSON stored in `locales/` directory: - -```json -// locales/en.json -{ - "welcome": "Welcome to the application", - "greeting": "Hello, {{.Name}}!", - "items_count": { - "one": "{{.Count}} item", - "other": "{{.Count}} items" - } -} -``` - -## Adding New Languages - -1. Create a new JSON file in `pkg/i18n/locales/`: - ``` - locales/es.json - ``` - -2. Add translations: - ```json - { - "welcome": "Bienvenido a la aplicación", - "greeting": "¡Hola, {{.Name}}!" - } - ``` - -3. The service automatically loads embedded locales at startup. - -## Language Detection - -The service can detect system language from the `LANG` environment variable: - -```go -// Automatic detection happens internally -// LANG=fr_FR.UTF-8 -> French -// LANG=de_DE.UTF-8 -> German -``` - -## Frontend Usage (TypeScript) - -```typescript -import { - SetLanguage, - Translate, - AvailableLanguages, - GetAllMessages -} from '@bindings/i18n/service'; - -// Set language -await SetLanguage("fr"); - -// Translate -const welcome = await Translate("welcome_message"); - -// Get available languages for a selector -const languages = await AvailableLanguages(); - -// Load all messages for client-side caching -const messages = await GetAllMessages("en"); -``` diff --git a/docs/framework/installation.md b/docs/framework/installation.md deleted file mode 100644 index 49e179a9..00000000 --- a/docs/framework/installation.md +++ /dev/null @@ -1,76 +0,0 @@ -# Installation - -## Prerequisites - -### Go 1.22+ - -```bash -# macOS -brew install go - -# Linux -sudo apt install golang-go - -# Windows - download from https://go.dev/dl/ -``` - -### Wails v3 - -```bash -go install github.com/wailsapp/wails/v3/cmd/wails3@latest -``` - -### Task (Build Automation) - -```bash -# macOS -brew install go-task - -# Linux -sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d - -# Windows -choco install go-task -``` - -## Install Core - -```bash -go get github.com/Snider/Core@latest -``` - -## Verify Installation - -```bash -# Check Go -go version - -# Check Wails -wails3 version - -# Check Task -task --version -``` - -## IDE Setup - -### VS Code - -Install the Go extension and configure: - -```json -{ - "go.useLanguageServer": true, - "gopls": { - "ui.semanticTokens": true - } -} -``` - -### GoLand / IntelliJ - -Go support is built-in. Enable the Wails plugin for additional features. - -## Next Steps - -Continue to [Quick Start](quickstart.md) to create your first application. diff --git a/docs/framework/io.md b/docs/framework/io.md deleted file mode 100644 index 6274d5fb..00000000 --- a/docs/framework/io.md +++ /dev/null @@ -1,165 +0,0 @@ -# IO Service - -The IO package (`pkg/io`) provides a unified interface for file operations across different storage backends (local filesystem, S3, SFTP, etc.). - -## Features - -- Abstract `Medium` interface for storage backends -- Local filesystem implementation -- Copy between different mediums -- Mock implementation for testing - -## Medium Interface - -All storage backends implement the `Medium` interface: - -```go -type Medium interface { - Read(path string) (string, error) - Write(path, content string) error - EnsureDir(path string) error - IsFile(path string) bool - FileGet(path string) (string, error) - FileSet(path, content string) error -} -``` - -## Local Filesystem - -```go -import ( - "github.com/Snider/Core/pkg/io" - "github.com/Snider/Core/pkg/io/local" -) - -// Pre-initialized global medium (root = "/") -content, err := io.Local.Read("/etc/hosts") - -// Create sandboxed medium -medium, err := local.New("/app/data") -content, err := medium.Read("config.json") // Reads /app/data/config.json -``` - -## Basic Operations - -```go -// Read file -content, err := medium.Read("path/to/file.txt") - -// Write file -err := medium.Write("path/to/file.txt", "content") - -// Check if file exists -if medium.IsFile("config.json") { - // File exists -} - -// Ensure directory exists -err := medium.EnsureDir("path/to/dir") - -// Convenience methods -content, err := medium.FileGet("file.txt") -err := medium.FileSet("file.txt", "content") -``` - -## Helper Functions - -Package-level functions that work with any Medium: - -```go -// Read from medium -content, err := io.Read(medium, "file.txt") - -// Write to medium -err := io.Write(medium, "file.txt", "content") - -// Ensure directory -err := io.EnsureDir(medium, "path/to/dir") - -// Check if file -exists := io.IsFile(medium, "file.txt") -``` - -## Copy Between Mediums - -```go -localMedium, _ := local.New("/local/path") -remoteMedium := s3.New(bucket, region) // hypothetical S3 implementation - -// Copy from local to remote -err := io.Copy(localMedium, "data.json", remoteMedium, "backup/data.json") -``` - -## Mock Medium for Testing - -```go -import "github.com/Snider/Core/pkg/io" - -func TestMyFunction(t *testing.T) { - mock := io.NewMockMedium() - - // Pre-populate files - mock.Files["config.json"] = `{"key": "value"}` - mock.Dirs["data"] = true - - // Use in tests - myService := NewService(mock) - - // Verify writes - err := myService.SaveData("test") - if mock.Files["data/test.json"] != expectedContent { - t.Error("unexpected content") - } -} -``` - -## Creating Custom Backends - -Implement the `Medium` interface for custom storage: - -```go -type S3Medium struct { - bucket string - client *s3.Client -} - -func (m *S3Medium) Read(path string) (string, error) { - // Implement S3 read -} - -func (m *S3Medium) Write(path, content string) error { - // Implement S3 write -} - -// ... implement remaining methods -``` - -## Error Handling - -```go -content, err := medium.Read("missing.txt") -if err != nil { - // File not found or read error - log.Printf("Read failed: %v", err) -} -``` - -## Frontend Usage - -The IO package is primarily used server-side. Frontend file operations should use the Display service dialogs or direct API calls: - -```typescript -import { OpenFileDialog, SaveFileDialog } from '@bindings/display/service'; - -// Open file picker -const path = await OpenFileDialog({ - title: "Select File", - filters: [{ displayName: "Text", pattern: "*.txt" }] -}); - -// Save file picker -const savePath = await SaveFileDialog({ - title: "Save As", - defaultFilename: "document.txt" -}); -``` diff --git a/docs/framework/ipc.md b/docs/framework/ipc.md deleted file mode 100644 index d506504e..00000000 --- a/docs/framework/ipc.md +++ /dev/null @@ -1,119 +0,0 @@ -# IPC & Actions - -Core provides an inter-process communication system for services to communicate without tight coupling. - -## Message Structure - -```go -type Message struct { - Type string // Message type identifier - Data map[string]any // Message payload - Source string // Originating service (optional) - Timestamp time.Time // When message was created -} -``` - -## Sending Messages - -```go -c.ACTION(core.Message{ - Type: "user.created", - Data: map[string]any{ - "id": "123", - "email": "user@example.com", - }, -}) -``` - -## Handling Messages - -Register action handlers during service initialization: - -```go -func NewNotificationService(c *core.Core) (any, error) { - svc := &NotificationService{} - - // Register handler - c.RegisterAction(func(c *core.Core, msg core.Message) error { - return svc.handleAction(msg) - }) - - return svc, nil -} - -func (s *NotificationService) handleAction(msg core.Message) error { - switch msg.Type { - case "user.created": - email := msg.Data["email"].(string) - return s.sendWelcomeEmail(email) - } - return nil -} -``` - -## Auto-Discovery - -Services implementing `HandleIPCEvents` are automatically registered: - -```go -type MyService struct{} - -// Automatically registered when using WithService -func (s *MyService) HandleIPCEvents(c *core.Core, msg core.Message) error { - // Handle messages - return nil -} -``` - -## Common Patterns - -### Request/Response - -```go -// Sender -responseChan := make(chan any) -c.ACTION(core.Message{ - Type: "data.request", - Data: map[string]any{ - "query": "SELECT * FROM users", - "response": responseChan, - }, -}) -result := <-responseChan - -// Handler -func (s *DataService) handleAction(msg core.Message) error { - if msg.Type == "data.request" { - query := msg.Data["query"].(string) - respChan := msg.Data["response"].(chan any) - - result, err := s.execute(query) - if err != nil { - return err - } - - respChan <- result - } - return nil -} -``` - -### Event Broadcasting - -```go -// Broadcast to all listeners -c.ACTION(core.Message{ - Type: "system.config.changed", - Data: map[string]any{ - "key": "theme", - "value": "dark", - }, -}) -``` - -## Best Practices - -1. **Use namespaced types** - `service.action` format -2. **Keep payloads simple** - Use primitive types when possible -3. **Handle errors** - Return errors from handlers -4. **Document message types** - Create constants for message types diff --git a/docs/framework/lifecycle.md b/docs/framework/lifecycle.md deleted file mode 100644 index 1830ce09..00000000 --- a/docs/framework/lifecycle.md +++ /dev/null @@ -1,101 +0,0 @@ -# Service Lifecycle - -Core provides lifecycle hooks for services to initialize and clean up resources. - -## Lifecycle Interfaces - -### Startable - -Called when the application starts: - -```go -type Startable interface { - OnStartup(ctx context.Context) error -} -``` - -### Stoppable - -Called when the application shuts down: - -```go -type Stoppable interface { - OnShutdown(ctx context.Context) error -} -``` - -## Implementation Example - -```go -type DatabaseService struct { - db *sql.DB -} - -func (s *DatabaseService) OnStartup(ctx context.Context) error { - db, err := sql.Open("postgres", os.Getenv("DATABASE_URL")) - if err != nil { - return err - } - - // Verify connection - if err := db.PingContext(ctx); err != nil { - return err - } - - s.db = db - return nil -} - -func (s *DatabaseService) OnShutdown(ctx context.Context) error { - if s.db != nil { - return s.db.Close() - } - return nil -} -``` - -## Lifecycle Order - -1. **Registration**: Services registered via `core.New()` -2. **Wails Binding**: Services bound to Wails app -3. **Startup**: `OnStartup()` called for each Startable service -4. **Running**: Application runs -5. **Shutdown**: `OnShutdown()` called for each Stoppable service - -## Context Usage - -The context passed to lifecycle methods includes: - -- Cancellation signal for graceful shutdown -- Deadline for timeout handling - -```go -func (s *Service) OnStartup(ctx context.Context) error { - select { - case <-ctx.Done(): - return ctx.Err() - case <-s.initialize(): - return nil - } -} -``` - -## Error Handling - -If `OnStartup` returns an error, the application will fail to start: - -```go -func (s *Service) OnStartup(ctx context.Context) error { - if err := s.validate(); err != nil { - return fmt.Errorf("validation failed: %w", err) - } - return nil -} -``` - -## Best Practices - -1. **Keep startup fast** - Defer heavy initialization -2. **Handle context cancellation** - Support graceful shutdown -3. **Clean up resources** - Always implement OnShutdown for services with resources -4. **Log lifecycle events** - Helps with debugging diff --git a/docs/framework/mcp-bridge.md b/docs/framework/mcp-bridge.md deleted file mode 100644 index d654a3e9..00000000 --- a/docs/framework/mcp-bridge.md +++ /dev/null @@ -1,220 +0,0 @@ -# MCP Bridge - -The MCP Bridge (`cmd/core-gui/mcp_bridge.go`) connects the Model Context Protocol server with Display, WebView, and WebSocket services. - -## Overview - -The MCP Bridge provides an HTTP API for AI assistants to interact with the desktop application, enabling: - -- Window and screen management -- JavaScript execution in webviews -- DOM interaction (click, type, select) -- Screenshot capture -- File and process management -- Real-time events via WebSocket - -## HTTP Endpoints - -| Endpoint | Description | -|----------|-------------| -| `GET /health` | Health check | -| `GET /mcp` | Server capabilities | -| `GET /mcp/tools` | List available tools | -| `POST /mcp/call` | Execute a tool | -| `WS /ws` | WebSocket for GUI clients | -| `WS /events` | WebSocket for display events | - -## Server Capabilities - -```bash -curl http://localhost:9877/mcp -``` - -Response: - -```json -{ - "name": "core", - "version": "0.1.0", - "capabilities": { - "webview": true, - "display": true, - "windowControl": true, - "screenControl": true, - "websocket": "ws://localhost:9877/ws", - "events": "ws://localhost:9877/events" - } -} -``` - -## Tool Categories - -### File Operations - -| Tool | Description | -|------|-------------| -| `file_read` | Read file contents | -| `file_write` | Write content to file | -| `file_edit` | Edit file by replacing text | -| `file_delete` | Delete a file | -| `file_exists` | Check if file exists | -| `dir_list` | List directory contents | -| `dir_create` | Create directory | - -### Window Control - -| Tool | Description | -|------|-------------| -| `window_list` | List all windows | -| `window_create` | Create new window | -| `window_close` | Close window | -| `window_position` | Move window | -| `window_size` | Resize window | -| `window_maximize` | Maximize window | -| `window_minimize` | Minimize window | -| `window_focus` | Bring window to front | - -### WebView Interaction - -| Tool | Description | -|------|-------------| -| `webview_eval` | Execute JavaScript | -| `webview_click` | Click element | -| `webview_type` | Type into element | -| `webview_screenshot` | Capture page | -| `webview_navigate` | Navigate to URL | -| `webview_console` | Get console messages | - -### Screen Management - -| Tool | Description | -|------|-------------| -| `screen_list` | List all monitors | -| `screen_primary` | Get primary screen | -| `screen_at_point` | Get screen at coordinates | -| `screen_work_areas` | Get usable screen space | - -### Layout Management - -| Tool | Description | -|------|-------------| -| `layout_save` | Save window arrangement | -| `layout_restore` | Restore saved layout | -| `layout_tile` | Auto-tile windows | -| `layout_snap` | Snap window to edge | - -## Calling Tools - -```bash -# List windows -curl -X POST http://localhost:9877/mcp/call \ - -H "Content-Type: application/json" \ - -d '{"tool": "window_list", "params": {}}' - -# Move window -curl -X POST http://localhost:9877/mcp/call \ - -H "Content-Type: application/json" \ - -d '{ - "tool": "window_position", - "params": {"name": "main", "x": 100, "y": 100} - }' - -# Execute JavaScript -curl -X POST http://localhost:9877/mcp/call \ - -H "Content-Type: application/json" \ - -d '{ - "tool": "webview_eval", - "params": { - "window": "main", - "code": "document.title" - } - }' - -# Click element -curl -X POST http://localhost:9877/mcp/call \ - -H "Content-Type: application/json" \ - -d '{ - "tool": "webview_click", - "params": { - "window": "main", - "selector": "#submit-button" - } - }' - -# Take screenshot -curl -X POST http://localhost:9877/mcp/call \ - -H "Content-Type: application/json" \ - -d '{ - "tool": "webview_screenshot", - "params": {"window": "main"} - }' -``` - -## WebSocket Events - -Connect to `/events` for real-time display events: - -```javascript -const ws = new WebSocket('ws://localhost:9877/events'); - -ws.onmessage = (event) => { - const data = JSON.parse(event.data); - switch (data.type) { - case 'window.focus': - console.log('Window focused:', data.name); - break; - case 'window.move': - console.log('Window moved:', data.name, data.x, data.y); - break; - case 'theme.change': - console.log('Theme changed:', data.isDark); - break; - } -}; -``` - -Event types: - -- `window.focus` - Window received focus -- `window.blur` - Window lost focus -- `window.move` - Window position changed -- `window.resize` - Window size changed -- `window.close` - Window was closed -- `window.create` - New window created -- `theme.change` - System theme changed -- `screen.change` - Screen configuration changed - -## Go Integration - -```go -import "github.com/Snider/Core/cmd/core-gui" - -// Create bridge -bridge := NewMCPBridge(9877, displayService) - -// Access services -mcpSvc := bridge.GetMCPService() -webview := bridge.GetWebView() -display := bridge.GetDisplay() -``` - -## Configuration - -The bridge starts automatically on Wails app startup via the `ServiceStartup` lifecycle hook: - -```go -func (b *MCPBridge) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { - b.app = application.Get() - b.webview.SetApp(b.app) - go b.startHTTPServer() - return nil -} -``` - -## Security - -The MCP server binds to localhost only by default. For production: - -- Consider firewall rules -- Add authentication if needed -- Limit exposed tools diff --git a/docs/framework/mcp.md b/docs/framework/mcp.md deleted file mode 100644 index cf437b20..00000000 --- a/docs/framework/mcp.md +++ /dev/null @@ -1,151 +0,0 @@ -# MCP Service - -The MCP service (`pkg/mcp`) implements the [Model Context Protocol](https://modelcontextprotocol.io/), enabling AI assistants like Claude to interact with your application. - -## Overview - -MCP provides a standardized way for AI tools to: - -- Execute operations in your application -- Query application state -- Interact with the UI -- Manage files and processes - -## Basic Setup - -```go -import "github.com/Snider/Core/pkg/mcp" - -// Create standalone MCP server -mcpService := mcp.NewStandaloneWithPort(9877) - -// Or integrate with Core -c, _ := core.New( - core.WithService(mcp.NewService), -) -``` - -## Available Tools - -The MCP service exposes numerous tools organized by category: - -### File Operations - -| Tool | Description | -|------|-------------| -| `file_read` | Read file contents | -| `file_write` | Write content to file | -| `file_edit` | Replace text in file | -| `file_delete` | Delete a file | -| `file_exists` | Check if file exists | -| `dir_list` | List directory contents | -| `dir_create` | Create directory | - -### Window Control - -| Tool | Description | -|------|-------------| -| `window_list` | List all windows | -| `window_create` | Create new window | -| `window_close` | Close window | -| `window_position` | Move window | -| `window_size` | Resize window | -| `window_maximize` | Maximize window | -| `window_minimize` | Minimize window | -| `window_focus` | Bring to front | - -### WebView Interaction - -| Tool | Description | -|------|-------------| -| `webview_eval` | Execute JavaScript | -| `webview_click` | Click element | -| `webview_type` | Type into element | -| `webview_screenshot` | Capture page | -| `webview_navigate` | Navigate to URL | -| `webview_console` | Get console logs | - -### Process Management - -| Tool | Description | -|------|-------------| -| `process_start` | Start a process | -| `process_stop` | Stop a process | -| `process_list` | List running processes | -| `process_output` | Get process output | - -## HTTP API - -The MCP service exposes an HTTP API: - -```bash -# Health check -curl http://localhost:9877/health - -# List available tools -curl http://localhost:9877/mcp/tools - -# Call a tool -curl -X POST http://localhost:9877/mcp/call \ - -H "Content-Type: application/json" \ - -d '{"tool": "window_list", "params": {}}' -``` - -## WebSocket Events - -Connect to `/events` for real-time updates: - -```javascript -const ws = new WebSocket('ws://localhost:9877/events'); -ws.onmessage = (event) => { - const data = JSON.parse(event.data); - console.log('Event:', data.type, data.data); -}; -``` - -## Integration with Display Service - -```go -mcpService := mcp.NewStandaloneWithPort(9877) -mcpService.SetDisplay(displayService) -mcpService.SetWebView(webviewService) -``` - -## Example: Claude Integration - -When Claude connects via MCP, it can: - -``` -User: "Move the settings window to the left side of the screen" - -Claude uses: window_position("settings", 0, 100) -``` - -``` -User: "Take a screenshot of the app" - -Claude uses: webview_screenshot("main") -``` - -``` -User: "Click the submit button" - -Claude uses: webview_click("main", "#submit-btn") -``` - -## Security Considerations - -- MCP server binds to localhost by default -- No authentication (designed for local AI assistants) -- Consider firewall rules for production - -## Configuration - -```go -// Custom port -mcp.NewStandaloneWithPort(8080) - -// With all services -bridge := NewMCPBridge(9877, displayService) -bridge.SetWebView(webviewService) -``` diff --git a/docs/framework/modules.md b/docs/framework/modules.md deleted file mode 100644 index d6a748d9..00000000 --- a/docs/framework/modules.md +++ /dev/null @@ -1,271 +0,0 @@ -# Module System - -The Module system (`pkg/module`) provides a declarative way to register UI menus, routes, and API endpoints using the `.itw3.json` configuration format. - -## Features - -- Declarative module configuration -- UI menu contributions -- Frontend route registration -- API endpoint declarations -- Multi-context support (developer, retail, miner) -- Binary/daemon management -- Module dependencies - -## Module Config Format - -Modules are defined using `.itw3.json` files: - -```json -{ - "code": "wallet", - "type": "core", - "name": "Wallet Manager", - "version": "1.0.0", - "namespace": "finance", - "description": "Cryptocurrency wallet management", - "author": "Your Name", - "contexts": ["default", "retail"], - "menu": [...], - "routes": [...], - "api": [...], - "config": {...} -} -``` - -## Module Types - -| Type | Description | -|------|-------------| -| `core` | Built-in core functionality | -| `app` | External web application | -| `bin` | Binary/daemon wrapper | - -## UI Contexts - -Modules can target specific UI contexts: - -| Context | Description | -|---------|-------------| -| `default` | Standard user interface | -| `developer` | Developer tools and debugging | -| `retail` | Point-of-sale interface | -| `miner` | Mining operations interface | - -## Menu Contributions - -Add items to the application menu: - -```json -{ - "menu": [ - { - "id": "wallet-send", - "label": "Send Funds", - "icon": "send", - "route": "/wallet/send", - "accelerator": "CmdOrCtrl+Shift+S", - "contexts": ["default", "retail"], - "order": 10 - }, - { - "id": "wallet-receive", - "label": "Receive", - "icon": "receive", - "route": "/wallet/receive", - "order": 20 - }, - { - "separator": true - }, - { - "id": "wallet-settings", - "label": "Settings", - "action": "wallet.open_settings", - "children": [ - {"id": "wallet-backup", "label": "Backup", "action": "wallet.backup"}, - {"id": "wallet-restore", "label": "Restore", "action": "wallet.restore"} - ] - } - ] -} -``` - -## Route Contributions - -Register frontend routes: - -```json -{ - "routes": [ - { - "path": "/wallet", - "component": "wallet-dashboard", - "title": "Wallet", - "icon": "wallet", - "contexts": ["default"] - }, - { - "path": "/wallet/send", - "component": "wallet-send-form", - "title": "Send Funds" - } - ] -} -``` - -## API Declarations - -Declare API endpoints the module provides: - -```json -{ - "api": [ - { - "method": "GET", - "path": "/balance", - "description": "Get wallet balance" - }, - { - "method": "POST", - "path": "/send", - "description": "Send transaction" - } - ] -} -``` - -## Binary Downloads - -For `bin` type modules, specify platform binaries: - -```json -{ - "downloads": { - "app": "https://example.com/wallet-ui.tar.gz", - "x86_64": { - "darwin": { - "url": "https://example.com/wallet-darwin-x64", - "checksum": "sha256:abc123..." - }, - "linux": { - "url": "https://example.com/wallet-linux-x64", - "checksum": "sha256:def456..." - }, - "windows": { - "url": "https://example.com/wallet-win-x64.exe", - "checksum": "sha256:ghi789..." - } - }, - "aarch64": { - "darwin": { - "url": "https://example.com/wallet-darwin-arm64" - } - } - } -} -``` - -## Web App Configuration - -For `app` type modules: - -```json -{ - "app": { - "url": "https://example.com/wallet-app.tar.gz", - "type": "spa", - "hooks": [ - { - "type": "rename", - "from": "dist", - "to": "wallet" - } - ] - } -} -``` - -## Dependencies - -Declare module dependencies: - -```json -{ - "depends": ["core", "crypto"] -} -``` - -## Using in Go - -### Module Registration - -```go -import "github.com/Snider/Core/pkg/module" - -// Create from config -cfg := module.Config{ - Code: "wallet", - Type: module.TypeCore, - Name: "Wallet", - Namespace: "finance", -} - -mod := module.Module{ - Config: cfg, - Handler: myHandler, -} -``` - -### Gin Router Integration - -```go -type WalletModule struct{} - -func (m *WalletModule) RegisterRoutes(group *gin.RouterGroup) { - group.GET("/balance", m.getBalance) - group.POST("/send", m.sendTransaction) -} - -// Register with Gin -router := gin.Default() -apiGroup := router.Group("/api/finance/wallet") -walletModule.RegisterRoutes(apiGroup) -``` - -## Registry Service - -The registry manages all modules: - -```go -import "github.com/Snider/Core/pkg/module" - -registry := module.NewRegistry() - -// Register module -registry.Register(walletModule) - -// Get module by code -mod := registry.Get("wallet") - -// List all modules -modules := registry.List() - -// Get modules for context -devModules := registry.ForContext(module.ContextDeveloper) -``` - -## Built-in Modules - -Core provides several built-in modules: - -- System information -- Configuration management -- Process management -- File operations - -Access via: - -```go -builtins := module.BuiltinModules() -``` diff --git a/docs/framework/overview.md b/docs/framework/overview.md deleted file mode 100644 index 1c6f1106..00000000 --- a/docs/framework/overview.md +++ /dev/null @@ -1,175 +0,0 @@ -# GUI Application - -The Core GUI (`cmd/core-gui`) is a Wails v3 desktop application that demonstrates the Core framework capabilities with integrated MCP support. - -## Features - -- Angular frontend with Wails bindings -- MCP HTTP server for AI tool integration -- WebView automation capabilities -- Real-time WebSocket communication -- System tray support -- Multi-window management - -## Architecture - -``` -┌─────────────────────────────────────────┐ -│ Angular Frontend │ -│ (TypeScript + Wails Bindings) │ -└─────────────────┬───────────────────────┘ - │ IPC -┌─────────────────┴───────────────────────┐ -│ Wails Runtime │ -│ (Window, Events, Bindings) │ -└─────────────────┬───────────────────────┘ - │ -┌─────────────────┴───────────────────────┐ -│ MCP Bridge │ -│ ┌─────────┬──────────┬─────────────┐ │ -│ │ Display │ WebView │ WebSocket │ │ -│ │ Service │ Service │ Hub │ │ -│ └─────────┴──────────┴─────────────┘ │ -└─────────────────────────────────────────┘ -``` - -## Running the GUI - -### Development Mode - -```bash -# From project root -task gui:dev - -# Or directly -cd cmd/core-gui -wails3 dev -``` - -### Production Build - -```bash -task gui:build -``` - -## Directory Structure - -``` -cmd/core-gui/ -├── main.go # Application entry point -├── mcp_bridge.go # MCP HTTP server and tool handler -├── claude_bridge.go # Claude MCP client (optional) -├── frontend/ # Angular application -│ ├── src/ -│ │ ├── app/ # Angular components -│ │ └── lib/ # Shared utilities -│ └── bindings/ # Generated Wails bindings -└── public/ # Static assets -``` - -## Services Integrated - -The GUI integrates several Core services: - -| Service | Purpose | -|---------|---------| -| Display | Window management, dialogs, tray | -| WebView | JavaScript execution, DOM interaction | -| MCP | AI tool protocol server | -| WebSocket | Real-time communication | - -## Configuration - -The application uses the Config service for settings: - -```go -// Default settings -DefaultRoute: "/" -Language: "en" -Features: [] -``` - -## Frontend Bindings - -Wails generates TypeScript bindings for Go services: - -```typescript -import { CreateWindow, ShowNotification } from '@bindings/display/service'; -import { Translate, SetLanguage } from '@bindings/i18n/service'; - -// Create a new window -await CreateWindow({ - name: "settings", - title: "Settings", - width: 800, - height: 600 -}); - -// Show notification -await ShowNotification({ - title: "Success", - message: "Operation completed!" -}); -``` - -## WebSocket Communication - -Connect to the WebSocket endpoint for real-time updates: - -```typescript -const ws = new WebSocket('ws://localhost:9877/ws'); - -ws.onmessage = (event) => { - const data = JSON.parse(event.data); - console.log('Received:', data); -}; - -ws.send(JSON.stringify({ - type: 'ping', - data: {} -})); -``` - -## System Tray - -The application includes system tray support: - -```go -// Set tray menu -display.SetTrayMenu([]display.TrayMenuItem{ - {Label: "Open", ActionID: "open"}, - {Label: "Settings", ActionID: "settings"}, - {IsSeparator: true}, - {Label: "Quit", ActionID: "quit"}, -}) -``` - -## Building for Distribution - -### macOS - -```bash -task gui:build -# Creates: build/bin/core-gui.app -``` - -### Windows - -```bash -task gui:build -# Creates: build/bin/core-gui.exe -``` - -### Linux - -```bash -task gui:build -# Creates: build/bin/core-gui -``` - -## Environment Variables - -| Variable | Description | -|----------|-------------| -| `MCP_PORT` | MCP server port (default: 9877) | -| `DEBUG` | Enable debug logging | diff --git a/docs/framework/plugins.md b/docs/framework/plugins.md deleted file mode 100644 index 945ff294..00000000 --- a/docs/framework/plugins.md +++ /dev/null @@ -1,172 +0,0 @@ -# Plugin System - -The Plugin system (`pkg/plugin`) allows you to extend Core applications with HTTP-based plugins that register routes under `/api/{namespace}/{name}/`. - -## Features - -- Namespace-based organization -- HTTP handler registration -- Lifecycle hooks (OnRegister, OnUnregister) -- Wails service integration - -## Plugin Interface - -All plugins implement the `Plugin` interface: - -```go -type Plugin interface { - // Name returns the unique identifier for this plugin - Name() string - - // Namespace returns the plugin's namespace (e.g., "core", "mining") - Namespace() string - - // ServeHTTP handles HTTP requests routed to this plugin - http.Handler - - // OnRegister is called when the plugin is registered - OnRegister(ctx context.Context) error - - // OnUnregister is called when the plugin is being removed - OnUnregister(ctx context.Context) error -} -``` - -## Using BasePlugin - -For simple plugins, embed `BasePlugin`: - -```go -import "github.com/Snider/Core/pkg/plugin" - -func NewMyPlugin() *plugin.BasePlugin { - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("Hello from plugin!")) - }) - - return plugin.NewBasePlugin("myapp", "greeting", handler). - WithDescription("A simple greeting plugin"). - WithVersion("1.0.0") -} -``` - -## Custom Plugin Implementation - -For more control, implement the full interface: - -```go -type DataPlugin struct { - db *sql.DB -} - -func (p *DataPlugin) Name() string { return "data" } -func (p *DataPlugin) Namespace() string { return "myapp" } - -func (p *DataPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) { - switch r.URL.Path { - case "/users": - p.handleUsers(w, r) - case "/items": - p.handleItems(w, r) - default: - http.NotFound(w, r) - } -} - -func (p *DataPlugin) OnRegister(ctx context.Context) error { - // Initialize database connection - db, err := sql.Open("postgres", os.Getenv("DATABASE_URL")) - if err != nil { - return err - } - p.db = db - return nil -} - -func (p *DataPlugin) OnUnregister(ctx context.Context) error { - if p.db != nil { - return p.db.Close() - } - return nil -} -``` - -## Plugin Info - -Access plugin metadata: - -```go -info := myPlugin.Info() -fmt.Println(info.Name) // "greeting" -fmt.Println(info.Namespace) // "myapp" -fmt.Println(info.Description) // "A simple greeting plugin" -fmt.Println(info.Version) // "1.0.0" -``` - -## Wails Integration - -Register plugins as Wails services: - -```go -app := application.New(application.Options{ - Services: []application.Service{ - application.NewServiceWithOptions( - myPlugin, - plugin.ServiceOptionsForPlugin(myPlugin), - ), - }, -}) -``` - -## URL Routing - -Plugins receive requests at: - -``` -/api/{namespace}/{name}/{path} -``` - -Examples: -- `/api/myapp/greeting/` → GreetingPlugin -- `/api/myapp/data/users` → DataPlugin (path: "/users") -- `/api/core/system/health` → SystemPlugin (path: "/health") - -## Built-in Plugins - -### System Plugin - -Located at `pkg/plugin/builtin/system`: - -```go -// Provides system information endpoints -/api/core/system/info - Application info -/api/core/system/health - Health check -``` - -## Plugin Router - -The Router manages plugin registration: - -```go -import "github.com/Snider/Core/pkg/plugin" - -router := plugin.NewRouter() - -// Register plugins -router.Register(ctx, myPlugin) -router.Register(ctx, dataPlugin) - -// Get all registered plugins -plugins := router.List() - -// Unregister a plugin -router.Unregister(ctx, "myapp", "greeting") -``` - -## Best Practices - -1. **Use namespaces** to group related plugins -2. **Implement OnRegister** for initialization that can fail -3. **Implement OnUnregister** to clean up resources -4. **Return meaningful errors** from lifecycle hooks -5. **Use standard HTTP patterns** in ServeHTTP diff --git a/docs/framework/quickstart.md b/docs/framework/quickstart.md deleted file mode 100644 index 5fe43b25..00000000 --- a/docs/framework/quickstart.md +++ /dev/null @@ -1,128 +0,0 @@ -# Quick Start - -Build a simple Core application in 5 minutes. - -## Create Project - -```bash -mkdir myapp && cd myapp -go mod init myapp -``` - -## Install Dependencies - -```bash -go get github.com/Snider/Core@latest -go get github.com/wailsapp/wails/v3@latest -``` - -## Create Main File - -Create `main.go`: - -```go -package main - -import ( - "context" - "embed" - "log" - - "github.com/Snider/Core/pkg/core" - "github.com/Snider/Core/pkg/display" - "github.com/wailsapp/wails/v3/pkg/application" -) - -//go:embed all:frontend/dist -var assets embed.FS - -func main() { - // Initialize Core with display service - c, err := core.New( - core.WithAssets(assets), - core.WithService(display.NewService), - ) - if err != nil { - log.Fatal(err) - } - - // Get display service for window creation - displaySvc := core.MustServiceFor[*display.Service](c, "display") - - // Create Wails application - app := application.New(application.Options{ - Name: "My App", - Assets: application.AssetOptions{ - FS: assets, - }, - }) - - // Create main window - app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ - Title: "My App", - Width: 1200, - Height: 800, - URL: "/", - }) - - // Register display service with Wails - app.RegisterService(displaySvc) - - // Run application - if err := app.Run(); err != nil { - log.Fatal(err) - } -} -``` - -## Create Frontend - -Create a minimal frontend: - -```bash -mkdir -p frontend/dist -``` - -Create `frontend/dist/index.html`: - -```html - - -
-