[agent/codex:gpt-5.3-codex-spark] Read .core/reference/RFC-CORE-008-AGENT-EXPERIENCE.md (the A... #8
7 changed files with 33 additions and 27 deletions
|
|
@ -98,8 +98,8 @@ func runContainer(image, name string, detach bool, memory, cpus, sshPort int) er
|
|||
core.Print(nil, "%s %s", successStyle.Render(i18n.Label("started")), c.ID)
|
||||
core.Print(nil, "%s %d", dimStyle.Render(i18n.T("cmd.vm.label.pid")), c.PID)
|
||||
core.Println()
|
||||
core.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": c.ID[:8]}))
|
||||
core.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": c.ID[:8]}))
|
||||
core.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": shortContainerID(c.ID)}))
|
||||
core.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": shortContainerID(c.ID)}))
|
||||
} else {
|
||||
core.Println()
|
||||
core.Print(nil, "%s %s", dimStyle.Render(i18n.T("cmd.vm.label.container_stopped")), c.ID)
|
||||
|
|
@ -184,13 +184,23 @@ func listContainers(all bool) error {
|
|||
}
|
||||
|
||||
core.Print(w, "%s\t%s\t%s\t%s\t%s\t%d",
|
||||
c.ID[:8], c.Name, imageName, status, duration, c.PID)
|
||||
shortContainerID(c.ID), c.Name, imageName, status, duration, c.PID)
|
||||
}
|
||||
|
||||
if err := w.Flush(); err != nil {
|
||||
return coreerr.E("listContainers", "flush output", err)
|
||||
}
|
||||
|
||||
_ = w.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
func shortContainerID(id string) string {
|
||||
if len(id) <= 8 {
|
||||
return id
|
||||
}
|
||||
return id[:8]
|
||||
}
|
||||
|
||||
func formatDuration(d time.Duration) string {
|
||||
if d < time.Minute {
|
||||
return core.Sprintf("%ds", int(d.Seconds()))
|
||||
|
|
@ -233,7 +243,7 @@ func stopContainer(id string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
core.Print(nil, "%s %s", dimStyle.Render(i18n.T("cmd.vm.stop.stopping")), fullID[:8])
|
||||
core.Print(nil, "%s %s", dimStyle.Render(i18n.T("cmd.vm.stop.stopping")), shortContainerID(fullID))
|
||||
|
||||
ctx := context.Background()
|
||||
if err := manager.Stop(ctx, fullID); err != nil {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,9 @@ func listTemplates() error {
|
|||
}
|
||||
core.Print(w, "%s\t%s", repoNameStyle.Render(tmpl.Name), desc)
|
||||
}
|
||||
_ = w.Flush()
|
||||
if err := w.Flush(); err != nil {
|
||||
return coreerr.E("listTemplates", "flush output", err)
|
||||
}
|
||||
|
||||
core.Println()
|
||||
core.Print(nil, "%s %s", i18n.T("cmd.vm.templates.hint.show"), dimStyle.Render("core vm templates show <name>"))
|
||||
|
|
@ -209,8 +211,8 @@ func RunFromTemplate(templateName string, vars map[string]string, runOpts contai
|
|||
core.Print(nil, "%s %s", successStyle.Render(i18n.T("common.label.started")), c.ID)
|
||||
core.Print(nil, "%s %d", dimStyle.Render(i18n.T("cmd.vm.label.pid")), c.PID)
|
||||
core.Println()
|
||||
core.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": c.ID[:8]}))
|
||||
core.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": c.ID[:8]}))
|
||||
core.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": shortContainerID(c.ID)}))
|
||||
core.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": shortContainerID(c.ID)}))
|
||||
} else {
|
||||
core.Println()
|
||||
core.Print(nil, "%s %s", dimStyle.Render(i18n.T("cmd.vm.label.container_stopped")), c.ID)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func New(m io.Medium) (*DevOps, error) {
|
|||
return nil, coreerr.E("devops.New", "failed to create image manager", err)
|
||||
}
|
||||
|
||||
mgr, err := container.NewLinuxKitManager(io.Local)
|
||||
mgr, err := container.NewLinuxKitManager(m)
|
||||
if err != nil {
|
||||
return nil, coreerr.E("devops.New", "failed to create container manager", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import (
|
|||
// ImageManager handles image downloads and updates.
|
||||
type ImageManager struct {
|
||||
medium io.Medium
|
||||
config *Config
|
||||
manifest *Manifest
|
||||
sources []sources.ImageSource
|
||||
}
|
||||
|
|
@ -83,7 +82,6 @@ func NewImageManager(m io.Medium, cfg *Config) (*ImageManager, error) {
|
|||
|
||||
return &ImageManager{
|
||||
medium: m,
|
||||
config: cfg,
|
||||
manifest: manifest,
|
||||
sources: srcs,
|
||||
}, nil
|
||||
|
|
|
|||
|
|
@ -240,7 +240,6 @@ func TestImageManager_InstallNoSourceAvailable_Bad(t *testing.T) {
|
|||
// Create manager with empty sources
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")},
|
||||
sources: nil, // no sources
|
||||
}
|
||||
|
|
@ -301,7 +300,6 @@ func TestImageManager_InstallWithMockSource_Good(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")},
|
||||
sources: []sources.ImageSource{mock},
|
||||
}
|
||||
|
|
@ -330,7 +328,6 @@ func TestImageManager_InstallDownloadError_Bad(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")},
|
||||
sources: []sources.ImageSource{mock},
|
||||
}
|
||||
|
|
@ -351,7 +348,6 @@ func TestImageManager_InstallVersionError_Bad(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")},
|
||||
sources: []sources.ImageSource{mock},
|
||||
}
|
||||
|
|
@ -377,7 +373,6 @@ func TestImageManager_InstallSkipsUnavailableSource_Good(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")},
|
||||
sources: []sources.ImageSource{unavailableMock, availableMock},
|
||||
}
|
||||
|
|
@ -402,7 +397,6 @@ func TestImageManager_CheckUpdateWithMockSource_Good(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{
|
||||
medium: io.Local,
|
||||
Images: map[string]ImageInfo{
|
||||
|
|
@ -432,7 +426,6 @@ func TestImageManager_CheckUpdateNoUpdate_Good(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{
|
||||
medium: io.Local,
|
||||
Images: map[string]ImageInfo{
|
||||
|
|
@ -461,7 +454,6 @@ func TestImageManager_CheckUpdateNoSource_Bad(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{
|
||||
medium: io.Local,
|
||||
Images: map[string]ImageInfo{
|
||||
|
|
@ -489,7 +481,6 @@ func TestImageManager_CheckUpdateVersionError_Bad(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{
|
||||
medium: io.Local,
|
||||
Images: map[string]ImageInfo{
|
||||
|
|
@ -511,7 +502,6 @@ func TestImageManager_InstallEmptySources_Bad(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")},
|
||||
sources: []sources.ImageSource{}, // Empty slice, not nil
|
||||
}
|
||||
|
|
@ -530,7 +520,6 @@ func TestImageManager_InstallAllUnavailable_Bad(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")},
|
||||
sources: []sources.ImageSource{mock1, mock2},
|
||||
}
|
||||
|
|
@ -549,7 +538,6 @@ func TestImageManager_CheckUpdateFirstSourceUnavailable_Good(t *testing.T) {
|
|||
|
||||
mgr := &ImageManager{
|
||||
medium: io.Local,
|
||||
config: DefaultConfig(),
|
||||
manifest: &Manifest{
|
||||
medium: io.Local,
|
||||
Images: map[string]ImageInfo{
|
||||
|
|
|
|||
|
|
@ -351,11 +351,13 @@ type followReader struct {
|
|||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
reader *bufio.Reader
|
||||
medium io.Medium
|
||||
path string
|
||||
}
|
||||
|
||||
func newFollowReader(ctx context.Context, m io.Medium, path string) (*followReader, error) {
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
file, err := m.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -370,8 +372,6 @@ func newFollowReader(ctx context.Context, m io.Medium, path string) (*followRead
|
|||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
reader: bufio.NewReader(file),
|
||||
medium: m,
|
||||
path: path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
8
state.go
8
state.go
|
|
@ -116,6 +116,10 @@ func (s *State) SaveState() error {
|
|||
|
||||
// Add adds a container to the state and persists it.
|
||||
func (s *State) Add(c *Container) error {
|
||||
if c == nil {
|
||||
return core.E("State.Add", "container cannot be nil", nil)
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
s.Containers[c.ID] = c
|
||||
s.mu.Unlock()
|
||||
|
|
@ -140,6 +144,10 @@ func (s *State) Get(id string) (*Container, bool) {
|
|||
|
||||
// Update updates a container in the state and persists it.
|
||||
func (s *State) Update(c *Container) error {
|
||||
if c == nil {
|
||||
return core.E("State.Update", "container cannot be nil", nil)
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
s.Containers[c.ID] = c
|
||||
s.mu.Unlock()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue