Commit graph

962 commits

Author SHA1 Message Date
Snider
8f2e3d9457 chore: clean up — remove core.go re-export, pkg/mnt, go-io/go-log deps
Removed:
- core.go (top-level re-export layer, no longer needed)
- pkg/mnt/ (absorbed into pkg/core/mnt.go)
- pkg/log/ (absorbed into pkg/core/log.go)
- go-io dependency (absorbed into pkg/core/io.go)
- go-log dependency (absorbed into pkg/core/error.go + log.go)

Remaining: single package pkg/core/ with 14 source files.
Only dependency: testify (test-only).
Production code: zero external dependencies.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 01:28:14 +00:00
Snider
16a985ad5c feat: absorb go-log into core — error.go + log.go in pkg/core
Brings go-log's errors and logger directly into the Core package:
  core.E("pkg.Method", "msg", err)     — structured errors
  core.Err{Op, Msg, Err, Code}         — error type
  core.Wrap(err, op, msg)              — error wrapping
  core.NewLogger(opts)                 — structured logger
  core.Info/Warn/Error/Debug(msg, kv)  — logging functions

Removed:
  pkg/core/e.go — was re-exporting from go-log, now source is inline
  pkg/log/ — was re-exporting, no longer needed

Renames to avoid conflicts:
  log.New() → core.NewLogger() (core.New is the DI constructor)
  log.Message() → core.ErrorMessage() (core.Message is the IPC type)

go-log still exists as a separate module for external consumers.
Core framework now has errors + logging built-in. Zero deps.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 01:23:02 +00:00
Snider
dd6803df10 fix(security): fix latent sandbox escape in IO.path()
filepath.Clean("/"+p) returns absolute path, filepath.Join(root, "/abs")
drops root on Linux. Strip leading "/" before joining with sandbox root.

Currently not exploitable (validatePath handles it), but any future
caller of path() with active sandbox would escape. Defensive fix.

Found by Gemini Pro security review.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 01:16:30 +00:00
Snider
55cbfea7ca fix: apply Gemini review findings on embed.go
- Fix decompress: check gz.Close() error (checksum verification)
- Remove dead groupPaths variable (never read)
- Remove redundant AssetRef.Path (duplicate of Name)
- Remove redundant AssetGroup.name (key in map is the name)

Gemini found 8 issues, 4 were real bugs/dead code.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 01:12:10 +00:00
Snider
81eba2777a fix: apply Gemini Pro review — maps.Clone for crash metadata
Prevents external mutation of crash handler metadata after construction.
Uses maps.Clone (Go 1.21+) as suggested by Gemini Pro review.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 01:02:48 +00:00
Snider
d1c9d4e4ad refactor: generic EtcGet[T] replaces typed getter boilerplate
GetString/GetInt/GetBool now delegate to EtcGet[T].
Gemini Pro review finding — three identical functions collapsed to one generic.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 01:00:47 +00:00
Snider
8935905ac9 fix: remove goio alias, use io directly
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 00:45:17 +00:00
Snider
d7f9447e7a feat: add core.Io() — local filesystem I/O on Core struct
Brings go-io/local into Core as c.Io():
  c.Io().Read("config.yaml")
  c.Io().Write("output.txt", content)
  c.Io().WriteMode("key.pem", data, 0600)
  c.Io().IsFile("go.mod")
  c.Io().List(".")
  c.Io().Delete("temp.txt")

Default: rooted at "/" (full access like os package).
Sandbox: core.WithIO("./data") restricts all operations.

c.Mnt() stays for embedded/mounted assets (read-only).
c.Io() is for local filesystem (read/write/delete).
WithMount stays for mounting fs.FS subdirectories.
WithIO added for sandboxing local I/O.

Based on go-io/local/client.go (~300 lines), zero external deps.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 00:42:41 +00:00
Snider
077fde9516 rename: pack.go → embed.go
It embeds assets into binaries. Pack is what bundlers do.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 00:23:13 +00:00
Snider
9331f5067c feat: add Slicer[T] generics + Pack (asset packing without go:embed)
Slicer[T] — generic typed slice operations (leaanthony/slicer rewrite):
  s := core.NewSlicer("a", "b", "c")
  s.AddUnique("d")
  s.Contains("a")      // true
  s.Filter(fn)          // new filtered slicer
  s.Deduplicate()       // remove dupes
  s.Each(fn)            // iterate

Pack — build-time asset packing (leaanthony/mewn pattern):
  Build tool: core.ScanAssets(files) → core.GeneratePack(pkg)
  Runtime: core.AddAsset(group, name, data) / core.GetAsset(group, name)

  Scans Go AST for core.GetAsset() calls, reads referenced files,
  gzip+base64 compresses, generates Go source with init().
  Works without go:embed — language-agnostic pattern for CoreTS bridge.

Both zero external dependencies.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 00:21:08 +00:00
Snider
8765458bc6 feat: add core.Crash() — panic recovery and crash reporting
Adfer (Welsh: recover). Built into the Core struct:
  defer c.Crash().Recover()     // capture panics
  c.Crash().SafeGo(fn)          // safe goroutine
  c.Crash().Reports(5)          // last 5 crash reports

CrashReport includes: timestamp, error, stack trace,
system info (OS/arch/Go version), custom metadata.

Optional file output: JSON array of crash reports.
Zero external dependencies.

Based on leaanthony/adfer (168 lines), integrated into pkg/core.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 00:17:19 +00:00
Snider
66b4b08600 feat: add core.Etc() — configuration, settings, and feature flags
Replaces the old Features struct with Etc on the Core struct:
  c.Etc().Set("api_url", "https://api.lthn.sh")
  c.Etc().Enable("coderabbit")
  c.Etc().Enabled("coderabbit")  // true
  c.Etc().GetString("api_url")   // "https://api.lthn.sh"

Also adds Var[T] — generic optional variable (from leaanthony/u):
  v := core.NewVar("hello")
  v.Get()    // "hello"
  v.IsSet()  // true
  v.Unset()  // zero value, IsSet() = false

Removes Features struct from Core (replaced by Etc).
Thread-safe via sync.RWMutex. Zero external dependencies.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 00:14:44 +00:00
Snider
9a57a7bc88 feat: integrate mnt into Core struct — c.Mnt() for mount operations
Mnt is now a built-in capability of the Core struct, not a service:
  c.Mnt().ReadString("persona/secops/developer.md")
  c.Mnt().Extract(targetDir, data)

Changes:
- Move mnt.go + mnt_extract.go into pkg/core/ (same package)
- Core struct: replace `assets embed.FS` with `mnt *Sub`
- WithAssets now creates a Sub mount (backwards compatible)
- Add WithMount(embed, "basedir") for subdirectory mounting
- Assets() deprecated, delegates to c.Mnt().Embed()
- Top-level core.go re-exports Mount, WithMount, Sub, ExtractOptions
- pkg/mnt still exists independently for standalone use

One import, one struct, methods on the struct:
  import core "forge.lthn.ai/core/go"
  c, _ := core.New(core.WithAssets(myEmbed))
  c.Mnt().ReadString("templates/coding.md")

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-18 00:06:29 +00:00
Snider
c0d50bdf92 feat: add top-level core.go — re-exports DI container API
Users can now:
  import core "forge.lthn.ai/core/go"
  c, _ := core.New(core.WithService(factory))
  svc, _ := core.ServiceFor[*MyService](c, "name")

Re-exports: New, WithService, WithName, WithServiceLock, WithAssets,
ServiceFor, Core, Option, Message, Startable, Stoppable, LocaleProvider,
ServiceRuntime.

Sub-packages imported directly: pkg/mnt, pkg/log, etc.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 23:39:33 +00:00
Snider
21c4f718d3 feat: add pkg/mnt — mount operations for Core framework
core.mnt provides zero-dep mount operations:
- mnt.FS(embed, "subdir") — scoped embed.FS access (debme pattern)
- mnt.Extract(fs, targetDir, data) — template directory extraction (gosod/Install pattern)

Template extraction supports:
- Go text/template in file contents (.tmpl suffix)
- Go text/template in directory and file names ({{.Name}})
- Ignore files, rename files
- Variable substitution from any struct or map

Based on leaanthony/debme (70 lines) + leaanthony/gosod (280 lines),
rewritten as single zero-dep package. All stdlib, no transitive deps.

8 tests covering FS, Sub, ReadFile, ReadString, ReadDir, Extract.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 23:32:53 +00:00
Snider
7a9c9caabc chore: sync dependencies for v0.3.3
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 17:52:47 +00:00
Snider
fbb26b1be2 chore: sync dependencies for v0.3.2
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 17:47:41 +00:00
Snider
29e6d06633 fix(core): replace fmt.Errorf with structured errors, add log service tests
- Replace all fmt.Errorf calls with coreerr.E() from go-log for structured
  error context (op, msg, underlying error) across core.go, service_manager.go,
  and runtime_pkg.go (12 violations fixed)
- Replace local Error type and E() in e.go with re-exports from go-log,
  eliminating duplicate implementation while preserving public API
- Add comprehensive tests for pkg/log Service (NewService, OnStartup,
  QueryLevel, TaskSetLevel) — coverage 72.2% → 87.8%
- Update CLAUDE.md: Go 1.25 → 1.26, runtime.go → runtime_pkg.go,
  document go-log error convention
- No os.ReadFile/os.WriteFile violations found (all I/O uses go-io)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 08:03:05 +00:00
Snider
f4e2701018 chore: save LocaleProvider and Locales changes
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 01:45:42 +00:00
Snider
d64099b028 feat(core): add LocaleProvider interface for automatic i18n collection
Services implementing LocaleProvider have their locale FS collected
during RegisterService. The i18n service reads Core.Locales() on
startup to load all translations. Zero explicit wiring needed.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-17 01:31:19 +00:00
Snider
e1294b8412 chore: sync workspace dependencies
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-15 15:44:39 +00:00
Snider
5e7c0e9ec4 chore: ignore workspace and IDE dirs 2026-03-15 10:21:42 +00:00
Snider
d66ff46312 docs: remove implemented plans, annotate partial ones
18 plan files deleted (absorbed into core.help docs).
4 kept with implementation notes (lint MCP, AltumCode Layer 2).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-14 08:09:20 +00:00
Snider
681c88795f docs: add scheduled actions implementation plan (7 tasks)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:15:45 +00:00
Snider
d98eef7d37 docs: add scheduled actions design
Attribute-driven, database-backed Action scheduling for CorePHP.
#[Scheduled] attribute on Actions, auto-discovery via scanner,
persist to scheduled_actions table, runtime control via admin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:12:08 +00:00
Snider
fd8a42a088 docs: add AltumCode update checker implementation plan (5 tasks)
TDD plan for uptelligence AltumCode version detection + Claude Code
download skill. Covers VendorUpdateCheckerService, vendor seeding,
deployed version sync, and browser-automated download plugin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 08:27:58 +00:00
Snider
831e0736b5 docs: add AltumCode update checker design
Two-layer system: uptelligence version detection (5 HTTP GETs)
+ Claude Code skill for browser-automated downloads from
LemonSqueezy (Playwright) and CodeCanyon (Chrome).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 08:20:24 +00:00
Snider
89d189dd95 docs: add human-friendly documentation for Core Go framework
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:02:37 +00:00
Snider
48346a32cb docs: add core/mcp extraction plan
Move Go MCP server from go-ai + PHP MCP from php-mcp into
a single core/mcp repo producing the core-mcp binary.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 18:29:48 +00:00
Snider
e3882963a9 docs: add plug package extraction implementation plan (11 tasks)
Covers extracting app/Plug/* into 8 core/php-plug-* packages with
Core\Plug\* namespace alignment. Contracts move to core/php framework,
Registry gains register() method for package self-registration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:22:02 +00:00
Snider
fba6ec6f8a docs: add plug package extraction design
Restores the original package split for Plug providers that was
flattened during GitHub→Forge migration. Contracts move into core/php,
8 category packages (social, web3, content, chat, business, cdn,
storage, stock) become independent repos on forge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:17:41 +00:00
Snider
e232edb7f1 docs: add go-blockchain modernisation implementation plan (8 tasks)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 16:06:50 +00:00
Snider
3dfac0f9c0 docs: add go-blockchain modernisation design
Full refactor plan: cli.Main() migration, DI services for P2P sync
and wallet, go-process daemon for headless mode, build config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 16:00:54 +00:00
Snider
2d8b1a8616 docs: add daemon registry & manifest implementation plan (6 tasks)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 14:39:23 +00:00
Snider
693c1dceaa docs: add daemon registry & project manifest design
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 14:36:41 +00:00
Snider
c9ddc798d9 docs: add go-devops decomposition design
Extract 4 loosely-coupled packages from go-devops (31K LOC):
- devkit → merge into core/lint (QA checks, complexity, coverage)
- infra → core/go-infra (Hetzner, CloudNS APIs)
- ansible → core/go-ansible (pure Go playbook engine)
- container → core/go-container (LinuxKit/TIM for Lethean nodes)

Keep build/release/deploy pipeline as go-devops core purpose.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:20:04 +00:00
Snider
29bb2c2b40 docs: add lint pattern catalog implementation plan (9 tasks)
Layer 1 only: core/lint repo with YAML catalog, pkg/lint library
(Rule, Catalog, Matcher, Scanner, Report), and core-lint CLI.
18 seed patterns from the Go ecosystem sweep.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:48:59 +00:00
Snider
2e2560dc60 docs: add lint pattern catalog & polish skill design
Three-layer system: core/lint (pattern catalog + regex matcher),
go-ai MCP subsystem (lint tools for agents), core/agent polish
skill (multi-AI review orchestration). Seeded with 18 patterns
from the Go ecosystem sweep.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:44:42 +00:00
Snider
e2a68fc283 fix: harden DI container — lifecycle safety, Go 1.26 modernisation
- Prevent nil service registration and empty name discovery
- PerformAsync uses sync.WaitGroup.Go() with shutdown guard (atomic.Bool)
- ServiceShutdown respects context deadline, no goroutine leak on cancel
- IPC handler signature mismatch now returns error instead of silent skip
- Runtime.ServiceStartup/ServiceShutdown return error for Wails v3 compat
- Replace manual sort/clone patterns with slices.Sorted, slices.Clone,
  slices.Backward, maps.Keys
- Add async_test.go for PerformAsync coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:11:22 +00:00
Snider
d08ecb1c0d docs: add Studio Phases 3-5 implementation plan
13 tasks: Phase 3 (TTS, voiceover, voice pipeline), Phase 4 (ComfyUI,
thumbnails, image overlays, batch remix for content flywheel),
Phase 5 (Livewire pages, Ansible playbooks, production deployment).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 06:23:25 +00:00
Snider
0ded875ff1 docs: add Studio multimedia pipeline implementation plan
15 tasks covering Phase 1 (Foundation) and Phase 2 (Remix Pipeline).
TDD with Pest tests, Actions pattern, API routes, Livewire UI.
Follows existing LEM module patterns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:49:49 +00:00
Snider
243ab4ebbe docs: add Studio multimedia pipeline design
Smart/dumb architecture — LEM produces JSON manifests (creative decisions),
ffmpeg executes mechanically. Remote-first GPU on homelab. Five-phase delivery
targeting April demo for OF agency video remixing use case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:41:17 +00:00
Snider
f3854f1077 feat: add .core/ build and release configuration
Adopts go-devops build system for the core framework library.
Build config validates compilation across targets, release config
enables changelog generation for tag-only library releases.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 17:40:40 +00:00
Snider
302fb038a2 docs: add help engine implementation plan (10 tasks)
Merge go-help → core/docs pkg/help, HLCRF layout via go-html,
gohelp sync target in go-devops, integration tests.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 16:28:23 +00:00
Snider
86b8a9136c docs: add core/docs help engine design
Merge go-help into core/docs as pkg/help, replace Hugo/Docsy with
native static generator + go-html HLCRF layout. Content owned by
package repos (docs/ convention), collected by go-devops for builds.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 16:25:13 +00:00
Snider
0cb6a4cff3 docs: update CLAUDE.md to reflect pure DI framework
Remove stale references to extracted packages (pkg/ws, pkg/webview,
pkg/mcp, cmd/bugseti, cmd/core-gui). Replace Taskfile commands with
`core go` equivalents. Describe current pkg/core + pkg/log scope.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 14:48:02 +00:00
Snider
3720761555 chore: remove boilerplate Taskfile
All tasks handled natively by `core go` commands.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 14:46:05 +00:00
Snider
915816b3b5 docs: add pkg/core documentation, remove 12MB stale generated site
- Add comprehensive docs/pkg/core.md covering DI container, service
  pattern, message bus (ACTION/QUERY/TASK), error handling, runtime
- Remove pkg/core/docs/site/ (ancient MkDocs HTML with Lethean branding)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 14:29:04 +00:00
Snider
f71f4c7d66 docs: remove stale CLI/ecosystem docs, keep framework-only content
Massive cleanup after module extraction sprint. core/go is now a pure
DI framework — docs should reflect that, not document CLI commands.

- Delete 130+ CLI command/example docs (already in core/cli)
- Delete 6 obsolete pkg-batch*-analysis.md files
- Delete plans/, skill/, static/, mcp/ (moved to correct repos)
- Rewrite index.md for DI framework (not CLI)
- Fix PACKAGE_STANDARDS.md: framework.* → core.* references
- Fix log.md: correct framework integration example

Remaining docs: index.md, pkg/PACKAGE_STANDARDS.md, pkg/log.md

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 14:24:35 +00:00
Snider
4f6209f590 refactor: promote pkg/framework/core to pkg/core
pkg/framework/core/ → pkg/core/ (first-class import path)
pkg/framework/ shim deleted (no longer needed)

Import path: forge.lthn.ai/core/go/pkg/core

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-06 14:10:34 +00:00