Compacted CLAUDE.md file

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Felipe M 2025-07-09 16:58:34 +02:00
parent 73149001eb
commit 4f0b94354c
No known key found for this signature in database
GPG key ID: 52E5D65FCF99808A

281
CLAUDE.md
View file

@ -1,261 +1,52 @@
# pluginctl - Mattermost Plugin Development CLI
# pluginctl - Claude Memory
## Project Overview
`pluginctl` is a command-line interface tool for Mattermost plugin development. It provides utilities to manage, inspect, and work with Mattermost plugins from the command line.
## Critical Architecture Rules
## Architecture Guidelines
### Command Structure
### Project Structure
```
pluginctl/
├── cmd/pluginctl/main.go # CLI entrypoint with command routing
├── plugin.go # Plugin manifest handling utilities
├── info.go # Info command implementation
├── [command].go # Additional command implementations
├── go.mod # Go module definition
├── go.sum # Go module dependencies
├── pluginctl # Built binary (gitignored)
└── CLAUDE.md # This architecture document
```
- **CRITICAL**: ALL command logic in separate files in ROOT folder (e.g., `info.go`, `enable.go`)
- **NEVER** put command implementation in `cmd/pluginctl/main.go` - only CLI framework code
- **Command pattern**: `run[Command]Command(args []string, pluginPath string) error`
- **Registration**: Add to `runCommand()` switch in main.go
### Design Principles
### Dependencies & Types
#### 1. **Separation of Concerns**
- **CLI Framework**: `cmd/pluginctl/main.go` handles argument parsing, command routing, and error handling
- **Command Implementation**: Each command gets its own file (e.g., `info.go`, `build.go`, `deploy.go`) **IN THE ROOT FOLDER, NOT IN cmd/pluginctl/**
- **Utility Functions**: Common plugin operations in `plugin.go`
**CRITICAL ARCHITECTURE RULE**: ALL COMMAND LOGIC MUST BE IN SEPARATE FILES IN THE ROOT FOLDER. The cmd/pluginctl/main.go file should ONLY contain CLI framework code (argument parsing, command routing, wrapper functions). Never put command implementation logic directly in main.go.
#### 2. **Plugin Manifest Handling**
- **Always use official Mattermost types**: Import `github.com/mattermost/mattermost/server/public/model` and use `model.Manifest`
- **Validation**: Always validate plugin.json existence and format before operations
- **Path handling**: Support both current directory and custom path operations
#### 3. **Command Structure**
- **Main command router**: Add new commands to the `runCommand()` function in `cmd/pluginctl/main.go`
- **Command functions**: Name pattern: `run[Command]Command(args []string, pluginPath string) error`
- **Error handling**: Return descriptive errors, let main.go handle exit codes
- **Command implementation**: Each command's logic goes in a separate file in the root folder (e.g., `enable.go`, `disable.go`, `reset.go`)
- **Command wrapper functions**: The main.go file contains simple wrapper functions that call the actual command implementations
#### 4. **Code Organization**
- **No inline implementations**: Keep command logic in separate files
- **Reusable utilities**: Common operations go in `plugin.go`
- **Self-contained**: Each command file should be importable and testable
### Current Commands
#### `info`
- **Purpose**: Display plugin manifest information
- **Implementation**: `info.go`
- **Usage**: `pluginctl info`
- **Features**:
- Shows plugin ID, name, version
- Displays minimum Mattermost version
- Indicates server/webapp code presence
- Shows settings schema availability
- **Path Resolution**: Uses global path logic (--plugin-path flag, environment variable, or current directory)
### Adding New Commands
#### Step 1: Create Command File
Create a new file named `[command].go` with the command implementation:
```go
package main
import (
"fmt"
"github.com/mattermost/mattermost/server/public/model"
)
func run[Command]Command(args []string, pluginPath string) error {
// Command implementation here
// Use pluginPath to load plugin manifest
return nil
}
```
#### Step 2: Register in Main Router
Add the command to the `runCommand()` function in `cmd/pluginctl/main.go`:
```go
func runCommand(command string, args []string, pluginPath string) error {
switch command {
case "info":
return runInfoCommand(args, pluginPath)
case "new-command":
return runNewCommandCommand(args, pluginPath)
// ... other commands
}
}
```
#### Step 3: Update Help Text
Add the command to the `showUsage()` function in `main.go`.
### Dependencies
#### Core Dependencies
- `github.com/mattermost/mattermost/server/public/model` - Official Mattermost plugin types
- Standard Go library for CLI operations
#### Dependency Management
- Use `go mod tidy` to manage dependencies
- Prefer standard library over external packages when possible
- Only add dependencies that provide significant value
### Build System and Development Tools
#### Tool Versions
The project uses pinned versions for reproducible builds:
- **golangci-lint**: v1.62.2
- **goreleaser**: v2.6.2
- **gosec**: v2.22.0
- **Go**: 1.24.3
#### Makefile Targets
**Development Workflow:**
- `make dev` - Quick development build (fmt, lint, build)
- `make check-changes` - Check changes (lint, security, test)
- `make verify` - Full verification (clean, lint, test, build)
**Building:**
- `make build` - Build binary for current platform
- `make build-all` - Build for all supported platforms
- `make install` - Install binary to GOPATH/bin
**Testing and Quality:**
- `make test` - Run tests
- `make test-coverage` - Run tests with coverage report
- `make lint` - Run linter
- `make lint-fix` - Fix linting issues automatically
- `make security` - Run security scan with gosec
**Development Setup:**
- `make dev-setup` - Install all development tools with pinned versions
- `make deps` - Install/update dependencies
- `make fmt` - Format code
**Release Management:**
- `make release` - Create production release (requires goreleaser)
- `make snapshot` - Create snapshot release for testing
**Utilities:**
- `make clean` - Clean build artifacts
- `make version` - Show version and tool information
- `make help` - Show all available targets
#### Configuration Files
**Makefile**
- Uses `go get -tool` for Go 1.24+ tool management
- Cross-platform build support (Linux, macOS, Windows)
- Git-based version information in binaries
**.goreleaser.yml**
- Multi-platform release automation
- GitHub releases with changelog generation
- Package manager integration (Homebrew, Scoop)
- Docker image building support
**.golangci.yml**
- 40+ enabled linters for comprehensive code quality
- Optimized for Go 1.24
- Security scanning integration
- Test file exclusions for appropriate linters
#### Development Workflow
1. **Setup**: `make dev-setup` (one-time)
2. **Development**: `make dev` (format, lint, build)
3. **Before commit**: `make check-changes` (lint, security, test)
4. **Full verification**: `make verify` (complete build verification)
#### Building
```bash
# Quick build
make build
# Cross-platform builds
make build-all
# Development build with checks
make dev
```
#### Testing
- Always test with a sample plugin.json file
- Test both current directory and custom path operations
- Verify help and version commands work correctly
- Use `make test-coverage` for coverage reports
### Error Handling Standards
#### Error Messages
- Use descriptive error messages that help users understand what went wrong
- Include file paths in error messages when relevant
- Wrap errors with context using `fmt.Errorf("operation failed: %w", err)`
#### Exit Codes
- `0`: Success
- `1`: General error
- Let main.go handle all exit codes - command functions should return errors
- Use `github.com/mattermost/mattermost/server/public/model.Manifest`
- Commands in `pluginctl` package, main.go calls them
### Plugin Path Resolution
#### Priority Order
1. **Command-line flag**: `--plugin-path /path/to/plugin`
2. **Environment variable**: `PLUGINCTL_PLUGIN_PATH=/path/to/plugin`
3. **Current directory**: Default fallback
1. `--plugin-path` flag
2. `PLUGINCTL_PLUGIN_PATH` env var
3. Current directory (default)
#### Implementation
- `getEffectivePluginPath(flagPath string) string` - Determines effective plugin path
- All commands receive the resolved plugin path as a parameter
- Path is resolved to absolute path before use
### Logging
### Plugin Validation
- **CRITICAL**: Use `pluginctl.Logger` (global slog instance)
- **Error**: `pluginctl.Logger.Error("message", "error", err)`
- **Info**: `pluginctl.Logger.Info("message")`
- **NEVER** use `fmt.Print*` or `log.*`
#### Required Checks
- Plugin.json file must exist
- Plugin.json must be valid JSON
- Plugin.json must conform to Mattermost manifest schema
### Build & Development
#### Utility Functions (plugin.go)
- `LoadPluginManifest()` - Load from current directory
- `LoadPluginManifestFromPath(path)` - Load from specific path
- `HasServerCode(manifest)` - Check for server-side code
- `HasWebappCode(manifest)` - Check for webapp code
- `IsValidPluginDirectory()` - Validate current directory
- **CRITICAL**: Use `make dev` for testing builds, NOT `go build`
- **Before commit**: `make check-changes`
- **Dependencies**: `make deps && go mod tidy`
### Future Command Ideas
- `init` - Initialize a new plugin project
- `build` - Build plugin for distribution
- `deploy` - Deploy plugin to Mattermost instance
- `validate` - Validate plugin structure and manifest
- `package` - Package plugin for distribution
- `test` - Run plugin tests
### Error Handling
### Version Management
- Current version: 0.1.0
- Update version in `main.go` when releasing
- Follow semantic versioning
- Commands return errors, main.go handles exit codes
- Use `fmt.Errorf("context: %w", err)` for wrapping
### Documentation Maintenance
- **CRITICAL**: Always keep README.md up to date with any changes
- When adding new commands, update both CLAUDE.md and README.md
- When changing build processes, update both architecture docs and user docs
- When adding new dependencies or tools, document them in both files
- README.md is the user-facing documentation - it must be comprehensive and current
### Adding New Commands
### Notes for Claude Sessions
- Always maintain the separation between CLI framework and command implementation
- Use the official Mattermost model types - never create custom manifest structs
- Keep command implementations in separate files for maintainability
- Always validate plugin.json before performing operations
- Test new commands with the sample plugin.json file
- Follow the established error handling patterns
- Use the build system: `make check-changes` before any commits
- Use pinned tool versions for reproducible development environments
1. Create `[command].go` in root with `Run[Command]Command` function
2. Add case to `runCommand()` switch in main.go
3. Update `showUsage()` in main.go
### Key Patterns
- Always validate plugin.json exists before operations
- Use structured logging with key-value pairs
- Follow existing naming conventions
- Keep command files self-contained and testable