Commit graph

155 commits

Author SHA1 Message Date
c340303314 refactor: flatten commands, extract php/ci to own repos (#2)
## Summary
- Extract PHP/Laravel commands to `core/php` repo (42 files, standalone module)
- Extract CI/release + SDK commands to `core/ci` repo (10 files)
- Remove `internal/variants/` build tag system entirely
- Move all 30 remaining command packages from `internal/cmd/` to top-level `cmd/`
- Rewrite `main.go` with direct imports — no more variant selection
- PHP and CI are now optional via commented import lines in main.go

Co-authored-by: Claude <developers@lethean.io>
Reviewed-on: #2
Co-authored-by: Charon <charon@lthn.ai>
Co-committed-by: Charon <charon@lthn.ai>
2026-02-16 14:45:06 +00:00
abe74a1a3d refactor: split CLI from monorepo, import core/go as library (#1)
- Change module from forge.lthn.ai/core/go to forge.lthn.ai/core/cli
- Remove pkg/ directory (now served from core/go)
- Add require + replace for forge.lthn.ai/core/go => ../go
- Update go.work to include ../go workspace module
- Fix all internal/cmd/* imports: pkg/ refs → forge.lthn.ai/core/go/pkg/
- Rename internal/cmd/sdk package to sdkcmd (avoids conflict with pkg/sdk)
- Remove SDK library files from internal/cmd/sdk/ (now in core/go/pkg/sdk/)
- Remove duplicate RAG helper functions from internal/cmd/rag/
- Remove stale cmd/core-ide/ (now in core/ide repo)
- Update IDE variant to remove core-ide import
- Fix test assertion for new module name
- Run go mod tidy to sync dependencies

core/cli is now a pure CLI application importing core/go for packages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Co-authored-by: Claude <developers@lethean.io>
Reviewed-on: #1
2026-02-16 14:24:37 +00:00
Snider
4e47485efe refactor: update import paths from cli to go package structure 2026-02-16 13:47:52 +00:00
a1306bc321 feat/ml-integration (#2)
Co-authored-by: Charon (snider-linux) <charon@lethean.io>
Co-authored-by: Snider <snider@host.uk.com>
Co-authored-by: Virgil <virgil@lethean.io>
Co-authored-by: Claude <developers@lethean.io>
Reviewed-on: #2
Co-authored-by: Snider <snider@lethean.io>
Co-committed-by: Snider <snider@lethean.io>
2026-02-16 06:19:09 +00:00
Claude
5ff4b8a2eb feat: add ML inference, scoring, and training pipeline (pkg/ml)
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>
2026-02-16 05:53:52 +00:00
Claude
23b82482f2 refactor: rename module from github.com/host-uk/core to forge.lthn.ai/core/cli
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>
2026-02-16 05:53:52 +00:00
Snider
177ce27e43 feat(bugseti): wire HubService into main.go with auto-registration
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>
2026-02-16 05:53:52 +00:00
Snider
69a0cd631a feat(bugseti): migrate from GitHub gh CLI to Forgejo SDK
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>
2026-02-16 05:53:52 +00:00
Snider
1e2e8e9c11 chore: migrate forge.lthn.ai → forge.lthn.io
Update Forgejo domain references in CI pipeline, vanity import
tool, and core-app codex prompt.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-16 05:53:52 +00:00
Claude
fd0188d808 fix(bugseti): add background TTL sweeper and configurable workspace limits
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>
2026-02-16 05:53:52 +00:00
Athena
794cff9409 feat(agentic): add agent allowance system for model quotas and budgets
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>
2026-02-16 05:53:52 +00:00
Athena
2e271d2e17 feat(agentic): add Forgejo integration bridge for PHP platform
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>
2026-02-16 05:53:52 +00:00
Athena
f174650f37 feat(agentic): add real-time dashboard with Livewire components (#96)
Add a live agent activity dashboard to the Core App Laravel frontend.
Provides real-time visibility into agent fleet status, job queue,
activity feed, metrics, and human-in-the-loop actions — replacing
SSH + tail -f as the operator interface.

Dashboard panels:
- Agent Fleet: grid of agent cards with heartbeat, status, model info
- Job Queue: filterable table with cancel/retry actions
- Live Activity Feed: real-time stream with agent/type filters
- Metrics: stat cards, budget gauge, cost breakdown, throughput chart
- Human Actions: inline question answering, review gate approval

Tech: Laravel Blade + Livewire 4 + Tailwind CSS + Alpine.js + ApexCharts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 05:53:52 +00:00
Athena
ded85b081f fix(bugseti): add gh CLI availability check with helpful error
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>
2026-02-16 05:53:52 +00:00
Claude (M3 Studio)
a3892209c3 fix(bugseti): add TTL cleanup and max size cap to workspace map (#55)
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>
2026-02-16 05:53:52 +00:00
Snider
ac19c682b4 fix(tray): replace placeholder icons with actual bug and diamond icons
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>
2026-02-09 10:39:50 +00:00
Snider
76c731ffb9 chore(bugseti): disable Angular CLI analytics
Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-09 10:24:22 +00:00
Snider
1b2866fc17 feat(bugseti): wire BugSETI into root build system and make functional
- Add bugseti:dev, bugseti:build, bugseti:frontend tasks to root Taskfile
- Update Wails v3 config to current dev_mode format (root_path, executes)
- Raise Angular component CSS budget to 6KB (inline styles by design)
- Fix vanity-import Dockerfile typo (---FROM → FROM)
- Verify: Go compiles, tests pass, frontend builds clean, binary runs

Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-09 02:49:01 +00:00
Snider
a668c5ab5a fix(core-ide): use path-based routing for multi-window SPA, clean up formatting
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>
2026-02-09 01:50:57 +00:00
Snider
c494c7b998 feat(core-ide): add MCP bridge (SERVER) and Claude bridge (CLIENT)
SERVER bridge (mcp_bridge.go):
- HTTP server on :9877 exposing 24 MCP tools
- Window management: list, get, position, size, bounds, maximize,
  minimize, restore, focus, visibility, title, fullscreen, create, close
- Webview: eval JS, navigate, list
- System: clipboard read/write, tray control
- Endpoints: /mcp, /mcp/tools, /mcp/call, /health, /ws, /claude

CLIENT bridge (claude_bridge.go):
- WebSocket relay between GUI clients and MCP core on :9876
- Auto-reconnect with backoff
- Bidirectional message forwarding (claude_message type)

Moved HTTP server from IDEService to MCPBridge for unified endpoint.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-08 23:12:51 +00:00
Snider
dd017288e7 fix(tray-apps): SPA routing, TypeScript fixes, and deferred onboarding
- 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>
2026-02-08 23:03:49 +00:00
Snider
5c3b70a1eb fix: resolve conflict markers and remove legacy code after branch consolidation
- Remove conflict markers from 19 files that were accidentally committed
  during merge resolutions (keeping HEAD versions)
- Remove legacy root-level code (core.go, main.go, config/, crypt/,
  display/, filesystem/, workspace/, docs/*.go, cmd/app/) from old
  architecture predating pkg/ restructure
- Remove duplicate pkg/config/loader.go (Load/Save already in config.go)
- Fix import alias in cmd_apply.go (errors -> core)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-08 22:08:35 +00:00
Snider
aba0698c24 Merge branch 'feature-core-integration' into new 2026-02-08 22:00:01 +00:00
Snider
2d48f2d335 Merge branch 'codex/bugseti-mcp' into new 2026-02-08 21:59:29 +00:00
Snider
0fc16305d9 Merge branch 'feat/frankenphp-native-app' into new
# Conflicts:
#	pkg/crypt/chachapoly/chachapoly.go
#	pkg/crypt/chachapoly/chachapoly_test.go
#	pkg/crypt/lthn/lthn.go
#	pkg/crypt/lthn/lthn_test.go
#	pkg/crypt/rsa/rsa.go
#	pkg/crypt/rsa/rsa_test.go
#	pkg/io/node/node.go
#	pkg/io/sigil/sigil.go
#	pkg/io/sigil/sigils.go
2026-02-08 21:18:41 +00:00
Claude
49da5b10c3 feat: add Go vanity import server and BugSETI CI pipeline
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>
2026-02-08 18:30:29 +00:00
Snider
cdd97441e9 updates 2026-02-08 15:17:18 +00:00
Snider
309dcaf0b4 updates 2026-02-08 15:17:12 +00:00
Claude
b74f8264d3 feat: add Woodpecker CI pipeline and workspace improvements (#1)
Co-authored-by: Claude <developers@lethean.io>
Co-committed-by: Claude <developers@lethean.io>
2026-02-08 13:25:06 +00:00
Snider
c13b6b8b02 feat(core-app): add auto-migration and session/cache tables
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>
2026-02-06 22:56:44 +00:00
Snider
e5c82dab5e feat(core-app): FrankenPHP + Wails v3 native desktop app
Single 53MB binary embedding PHP 8.4 ZTS runtime, Laravel 12,
Livewire 4, and Octane worker mode inside a Wails v3 native
desktop window.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:50:18 +00:00
Snider
c0fd80a2b6 feat(bugseti): add marketplace MCP root
- add MarketplaceMCPRoot config and UI setting\n- prefer config root before env or auto-discovery\n- thread config root into ethics guard usage
2026-02-05 22:07:24 +00:00
dependabot[bot]
89dd2b8eb5 build(deps): bump tar (#337)
Bumps the npm_and_yarn group with 1 update in the /cmd/bugseti/frontend directory: [tar](https://github.com/isaacs/node-tar).


Updates `tar` from 6.2.1 to 7.5.7
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v6.2.1...v7.5.7)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.7
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Snider <snider@host.uk.com>
2026-02-05 17:42:25 +00:00
Vi
4debdc1449 feat: BugSETI app, WebSocket hub, browser automation, and MCP tools (#336)
* 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>
2026-02-05 17:22:05 +00:00
Snider
5b2c4eef75 refactor: move CLI entry point to pkg/cli, remove cmd/
Consolidate CLI code into pkg/cli:
- Add pkg/cli/app.go with Main() entry point and completionCmd
- Move build variants to internal/variants/ (avoids import cycle)
- Move i18n-validate tool to internal/tools/
- Update main.go to call cli.Main()
- Remove cmd/ directory entirely

Structure:
- main.go imports internal/variants (triggers command registration)
- main.go calls cli.Main() which runs the CLI
- Build variants: go build, go build -tags ci/php/minimal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:11:35 +00:00
Snider
9931593f9d refactor(cli): move commands from cmd/ to pkg/ with self-registration
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>
2026-01-30 21:55:55 +00:00
Snider
415e558c19 refactor(i18n): use grammar system for PHP QA messages
- 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>
2026-01-30 20:23:28 +00:00
Snider
edfb84cf1d chore(php): remove analyse alias for stan command
No backwards compatibility - use `core php stan` directly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:08:34 +00:00
Snider
9aaaa0ad26 refactor(php): rename analyse to stan
- 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>
2026-01-30 20:06:51 +00:00
Snider
8c32539958 refactor(php): use pkg/process for QA pipeline
- 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>
2026-01-30 20:02:03 +00:00
Snider
e8cdb31a98 refactor(i18n): remove redundant P, PS, L shorthand functions
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>
2026-01-30 15:05:24 +00:00
Snider
282be9c7bc feat(i18n): add localized time formatting helpers
- 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>
2026-01-30 14:44:42 +00:00
Snider
94723454a8 feat(i18n): add compile-time key validation tool
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>
2026-01-30 13:18:58 +00:00
Snider
fc74d4df9c refactor(i18n): use grammar engine for progress messages
- Replace cli.progress.* keys with i18n.P() dynamic generation
- Remove 7 static progress keys from en_GB.json (building, checking, etc.)
- Add additional core.* intents (format, analyse, link, unlink, fetch, etc.)
- Add grammar helpers: Progress(), ProgressSubject(), ActionResult(), Label()
- Add package-level convenience functions: P(), PS(), L()
- Update commands to use common.prompt.abort instead of cli.confirm.abort

The grammar engine now generates progress messages dynamically:
  i18n.P("check")  → "Checking..."
  i18n.P("fetch")  → "Fetching..."

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:43:03 +00:00
Snider
6f6ee99008 refactor(i18n): consolidate 85 keys into reusable templates
Replace specific messages with parameterized templates:

- 60 "failed to X" errors -> common.error.failed + Action
- 10 "Running X" messages -> common.progress.running + Task
- 4 "Checking X" messages -> common.progress.checking + Item
- 13 "X successfully" messages -> common.success.completed + Action

This reduces translation maintenance - translators only need to
translate 3 templates instead of 85 individual messages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:44:45 +00:00
Snider
bcf74fe84e refactor(i18n): use common.error.failed template for all error messages
Replace specific error keys with the generic template:
- common.error.working_dir -> common.error.failed + Action
- common.error.load_config -> common.error.failed + Action
- common.error.build_failed -> common.error.failed + Action
- common.error.get_logs -> common.error.failed + Action
- common.error.tests_failed -> common.error.failed + Action

This reduces 5 duplicate error keys to 1 reusable template:
"Failed to {{.Action}}"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:35:38 +00:00
Snider
3169728d3a refactor(i18n): consolidate duplicate translation keys into common section
Add common.* keys for reusable translations:
- common.label.* - UI labels (error, done, status, version, etc.)
- common.status.* - status words (running, stopped, dirty, synced)
- common.error.* - error messages (failed, not_found, working_dir)
- common.flag.* - CLI flag descriptions (registry, verbose, etc.)
- common.count.* - count templates (failed, passed, skipped)
- common.result.* - result messages (all_passed, no_issues)
- common.progress.* - progress messages (running, checking)
- common.hint.* - help hints (install_with, fix_deps)

Update all cmd/* files to use common keys instead of duplicated
command-specific keys. Reduces translation maintenance burden
and ensures consistency across the CLI.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:32:25 +00:00
Snider
5e2d058b26 feat(cli): wire Core runtime with i18n and log services
- 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>
2026-01-30 10:55:30 +00:00
Snider
22aa1df30a refactor(cli): clean DX with direct function calls
- cli.Success(), cli.Error(), etc. now print directly
- String-returning versions renamed to cli.FmtSuccess(), etc.
- Removes App() from common usage path
- Usage: cli.Success("done") instead of fmt.Println(cli.Success("done"))

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:41:35 +00:00
Snider
23d399407c refactor(cli): move cmd/shared to pkg/cli with runtime
Moves shared utilities (styles, utils) from cmd/shared to pkg/cli.
Adds CLI runtime with global singleton pattern:
- cli.Init() initialises the runtime
- cli.App() returns the global instance
- OutputService for styled terminal printing
- SignalService for graceful shutdown handling

All cmd/ packages now import pkg/cli instead of cmd/shared.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:32:05 +00:00