2026-03-11 13:02:37 +00:00
---
title: Getting Started
2026-03-21 10:05:04 +00:00
description: Build a first CoreGO application with the current API.
2026-03-11 13:02:37 +00:00
---
# Getting Started
2026-03-21 10:05:04 +00:00
This page shows the shortest path to a useful CoreGO application using the API that exists in this repository today.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## Install
2026-03-11 13:02:37 +00:00
```bash
2026-03-21 10:05:04 +00:00
go get dappco.re/go/core
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
## Create a Core
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
`New` takes zero or more `core.Options` slices, but the current implementation only reads the first one. In practice, treat the constructor as `core.New(core.Options{...})` .
2026-03-11 13:02:37 +00:00
```go
package main
2026-03-21 10:05:04 +00:00
import "dappco.re/go/core"
2026-03-11 13:02:37 +00:00
func main() {
2026-03-21 10:05:04 +00:00
c := core.New(core.Options{
{Key: "name", Value: "agent-workbench"},
})
_ = c
2026-03-11 13:02:37 +00:00
}
```
2026-03-21 10:05:04 +00:00
The `name` option is copied into `c.App().Name` .
## Register a Service
Services are registered explicitly with a name and a `core.Service` DTO.
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
c.Service("audit", core.Service{
OnStart: func() core.Result {
core.Info("audit service started", "app", c.App().Name)
return core.Result{OK: true}
},
OnStop: func() core.Result {
core.Info("audit service stopped", "app", c.App().Name)
return core.Result{OK: true}
},
})
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
This registry stores `core.Service` values. It is a lifecycle registry, not a typed object container.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## Register a Query, Task, and Command
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
type workspaceCountQuery struct{}
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
type createWorkspaceTask struct {
Name string
2026-03-11 13:02:37 +00:00
}
2026-03-21 10:05:04 +00:00
c.RegisterQuery(func(_ *core.Core, q core.Query) core.Result {
switch q.(type) {
case workspaceCountQuery:
return core.Result{Value: 1, OK: true}
}
return core.Result{}
})
c.RegisterTask(func(_ *core.Core, t core.Task) core.Result {
switch task := t.(type) {
case createWorkspaceTask:
path := "/tmp/agent-workbench/" + task.Name
return core.Result{Value: path, OK: true}
}
return core.Result{}
})
c.Command("workspace/create", core.Command{
Action: func(opts core.Options) core.Result {
return c.PERFORM(createWorkspaceTask{
Name: opts.String("name"),
})
},
})
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
## Start the Runtime
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
if !c.ServiceStartup(context.Background(), nil).OK {
panic("startup failed")
}
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
`ServiceStartup` returns `core.Result` , not `error` .
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## Run Through the CLI Surface
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
r := c.Cli().Run("workspace", "create", "--name=alpha")
if r.OK {
fmt.Println("created:", r.Value)
}
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
For flags with values, the CLI stores the value as a string. `--name=alpha` becomes `opts.String("name") == "alpha"` .
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## Query the System
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
count := c.QUERY(workspaceCountQuery{})
if count.OK {
fmt.Println("workspace count:", count.Value)
}
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
## Shut Down Cleanly
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
_ = c.ServiceShutdown(context.Background())
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
Shutdown cancels `c.Context()` , broadcasts `ActionServiceShutdown{}` , waits for background tasks to finish, and then runs service stop hooks.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## Full Example
2026-03-11 13:02:37 +00:00
```go
package main
import (
2026-03-21 10:05:04 +00:00
"context"
"fmt"
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
"dappco.re/go/core"
2026-03-11 13:02:37 +00:00
)
2026-03-21 10:05:04 +00:00
type workspaceCountQuery struct{}
type createWorkspaceTask struct {
Name string
}
2026-03-11 13:02:37 +00:00
func main() {
2026-03-21 10:05:04 +00:00
c := core.New(core.Options{
{Key: "name", Value: "agent-workbench"},
})
c.Config().Set("workspace.root", "/tmp/agent-workbench")
c.Config().Enable("workspace.templates")
c.Service("audit", core.Service{
OnStart: func() core.Result {
core.Info("service started", "service", "audit")
return core.Result{OK: true}
},
OnStop: func() core.Result {
core.Info("service stopped", "service", "audit")
return core.Result{OK: true}
},
})
c.RegisterQuery(func(_ *core.Core, q core.Query) core.Result {
switch q.(type) {
case workspaceCountQuery:
return core.Result{Value: 1, OK: true}
}
return core.Result{}
})
c.RegisterTask(func(_ *core.Core, t core.Task) core.Result {
switch task := t.(type) {
case createWorkspaceTask:
path := c.Config().String("workspace.root") + "/" + task.Name
return core.Result{Value: path, OK: true}
}
return core.Result{}
})
c.Command("workspace/create", core.Command{
Action: func(opts core.Options) core.Result {
return c.PERFORM(createWorkspaceTask{
Name: opts.String("name"),
})
},
})
if !c.ServiceStartup(context.Background(), nil).OK {
panic("startup failed")
}
created := c.Cli().Run("workspace", "create", "--name=alpha")
fmt.Println("created:", created.Value)
count := c.QUERY(workspaceCountQuery{})
fmt.Println("workspace count:", count.Value)
_ = c.ServiceShutdown(context.Background())
2026-03-11 13:02:37 +00:00
}
```
## Next Steps
2026-03-21 10:05:04 +00:00
- Read [primitives.md ](primitives.md ) next so the repeated shapes are clear.
- Read [commands.md ](commands.md ) if you are building a CLI-first system.
- Read [messaging.md ](messaging.md ) if services need to collaborate without direct imports.