Skip to content

Commit 900bb8a

Browse files
authored
Merge pull request #452 from bborn/task/1185-fix-executor-status-message-accuracy
Fix executor status message accuracy
2 parents 4ba8c17 + 8276205 commit 900bb8a

File tree

5 files changed

+167
-1
lines changed

5 files changed

+167
-1
lines changed

.devcontainer/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Development Container Configuration
2+
3+
This directory contains configuration for cloud development environments (VS Code Dev Containers, GitHub Codespaces, etc.).
4+
5+
## Features
6+
7+
- Automatically installs Claude CLI on container creation
8+
- Pre-configured Go development environment
9+
- VS Code extensions for Go development
10+
11+
## Manual Installation
12+
13+
If you're not using a devcontainer-compatible environment, you can manually install Claude CLI:
14+
15+
```bash
16+
curl -fsSL https://claude.ai/install.sh | bash
17+
```
18+
19+
After installation, authenticate with:
20+
21+
```bash
22+
claude login
23+
```
24+
25+
## Supported Platforms
26+
27+
- VS Code Dev Containers
28+
- GitHub Codespaces
29+
- Any Docker-based development environment that supports devcontainer.json

.devcontainer/devcontainer.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "Workflow Development",
3+
"image": "mcr.microsoft.com/devcontainers/go:1-1.21-bullseye",
4+
"features": {},
5+
"postCreateCommand": "bash .devcontainer/post-create.sh",
6+
"customizations": {
7+
"vscode": {
8+
"extensions": [
9+
"golang.go"
10+
]
11+
}
12+
}
13+
}

.devcontainer/post-create.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "Installing Claude CLI..."
5+
curl -fsSL https://claude.ai/install.sh | bash
6+
7+
echo "Claude CLI installation complete!"
8+
claude --version || echo "Claude installed - you may need to run 'claude login' to authenticate"

internal/ui/app.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,12 @@ func (m *AppModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
816816
}
817817
if prompt := m.latestPermissionPrompt(t.ID); prompt != "" {
818818
m.tasksNeedingInput[t.ID] = true
819-
m.executorPrompts[t.ID] = prompt
819+
// Extract just the meaningful part after "Waiting for permission: "
820+
displayPrompt := prompt
821+
if strings.HasPrefix(prompt, "Waiting for permission: ") {
822+
displayPrompt = strings.TrimPrefix(prompt, "Waiting for permission: ")
823+
}
824+
m.executorPrompts[t.ID] = displayPrompt
820825
}
821826
}
822827

internal/ui/app_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,117 @@ func containsSubstr(s, substr string) bool {
11751175
return false
11761176
}
11771177

1178+
func TestLatestPermissionPrompt_PermissionMessage(t *testing.T) {
1179+
database, err := db.Open(":memory:")
1180+
if err != nil {
1181+
t.Fatalf("Failed to create test database: %v", err)
1182+
}
1183+
defer database.Close()
1184+
1185+
m := &AppModel{db: database}
1186+
1187+
// Create a task
1188+
task := &db.Task{Title: "Test task", Status: db.StatusBlocked}
1189+
if err := database.CreateTask(task); err != nil {
1190+
t.Fatalf("Failed to create task: %v", err)
1191+
}
1192+
1193+
// Log a permission message (as the notification hook would)
1194+
database.AppendTaskLog(task.ID, "system", "Waiting for permission: Edit(src/models/offer.rb)")
1195+
1196+
// Should return the full permission message
1197+
result := m.latestPermissionPrompt(task.ID)
1198+
if result != "Waiting for permission: Edit(src/models/offer.rb)" {
1199+
t.Errorf("expected 'Waiting for permission: Edit(src/models/offer.rb)', got '%s'", result)
1200+
}
1201+
}
1202+
1203+
func TestLatestPermissionPrompt_GenericWaiting(t *testing.T) {
1204+
database, err := db.Open(":memory:")
1205+
if err != nil {
1206+
t.Fatalf("Failed to create test database: %v", err)
1207+
}
1208+
defer database.Close()
1209+
1210+
m := &AppModel{db: database}
1211+
1212+
task := &db.Task{Title: "Test task", Status: db.StatusBlocked}
1213+
if err := database.CreateTask(task); err != nil {
1214+
t.Fatalf("Failed to create task: %v", err)
1215+
}
1216+
1217+
// Log a generic waiting message (no specific message from hook)
1218+
database.AppendTaskLog(task.ID, "system", "Waiting for permission")
1219+
1220+
result := m.latestPermissionPrompt(task.ID)
1221+
if result != "Waiting for permission" {
1222+
t.Errorf("expected 'Waiting for permission', got '%s'", result)
1223+
}
1224+
}
1225+
1226+
func TestLatestPermissionPrompt_ResumedClears(t *testing.T) {
1227+
database, err := db.Open(":memory:")
1228+
if err != nil {
1229+
t.Fatalf("Failed to create test database: %v", err)
1230+
}
1231+
defer database.Close()
1232+
1233+
m := &AppModel{db: database}
1234+
1235+
task := &db.Task{Title: "Test task", Status: db.StatusBlocked}
1236+
if err := database.CreateTask(task); err != nil {
1237+
t.Fatalf("Failed to create task: %v", err)
1238+
}
1239+
1240+
// Log a permission message, then a resumed message
1241+
database.AppendTaskLog(task.ID, "system", "Waiting for permission: Edit(file.go)")
1242+
database.AppendTaskLog(task.ID, "system", "Claude resumed working")
1243+
1244+
// Should return empty since Claude resumed
1245+
result := m.latestPermissionPrompt(task.ID)
1246+
if result != "" {
1247+
t.Errorf("expected empty string after resume, got '%s'", result)
1248+
}
1249+
}
1250+
1251+
func TestLatestPermissionPrompt_NoLogs(t *testing.T) {
1252+
database, err := db.Open(":memory:")
1253+
if err != nil {
1254+
t.Fatalf("Failed to create test database: %v", err)
1255+
}
1256+
defer database.Close()
1257+
1258+
m := &AppModel{db: database}
1259+
1260+
// No task or logs - should return empty
1261+
result := m.latestPermissionPrompt(999)
1262+
if result != "" {
1263+
t.Errorf("expected empty string for nonexistent task, got '%s'", result)
1264+
}
1265+
}
1266+
1267+
func TestLatestPermissionPrompt_UserInputMessage(t *testing.T) {
1268+
database, err := db.Open(":memory:")
1269+
if err != nil {
1270+
t.Fatalf("Failed to create test database: %v", err)
1271+
}
1272+
defer database.Close()
1273+
1274+
m := &AppModel{db: database}
1275+
1276+
task := &db.Task{Title: "Test task", Status: db.StatusBlocked}
1277+
if err := database.CreateTask(task); err != nil {
1278+
t.Fatalf("Failed to create task: %v", err)
1279+
}
1280+
1281+
database.AppendTaskLog(task.ID, "system", "Waiting for user input")
1282+
1283+
result := m.latestPermissionPrompt(task.ID)
1284+
if result != "Waiting for user input" {
1285+
t.Errorf("expected 'Waiting for user input', got '%s'", result)
1286+
}
1287+
}
1288+
11781289
func TestJumpToNotificationKey_FocusExecutor(t *testing.T) {
11791290
// Create app model with kanban board and notification
11801291
tasks := []*db.Task{

0 commit comments

Comments
 (0)