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>
The main.go was removed when Wails3 apps were added to cmd/, breaking
`go build .` for the core CLI. Restore it and update variants/full.go
to include daemon, forge, mcpcmd, prod, and session commands. Drop gitea
(superseded by forge) and unifi (unused).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace no-op stubs with real implementations for queueOp, drainPendingOps,
savePendingOps, and loadPendingOps. Operations are persisted to hub_pending.json
and replayed on next hub connection — 5xx/transport errors are retried, 4xx
responses are dropped as stale. Adds PendingCount() for queue inspection.
Co-Authored-By: Virgil <virgil@lethean.io>
Add Register, Heartbeat, ClaimIssue, UpdateStatus, ReleaseClaim,
and SyncStats methods for hub coordination. ClaimIssue returns
ConflictError on 409 and calls drainPendingOps before mutating.
Co-Authored-By: Virgil <virgil@lethean.io>
Exchange a Forge API token for a hub API key by POSTing to
/api/bugseti/auth/forge. Skips if hub token already cached.
Adds drainPendingOps() stub for future Task 7 use.
Co-Authored-By: Virgil <virgil@lethean.io>
Add doRequest() and doJSON() methods for hub API communication. doRequest
builds full URLs, sets bearer auth and JSON headers, tracks connected
state. doJSON handles status codes: 401 unauthorised, 409 ConflictError,
404 NotFoundError, and generic errors for other 4xx/5xx responses.
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce HubService struct with types for hub coordination: PendingOp,
HubClaim, LeaderboardEntry, GlobalStats, ConflictError, NotFoundError.
Constructor generates a crypto/rand client ID when none exists. Includes
no-op loadPendingOps/savePendingOps stubs for future persistence.
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add HubURL, HubToken, ClientID, and ClientName fields to Config struct
for agentic portal integration. Include getter/setter methods following
the existing pattern (SetForgeURL, SetForgeToken also added).
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Move shared state initialization (issues, seen) and the load() call
inside the mutex scope in NewQueueService() to eliminate the race
window where concurrent callers could observe partially initialized
state. Remove the redundant heap.Init before the lock since load()
already calls heap.Init when restoring from disk.
Add documentation to save() and load() noting they must be called
with q.mu held.
Fixes#51
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract buildForkURL helper for testable fork URL construction and add
19 tests covering Submit validation, HTTPS/SSH fork URLs, PR body
generation, and ensureFork error handling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SanitizeEnv() only removed control characters but not shell
metacharacters. A malicious repo name could execute arbitrary commands
via environment variable injection (e.g. backticks, $(), semicolons).
Add stripShellMeta() to strip backticks, dollar signs, semicolons,
pipes, ampersands, and other shell-significant characters from values
passed to the bash seed script environment.
Fixes#59
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit updates the file permissions for the BugSETI configuration file from 0644 to 0600, ensuring owner-only access. This addresses the security concern where the GitHub token stored in the config file was world-readable.
Fixes#53
Add sync.Mutex to SeederService to protect shared state during
concurrent SeedIssue, GetWorkspaceDir, and CleanupWorkspace calls.
Extract getWorkspaceDir as lock-free helper to avoid double-locking.
Closes#63
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Capture and log the error from `git fetch origin` in createBranch()
instead of silently ignoring it. Warns the user they may be proceeding
with stale data if the fetch fails.
Fixes#62
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>
Add fetcher_test.go covering: service creation, start/pause lifecycle,
calculatePriority scoring for all label types, label query construction
with custom and default labels, gh CLI JSON parsing for both list and
single-issue endpoints, channel backpressure when issuesCh is full,
fetchAll with no repos configured, and missing binary error handling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
q.load() accesses shared state (issues, seen, current) without holding
the mutex, creating a race condition. Wrap the call with q.mu.Lock().
Fixes#52
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds pkg/ratelimit for Gemini API rate limiting with sliding window
(RPM/TPM/RPD), persistent state, and token counting. Replaces the
bash agent-runner.sh with a native Go implementation under
`core ai dispatch {run,watch,status}` for local queue processing.
Rate limiting:
- Per-model quotas (RPM, TPM, RPD) with 1-minute sliding window
- WaitForCapacity blocks until capacity available or context cancelled
- Persistent state in ~/.core/ratelimits.yaml
- Default quotas for Gemini 3 Pro/Flash, 2.5 Pro, 2.0 Flash/Lite
- CountTokens helper calls Google tokenizer API
- CLI: core ai ratelimits {show,reset,count,config,check}
Dispatch runner:
- core ai dispatch run — process single ticket from queue
- core ai dispatch watch — daemon mode with configurable interval
- core ai dispatch status — show queue/active/done counts
- Supports claude/codex/gemini runners with rate-limited Gemini
- File-based locking with stale PID detection
- Completion handler updates issue labels on success/failure
Closes#42
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace fmt.Errorf() with structured log.E() errors in agentci, forge,
jobrunner packages. Update PipelineSignal comment to reflect dispatch
fields. Add TODO markers for charmbracelet/ssh migration across all
exec ssh call sites.
Co-Authored-By: Virgil <virgil@lethean.io>
Config-driven agent targets replace hardcoded map so new agents
can be added via CLI instead of recompiling. Includes setup script
for bootstrapping agent machines and CLI commands for management.
- Add pkg/agentci with config types and CRUD (LoadAgents, SaveAgent, etc.)
- Add CLI: core ai agent {add,list,status,logs,setup,remove}
- Add scripts/agent-setup.sh (SSH bootstrap: dirs, cron, prereq check)
- Headless loads agents from ~/.core/config.yaml
- Dispatch ticket includes forgejo_user for dynamic clone URLs
- agent-runner.sh reads username from ticket JSON, not hardcoded
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dispatch handler matches child issues that need coding (no PR yet,
assigned to a known agent) and SCPs ticket JSON to the agent's
queue directory via SSH. Includes dedup across queue/active/done
and posts dispatch comments on issues.
- Extend PipelineSignal with NeedsCoding, Assignee, IssueTitle, IssueBody
- Extend ForgejoSource to emit signals for unstarted children
- Add DispatchHandler with Match/Execute (SCP ticket delivery)
- Add agent-runner.sh cron-based queue runner for agent machines
- Wire dispatch handler into headless mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Replace all GitHub API and gh CLI dependencies with Forgejo SDK via
pkg/forge. The bash dispatcher burned a week of credit in a day due to
bugs — the jobrunner now talks directly to Forgejo.
- Add forge client methods: CreateIssueComment, CloseIssue, MergePullRequest,
SetPRDraft, ListPRReviews, GetCombinedStatus, DismissReview
- Create ForgejoSource implementing JobSource (epic polling, checklist
parsing, commit status via combined status API)
- Rewrite all 5 handlers to accept *forge.Client instead of shelling out
- Replace ResolveThreadsHandler with DismissReviewsHandler (Forgejo has
no thread resolution API — dismiss stale REQUEST_CHANGES reviews instead)
- Delete pkg/jobrunner/github/ and handlers/exec.go entirely
- Update internal/core-ide/headless.go to wire Forgejo source and handlers
- All 33 tests pass with mock Forgejo HTTP servers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reconcile callers with actual function signatures after merging IO
migration branches. Some functions gained io.Medium params (repos.*),
others kept their original signatures (release.*, cache.*, container.*).
- Add io.Local to repos.LoadRegistry/FindRegistry/ScanDirectory callers
- Remove extra io.Local from release.ConfigExists/LoadConfig/WriteConfig callers
- Fix cache.New call (remove nil Medium arg)
- Add missing IsCPPProject to build discovery
- Add missing fields to mcp.Service struct (subsystems, logger, etc.)
- Add DefaultTCPAddr constant to mcp transport
- Fix node.go interface check (coreio.Medium, not coreio.Node)
- Fix container.linuxkit LoadState/EnsureLogsDir arg counts
- Fix vm templates to use package-level functions
- Remove unused Medium field from DaemonOptions
Co-Authored-By: Virgil <virgil@lethean.io>
- add MCP marketplace client for plugin/ethics discovery\n- resolve seed-agent-developer via marketplace and sanitize context\n- apply ethics guardrails for notifications and PR metadata\n- add bugseti tests for sanitization and skill lookup\n- include mcp-go dependency for BugSETI
Implements the daemon mode feature for running core as a background service
with MCP server capabilities.
New features:
- `core daemon` command with configurable MCP transport
- Support for stdio, TCP, and Unix socket transports
- Environment variable configuration (CORE_MCP_TRANSPORT, CORE_MCP_ADDR)
- CLI flags for runtime configuration
- Integration with existing daemon infrastructure (PID file, health checks)
Files added:
- internal/cmd/daemon/cmd.go - daemon command implementation
- pkg/mcp/transport_stdio.go - stdio transport wrapper
- pkg/mcp/transport_unix.go - Unix domain socket transport
Files modified:
- pkg/mcp/mcp.go - added log import
- pkg/mcp/transport_tcp.go - added log import
- pkg/mcp/transport_tcp_test.go - fixed port binding test
Usage:
core daemon # TCP on 127.0.0.1:9100
core daemon --mcp-transport=socket --mcp-addr=/tmp/core.sock
CORE_MCP_TRANSPORT=stdio core daemon # for Claude Code integration
Fixes#119
Co-authored-by: Claude <developers@lethean.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Snider <snider@host.uk.com>
* feat(linux): add Ubuntu setup script and improve systemd services
Add comprehensive Ubuntu setup script that transforms a fresh Ubuntu
installation into a native tool building machine with:
- System dependencies (WebKitGTK, GTK3, libappindicator)
- Development tools (Go 1.25.6, Node.js 22.x, gh CLI)
- Claude Code CLI installation
- Core CLI and core-ide from GitHub releases
- XDG autostart configuration
- SSH key generation and GitHub authentication
Improve systemd services:
- Add security hardening to system service (NoNewPrivileges, PrivateTmp,
ProtectSystem)
- Add user-level service for non-root deployment
- Include user service in nfpm package
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: apply gofmt formatting to io.go and transport_tcp.go
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude <developers@lethean.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Snider <snider@host.uk.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>
During conflict resolution for PR #313 (streaming API), the agent
incorrectly assumed that modify/delete conflicts meant the PR intended
to remove these packages. This was wrong - PR #313 was only about
adding streaming API to pkg/io.
Restored packages:
- pkg/workspace - workspace management service
- pkg/unifi - UniFi controller client
- pkg/gitea - Gitea API client
- pkg/crypt/openpgp - OpenPGP encryption service
- internal/cmd/gitea - Gitea CLI commands
- internal/cmd/unifi - UniFi CLI commands
Also restored:
- Various test files (bench_test.go, integration_test.go, etc.)
- pkg/framework/core/interfaces.go (Workspace/Crypt interfaces)
- pkg/log/errors.go (error helpers)
- Documentation (faq.md, user-guide.md)
This allows PR #297 (MCP daemon mode) to proceed as it depends on
pkg/workspace.
Co-authored-by: Claude <developers@lethean.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>