Port remaining lem-repo components into pkg/ml/:
- convert.go: safetensors reader/writer, MLX→PEFT converter
- gguf.go: GGUF v3 writer, MLX→GGUF LoRA converter
- export.go: training data JSONL export with split/filter
- parquet.go: Parquet export with snappy compression
- db.go: DuckDB wrapper for golden set and expansion prompts
- influx.go: InfluxDB v3 client for metrics/status
- ollama.go: Ollama model management (create/delete with adapters)
- status.go: training and generation status display
- expand.go: expansion generation pipeline (Backend interface)
- agent.go: scoring agent with probe running and InfluxDB push
- worker.go: distributed worker for LEM API task processing
Adds parquet-go and go-duckdb dependencies.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move Go module path to production Forgejo instance.
Updates all imports, go.mod, go.sum, docs, and CI configs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds FindByForgejoUser() to Spinner so dispatch matches issues
assigned to Forgejo users (Virgil, Claude, Charon) even when the
agent config key differs (e.g. Hypnos → forgejo_user: Claude).
Searches config key first (direct match), then ForgejoUser field.
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>
Support gemini -p -y (non-interactive yolo mode) alongside claude
and codex runners. Three AI backends for different cost profiles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tickets now carry model (sonnet/haiku/opus) and runner (claude/codex)
fields. agent-runner.sh dispatches to the right backend. Defaults to
claude with sonnet model for cost efficiency.
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>
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>
- 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>