Backend: - Replace on-the-fly Ollama calls with versioned feature store (task_features, task_edges) - Background Tokio worker drains pending rows; write path returns immediately - MLConfig versioning: changing model IDs triggers automatic backfill via next_stale() - AppState with FromRef; new GET /api/ml/status observability endpoint - Idempotent mark_pending (content hash guards), retry failed rows after 30s - Remove tracked build artifacts (backend/target/, frontend/.next/, node_modules/) Frontend: - TaskItem: items-center alignment (fixes checkbox/text offset), break-words for overflow - TaskDetailPanel: fix invisible AI context (text-gray-700→text-gray-400), show all fields - TaskDetailPanel: pending placeholder when latent_desc not yet computed, show task ID - GraphView: surface pending_count as amber pulsing "analyzing N tasks…" hint in legend - Fix Task.created_at type (number/Unix seconds, not string) - Auth gate: LoginPage + sessionStorage; fix e2e tests to bypass gate in jsdom - Fix deleteTask test assertion and '1 remaining'→'1 left' stale text Docs: - VitePress docs in docs/ with guide, MLOps pipeline, and API reference Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2.3 KiB
API Reference
All endpoints are under http://localhost:3001/api and require HTTP Basic Auth (admin / configured password).
Tasks
GET /api/tasks
Returns all tasks ordered by created_at ascending.
Response
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Buy groceries @home #errand",
"description": null,
"completed": false,
"created_at": 1760000000,
"project": "home",
"tags": "errand",
"latent_desc": "This task involves…"
}
]
POST /api/tasks
Create a new task. Automatically parses @project and #tag tokens from the title. Seeds a pending feature row and wakes the ML worker.
Body
{ "title": "Deploy to prod @work #urgent", "description": "optional" }
Response — 201 Created with the created Task object. latent_desc is always null on creation.
PATCH /api/tasks/:id
Update one or more fields of a task. If the title changes, the feature row is re-queued.
Body (all fields optional)
{ "title": "New title", "description": "Updated", "completed": true }
Response — 200 OK with the updated Task.
DELETE /api/tasks/:id
Delete a task and cascade-delete its feature row and all edges it appears in.
Response — 204 No Content
Graph
GET /api/graph
Returns the task graph ready for react-force-graph-2d. No inference is performed at query time.
Response
{
"nodes": [
{ "id": "uuid…", "label": "Buy groceries", "completed": false, "project": "home" }
],
"edges": [
{ "source": "uuid-a", "target": "uuid-b", "weight": 0.923 }
],
"pending_count": 3
}
pending_count is the number of tasks whose embeddings haven't been computed (or whose last attempt failed). The frontend uses this to show an "analyzing N tasks…" hint in the graph legend.
ML
GET /api/ml/status
Observability endpoint — returns current ML config and feature store counters.
Response
{
"desc_model": "qwen2.5:1.5b",
"embed_model": "nomic-embed-text",
"prompt_version": "v1",
"min_similarity": 0.8,
"pending": 2,
"ready": 15,
"failed": 0,
"edges": 28,
"last_error": null
}
last_error is the error string from the most recently failed feature row (useful for diagnosing Ollama connectivity issues).