diff options
| -rw-r--r-- | docs/plan-summary-qa-feature.md | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/docs/plan-summary-qa-feature.md b/docs/plan-summary-qa-feature.md new file mode 100644 index 0000000..b4ff29c --- /dev/null +++ b/docs/plan-summary-qa-feature.md @@ -0,0 +1,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 | |
