pkg/cli now lives in forge.lthn.ai/core/cli as its own module.
All cmd/gocmd imports updated. qa docblock check stubbed pending
go-devops circular dependency resolution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the RegisterCommands/attachRegisteredCommands side-channel with
WithCommands(), which wraps command registration functions as framework
services. Commands now participate in the Core lifecycle via OnStartup,
receiving the root cobra.Command through Core.App.
Main() accepts variadic framework.Option so binaries pass their commands
explicitly — no init(), no blank imports, no global state.
Co-Authored-By: Virgil <virgil@lethean.io>
- Fix remaining 187 pkg/ files referencing core/cli → core/go
- Move SDK library code from internal/cmd/sdk/ → pkg/sdk/ (new package)
- Create pkg/rag/helpers.go with convenience functions from internal/cmd/rag/
- Fix pkg/mcp/tools_rag.go to use pkg/rag instead of internal/cmd/rag
- Fix pkg/build/buildcmd/cmd_sdk.go and pkg/release/sdk.go to use pkg/sdk
- Remove all non-library content: main.go, internal/, cmd/, docker/,
scripts/, tasks/, tools/, .core/, .forgejo/, .woodpecker/, Taskfile.yml
- Run go mod tidy to trim unused dependencies
core/go is now a pure Go package suite (library only).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Claude <developers@lethean.io>
Reviewed-on: #3
Port LEM scoring/training pipeline into CoreGo as pkg/ml with:
- Inference abstraction with HTTP, llama-server, and Ollama backends
- 3-tier scoring engine (heuristic, exact, LLM judge)
- Capability and content probes for model evaluation
- GGUF/safetensors format converters, MLX to PEFT adapter conversion
- DuckDB integration for training data pipeline
- InfluxDB metrics for lab dashboard
- Training data export (JSONL + Parquet)
- Expansion generation pipeline with distributed workers
- 10 CLI commands under 'core ml' (score, probe, export, expand, status, gguf, convert, agent, worker)
- 5 MCP tools (ml_generate, ml_score, ml_probe, ml_status, ml_backends)
All 37 ML tests passing. Binary builds at 138MB with all commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move module identity to our own Forgejo instance. All import paths
updated across 434 Go files, sub-module go.mod files, and go.work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add HubService to the Wails service list and attempt hub registration
at startup when hubUrl is configured. Drains any pending operations
queued from previous sessions.
Co-Authored-By: Virgil <virgil@lethean.io>
Replace all exec.Command("gh", ...) calls with the existing pkg/forge
wrapper around the Forgejo Go SDK. BugSETI no longer requires the gh
CLI to be installed.
Changes:
- fetcher: use forge.ListIssues/GetIssue instead of gh issue list/view
- submit: use forge.ForkRepo/CreatePullRequest instead of gh pr create
- seeder: use git clone with forge URL + token auth instead of gh clone
- ghcheck: CheckForge() returns *forge.Client via forge.NewFromConfig()
- config: add ForgeURL/ForgeToken fields (GitHubToken kept for migration)
- pkg/forge: add Token(), GetCurrentUser(), ForkRepo(), CreatePullRequest(),
ListIssueComments(), and label filtering to ListIssuesOpts
Co-Authored-By: Virgil <virgil@lethean.io>
The workspace map previously only cleaned up during Capture() calls,
meaning stale entries would accumulate indefinitely if no new captures
occurred. This adds:
- Background sweeper goroutine (Start/Stop lifecycle) that runs every 5
minutes to evict expired workspaces
- Configurable MaxWorkspaces and WorkspaceTTLMinutes in Config (defaults:
100 entries, 24h TTL) replacing hardcoded constants
- cleanup() now returns eviction count for observability logging
- Nil-config fallback to safe defaults
Fixes#54
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements quota enforcement for agents including daily token limits,
daily job limits, concurrent job caps, model allowlists, and global
per-model budgets. Quota recovery returns 50% for failed jobs and
100% for cancelled jobs.
Go: AllowanceService with MemoryStore, AllowanceStore interface, and
25 tests covering all enforcement paths.
Laravel: migration for 5 tables (agent_allowances, quota_usage,
model_quotas, usage_reports, repo_limits), Eloquent models,
AllowanceService, QuotaMiddleware, and REST API routes.
Closes#99
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ForgejoClient and ForgejoService to the Laravel app, providing a
clean service layer for all Forgejo REST API operations the orchestrator
needs. Supports multiple instances (forge, dev, qa) with config-driven
auto-routing, token auth, retry with circuit breaker, and pagination.
Covers issues, PRs, repos, branches, user/token management, and orgs.
Closes#98
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a startup check that verifies gh is in PATH and authenticated
before initializing services. Provides clear install/auth instructions
on failure instead of cryptic exec errors at runtime.
Closes#61
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The workspaces map in WorkspaceService grew unboundedly. Add cleanup()
that evicts entries older than 24h and enforces a 100-entry cap by
removing oldest entries first. Called on each Capture().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BugSETI: bug with antennae and legs (black template, white dark, green app)
Core IDE: diamond shape (black template, white dark, blue app)
Co-Authored-By: Virgil <virgil@lethean.io>
Switch Angular from hash-based to path-based routing so each Wails window
(/tray, /main, /settings) loads its correct route. Archive GitHub Actions
workflows to .gh-actions/, update Forgejo deploy registry to dappco.re/osi,
and apply gofmt/alignment fixes across packages.
Co-Authored-By: Virgil <virgil@lethean.io>
- Add spaHandler() to both BugSETI and Core IDE for Angular client-side
routing (AssetFileServerFS doesn't fallback to index.html)
- Fix jellyfin.component.ts sanitizer initialization order (both apps)
- Fix chat.component.ts Event/KeyboardEvent type mismatch
- Defer onboarding window to ApplicationStarted event hook
Co-Authored-By: Virgil <virgil@lethean.io>
Add dappco.re vanity import handler (cmd/vanity-import/) that serves
go-import meta tags, enabling `go get dappco.re/core` to resolve to
forge.lthn.ai/host-uk/core. Deployed as a Docker container behind
Traefik on snider-linux.
Add Woodpecker CI pipeline (.woodpecker/bugseti.yml) for BugSETI
cross-platform builds. Phase 1: Linux amd64 with CGO, triggered on
bugseti-v* tags and main branch pushes to cmd/bugseti/.
Closes#3, closes#9
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AppServiceProvider runs migrate --force on first request.
Sessions and cache tables created automatically in SQLite.
Removed synthetic HTTP migration approach in favour of pure
PHP service provider — cleaner, works with Octane workers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add security logging and fix framework regressions
This commit implements comprehensive security event logging and resolves critical regressions in the core framework.
Security Logging:
- Enhanced `pkg/log` with a `Security` level and helper.
- Added `log.Username()` to consistently identify the executing user.
- Instrumented GitHub CLI auth, Agentic configuration, filesystem sandbox, MCP handlers, and MCP TCP transport with security logs.
- Added `SecurityStyle` to the CLI for consistent visual representation of security events.
UniFi Security (CodeQL):
- Refactored `pkg/unifi` to remove hardcoded `InsecureSkipVerify`, resolving a high-severity alert.
- Added a `--verify-tls` flag and configuration option to control TLS verification.
- Updated command handlers to support the new verification parameter.
Framework Fixes:
- Restored original signatures for `MustServiceFor`, `Config()`, and `Display()` in `pkg/framework/core`, which had been corrupted during a merge.
- Fixed `pkg/framework/framework.go` and `pkg/framework/core/runtime_pkg.go` to match the restored signatures.
- These fixes resolve project-wide compilation errors caused by the signature mismatches.
I encountered significant blockers due to a corrupted state of the `dev` branch after a merge, which introduced breaking changes in the core framework's DI system. I had to manually reconcile these signatures with the expected usage across the codebase to restore build stability.
* feat(mcp): add RAG tools (query, ingest, collections)
Add vector database tools to the MCP server for RAG operations:
- rag_query: Search for relevant documentation using semantic similarity
- rag_ingest: Ingest files or directories into the vector database
- rag_collections: List available collections
Uses existing internal/cmd/rag exports (QueryDocs, IngestDirectory, IngestFile)
and pkg/rag for Qdrant client access. Default collection is "hostuk-docs"
with topK=5 for queries.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(mcp): add metrics tools (record, query)
Add MCP tools for recording and querying AI/security metrics events.
The metrics_record tool writes events to daily JSONL files, and the
metrics_query tool provides aggregated statistics by type, repo, and agent.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add 'core mcp serve' command
Add CLI command to start the MCP server for AI tool integration.
- Create internal/cmd/mcpcmd package with serve subcommand
- Support --workspace flag for directory restriction
- Handle SIGINT/SIGTERM for clean shutdown
- Register in full.go build variant
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(ws): add WebSocket hub package for real-time streaming
Add pkg/ws package implementing a hub pattern for WebSocket connections:
- Hub manages client connections, broadcasts, and channel subscriptions
- Client struct represents connected WebSocket clients
- Message types: process_output, process_status, event, error, ping/pong
- Channel-based subscription system (subscribe/unsubscribe)
- SendProcessOutput and SendProcessStatus for process streaming integration
- Full test coverage including concurrency tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(mcp): add process management and WebSocket MCP tools
Add MCP tools for process management:
- process_start: Start a new external process
- process_stop: Gracefully stop a running process
- process_kill: Force kill a process
- process_list: List all managed processes
- process_output: Get captured process output
- process_input: Send input to process stdin
Add MCP tools for WebSocket:
- ws_start: Start WebSocket server for real-time streaming
- ws_info: Get hub statistics (clients, channels)
Update Service struct with optional process.Service and ws.Hub fields,
new WithProcessService and WithWSHub options, getter methods, and
Shutdown method for cleanup.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(webview): add browser automation package via Chrome DevTools Protocol
Add pkg/webview package for browser automation:
- webview.go: Main interface with Connect, Navigate, Click, Type, QuerySelector, Screenshot, Evaluate
- cdp.go: Chrome DevTools Protocol WebSocket client implementation
- actions.go: DOM action types (Click, Type, Hover, Scroll, etc.) and ActionSequence builder
- console.go: Console message capture and filtering with ConsoleWatcher and ExceptionWatcher
- angular.go: Angular-specific helpers for router navigation, component access, and Zone.js stability
Add MCP tools for webview:
- webview_connect/disconnect: Connection management
- webview_navigate: Page navigation
- webview_click/type/query/wait: DOM interaction
- webview_console: Console output capture
- webview_eval: JavaScript execution
- webview_screenshot: Screenshot capture
Add documentation:
- docs/mcp/angular-testing.md: Guide for Angular application testing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: document new packages and BugSETI application
- Update CLAUDE.md with documentation for:
- pkg/ws (WebSocket hub for real-time streaming)
- pkg/webview (Browser automation via CDP)
- pkg/mcp (MCP server tools: process, ws, webview)
- BugSETI application overview
- Add comprehensive README for BugSETI with:
- Installation and configuration guide
- Usage workflow documentation
- Architecture overview
- Contributing guidelines
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(bugseti): add BugSETI system tray app with auto-update
BugSETI - Distributed Bug Fixing like SETI@home but for code
Features:
- System tray app with Wails v3
- GitHub issue fetching with label filters
- Issue queue with priority management
- AI context seeding via seed-agent-developer skill
- Automated PR submission flow
- Stats tracking and leaderboard
- Cross-platform notifications
- Self-updating with stable/beta/nightly channels
Includes:
- cmd/bugseti: Main application with Angular frontend
- internal/bugseti: Core services (fetcher, queue, seeder, submit, config, stats, notify)
- internal/bugseti/updater: Auto-update system (checker, downloader, installer)
- .github/workflows/bugseti-release.yml: CI/CD for all platforms
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: resolve import cycle and code duplication
- Remove pkg/log import from pkg/io/local to break import cycle
(pkg/log/rotation.go imports pkg/io, creating circular dependency)
- Use stderr logging for security events in sandbox escape detection
- Remove unused sync/atomic import from core.go
- Fix duplicate LogSecurity function declarations in cli/log.go
- Update workspace/service.go Crypt() call to match interface
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: update tests for new function signatures and format code
- Update core_test.go: Config(), Display() now panic instead of returning error
- Update runtime_pkg_test.go: sr.Config() now panics instead of returning error
- Update MustServiceFor tests to use assert.Panics
- Format BugSETI, MCP tools, and webview packages with gofmt
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Snider <631881+Snider@users.noreply.github.com>
Co-authored-by: Claude <developers@lethean.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Implements defence in depth through build variants - only compiled code
exists in the binary. Commands now self-register via cli.RegisterCommands()
in their init() functions, mirroring the i18n.RegisterLocales() pattern.
Structure changes:
- cmd/{ai,build,ci,dev,docs,doctor,go,php,pkg,sdk,setup,test,vm}/ → pkg/*/cmd_*.go
- cmd/core_dev.go, cmd/core_ci.go → cmd/variants/{full,ci,php,minimal}.go
- Added pkg/cli/commands.go with RegisterCommands API
- Updated pkg/cli/runtime.go to attach registered commands
Build variants:
- go build → full (21MB, all 13 command groups)
- go build -tags ci → ci (18MB, build/ci/sdk/doctor)
- go build -tags php → php (14MB, php/doctor)
- go build -tags minimal → minimal (11MB, doctor only)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add i18n.SetDefault() in CLI service for global i18n.T() access
- Replace explicit cmd.php.qa.* keys with grammar-based composition
- Use i18n.Label(), i18n.ProgressSubject() for structured messages
- Use i18n.done.*, i18n.fail.*, i18n.count.* magic namespaces
- Simplify GetIssueMessage() to use grammar patterns
This reduces translation key explosion by composing messages from
grammar primitives rather than defining explicit keys for every phrase.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename "analyse" check to "stan" (PHPStan is commonly called "stan")
- Command: `core php stan` (with "analyse" alias for compatibility)
- Update QA pipeline to use "stan" for check name
- Update dependency chain: fmt → stan → psalm → test
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add QARunner that wraps process.Service and process.Runner
- Replace sequential runQACheck() with dependency-ordered execution
- Checks run in proper sequence: audit → fmt → analyse → psalm → test → rector/infection
- Process events broadcast via Core ACTION() messages
- Display results with stage grouping and duration tracking
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These are now redundant with the i18n.* namespace magic:
- P("fetch") → T("i18n.progress.fetch")
- PS("build", "x") → T("i18n.progress.build", "x")
- L("status") → T("i18n.label.status")
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TimeAgo(t time.Time) for relative time strings
- Add FormatAgo(count, unit) for "N units ago" composition
- Add i18n.ago namespace pattern: T("i18n.ago", 5, "minute")
- Uses existing time.ago.{unit} keys with CLDR pluralization
- Remove local formatTimeAgo from cmd/php in favor of i18n.TimeAgo
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds cmd/i18n-validate that scans Go source files for i18n key usage
and validates them against locale JSON files and registered intents.
Features:
- Scans T(), C(), I(), and qualified i18n.* calls
- Expands ./... pattern to find all Go packages
- Validates message keys against locale JSON files
- Validates intent keys against registered core.* intents
- Reports missing keys with file:line locations
- Skips constant references (type-safe usage)
Usage:
go run ./cmd/i18n-validate ./...
task i18n:validate
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add i18n service wrapping pkg/i18n for translations via cli.T()
- Add log service with levels (quiet/error/warn/info/debug)
- Wire cli.Init() in cmd.Execute() with explicit service names
- Fix main.go to print errors to stderr and exit with code 1
- Update runtime.go to accept additional services via Options
Services use WithName() to avoid name collision since both are
defined in pkg/cli (WithService would auto-name both "cli").
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>