2026-03-29 20:15:58 +00:00
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
|
|
2026-03-16 10:58:25 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2026-03-30 00:00:33 +00:00
|
|
|
"context"
|
|
|
|
|
"syscall"
|
|
|
|
|
|
2026-03-30 16:40:53 +00:00
|
|
|
agentpkg "dappco.re/go/agent"
|
refactor: migrate core/agent to Core primitives — reference implementation
Phase 1: go-io/go-log → core.Fs{}, core.E(), core.Error/Info/Warn
Phase 2: strings/fmt → core.Contains, core.Sprintf, core.Split etc
Phase 3: embed.FS → core.Mount/core.Embed, core.Extract
Phase 4: cmd/main.go → core.Command(), c.Cli().Run(), no cli package
All packages migrated:
- pkg/lib (Codex): core.Mount, core.Extract, Result returns, AX comments
- pkg/setup (Codex): core.Fs, core.E, fixed missing lib helpers
- pkg/brain (Codex): Core primitives, AX comments
- pkg/monitor (Codex): Core string/logging primitives
- pkg/agentic (Codex): 20 files, Core primitives throughout
- cmd/main.go: pure Core CLI, no fmt/log/filepath/strings/cli
Remaining stdlib: path/filepath (Core doesn't wrap OS paths),
fmt.Sscanf/strings.Map (no Core equivalent).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 06:13:41 +00:00
|
|
|
"dappco.re/go/core"
|
2026-03-16 10:58:25 +00:00
|
|
|
|
2026-03-21 11:10:31 +00:00
|
|
|
"dappco.re/go/agent/pkg/agentic"
|
|
|
|
|
"dappco.re/go/agent/pkg/brain"
|
|
|
|
|
"dappco.re/go/agent/pkg/monitor"
|
feat(runner): extract dispatch runner into independent Core service
Moves concurrency, queue drain, workspace lifecycle, and frozen state
from agentic/prep into pkg/runner/ — a standalone Core service that
communicates via IPC Actions only.
- runner.Register wires Actions: dispatch, status, start, stop, kill, poke
- runner.HandleIPCEvents catches AgentCompleted → ChannelPush + queue poke
- Agentic dispatch asks runner for permission via c.Action("runner.dispatch")
- Dispatch mutex moved to struct-level sync.Mutex (fixes core.Lock init race)
- Registry-based concurrency counting replaces disk scanning
- TrackWorkspace called on both queued and running status writes
- SpawnQueued message added for runner→agentic spawn requests
- ChannelPush message in core/mcp enables any service to push channel events
- 51 new tests covering runner service, queue, and config parsing
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 11:00:47 +00:00
|
|
|
"dappco.re/go/agent/pkg/runner"
|
2026-04-01 18:33:34 +00:00
|
|
|
"dappco.re/go/agent/pkg/setup"
|
2026-03-16 10:58:25 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func main() {
|
2026-03-30 00:00:33 +00:00
|
|
|
if err := runCoreAgent(); err != nil {
|
2026-03-30 14:16:38 +00:00
|
|
|
core.Error("core-agent failed", "err", err)
|
2026-03-30 00:00:33 +00:00
|
|
|
syscall.Exit(1)
|
|
|
|
|
}
|
2026-03-29 22:26:12 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:58:24 +00:00
|
|
|
// app := newCoreAgent()
|
|
|
|
|
// core.Println(app.App().Name) // "core-agent"
|
|
|
|
|
// core.Println(app.App().Version) // "dev" or linked version
|
2026-03-29 22:26:12 +00:00
|
|
|
func newCoreAgent() *core.Core {
|
2026-03-30 21:11:06 +00:00
|
|
|
coreApp := core.New(
|
2026-03-30 21:30:49 +00:00
|
|
|
core.WithOption("name", "core-agent"),
|
2026-03-25 00:03:22 +00:00
|
|
|
core.WithService(agentic.ProcessRegister),
|
2026-03-24 16:33:04 +00:00
|
|
|
core.WithService(agentic.Register),
|
feat(runner): extract dispatch runner into independent Core service
Moves concurrency, queue drain, workspace lifecycle, and frozen state
from agentic/prep into pkg/runner/ — a standalone Core service that
communicates via IPC Actions only.
- runner.Register wires Actions: dispatch, status, start, stop, kill, poke
- runner.HandleIPCEvents catches AgentCompleted → ChannelPush + queue poke
- Agentic dispatch asks runner for permission via c.Action("runner.dispatch")
- Dispatch mutex moved to struct-level sync.Mutex (fixes core.Lock init race)
- Registry-based concurrency counting replaces disk scanning
- TrackWorkspace called on both queued and running status writes
- SpawnQueued message added for runner→agentic spawn requests
- ChannelPush message in core/mcp enables any service to push channel events
- 51 new tests covering runner service, queue, and config parsing
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 11:00:47 +00:00
|
|
|
core.WithService(runner.Register),
|
2026-03-24 16:33:04 +00:00
|
|
|
core.WithService(monitor.Register),
|
|
|
|
|
core.WithService(brain.Register),
|
2026-04-01 18:33:34 +00:00
|
|
|
core.WithService(setup.Register),
|
2026-03-30 20:05:47 +00:00
|
|
|
core.WithService(registerMCPService),
|
2026-03-24 16:23:44 +00:00
|
|
|
)
|
2026-03-30 21:30:49 +00:00
|
|
|
coreApp.App().Version = applicationVersion()
|
2026-03-24 16:23:44 +00:00
|
|
|
|
2026-03-30 21:11:06 +00:00
|
|
|
coreApp.Cli().SetBanner(func(_ *core.Cli) string {
|
|
|
|
|
return core.Concat("core-agent ", coreApp.App().Version, " — agentic orchestration for the Core ecosystem")
|
feat: Forge CLI commands — issue, PR, and repo operations
New commands via go-forge library:
issue/get, issue/list, issue/comment
pr/get, pr/list, pr/merge
repo/get, repo/list
Enables CLI-driven Forge interaction for dispatch automation.
Agent can now read issues, create PRs, merge, and list repos
without MCP.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 14:07:25 +00:00
|
|
|
})
|
|
|
|
|
|
2026-03-30 21:30:49 +00:00
|
|
|
registerApplicationCommands(coreApp)
|
refactor: migrate core/agent to Core primitives — reference implementation
Phase 1: go-io/go-log → core.Fs{}, core.E(), core.Error/Info/Warn
Phase 2: strings/fmt → core.Contains, core.Sprintf, core.Split etc
Phase 3: embed.FS → core.Mount/core.Embed, core.Extract
Phase 4: cmd/main.go → core.Command(), c.Cli().Run(), no cli package
All packages migrated:
- pkg/lib (Codex): core.Mount, core.Extract, Result returns, AX comments
- pkg/setup (Codex): core.Fs, core.E, fixed missing lib helpers
- pkg/brain (Codex): Core primitives, AX comments
- pkg/monitor (Codex): Core string/logging primitives
- pkg/agentic (Codex): 20 files, Core primitives throughout
- cmd/main.go: pure Core CLI, no fmt/log/filepath/strings/cli
Remaining stdlib: path/filepath (Core doesn't wrap OS paths),
fmt.Sscanf/strings.Map (no Core equivalent).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 06:13:41 +00:00
|
|
|
|
2026-03-30 21:11:06 +00:00
|
|
|
return coreApp
|
2026-03-16 10:58:25 +00:00
|
|
|
}
|
2026-03-26 06:38:02 +00:00
|
|
|
|
2026-03-30 21:58:24 +00:00
|
|
|
// agentpkg.Version = "0.15.0"
|
|
|
|
|
// applicationVersion() // "0.15.0"
|
2026-03-30 21:30:49 +00:00
|
|
|
func applicationVersion() string {
|
2026-03-30 16:40:53 +00:00
|
|
|
if agentpkg.Version != "" {
|
|
|
|
|
return agentpkg.Version
|
2026-03-26 06:38:02 +00:00
|
|
|
}
|
|
|
|
|
return "dev"
|
|
|
|
|
}
|
2026-03-30 00:00:33 +00:00
|
|
|
|
2026-03-30 21:58:24 +00:00
|
|
|
// if err := runCoreAgent(); err != nil {
|
|
|
|
|
// core.Error("core-agent failed", "err", err)
|
|
|
|
|
// }
|
2026-03-30 00:00:33 +00:00
|
|
|
func runCoreAgent() error {
|
|
|
|
|
return runApp(newCoreAgent(), startupArgs())
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:58:24 +00:00
|
|
|
// app := newCoreAgent()
|
|
|
|
|
// _ = runApp(app, []string{"version"})
|
2026-03-30 21:11:06 +00:00
|
|
|
func runApp(coreApp *core.Core, cliArgs []string) error {
|
|
|
|
|
if coreApp == nil {
|
2026-03-30 00:00:33 +00:00
|
|
|
return core.E("main.runApp", "core is required", nil)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:11:06 +00:00
|
|
|
defer coreApp.ServiceShutdown(context.Background())
|
2026-03-30 00:00:33 +00:00
|
|
|
|
2026-03-30 21:11:06 +00:00
|
|
|
result := coreApp.ServiceStartup(coreApp.Context(), nil)
|
2026-03-30 00:00:33 +00:00
|
|
|
if !result.OK {
|
|
|
|
|
return resultError("main.runApp", "startup failed", result)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:11:06 +00:00
|
|
|
if cli := coreApp.Cli(); cli != nil {
|
2026-03-30 00:00:33 +00:00
|
|
|
result = cli.Run(cliArgs...)
|
|
|
|
|
if !result.OK {
|
|
|
|
|
return resultError("main.runApp", "cli failed", result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 21:58:24 +00:00
|
|
|
// result := core.Result{OK: false, Value: core.E("main.runApp", "startup failed", nil)}
|
|
|
|
|
// err := resultError("main.runApp", "startup failed", result)
|
2026-03-30 00:00:33 +00:00
|
|
|
func resultError(op, msg string, result core.Result) error {
|
|
|
|
|
if result.OK {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
if err, ok := result.Value.(error); ok && err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return core.E(op, msg, nil)
|
|
|
|
|
}
|