diff options
| -rw-r--r-- | SESSION_STATE.md | 124 | ||||
| -rw-r--r-- | internal/handlers/handlers_test.go | 21 |
2 files changed, 53 insertions, 92 deletions
diff --git a/SESSION_STATE.md b/SESSION_STATE.md index 6e076f5..9ecbcbe 100644 --- a/SESSION_STATE.md +++ b/SESSION_STATE.md @@ -1,97 +1,37 @@ # Session State ## Current Focus -Implementing bugs from production database - -## Recently Completed Bugs -- **#74**: Feature toggles - Added feature toggle system with UI at `/settings` -- **#56**: Box contents overflow - Added overflow-hidden to card/panel classes -- **#65**: Google tasks don't show up - Added logging, fixed tasks without due dates -- **#66**: Tasks use outdated template - Added no-cache headers to dynamic responses -- **#67**: Pop up menus need higher z-index - Updated to z-[100] -- **#68**: Track completion in external sources - Already implemented -- **#69**: Timeline calendar view - Implemented calendar-style Today section with: - - Hourly grid (6am-10pm) - - Events positioned by time with duration-based height - - Separate compact section for overdue/all-day/untimed items - - Added IsOverdue and IsAllDay fields to TimelineItem model -- **#70**: Clear input boxes on success - Fixed shopping-mode.html reset -- **#71**: Shopping items no checkmarks - Removed checkboxes from shopping-tab (only in shopping mode) -- **#72**: Inline add per store - Added inline input at end of each store section -- **#73**: Store grouping optional - Added Grouped/Flat view toggle with query param - -## Active Feature -**Agent Context API** — `issues/feature_agent_context_api.md` -- Status: [REVIEW_READY] Phase 1 Complete + Browser-Only Agent Endpoints + Refactored +Infrastructure & documentation improvements + +## Recently Completed +- Build version footer with ldflags injection (`deploy.sh`, `index.html`) +- `assertTemplateContains` test helper, refactored existing template tests +- `scripts/logs` for fetching production journalctl +- Fix passkey registration: hide UI when WebAuthn not configured (WebAuthnEnabled flag) +- Added no-cache header tests for #66 + +## Completed Bugs (All Verified) +- **#74**: Feature toggles — tests: `TestHandleToggleFeature`, `TestHandleCreateFeature`, `TestHandleDeleteFeature`; docs: DESIGN.md §4.3 +- **#56**: Box contents overflow — CSS-only fix, documented in DESIGN.md +- **#65**: Google Tasks — timeline tests cover integration; API client lacks dedicated unit tests +- **#66**: No-cache headers — tests: `TestHTMLResponse_SetsNoCacheHeaders`, `TestJSONResponse_SetsNoCacheHeaders` +- **#67**: Z-index — CSS-only fix, documented in DESIGN.md §z-index hierarchy +- **#68**: Track completion — tests: `TestHandleCompleteAtom_Todoist`, `TestHandleCompleteAtom_Trello` +- **#69**: Timeline calendar — tests: `TestCalcCalendarBounds`, `TestBuildTimeline_IncludesOverdueItems`; docs: DESIGN.md §Timeline View +- **#70**: Clear inputs — tests: `TestShoppingQuickAdd_Success`; docs: DESIGN.md §Quick Add UX +- **#71**: Shopping checkmarks — tests: `TestShoppingModeItemsTemplateFiltersChecked` +- **#72**: Inline add per store — tests: `TestShoppingQuickAdd_ShoppingModeReturnsStoreItems` +- **#73**: Store grouping — partial tests, partial docs + +## Agent Context API +- Status: [REVIEW_READY] Phase 1 Complete +- Tests: `internal/handlers/agent_test.go` (comprehensive) +- Docs: ADR-005, DESIGN.md §Agent Context API - Phase 2 (Write Operations) and Phase 3 (Create + Management) pending -### Recent Updates -**Refactoring (agent.go):** -- Reused `BuildTimeline()` from timeline_logic.go instead of duplicating fetch logic -- Added section headers for code organization -- Extracted helpers: `isSessionExpired()`, `renderAgentTemplate()` - -**Enhanced Context API:** -- Extended date range: 7 days back (overdue) to 14 days forward -- Added `completed_log` - tracks completed tasks with title, due date, completion date -- Added `day_section` field to timeline items (overdue/today/tomorrow/later) -- Calendar-style view for today (6am-10pm) in HTML template -- Tabs for Timeline vs Completed Log in web view - -**New Database:** -- `completed_tasks` table (migration 011) - logs completed task history -- `SaveCompletedTask()` / `GetCompletedTasks()` store methods -- `CompletedTask` model type - -### Phase 1 Completed Items -- [x] Migration `migrations/010_agent_tables.sql` — agents and agent_sessions tables -- [x] Store methods in `internal/store/sqlite.go` — full CRUD for agents/sessions -- [x] Agent handlers in `internal/handlers/agent.go`: - - POST `/agent/auth/request` — request access (returns request_token) - - GET `/agent/auth/poll` — poll for approval status - - POST `/agent/auth/approve` — user approves (browser auth required) - - POST `/agent/auth/deny` — user denies (browser auth required) - - GET `/agent/context` — full 7-day context (agent session required) -- [x] WebSocket hub in `internal/handlers/websocket.go`: - - GET `/ws/notifications` — push agent request alerts to browsers -- [x] Routes registered in `cmd/dashboard/main.go` -- [x] Frontend approval UI in `web/static/js/app.js`: - - WebSocket connection with auto-reconnect - - Approval modal with trust indicators - - Countdown timer for request expiry -- [x] Unit tests in `internal/handlers/agent_test.go` - -### Phase 1.5: Browser-Only Agent Endpoints (NEW) -- [x] GET `/agent/web/request?name=X&agent_id=Y` — HTML page with request token -- [x] GET `/agent/web/status?token=TOKEN` — HTML page showing approval status -- [x] GET `/agent/web/context?session=TOKEN` — HTML page with timeline data -- [x] Templates: `agent-request.html`, `agent-status.html`, `agent-context.html`, `agent-error.html` -- [x] All templates include embedded JSON in `<script type="application/json" id="agent-data">` for parsing -- [x] Store method: `GetPendingAgentSessionByAgentID()` — returns existing pending session -- [x] Bug fix: SQLite datetime comparison now uses `datetime('now', 'localtime')` for proper timezone handling -- [x] Tests for all new endpoints - -### Key Design Decisions -- Auth: Notification-based approval via WebSocket to browser -- Identity: Name + UUID binding with impersonation detection -- Session: 1 hour TTL, one session per agent, re-auth on expiry -- Scope: 7-day context (timeline from cached tasks, cards, meals) -- Rate limit: 10 requests/minute per IP on auth request endpoint - -### Files Modified -- `migrations/010_agent_tables.sql` (new) -- `internal/models/types.go` (added Agent, AgentSession, AgentAuthRequest, etc.) -- `internal/store/sqlite.go` (added ~250 lines of agent/session CRUD) -- `internal/handlers/agent.go` (new) -- `internal/handlers/websocket.go` (new) -- `internal/handlers/agent_test.go` (new) -- `cmd/dashboard/main.go` (route registration) -- `web/static/js/app.js` (WebSocket + approval modal) -- `go.mod`, `go.sum` (added gorilla/websocket) - -## Previous Work (Completed) -- [x] Bug fixes (Trello filter, recurring tasks) -- [x] Scripts: `bugs`, `resolve-bug` +## Known Gaps +- Google Tasks/Calendar API clients lack dedicated unit tests (integration tested via timeline) +- WebAuthn passkeys require `WEBAUTHN_RP_ID` and `WEBAUTHN_ORIGIN` env vars in production ## Remaining Items (Feature Requests) - #12: Research task durations @@ -101,6 +41,6 @@ Implementing bugs from production database - #33-38: Shopping/timeline features ## Next Steps -1. **Phase 2**: Implement write operations (complete, uncomplete, update due date) -2. **Phase 3**: Create task/shopping item, agent management UI -3. Test full auth flow manually with a real agent +1. Set `WEBAUTHN_RP_ID` and `WEBAUTHN_ORIGIN` in production to enable passkeys +2. **Phase 2**: Agent write operations (complete, uncomplete, update due date) +3. **Phase 3**: Create task/shopping item, agent management UI diff --git a/internal/handlers/handlers_test.go b/internal/handlers/handlers_test.go index b338aa2..6f7cc92 100644 --- a/internal/handlers/handlers_test.go +++ b/internal/handlers/handlers_test.go @@ -1538,6 +1538,27 @@ func TestHandleDeleteFeature(t *testing.T) { // Response Helper Tests // ============================================================================= +func TestHTMLResponse_SetsNoCacheHeaders(t *testing.T) { + w := httptest.NewRecorder() + r := NewMockRenderer() + HTMLResponse(w, r, "test", nil) + + cc := w.Header().Get("Cache-Control") + if !strings.Contains(cc, "no-cache") { + t.Errorf("Expected Cache-Control no-cache, got %s", cc) + } +} + +func TestJSONResponse_SetsNoCacheHeaders(t *testing.T) { + w := httptest.NewRecorder() + JSONResponse(w, map[string]string{"ok": "true"}) + + cc := w.Header().Get("Cache-Control") + if !strings.Contains(cc, "no-cache") { + t.Errorf("Expected Cache-Control no-cache, got %s", cc) + } +} + func TestHTMLString(t *testing.T) { w := httptest.NewRecorder() HTMLString(w, "<div>Test</div>") |
