summaryrefslogtreecommitdiff
path: root/issues/feature_agent_context_api.md
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-23 06:50:43 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-23 06:50:43 +0000
commitb0688c8819da1b7fcb4a97b6ec1fa58050e4841e (patch)
treec62b4ea3e5cdb56225c39ad930dd3e5584053827 /issues/feature_agent_context_api.md
parentef7a45361996b7a49226a0b088e2599f2801d017 (diff)
feat: complete Agent Context API Phase 2 & 3 (Write/Create/Management)
- Implement write operations (complete, uncomplete, update due date, update task) - Implement create operations (create task, add shopping item) - Add Trusted Agents management UI in Settings with revocation support - Fix SQLite timestamp scanning bug for completed tasks - Add comprehensive unit tests for all new agent endpoints - Update worklog and feature documentation
Diffstat (limited to 'issues/feature_agent_context_api.md')
-rw-r--r--issues/feature_agent_context_api.md271
1 files changed, 39 insertions, 232 deletions
diff --git a/issues/feature_agent_context_api.md b/issues/feature_agent_context_api.md
index 7be5f50..69b3feb 100644
--- a/issues/feature_agent_context_api.md
+++ b/issues/feature_agent_context_api.md
@@ -1,114 +1,46 @@
# Feature: Agent Context API
-**Status:** [IN_PROGRESS] Phase 1 Complete
+**Status:** [COMPLETED]
**Created:** 2026-01-27
+**Updated:** 2026-03-23
**Author:** Architect
---
## Overview
-Expose a JSON API that allows external chat agents (e.g., Claude Code) to query dashboard context and manipulate items. Authentication uses a notification-based approval flow with agent identity binding.
+Expose a JSON API that allows external chat agents (e.g., Claude Code, Gemini CLI) to query dashboard context and manipulate items. Authentication uses a notification-based approval flow with agent identity binding.
---
## User Stories
-1. **As a user**, I can approve/deny agent access requests from the dashboard UI
-2. **As a user**, I can see which agents have been granted access and revoke them
-3. **As an agent**, I can request access by providing my name and unique ID
-4. **As an agent**, once approved, I can query the 7-day context (tasks, meals, timeline)
-5. **As an agent**, I can complete/uncomplete tasks, update due dates, modify details, and create items
+1. [x] **As a user**, I can approve/deny agent access requests from the dashboard UI
+2. [x] **As a user**, I can see which agents have been granted access and revoke them
+3. [x] **As an agent**, I can request access by providing my name and unique ID
+4. [x] **As an agent**, once approved, I can query the 7-day context (tasks, meals, timeline)
+5. [x] **As an agent**, I can complete/uncomplete tasks, update due dates, modify details, and create items
---
-## Authentication Flow
+## Implementation Status
-```
-Agent Dashboard API Browser Tab
- │ │ │
- │ POST /agent/auth/request │ │
- │ {name, agent_id} │ │
- │ ──────────────────────────────>│ │
- │ │ │
- │ {request_token, status: │ WebSocket push: │
- │ "pending"} │ "Agent X wants access" │
- │ <──────────────────────────────│ ────────────────────────────>│
- │ │ │
- │ │ User approves
- │ │ │
- │ │ POST /agent/auth/approve │
- │ │ <────────────────────────────│
- │ │ │
- │ GET /agent/auth/poll │ │
- │ ?token=X │ │
- │ ──────────────────────────────>│ │
- │ │ │
- │ {status: "approved", │ │
- │ session_token, expiry} │ │
- │ <──────────────────────────────│ │
- │ │ │
- │ GET /agent/context │ │
- │ Authorization: Bearer X │ │
- │ ──────────────────────────────>│ │
- │ │ │
- │ {timeline, tasks, ...} │ │
- │ <──────────────────────────────│ │
-```
+### Phase 1: Auth Flow + Read Context (Complete)
+- [x] Agent authentication handshake (Request -> Approve -> Token)
+- [x] `/agent/context` endpoint returning timeline + today items
+- [x] WebSocket notification for approval requests
+- [x] Browser-only agent support (`/agent/web/context`)
----
-
-## Agent Identity Binding
-
-| Scenario | Behavior |
-|----------|----------|
-| New agent (name + ID never seen) | Show approval prompt, store pairing on approve |
-| Known agent (name + ID match stored) | Show approval prompt with "Recognized" indicator |
-| Suspicious (known name, different ID) | Show warning: "Agent 'X' with different ID" — require explicit re-trust |
-
----
-
-## Design Decisions
+### Phase 2: Write Operations (Complete)
+- [x] `POST /agent/tasks/{id}/complete`
+- [x] `POST /agent/tasks/{id}/uncomplete`
+- [x] `PATCH /agent/tasks/{id}/due`
+- [x] `PATCH /agent/tasks/{id}` (generic update)
-| Decision | Choice | Rationale |
-|----------|--------|-----------|
-| Session refresh | None — re-authenticate after expiry | Keep it simple |
-| Concurrent sessions | One per agent — new approval invalidates previous | Predictable state |
-| Deny behavior | Single-request denial, no blocking | Simple first pass |
-
----
-
-## Database Schema
-
-### New Tables
-
-```sql
--- Registered/approved agents
-CREATE TABLE agents (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- name TEXT NOT NULL,
- agent_id TEXT NOT NULL UNIQUE, -- UUID from agent
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
- last_seen DATETIME,
- trusted BOOLEAN DEFAULT 1 -- can be revoked
-);
-
--- Pending access requests and sessions
-CREATE TABLE agent_sessions (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- request_token TEXT NOT NULL UNIQUE,
- agent_name TEXT NOT NULL,
- agent_id TEXT NOT NULL,
- status TEXT DEFAULT 'pending', -- pending, approved, denied, expired
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
- expires_at DATETIME NOT NULL, -- request expires after 5 min
- session_token TEXT, -- populated on approval
- session_expires_at DATETIME -- session TTL (1 hour)
-);
-
-CREATE INDEX idx_agent_sessions_request ON agent_sessions(request_token);
-CREATE INDEX idx_agent_sessions_session ON agent_sessions(session_token);
-```
+### Phase 3: Create + Management (Complete)
+- [x] `POST /agent/tasks` (Quick add)
+- [x] `POST /agent/shopping` (Add shopping item)
+- [x] Trusted Agent management UI in Settings (list, revoke)
---
@@ -128,149 +60,23 @@ CREATE INDEX idx_agent_sessions_session ON agent_sessions(session_token);
| POST | `/agent/auth/approve` | User approves request |
| POST | `/agent/auth/deny` | User denies request |
-### Context (agent session required)
+### Context & Operations (agent session required)
| Method | Path | Purpose |
|--------|------|---------|
| GET | `/agent/context` | Full 7-day context |
+| POST | `/agent/tasks` | Create task |
+| POST | `/agent/tasks/{id}/complete` | Complete task |
+| POST | `/agent/tasks/{id}/uncomplete` | Reopen task |
+| PATCH | `/agent/tasks/{id}/due` | Update due date |
+| PATCH | `/agent/tasks/{id}` | Update details (title, desc) |
+| POST | `/agent/shopping` | Add shopping item |
-### Write Operations (agent session required)
-
-| Method | Path | Purpose | Priority |
-|--------|------|---------|----------|
-| PATCH | `/agent/tasks/{id}/due` | Update due date | P1 |
-| POST | `/agent/tasks/{id}/complete` | Complete task | P1 |
-| POST | `/agent/tasks/{id}/uncomplete` | Reopen task | P1 |
-| PATCH | `/agent/tasks/{id}` | Update details (title, desc) | P2 |
-| POST | `/agent/tasks` | Create task | P3 |
-| POST | `/agent/shopping/add` | Add shopping item | P3 |
-
----
-
-## Context Response Format
-
-```json
-{
- "generated_at": "2026-01-27T10:30:00-10:00",
- "range": {
- "start": "2026-01-27",
- "end": "2026-02-03"
- },
- "timeline": [
- {
- "id": "task_123",
- "source": "todoist",
- "type": "task",
- "title": "Buy groceries",
- "description": "Milk, eggs, bread",
- "due": "2026-01-27T17:00:00-10:00",
- "priority": 2,
- "completable": true,
- "url": "https://todoist.com/..."
- }
- ],
- "summary": {
- "total_items": 42,
- "by_source": {"todoist": 15, "trello": 20, "plantoeat": 7},
- "overdue": 3,
- "today": 8
- }
-}
-```
-
----
-
-## Browser Components
-
-### WebSocket Endpoint
-- Path: `/ws/notifications`
-- Purpose: Push agent request alerts to open browser tabs
-- Must handle: reconnect on disconnect, authentication check
-
-### Approval UI
-- Trigger: WebSocket message of type `agent_request`
-- Display: Modal or toast notification
-- Content:
- - Agent name
- - Agent ID (truncated to 8 chars)
- - Trust indicator: "New Agent" / "Recognized" / "Warning: Different ID"
-- Actions: Approve / Deny buttons
+### Management (browser session required)
-### Agent Management (Phase 3)
-- List of trusted agents with last-seen timestamp
-- Revoke access button per agent
-
----
-
-## Session Configuration
-
-| Parameter | Value |
-|-----------|-------|
-| Request expiry | 5 minutes |
-| Session TTL | 1 hour |
-| Poll interval (agent-side) | 2 seconds |
-
----
-
-## Security Considerations
-
-1. **Rate limiting** on `/agent/auth/request` — 10 requests/minute per IP
-2. **Tokens** are cryptographically random (32 bytes, base64url)
-3. **HTTPS required** — tokens in Authorization header
-4. **No CSRF** for agent endpoints — token-based auth, not cookies
-5. **One session per agent** — new approval invalidates previous session
-
----
-
-## Implementation Phases
-
-### Phase 1: Auth Flow + Read Context
-Files to create/modify:
-- `migrations/010_agent_tables.sql` — new tables
-- `internal/store/sqlite.go` — agent/session CRUD methods
-- `internal/handlers/agent.go` — new handler file for agent endpoints
-- `internal/handlers/websocket.go` — WebSocket notification hub
-- `cmd/dashboard/main.go` — register new routes
-- `web/templates/partials/agent-approval.html` — approval modal
-- `web/static/js/app.js` — WebSocket connection + approval UI logic
-
-Endpoints:
-- POST `/agent/auth/request`
-- GET `/agent/auth/poll`
-- POST `/agent/auth/approve`
-- POST `/agent/auth/deny`
-- GET `/agent/context`
-- WS `/ws/notifications`
-
-### Phase 2: Write Operations (P1 + P2)
-- POST `/agent/tasks/{id}/complete`
-- POST `/agent/tasks/{id}/uncomplete`
-- PATCH `/agent/tasks/{id}/due`
-- PATCH `/agent/tasks/{id}`
-
-### Phase 3: Create + Management
-- POST `/agent/tasks`
-- POST `/agent/shopping/add`
-- Agent management UI (list, revoke)
-
----
-
-## Testing Strategy
-
-### Unit Tests
-- `internal/store/sqlite_test.go` — agent/session CRUD
-- `internal/handlers/agent_test.go` — endpoint logic
-
-### Integration Tests
-- Full auth flow: request → approve → poll → context
-- Identity binding: same name different ID triggers warning
-- Session expiry: requests fail after TTL
-
-### Manual Testing
-- Open dashboard in browser
-- Run agent simulation script to request access
-- Verify notification appears
-- Approve and verify context returned
+| Method | Path | Purpose |
+|--------|------|---------|
+| DELETE | `/settings/agents/{id}` | Revoke agent access |
---
@@ -280,8 +86,9 @@ Endpoints:
|---------|------|
| Migration | `migrations/010_agent_tables.sql` |
| Store methods | `internal/store/sqlite.go` |
-| Agent handlers | `internal/handlers/agent.go` (new) |
-| WebSocket hub | `internal/handlers/websocket.go` (new) |
+| Agent handlers | `internal/handlers/agent.go` |
+| WebSocket hub | `internal/handlers/websocket.go` |
| Route registration | `cmd/dashboard/main.go` |
-| Approval modal | `web/templates/partials/agent-approval.html` (new) |
-| Client JS | `web/static/js/app.js` |
+| Settings handler | `internal/handlers/settings.go` |
+| Settings template | `web/templates/settings.html` |
+| Tests | `internal/handlers/agent_test.go` |