Skip to content

Latest commit

 

History

History
270 lines (183 loc) · 9.11 KB

File metadata and controls

270 lines (183 loc) · 9.11 KB
date 2026-03-19

Loci Dashboard API

Base URL: http://localhost:8765

All POST endpoints accept Content-Type: application/json. Success response: {"ok": true, ...}. Error response: {"error": "message"}.


GET /api/data

Returns the full live brain state. This is what the dashboard renders and what API workflows read.

Response keys: config, plan, inbox, me, tasks, planning, people, decisions, finance, content, learning, links, references, notes, projects, stats, build_time

curl http://localhost:8765/api/data

Tasks

POST /api/tasks/add

Add a task to tasks/tasks.json and regenerate tasks/active.md.

Field Type Required Default Description
text string yes — Task text
date string no null Intended date in YYYY-MM-DD format
startTime string no null Optional HH:MM start time
endTime string no null Optional HH:MM end time
project string no null Related project
source string no dashboard Source of the task
curl -X POST http://localhost:8765/api/tasks/add \
  -H 'Content-Type: application/json' \
  -d '{"text":"Buy groceries","date":"2026-05-31"}'

POST /api/tasks/toggle

Toggle a task's completion state in tasks/tasks.json.

Field Type Required Description
id string recommended Stable task id
task string fallback Task text (exact match)
checked boolean yes true = [x], false = [ ]
curl -X POST http://localhost:8765/api/tasks/toggle \
  -H 'Content-Type: application/json' \
  -d '{"id":"task_20260530_001","checked":true}'

POST /api/tasks/move

Change a task status.

Field Type Required Description
id string recommended Stable task id
task string fallback Task text (exact match)
to string yes open, done, or archived
  • to: "done" → sets completedAt
  • to: "open" → clears completedAt
  • to: "archived" → hides from normal startup/dashboard flow while keeping history
curl -X POST http://localhost:8765/api/tasks/move \
  -H 'Content-Type: application/json' \
  -d '{"id":"task_20260530_001","to":"archived"}'

Daily Plans

POST /api/daily/add-task

Add a checklist line to a daily note. This is for notes/reviews, not the canonical task database. Real tasks should use /api/tasks/add.

Field Type Required Description
date string yes Date in YYYY-MM-DD format
task string yes Task text
curl -X POST http://localhost:8765/api/daily/add-task \
  -H 'Content-Type: application/json' \
  -d '{"date":"2026-03-19","task":"Morning run"}'

POST /api/daily/toggle

Toggle a task in a daily plan file.

Field Type Required Description
date string yes Date in YYYY-MM-DD format
taskText string yes Task text (exact match)
done boolean yes New state

POST /api/daily/remove-task

Remove a task from a daily plan file.

Field Type Required Description
date string yes Date in YYYY-MM-DD format
task string yes Task text (exact match)

POST /api/daily/save

Save the full content of a daily plan file.

Field Type Required Description
date string yes Date in YYYY-MM-DD format
content string yes Full markdown content

Calendar

POST /api/calendar/add

Add a schedule event (a block of occupied time) to tasks/calendar.json.

Tasks and the schedule are separate: a timed task lives only in tasks/tasks.json and is never auto-projected onto the calendar — the dashboard reminder reads timed tasks straight from the task pool. Only call this endpoint for schedule items, or when the user deliberately pulls a task onto the schedule.

Field Type Required Description
title string yes Event title
date string yes Date in YYYY-MM-DD format
startMin number no Start minutes from midnight (default 540)
endMin number no End minutes from midnight (default start + 60)
allDay boolean no All-day event (with optional startDate / endDate)
location string no Location
note string no Note text
fromTask boolean no true only when the user deliberately pulled a task onto the schedule
taskId string no Related task id when fromTask is true

Journal

POST /api/journal/save

Save a journal entry.

Field Type Required Description
date string yes Date in YYYY-MM-DD format
content string yes Journal markdown content

Inbox

POST /api/inbox/add

Add an item to inbox.md.

Field Type Required Description
text string yes Inbox item text

Week/Month Plans

POST /api/plan/save

Save week or month plan items.

Field Type Required Description
type string yes week or month
key string yes Week: YYYY-MM-DD (Monday). Month: YYYY-MM
items array yes Array of {text, done} objects
curl -X POST http://localhost:8765/api/plan/save \
  -H 'Content-Type: application/json' \
  -d '{"type":"week","key":"2026-03-16","items":[{"text":"Ship README","done":false}]}'

POST /api/plan/load

Load week or month plan items.

Field Type Required Description
type string yes week or month
key string yes Same key format as save

Journal Notes

POST /api/journal/save-notes

Persist personal log notes (previously localStorage-only).

Field Type Required Description
date string yes YYYY-MM-DD format
notes array yes Array of {id, name, content} objects

POST /api/journal/load-notes

Load personal log notes for a date.

Field Type Required Description
date string yes YYYY-MM-DD format

Other Endpoints

The server also exposes endpoints for tasks (/api/tasks/reorder, /api/tasks/update-detail — task records carry optional people and scraps link arrays; scraps holds scrap ids such as ref:2026-09-03-x.md), inbox (/api/inbox/remove), references (/api/references/add, /api/references/remove), notes (/api/notes/* — raw, save, create, delete, import, folder management, source mount/unmount), people (/api/people/add, /api/people/update, /api/people/avatar), and projects (/api/project/connect, /api/project/open, /api/project/browse, /api/project/disconnect). See .loci/dashboard/server.js for the authoritative list.


Scraps (碎片)

Everything the user collected — text, links, quotes, images, files — read live from references/ (plus legacy inbox.md lines). Lives in lib/scraps.js + lib/routes/scraps.js.

GET /api/scraps

{ items, total, tags, pending, enrich } — items newest first, each { id, kind, title, text, note, url, site, file, fileUrl, tags, aiTags, summary, caption, created, source, titlePending, legacy }. /api/data carries the same object under scraps.

POST /api/scraps/add

{ "text": "https://… 这个运镜不错", "tags": ["a"], "note": "", "kind": "", "file": { "name": "shot.png", "type": "image/png", "data": "data:image/png;base64,…" }, "source": "paste" }

Any of text / url(s) / file(s) is enough — urls: [...] and files: [...] let several links or attachments share one scrap. text is the scrap's own content (paragraphs are kept); URLs found inside it become link blocks; #tags in the text become tags; note is the 标注 and is never inferred from the text. Returns { ok, item } immediately; title fetch and the AI pass run afterwards and the page is nudged over the live-reload stream.

POST /api/scraps/update

{ id, title?, note?, tags?, aiTags?, acceptTag?, acceptAll?, kind?, text?, url?, by? } → { ok, item }. Editing a legacy inbox.md line turns it into a file (the returned id changes).

POST /api/scraps/remove

{ id } → moves the file (and its binary) to archive/references/.

POST /api/scraps/enrich

{ id } → queue the title fetch + AI pass again. GET /api/scraps/status reports { enabled, model, queue, running, lastError }.

GET /scrap-files/<name>

The image / PDF behind a scrap (references/files/).


Error Handling

All errors return HTTP 200 with an error body (except 404 for unknown routes):

{"error": "Task not found: Buy groceries"}
{"error": "Missing task text"}
{"error": "Invalid JSON: Unexpected token ..."}