@@ -108,10 +108,22 @@ func (w *AppWorkspace) AgentRun(ctx context.Context, sessionID, prompt string, a
108108}
109109
110110func (w *AppWorkspace) AgentRunShellCommand(ctx context.Context, sessionID, command string, termWidth int) (proto.ShellCommandResponse, error) {
111+ var isFirstMessage bool
111112 var persist shell.PersistFunc
112113 if sessionID != "" {
113114 persist = func(cmd, output string, exitCode int) error {
114− _, err := w.app.Messages.Create(ctx, sessionID, message.CreateMessageParams{
115+ // Check if this is the first user message before persisting.
116+ msgs, err := w.app.Messages.List(ctx, sessionID)
117+ if err == nil {
118+ isFirstMessage = true
119+ for _, msg := range msgs {
120+ if msg.Role == message.User {
121+ isFirstMessage = false
122+ break
123+ }
124+ }
125+ }
126+ _, err = w.app.Messages.Create(ctx, sessionID, message.CreateMessageParams{
115127 Role: message.User,
116128 Parts: []message.ContentPart{message.ShellCommand{
117129 Command: cmd,
@@ -132,6 +144,20 @@ func (w *AppWorkspace) AgentRunShellCommand(ctx context.Context, sessionID, comm
132144 return proto.ShellCommandResponse{}, err
133145 }
134146
147+ // Generate a title from the shell command if it was the first message.
148+ if isFirstMessage {
149+ go func() {
150+ titleCtx := context.WithoutCancel(ctx)
151+ // Wait for the agent to be ready before generating.
152+ for i := 0; i < 50 && w.app.AgentCoordinator == nil; i++ {
153+ time.Sleep(100 * time.Millisecond)
154+ }
155+ if w.app.AgentCoordinator != nil {
156+ w.app.AgentCoordinator.GenerateTitle(titleCtx, sessionID, "$ "+command)
157+ }
158+ }()
159+ }
160+
135161 return proto.ShellCommandResponse{
136162 Output: result.Output,
137163 ExitCode: result.ExitCode,