Commit graph

3 commits

Author SHA1 Message Date
Snider
9bcb367dd0 feat: Command() and i18n.SetLanguage() return Result
Command(path, Command{Action: handler}) — typed struct input, Result output.
Command fields exported: Name, Description, Path, Action, Lifecycle, Flags, Hidden.

i18n.SetLanguage returns Result instead of error.

All public methods across core/go now return Result where applicable.

231 tests, 76.5% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 14:44:29 +00:00
Snider
5d67088080 feat: Service as typed struct, Result without generics
Service is now a proper struct with OnStart/OnStop/OnReload lifecycle
functions — not a registry wrapping any. Packages create Service{} with
typed fields, same pattern as Command and Option.

Result drops generics — Value is any. The struct is the container,
Value is the generic. No more Result[T] ceremony.

Service(name, Service{}) to register, Service(name) to get — both
return Result. ServiceFactory returns Result not (any, error).

NewWithFactories/NewRuntime return Result.

232 tests, 77.8% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 13:30:22 +00:00
Snider
afc235796f feat: Command DTO + Cli surface — AX-native CLI primitives
Command is now a DTO with no root/child awareness:
- Path-based registration: c.Command("deploy/to/homelab", handler)
- Description is an i18n key derived from path: cmd.deploy.to.homelab.description
- Lifecycle: Run(), Start(), Stop(), Restart(), Reload(), Signal()
- All return core.Result — errors flow through Core internally
- Parent commands auto-created from path segments

Cli is now a surface layer that reads from Core's command registry:
- Resolves os.Args to command path
- Parses flags into Options (--port=8080 → Option{K:"port", V:"8080"})
- Calls command action with parsed Options
- Banner and help use i18n

Old Clir code preserved in tests/testdata/cli_clir.go.bak for reference.

211 tests, 77.5% coverage.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-20 12:08:19 +00:00