1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
# Implementation Plan: Task Summary & Q&A Display
## Overview
Require agents to conclude with a final summary paragraph. Persist all Q&A interactions. Display both in the task UI.
## 1. Update Agent Preamble (preamble.go)
**File**: `internal/executor/preamble.go`
Add a new section to `planningPreamble` after the Git Discipline section:
```
## Final Summary (mandatory)
Before exiting, write a brief summary paragraph (2-5 sentences) describing:
- What was accomplished
- Key decisions made
- Any issues or follow-ups
Start the summary with "## Summary" on its own line so it can be parsed.
```
## 2. Add Task Fields (task.go + storage)
**File**: `internal/task/task.go`
Add to Task struct:
```go
Summary string `yaml:"-" json:"summary,omitempty"`
InteractionsJSON string `yaml:"-" json:"interactions,omitempty"`
```
**File**: `internal/storage/db.go`
Add migration:
```go
`ALTER TABLE tasks ADD COLUMN summary TEXT`,
`ALTER TABLE tasks ADD COLUMN interactions_json TEXT`,
```
Update all `scanTask` calls to include new columns.
Add `UpdateTaskSummary(taskID, summary string)` method.
Add `AppendTaskInteraction(taskID string, interaction Interaction)` method.
## 3. Define Interaction Type
**File**: `internal/task/task.go` (or new `internal/task/interaction.go`)
```go
type Interaction struct {
Type string `json:"type"` // "question" or "answer"
Content string `json:"content"` // the text
Timestamp string `json:"timestamp"` // ISO 8601
ToolUseID string `json:"tool_use_id,omitempty"`
}
```
## 4. Extract Summary from Agent Output
**File**: `internal/executor/claude.go`
After execution completes successfully, read stdout.log and extract the summary:
- Scan for text blocks in stream-json `assistant` messages
- Look for the last text content containing "## Summary"
- Extract everything after that marker as the summary
- Store via `store.UpdateTaskSummary()`
New function: `extractSummary(stdoutPath string) string`
**File**: `internal/executor/executor.go`
In `handleRunResult()`, after successful completion, call summary extraction and persist it.
## 5. Persist Q&A Interactions
**File**: `internal/executor/executor.go` or `internal/executor/question.go`
When a question is detected (in `handleRunResult` when `BlockedError`):
- Append a "question" interaction to `interactions_json`
**File**: `internal/api/server.go`
When an answer is submitted (`POST /api/tasks/{id}/answer`):
- Append an "answer" interaction to `interactions_json`
## 6. Update Storage Layer
**File**: `internal/storage/db.go`
- Add `summary` and `interactions_json` to SELECT queries in `scanTask`
- Add `UpdateTaskSummary(taskID, summary string) error`
- Add `AppendTaskInteraction(taskID string, interactionJSON string) error` — reads current JSON array, appends, writes back
Update the `Store` interface in `internal/executor/executor.go` to include new methods.
## 7. Update UI
**File**: `web/app.js`
In `renderTaskPanel()` (line 1290):
- After Overview section, add **Summary** section if `task.summary` is non-empty
- After Agent Config section, add **Q&A History** section if `task.interactions` is non-empty
- Render interactions as a timeline: question/answer pairs with timestamps
**File**: `web/style.css`
Add styles for:
- `.task-summary` — summary display block
- `.qa-timeline` — Q&A interaction timeline
- `.qa-item` — individual Q&A entry with type indicator
## 8. API Changes
**File**: `internal/api/server.go`
No new endpoints needed — summary and interactions are returned as part of the task JSON via existing `GET /api/tasks/{id}`.
## 9. Test Strategy
### Unit Tests
- `internal/task/task_test.go`: Interaction struct JSON marshal/unmarshal
- `internal/executor/summary_test.go`: `extractSummary()` with various stream-json outputs
- `internal/storage/db_test.go`: `UpdateTaskSummary`, `AppendTaskInteraction`, verify `scanTask` includes new fields
### Integration Tests
- `internal/executor/executor_test.go`: Verify summary extraction after successful execution
- `internal/api/server_test.go`: Verify task JSON response includes summary and interactions
### UI Tests (if framework exists)
- Verify renderTaskPanel shows summary section when present
- Verify Q&A history renders correctly
## File Change Summary
| File | Change |
|------|--------|
| `internal/executor/preamble.go` | Add summary requirement to preamble |
| `internal/task/task.go` | Add Summary, InteractionsJSON fields; Interaction type |
| `internal/storage/db.go` | Migration, scan changes, new update methods |
| `internal/executor/executor.go` | Store interface update, summary extraction call |
| `internal/executor/claude.go` | `extractSummary()` function |
| `internal/api/server.go` | Append interaction on answer |
| `web/app.js` | Summary + Q&A sections in renderTaskPanel |
| `web/style.css` | New styles |
| Tests in respective `_test.go` files |
|