Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ type Environment struct {
mu sync.RWMutex
}

func New(ctx context.Context, dag *dagger.Client, id, title, worktree string, initialSourceDir *dagger.Directory) (*Environment, error) {
func New(ctx context.Context, dag *dagger.Client, id, title, summary, worktree string, initialSourceDir *dagger.Directory) (*Environment, error) {
env := &Environment{
EnvironmentInfo: &EnvironmentInfo{
ID: id,
Worktree: worktree,
Config: DefaultConfig(),
State: &State{
Title: title,
Summary: summary,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
Expand Down
1 change: 1 addition & 0 deletions environment/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
type State struct {
Container string `json:"container,omitempty"`
Title string `json:"title,omitempty"`
Summary string `json:"summary,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
}
Expand Down
24 changes: 21 additions & 3 deletions mcpserver/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func init() {
type EnvironmentResponse struct {
ID string `json:"id"`
Title string `json:"title"`
Summary string `json:"summary"`
BaseImage string `json:"base_image"`
SetupCommands []string `json:"setup_commands"`
Instructions string `json:"instructions"`
Expand Down Expand Up @@ -157,6 +158,7 @@ func marshalEnvironmentInfo(envInfo *environment.EnvironmentInfo) (string, error
resp := &EnvironmentResponse{
ID: envInfo.ID,
Title: envInfo.State.Title,
Summary: envInfo.State.Summary,
Instructions: envInfo.Config.Instructions,
BaseImage: envInfo.Config.BaseImage,
SetupCommands: envInfo.Config.SetupCommands,
Expand Down Expand Up @@ -227,6 +229,10 @@ DO NOT manually install toolchains inside the environment, instead explicitly ca
mcp.Description("Short description of the work that is happening in this environment. Keep this title updated using `environment_update`."),
mcp.Required(),
),
mcp.WithString("summary",
mcp.Description("Summary of all the changes that happened in this environment. MUST be in the format of Conventional Commits. Add a body with further details if needed. MUST BE kept up to date with `environment_update`."),
mcp.Required(),
),
mcp.WithString("environment_source",
mcp.Description("Absolute path to the source git repository for the environment."),
mcp.Required(),
Expand All @@ -241,13 +247,17 @@ DO NOT manually install toolchains inside the environment, instead explicitly ca
if err != nil {
return nil, err
}
summary, err := request.RequireString("summary")
if err != nil {
return nil, err
}

dag, ok := ctx.Value("dagger_client").(*dagger.Client)
if !ok {
return mcp.NewToolResultErrorFromErr("dagger client not found in context", nil), nil
}

env, err := repo.Create(ctx, dag, title, request.GetString("explanation", ""))
env, err := repo.Create(ctx, dag, title, summary, request.GetString("explanation", ""))
if err != nil {
return mcp.NewToolResultErrorFromErr("failed to create environment", err), nil
}
Expand Down Expand Up @@ -280,6 +290,10 @@ var EnvironmentUpdateTool = &Tool{
mcp.Description("Short description of the work that is happening in this environment."),
mcp.Required(),
),
mcp.WithString("summary",
mcp.Description("Summary of all the changes that happened in this environment. This should be formatted like a commit message and always kept up to date `environment_update`."),
mcp.Required(),
),
Comment on lines +293 to +296
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instructions, title, base_image, setup commands, envs, and secrets need to be optional if this is required, and if we're going that far, maybe everything on here should be optional.

mcp.WithString("base_image",
mcp.Description("Change the base image for the environment."),
mcp.Required(),
Expand Down Expand Up @@ -350,6 +364,10 @@ Supported schemas are:
env.State.Title = title
}

if summary := request.GetString("summary", ""); summary != "" {
env.State.Summary = summary
}

if err := env.UpdateConfig(ctx, request.GetString("explanation", ""), config); err != nil {
return mcp.NewToolResultErrorFromErr("unable to update the environment", err), nil
}
Expand Down Expand Up @@ -503,7 +521,7 @@ Background commands are unaffected by filesystem and any other kind of changes.
return mcp.NewToolResultErrorFromErr("failed to run command", runErr), nil
}

return mcp.NewToolResultText(fmt.Sprintf("%s\n\nAny changes to the container workdir (%s) have been committed and pushed to container-use/ remote", stdout, env.Config.Workdir)), nil
return mcp.NewToolResultText(fmt.Sprintf("%s\n\nAny changes to the container workdir (%s) have been committed and pushed to container-use/ remote.\nMake sure to update the summary with `environment_update` if necessary. Current summary: %q", stdout, env.Config.Workdir, env.State.Summary)), nil
},
}

Expand Down Expand Up @@ -643,7 +661,7 @@ var EnvironmentFileWriteTool = &Tool{
return mcp.NewToolResultErrorFromErr("unable to update the environment", err), nil
}

return mcp.NewToolResultText(fmt.Sprintf("file %s written successfully and committed to container-use/ remote", targetFile)), nil
return mcp.NewToolResultText(fmt.Sprintf("file %s written successfully and committed to container-use/ remote.\nMake sure to update the summary with `environment_update` if necessary. Current summary: %q", targetFile, env.State.Summary)), nil
},
}

Expand Down
4 changes: 2 additions & 2 deletions repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func (r *Repository) exists(ctx context.Context, id string) error {

// Create creates a new environment with the given description and explanation.
// Requires a dagger client for container operations during environment initialization.
func (r *Repository) Create(ctx context.Context, dag *dagger.Client, description, explanation string) (*environment.Environment, error) {
func (r *Repository) Create(ctx context.Context, dag *dagger.Client, title, summary, explanation string) (*environment.Environment, error) {
id := petname.Generate(2, "-")
worktree, err := r.initializeWorktree(ctx, id)
if err != nil {
Expand Down Expand Up @@ -172,7 +172,7 @@ func (r *Repository) Create(ctx context.Context, dag *dagger.Client, description
return nil, fmt.Errorf("failed loading initial source directory: %w", err)
}

env, err := environment.New(ctx, dag, id, description, worktree, baseSourceDir)
env, err := environment.New(ctx, dag, id, title, summary, worktree, baseSourceDir)
if err != nil {
return nil, err
}
Expand Down
Loading