Narrow Scribe to a work system-of-record — remove calendar + person/place/list surfaces #77
@@ -8,7 +8,7 @@ Notes and tasks with a Markdown editor, sub-tasks, milestones, issues, and kanba
|
|||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
**Prerequisites:** Docker and Docker Compose. 8 GB+ RAM recommended for LLM inference.
|
**Prerequisites:** Docker and Docker Compose. No GPU or local model needed — Claude is the sole assistant, reached over MCP.
|
||||||
|
|
||||||
Download [`docker-compose.quickstart.yml`](docker-compose.quickstart.yml) from this repo, then:
|
Download [`docker-compose.quickstart.yml`](docker-compose.quickstart.yml) from this repo, then:
|
||||||
|
|
||||||
@@ -19,9 +19,7 @@ export SECRET_KEY=your-random-secret-here
|
|||||||
docker compose -f docker-compose.quickstart.yml up -d
|
docker compose -f docker-compose.quickstart.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Open `http://localhost:5000`. The first user to register becomes admin. Go to **Settings → General** to pull an LLM model — `qwen3:8b` or `llama3.1:8b` are good starting points.
|
Open `http://localhost:5000`. The first user to register becomes admin. To connect Claude, create an API key under **Settings → API Keys** and install the Claude Code plugin — see [API Keys & MCP](docs/api-keys-and-mcp.md).
|
||||||
|
|
||||||
> **GPU:** Ollama runs CPU-only by default. See the comments in `docker-compose.quickstart.yml` to enable NVIDIA GPU passthrough.
|
|
||||||
|
|
||||||
> **Development:** To build from source, see [Development](docs/development.md).
|
> **Development:** To build from source, see [Development](docs/development.md).
|
||||||
|
|
||||||
|
|||||||
+135
-171
@@ -1,242 +1,206 @@
|
|||||||
# API Reference
|
# API Reference
|
||||||
|
|
||||||
All endpoints require login (session cookie or `Authorization: Bearer <api-key>`) unless marked **(public)**.
|
All endpoints are JSON over HTTP under `/api`, and require login unless marked
|
||||||
|
**(public)**. Browser sessions authenticate with a cookie; programmatic clients use an
|
||||||
|
`fmcp_` API key as `Authorization: Bearer <key>` (see
|
||||||
|
[API Keys & MCP](api-keys-and-mcp.md)). Claude reaches the same data through the MCP
|
||||||
|
endpoint at `/mcp`, not these REST routes.
|
||||||
|
|
||||||
## Health
|
## Health
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/health` | Health check **(public)** |
|
| GET | `/api/health` | Health check **(public)** |
|
||||||
|
| GET | `/api/version` | App version **(public)** |
|
||||||
|
|
||||||
## Auth
|
## Auth
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/auth/status` | `{has_users, registration_open, oauth_enabled, local_auth_enabled}` **(public)** |
|
| GET | `/api/auth/status` | `{has_users, registration_open, oauth_enabled, local_auth_enabled}` **(public)** |
|
||||||
| POST | `/api/auth/register` | Register new user (first user becomes admin; 403 if registration closed or local auth disabled) |
|
| POST | `/api/auth/register` | Register (first user becomes admin) |
|
||||||
| POST | `/api/auth/login` | Login with username/password (403 if local auth disabled) |
|
| POST | `/api/auth/login` | Login with username/password |
|
||||||
| POST | `/api/auth/logout` | Clear session |
|
| POST | `/api/auth/logout` | Clear session |
|
||||||
| GET | `/api/auth/me` | Current user info (includes `has_password: bool`) |
|
| GET | `/api/auth/me` | Current user info |
|
||||||
| PUT | `/api/auth/password` | Change password `{current_password, new_password}` |
|
| PUT | `/api/auth/password` | Change password |
|
||||||
| PUT | `/api/auth/email` | Change email `{email, password?}` (password required only for local-auth users) |
|
| PUT | `/api/auth/email` | Change email |
|
||||||
| POST | `/api/auth/invalidate-sessions` | Bump `session_version` — evicts all other sessions, keeps current alive |
|
| POST | `/api/auth/invalidate-sessions` | Evict all other sessions |
|
||||||
| POST | `/api/auth/forgot-password` | Send password reset email `{email}` |
|
| POST | `/api/auth/forgot-password` | Send password-reset email |
|
||||||
| POST | `/api/auth/reset-password` | Reset password with token `{token, new_password}` |
|
| POST | `/api/auth/reset-password` | Reset password with token |
|
||||||
| GET | `/api/auth/oauth/login` | Initiate OIDC PKCE flow → redirect to provider |
|
| GET | `/api/auth/oauth/login` | Begin OIDC (PKCE) flow |
|
||||||
| GET | `/api/auth/oauth/callback` | OIDC callback — exchange code, find/create user, redirect to `/` |
|
| GET | `/api/auth/oauth/callback` | OIDC callback |
|
||||||
| GET | `/api/auth/invitation/:token` | Validate invitation token **(public)** |
|
| GET | `/api/auth/invitation/:token` | Validate an invite **(public)** |
|
||||||
| POST | `/api/auth/register-with-invite` | Register with token `{token, username, password}` **(public)** |
|
| POST | `/api/auth/register-with-invite` | Register with a token **(public)** |
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/notes` | List notes. Params: `q`, `tag`, `sort`, `order`, `limit`, `offset`, `project_id`, `milestone_id`, `parent_id`, `type` (`note`/`task`/`all`) |
|
| GET | `/api/notes` | List notes (params: `q`, `tag`, `sort`, `order`, `limit`, `offset`, `project_id`, `milestone_id`, `parent_id`) |
|
||||||
| POST | `/api/notes` | Create note `{title, body, tags?, status?, priority?, due_date?, project_id?, milestone_id?, parent_id?}` |
|
| POST | `/api/notes` | Create note |
|
||||||
| GET | `/api/notes/tags` | All tags (param: `q` for filter) |
|
| GET | `/api/notes/tags` | All tags (param: `q`) |
|
||||||
| POST | `/api/notes/suggest-tags` | LLM tag suggestions `{title, body, current_tags?}` → `{suggested_tags}` |
|
| POST | `/api/notes/:id/append-tag` | Add a tag `{tag}` |
|
||||||
| POST | `/api/notes/link-suggestions` | Detect note titles as plain text in body `{body, project_id, exclude_note_id}` → `[{note_id, title, count}]` |
|
| POST | `/api/notes/link-suggestions` | Detect note titles as plain text → wikilink candidates |
|
||||||
| GET | `/api/notes/by-title` | Resolve note by exact title (param: `title`) |
|
| GET | `/api/notes/by-title` | Resolve note by exact title |
|
||||||
| POST | `/api/notes/resolve-title` | Get-or-create note by title `{title}` (wikilink click) |
|
| POST | `/api/notes/resolve-title` | Get-or-create by title (wikilink click) |
|
||||||
| GET | `/api/notes/:id` | Get single note |
|
| GET / PUT / PATCH / DELETE | `/api/notes/:id` | Read / replace / patch / delete |
|
||||||
| PUT | `/api/notes/:id` | Full update |
|
| POST | `/api/notes/:id/convert-to-task` | Note → task |
|
||||||
| PATCH | `/api/notes/:id` | Partial update (same fields as PUT) |
|
| POST | `/api/notes/:id/convert-to-note` | Task → note |
|
||||||
| DELETE | `/api/notes/:id` | Delete note |
|
|
||||||
| POST | `/api/notes/:id/convert-to-task` | Set `status='todo'`, `priority='none'` |
|
|
||||||
| POST | `/api/notes/:id/convert-to-note` | Clear `status`, `priority`, `due_date` |
|
|
||||||
| POST | `/api/notes/:id/append-tag` | Add tag `{tag}` → updated note |
|
|
||||||
| GET | `/api/notes/:id/backlinks` | Notes/tasks with `[[Title]]` references to this note |
|
| GET | `/api/notes/:id/backlinks` | Notes/tasks with `[[Title]]` references to this note |
|
||||||
| GET | `/api/notes/:id/versions` | List note version history |
|
| GET | `/api/notes/:id/versions` | Version history |
|
||||||
| GET | `/api/notes/:id/versions/:vid` | Get a specific version |
|
| GET | `/api/notes/:id/versions/:vid` | A specific version |
|
||||||
| GET | `/api/notes/:id/draft` | Get current AI draft |
|
| POST | `/api/notes/:id/versions/:vid/pin` | Pin a version |
|
||||||
| PUT | `/api/notes/:id/draft` | Save AI draft |
|
| GET / PUT / DELETE | `/api/notes/:id/draft` | Unsaved-edit draft (restore across page loads) |
|
||||||
| DELETE | `/api/notes/:id/draft` | Delete AI draft |
|
| GET | `/api/notes/graph` | Knowledge-graph nodes/edges |
|
||||||
| POST | `/api/notes/assist` | Launch AI assist generation → 202 `{body, target_section?, instruction, whole_doc?}` |
|
|
||||||
| GET | `/api/notes/assist/stream` | SSE stream for assist (Last-Event-ID reconnect; events: `chunk`, `done`, `error`) |
|
|
||||||
|
|
||||||
## Tasks
|
## Tasks
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/tasks` | List tasks. Params: `q`, `tag`, `status`, `priority`, `due_before`, `due_after`, `sort`, `order`, `limit`, `offset` |
|
| GET | `/api/tasks` | List tasks (params: `q`, `tag`, `status`, `priority`, `overdue`, `sort`, `order`, `limit`, `offset`) |
|
||||||
| POST | `/api/tasks` | Create task (accepts `project` name string → resolved to `project_id`) |
|
| POST | `/api/tasks` | Create task (accepts a `project` name string → resolved to `project_id`) |
|
||||||
| GET | `/api/tasks/:id` | Get task (includes `parent_title`) |
|
| POST | `/api/tasks/planning` | Start a plan (milestone + steps) |
|
||||||
| PUT | `/api/tasks/:id` | Full update |
|
| GET / PUT / PATCH / DELETE | `/api/tasks/:id` | Read / update / delete |
|
||||||
| PATCH | `/api/tasks/:id/status` | Quick status update `{status}` |
|
| PATCH | `/api/tasks/:id/status` | Quick status update `{status}` |
|
||||||
| DELETE | `/api/tasks/:id` | Delete task |
|
| GET | `/api/tasks/:id/recurrence-preview` | Preview next recurrence occurrences |
|
||||||
| GET | `/api/tasks/:id/logs` | List work logs |
|
|
||||||
| POST | `/api/tasks/:id/logs` | Create log `{content, duration_minutes?}` |
|
|
||||||
| PATCH | `/api/tasks/:id/logs/:log_id` | Update log |
|
|
||||||
| DELETE | `/api/tasks/:id/logs/:log_id` | Delete log |
|
|
||||||
|
|
||||||
## Projects & Milestones
|
**Task work logs**
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/projects` | List projects (owned + shared) |
|
| GET / POST | `/api/tasks/:id/logs` | List / append a work log `{content, duration_minutes?}` |
|
||||||
| POST | `/api/projects` | Create project |
|
| PATCH / DELETE | `/api/tasks/:id/logs/:log_id` | Update / delete a log |
|
||||||
| GET | `/api/projects/:id` | Get project with `milestone_summary` |
|
|
||||||
| PATCH | `/api/projects/:id` | Update project |
|
## Projects, Milestones, Systems, Issues
|
||||||
| DELETE | `/api/projects/:id` | Delete project |
|
|
||||||
|
| Method | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| GET / POST | `/api/projects` | List (owned + shared) / create |
|
||||||
|
| GET / PATCH / DELETE | `/api/projects/:id` | Read (with `milestone_summary`) / update / delete |
|
||||||
| GET | `/api/projects/:id/notes` | Notes + tasks in this project |
|
| GET | `/api/projects/:id/notes` | Notes + tasks in this project |
|
||||||
| GET | `/api/projects/:id/milestones` | List milestones |
|
| GET / POST | `/api/projects/:id/milestones` | List / create milestones |
|
||||||
| POST | `/api/projects/:id/milestones` | Create milestone |
|
| GET / PATCH / DELETE | `/api/projects/:id/milestones/:mid` | Read / update / delete |
|
||||||
| PATCH | `/api/projects/:id/milestones/:mid` | Update milestone |
|
| GET | `/api/projects/:id/milestones/:mid/tasks` | Tasks in a milestone |
|
||||||
| DELETE | `/api/projects/:id/milestones/:mid` | Delete milestone |
|
| GET / POST | `/api/projects/:id/systems` | List / create systems |
|
||||||
|
| GET / PATCH / DELETE | `/api/projects/:id/systems/:sid` | Read / update / delete |
|
||||||
|
| GET | `/api/projects/:id/systems/:sid/records` | Records linked to a system |
|
||||||
|
| GET | `/api/projects/:id/issues` | Project issues |
|
||||||
|
|
||||||
|
## Knowledge browse
|
||||||
|
|
||||||
|
| Method | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| GET | `/api/knowledge` | Unified note/task/plan/process feed (params: `type`, `tags`, `sort`, `q`, `limit`, `offset`) |
|
||||||
|
| GET | `/api/knowledge/ids` | ID-only page (two-tier pagination) |
|
||||||
|
| GET | `/api/knowledge/batch` | Fetch items by id |
|
||||||
|
| GET | `/api/knowledge/tags` | Tags in scope |
|
||||||
|
| GET | `/api/knowledge/counts` | Per-type counts |
|
||||||
|
|
||||||
|
## Search
|
||||||
|
|
||||||
|
| Method | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| GET | `/api/search` | Semantic + keyword search over notes/tasks (params: `q`, `type`, `limit`) |
|
||||||
|
|
||||||
|
## Rulebooks and rules
|
||||||
|
|
||||||
|
| Method | Path | Description |
|
||||||
|
|--------|------|-------------|
|
||||||
|
| GET / POST | `/api/rulebooks` | List / create rulebooks |
|
||||||
|
| GET / PATCH / DELETE | `/api/rulebooks/:id` | Read / update / delete |
|
||||||
|
| GET / POST | `/api/rulebooks/:id/topics` | List / create topics |
|
||||||
|
| PATCH / DELETE | `/api/rulebook-topics/:tid` | Edit / delete a topic |
|
||||||
|
| GET | `/api/rules` | List rules |
|
||||||
|
| POST | `/api/rulebook-topics/:tid/rules` | Add a rule to a topic |
|
||||||
|
| GET / PATCH / DELETE | `/api/rules/:id` | Read / update / delete a rule |
|
||||||
|
| POST | `/api/projects/:id/rulebook-subscriptions` | Subscribe a project to a rulebook |
|
||||||
|
| GET | `/api/projects/:id/rules` | Applicable rules for a project |
|
||||||
|
| POST | `/api/projects/:id/rules` | Create a project-scoped rule |
|
||||||
|
| POST / DELETE | `/api/projects/:id/suppressions/rules/:rid` | Suppress / unsuppress a rule |
|
||||||
|
| POST / DELETE | `/api/projects/:id/suppressions/topics/:tid` | Suppress / unsuppress a topic |
|
||||||
|
|
||||||
## Sharing
|
## Sharing
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/projects/:id/shares` | List project shares |
|
| GET / POST | `/api/projects/:id/shares` | List / add project shares `{user_id?, group_id?, permission}` |
|
||||||
| POST | `/api/projects/:id/shares` | Create project share `{user_id?, group_id?, permission}` |
|
| PATCH / DELETE | `/api/projects/:id/shares/:sid` | Update permission / remove |
|
||||||
| PATCH | `/api/projects/:id/shares/:sid` | Update permission |
|
| GET / POST | `/api/notes/:id/shares` | List / add note shares |
|
||||||
| DELETE | `/api/projects/:id/shares/:sid` | Remove share |
|
| PATCH / DELETE | `/api/notes/:id/shares/:sid` | Update permission / remove |
|
||||||
| GET | `/api/notes/:id/shares` | List note shares |
|
|
||||||
| POST | `/api/notes/:id/shares` | Create note share |
|
|
||||||
| PATCH | `/api/notes/:id/shares/:sid` | Update permission |
|
|
||||||
| DELETE | `/api/notes/:id/shares/:sid` | Remove share |
|
|
||||||
| GET | `/api/shared-with-me` | All resources shared with the current user |
|
| GET | `/api/shared-with-me` | All resources shared with the current user |
|
||||||
|
|
||||||
## Groups
|
## Groups
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/groups` | List all groups (admin only) |
|
| GET / POST | `/api/groups` | List / create groups |
|
||||||
| POST | `/api/groups` | Create group `{name, description?}` |
|
| GET / PATCH / DELETE | `/api/groups/:id` | Read / update / delete |
|
||||||
| PATCH | `/api/groups/:id` | Update group |
|
| GET / POST | `/api/groups/:id/members` | List / add members `{user_id, role}` |
|
||||||
| DELETE | `/api/groups/:id` | Delete group |
|
| PATCH / DELETE | `/api/groups/:id/members/:uid` | Update role / remove |
|
||||||
| GET | `/api/groups/:id/members` | List members |
|
|
||||||
| POST | `/api/groups/:id/members` | Add member `{user_id, role}` |
|
|
||||||
| PATCH | `/api/groups/:id/members/:uid` | Update member role |
|
|
||||||
| DELETE | `/api/groups/:id/members/:uid` | Remove member |
|
|
||||||
|
|
||||||
## Chat
|
|
||||||
|
|
||||||
| Method | Path | Description |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| GET | `/api/chat/conversations` | List conversations (params: `limit`, `offset`) |
|
|
||||||
| POST | `/api/chat/conversations` | Create conversation `{title?, model?}` |
|
|
||||||
| POST | `/api/chat/conversations/bulk-delete` | Delete multiple conversations `{ids: number[]}` |
|
|
||||||
| GET | `/api/chat/conversations/:id` | Get conversation with all messages |
|
|
||||||
| PATCH | `/api/chat/conversations/:id` | Update title or model |
|
|
||||||
| DELETE | `/api/chat/conversations/:id` | Delete conversation (cascades to messages) |
|
|
||||||
| POST | `/api/chat/conversations/:id/messages` | Start generation → 202. Body: `{content, context_note_id?, include_note_ids?, rag_project_id?, workspace_project_id?, think?}` |
|
|
||||||
| GET | `/api/chat/conversations/:id/generation/stream` | SSE stream (Last-Event-ID reconnect; events: `context`, `chunk`, `tool_call`, `status`, `done`, `error`) |
|
|
||||||
| POST | `/api/chat/conversations/:id/generation/cancel` | Cancel active generation |
|
|
||||||
| POST | `/api/chat/messages/:id/save-as-note` | Save assistant message as note |
|
|
||||||
| POST | `/api/chat/conversations/:id/summarize` | Summarize conversation → note |
|
|
||||||
| GET | `/api/chat/status` | Ollama availability + model state `{ollama, model, default_model}` |
|
|
||||||
| GET | `/api/chat/models` | List installed Ollama models (includes `loaded: bool`, `modified_at`) |
|
|
||||||
| POST | `/api/chat/models/pull` | Pull model (SSE NDJSON progress) `{model}` |
|
|
||||||
| POST | `/api/chat/models/delete` | Delete model `{model}` |
|
|
||||||
| GET | `/api/chat/ps` | Currently loaded (hot) models |
|
|
||||||
| POST | `/api/chat/warm` | Pre-load model into VRAM `{model}` → 202 |
|
|
||||||
|
|
||||||
## Quick Capture
|
|
||||||
|
|
||||||
| Method | Path | Description |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| POST | `/api/quick-capture` | Classify + create item from natural language `{text}` → `{success, type, message, data}` |
|
|
||||||
|
|
||||||
## Search
|
|
||||||
|
|
||||||
| Method | Path | Description |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| GET | `/api/search` | Semantic + keyword search across notes and tasks. Params: `q`, `type` (`note`/`task`/`all`), `limit` |
|
|
||||||
|
|
||||||
## Journal
|
|
||||||
|
|
||||||
| Method | Path | Description |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| GET | `/api/journal/config` | Get journal configuration (locations, temp_unit, prep schedule) |
|
|
||||||
| PUT | `/api/journal/config` | Save journal configuration; live-reschedules the prep job |
|
|
||||||
| GET | `/api/journal/today` | Get/create today's journal conversation + messages |
|
|
||||||
| GET | `/api/journal/day/:iso` | Get a specific day's journal conversation (read-only) |
|
|
||||||
| GET | `/api/journal/days` | List dates with journal content, newest first |
|
|
||||||
| POST | `/api/journal/trigger-prep` | Force-regenerate today's prep (or `{date}` for a specific day) |
|
|
||||||
| GET | `/api/journal/weather` | Cached weather rows; auto-refreshes stale rows in the background |
|
|
||||||
| GET | `/api/journal/weather/current` | Live current conditions for the primary configured location |
|
|
||||||
| POST | `/api/journal/weather/refresh` | Manual refresh of all configured locations |
|
|
||||||
| POST | `/api/journal/weather/geocode` | Geocode place name `{query}` → `{lat, lon, label}` |
|
|
||||||
| POST | `/api/journal/moments/:id/update` | Update a recorded moment |
|
|
||||||
| DELETE | `/api/journal/moments/:id` | Delete a moment |
|
|
||||||
|
|
||||||
## Settings
|
|
||||||
|
|
||||||
| Method | Path | Description |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| GET | `/api/settings` | All settings as `{key: value}` |
|
|
||||||
| PUT | `/api/settings` | Update settings `{key: value, ...}` |
|
|
||||||
| GET | `/api/settings/models` | Installed models + defaults |
|
|
||||||
| GET | `/api/settings/search` | Proxy SearXNG search (params: `q`) |
|
|
||||||
|
|
||||||
## API Keys
|
|
||||||
|
|
||||||
| Method | Path | Description |
|
|
||||||
|--------|------|-------------|
|
|
||||||
| GET | `/api/api-keys` | List user's API keys |
|
|
||||||
| POST | `/api/api-keys` | Create key `{name, scope}` → `{key, ...}` (key shown once) |
|
|
||||||
| DELETE | `/api/api-keys/:id` | Revoke key |
|
|
||||||
|
|
||||||
## Scribe MCP
|
|
||||||
|
|
||||||
The MCP tool surface is served at `POST /mcp` (streamable HTTP, Bearer auth) by
|
|
||||||
the in-app server in `src/scribe/mcp/`. It is not a REST surface — see
|
|
||||||
[API Keys and Scribe MCP](api-keys-and-mcp.md) for client configuration.
|
|
||||||
|
|
||||||
## Notifications
|
## Notifications
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/notifications` | List notifications |
|
| GET | `/api/notifications` | List in-app notifications |
|
||||||
| GET | `/api/notifications/count` | Unread count |
|
| GET | `/api/notifications/count` | Unread count |
|
||||||
| POST | `/api/notifications/:id/read` | Mark read |
|
| POST | `/api/notifications/:id/read` | Mark one read |
|
||||||
| POST | `/api/notifications/read-all` | Mark all read |
|
| POST | `/api/notifications/read-all` | Mark all read |
|
||||||
|
|
||||||
## Push
|
## Profile and Settings
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/push/vapid-public-key` | VAPID public key for subscription |
|
| GET / PUT | `/api/profile` | Read / update the per-user profile |
|
||||||
| POST | `/api/push/subscribe` | Register push subscription |
|
| GET / PUT | `/api/settings` | Read / update key-value settings |
|
||||||
| DELETE | `/api/push/subscribe` | Unregister push subscription |
|
| GET | `/api/settings/search` | SearXNG configuration status |
|
||||||
|
|
||||||
## Images
|
## API keys
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/images/:id` | Serve cached image **(no auth required — IDs are opaque SHA-256)** |
|
| GET / POST | `/api/api-keys` | List / create `fmcp_` keys (key shown once) |
|
||||||
|
| DELETE | `/api/api-keys/:id` | Revoke a key |
|
||||||
|
|
||||||
## Users
|
## Plugin (Claude Code)
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/users/search` | Search users by username/email prefix (param: `q`, min 2 chars, excludes self) |
|
| GET | `/api/plugin/context` | SessionStart context payload (rules + active-project) |
|
||||||
|
| GET | `/api/plugin/retrieve` | Title-first knowledge-injection candidates |
|
||||||
|
| GET | `/api/plugin/processes` | Stored Processes for skill-stub sync |
|
||||||
|
| GET / PUT | `/api/plugin/marketplace-url` | Read / set the plugin marketplace URL |
|
||||||
|
|
||||||
## Export
|
## Dashboard, Export, Trash, Users
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/export` | Export data. Params: `format=markdown` (ZIP with `.md` + YAML frontmatter) or `format=json` |
|
| GET | `/api/dashboard` | Home dashboard payload |
|
||||||
|
| GET | `/api/export` | Personal export (`format=markdown` ZIP or `format=json`) |
|
||||||
|
| GET | `/api/trash` | List trashed items, grouped by delete batch |
|
||||||
|
| POST | `/api/trash/:batch/restore` | Restore a batch |
|
||||||
|
| DELETE | `/api/trash/:batch` | Purge a batch (irreversible) |
|
||||||
|
| GET | `/api/users/search` | Search users by prefix (for sharing) |
|
||||||
|
|
||||||
## Admin
|
## Admin
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Method | Path | Description |
|
||||||
|--------|------|-------------|
|
|--------|------|-------------|
|
||||||
| GET | `/api/admin/backup` | Export backup (`?scope=user` for own data; full requires admin) |
|
| GET | `/api/admin/backup` | Export backup (format v4; `?scope=user` for own data) |
|
||||||
| POST | `/api/admin/restore` | Restore from JSON backup |
|
| POST | `/api/admin/restore` | Restore from a backup |
|
||||||
| GET | `/api/admin/users` | List all users |
|
| GET / DELETE | `/api/admin/users` · `/api/admin/users/:id` | List / delete users |
|
||||||
| DELETE | `/api/admin/users/:id` | Delete user (cannot delete self) |
|
| GET / PUT | `/api/admin/registration` | Get / toggle registration |
|
||||||
| GET | `/api/admin/registration` | Get registration open/closed state |
|
| GET / PUT | `/api/admin/smtp` · POST `/api/admin/smtp/test` | SMTP config + test email |
|
||||||
| PUT | `/api/admin/registration` | Toggle registration `{open: bool}` |
|
| GET | `/api/admin/logs` · `/api/admin/logs/stats` | Log entries + category counts |
|
||||||
| POST | `/api/admin/invitations` | Create invitation `{email}` → sends email |
|
| GET / PUT | `/api/admin/base-url` | Get / set the public base URL |
|
||||||
| GET | `/api/admin/invitations` | List pending invitations |
|
| GET / PUT | `/api/admin/db-maintenance` (+ `/health`, POST `/run`) | VACUUM schedule, health, manual run |
|
||||||
| DELETE | `/api/admin/invitations/:id` | Revoke invitation |
|
| POST / GET / DELETE | `/api/admin/invitations` (+ `/:id`) | Create / list / revoke invite links |
|
||||||
| GET | `/api/admin/logs` | Log entries. Params: `category`, `user_id`, `search`, `date_from`, `date_to`, `limit`, `offset` |
|
|
||||||
| GET | `/api/admin/logs/stats` | Log category counts |
|
## Scribe MCP
|
||||||
| GET | `/api/admin/base-url` | Get base URL setting |
|
|
||||||
| PUT | `/api/admin/base-url` | Set base URL `{base_url}` |
|
Claude clients connect to the built-in MCP server at `POST /mcp` (streamable HTTP,
|
||||||
| GET | `/api/admin/smtp` | Get SMTP config (password masked) |
|
Bearer auth with an `fmcp_` key), served by `src/scribe/mcp/`. It is not a REST
|
||||||
| PUT | `/api/admin/smtp` | Save SMTP config |
|
surface — it exposes the same data as typed tools (`create_note`, `create_task`,
|
||||||
| POST | `/api/admin/smtp/test` | Send test email `{recipient}` |
|
`start_planning`, `search`, `enter_project`, `list_always_on_rules`, …) with
|
||||||
|
server-level usage guidance delivered in the MCP `instructions` block. See
|
||||||
|
[API Keys & MCP](api-keys-and-mcp.md).
|
||||||
|
|||||||
+118
-105
@@ -1,155 +1,168 @@
|
|||||||
# Features
|
# Features
|
||||||
|
|
||||||
|
Scribe is a self-hosted work system-of-record for software projects, built to be
|
||||||
|
driven by Claude Code. There is **no in-app LLM** — Claude is the sole assistant,
|
||||||
|
reaching Scribe through a built-in MCP endpoint and a bundled Claude Code plugin. The
|
||||||
|
web UI is a clean surface for humans to read and edit the same data.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
Write in Markdown with a live-preview editor (Tiptap/ProseMirror). Headings, bold, italic, lists, code blocks, and task checklists render inline. A slash-command menu (`/`) inserts common blocks.
|
Write in Markdown with a live-preview editor (Tiptap/ProseMirror). Headings, bold,
|
||||||
|
italic, lists, code blocks, and task checklists render inline. A slash-command menu
|
||||||
|
(`/`) inserts common blocks.
|
||||||
|
|
||||||
**Wikilinks** — Link notes with `[[Title]]` or `[[Title|Display Text]]` syntax. Clicking a wikilink navigates to (or auto-creates) the referenced note. The editor suggests existing note titles as candidate links while typing `[[`. Backlinks appear in the note viewer sidebar.
|
- **Wikilinks** — Link notes with `[[Title]]` or `[[Title|Display Text]]`. Clicking
|
||||||
|
navigates to (or auto-creates) the referenced note; the editor suggests existing
|
||||||
|
titles while you type `[[`. Backlinks appear in the note viewer sidebar.
|
||||||
|
- **Tags** — First-class `ARRAY[text]` column with autocomplete. Hierarchical tags
|
||||||
|
(`area/backend`) supported — filtering by `area` matches all `area/*` children.
|
||||||
|
- **Version history** — Every body edit snapshots a version (up to 20 per note).
|
||||||
|
Browse, diff, and restore from the editor's History panel.
|
||||||
|
- **Draft recovery** — In-progress edits persist across page loads and are restored
|
||||||
|
when you reopen a note.
|
||||||
|
- **Convert freely** — Turn a note into a task (sets `status=todo`) or back again.
|
||||||
|
|
||||||
**Tags** — First-class `ARRAY[text]` column. Tag autocomplete in the editor sidebar suggests existing tags. Hierarchical tags (`project/webapp`) supported — filtering by `project` matches all `project/*` children. Tags are browsable via the knowledge graph.
|
## Tasks and Issues
|
||||||
|
|
||||||
**Version history** — Every body edit snapshots a version (up to 20 per note). Browse and restore from the editor's History panel. Diff view shows changes against the current body.
|
Tasks carry status (`todo` → `in_progress` → `done`/`cancelled`), priority
|
||||||
|
(`none`/`low`/`medium`/`high`), due date, milestone assignment, and a parent task
|
||||||
|
(sub-tasks). Notes and tasks share one model — a task is a note with a status.
|
||||||
|
|
||||||
**AI writing assist** — Select a passage or work on the full document. Give an instruction ("make this more concise", "add examples"). The assistant streams a proposal; a diff view shows changes to accept or reject. Drafts persist across page loads.
|
- **Work logs** — Append timestamped progress entries (with optional duration) to a
|
||||||
|
task without rewriting its body; shown chronologically in the task view.
|
||||||
**Link suggestions** — The editor detects note titles appearing as plain text in the body and suggests converting them to wikilinks.
|
- **Issues** — A task whose `kind` is corrective: a problem you fixed or are fixing,
|
||||||
|
with symptom → root cause → fix in the body. An issue can link the task it arose
|
||||||
## Tasks
|
from and the System(s) it touches.
|
||||||
|
- **Recurring tasks** — An interval or calendar recurrence rule spawns the next
|
||||||
Tasks carry status (`todo` → `in_progress` → `done`), priority (`none`/`low`/`medium`/`high`), due date, milestone assignment, and a parent task (sub-tasks).
|
occurrence when a task is completed (a background job drains due spawns).
|
||||||
|
- **Sub-tasks** — Any task can have children via `parent_id`; the viewer shows them
|
||||||
**Task work logs** — Append progress log entries to a task with optional duration. Time tracking is visible in the task editor sidebar.
|
inline.
|
||||||
|
|
||||||
**Sub-tasks** — Any task can have child tasks via `parent_id`. The task viewer shows sub-tasks inline.
|
|
||||||
|
|
||||||
**Convert freely** — Convert a note to a task (sets `status=todo`) or a task back to a note from the viewer toolbar.
|
|
||||||
|
|
||||||
## Projects and Milestones
|
## Projects and Milestones
|
||||||
|
|
||||||
**Projects** — Group related notes and tasks. Each project has a title, description, goal, status (`active`/`completed`/`archived`), and a colour.
|
- **Projects** — Group related notes and tasks. Title, description, goal, status
|
||||||
|
(`active`/`paused`/`completed`/`archived`), and a colour.
|
||||||
|
- **Milestones** — Ordered stages within a project. A milestone is also the home of a
|
||||||
|
**plan** — its body holds the design (Goal/Approach/Verification) and its child
|
||||||
|
tasks are the steps. Completion percentage is shown on the project page.
|
||||||
|
- **Kanban view** — `/projects/:id` groups tasks by milestone in a column layout with
|
||||||
|
status-advance buttons on the cards.
|
||||||
|
|
||||||
**Milestones** — Ordered stages within a project. Tasks are assigned to milestones. Milestone completion percentage shown on the project page.
|
## Systems
|
||||||
|
|
||||||
**Kanban view** — `/projects/:id` groups tasks by milestone in a kanban-style column layout with status-advance buttons directly on cards (→ advance, ✓ complete).
|
A **System** is a per-project, reusable, self-describing subsystem or area (e.g.
|
||||||
|
"auth", "billing"). Associate any note, task, or issue with a System so research,
|
||||||
|
build-work, and fixes for the same area line up and recurring problem-spots surface.
|
||||||
|
|
||||||
**Project Workspace** — `/workspace/:projectId` opens a three-panel environment (tasks / chat / notes) locked to a project. The AI assistant creates and updates content directly in the workspace; new notes auto-load in the editor and the task list refreshes automatically after tool calls.
|
## Rules and Rulebooks
|
||||||
|
|
||||||
|
Scribe stores the operator's engineering and workflow **rules** so Claude follows them
|
||||||
|
across sessions.
|
||||||
|
|
||||||
|
- **Rulebooks → topics → rules** — Rules are grouped by topic inside a rulebook.
|
||||||
|
- **Always-on rules** — A rulebook can be flagged always-on; its rules load at the
|
||||||
|
start of every session through the plugin's push channel.
|
||||||
|
- **Per-project scope** — A project subscribes to rulebooks, and can add
|
||||||
|
project-scoped rules or suppress individual inherited rules/topics.
|
||||||
|
|
||||||
|
## Stored Processes
|
||||||
|
|
||||||
|
Reusable saved prompts (a note with `note_type=process`) — e.g. a drift-audit or a
|
||||||
|
DRY pass. The bundled plugin syncs each Process into a local Claude Code skill stub
|
||||||
|
(`/scribe:sync`) that auto-surfaces by relevance and fetches the live procedure on
|
||||||
|
demand.
|
||||||
|
|
||||||
|
## Search and Knowledge Injection
|
||||||
|
|
||||||
|
- **Semantic search** — pgvector-backed similarity search over notes and tasks
|
||||||
|
(in-process `fastembed` embeddings; no external model).
|
||||||
|
- **Proactive knowledge-injection** — the plugin's `UserPromptSubmit` hook surfaces a
|
||||||
|
short, high-confidence menu of maybe-relevant note *titles* into Claude's context
|
||||||
|
each turn; Claude pulls a full body only when it judges it relevant. Gated so it
|
||||||
|
stays quiet on most turns and never repeats within a session.
|
||||||
|
|
||||||
## Knowledge Graph
|
## Knowledge Graph
|
||||||
|
|
||||||
`/graph` renders all notes, tasks, and tags as a D3 force-directed graph. Tag nodes cluster notes that share tags; invisible project hub nodes attract project members. Physics controls: repulsion, link distance, link strength, hub pull, gravity. Click any node to open a slide-in peek panel. Click a tag node to filter the notes list.
|
`/graph` renders notes, tasks, and tags as a D3 force-directed graph. Tag nodes
|
||||||
|
cluster notes that share tags; invisible project hubs attract project members. Physics
|
||||||
|
controls (repulsion, link distance/strength, hub pull, gravity); click a node to peek,
|
||||||
|
click a tag to filter.
|
||||||
|
|
||||||
## AI Chat
|
## Claude via MCP and the plugin
|
||||||
|
|
||||||
Full conversation history with SSE streaming. Features:
|
The whole store is reachable by Claude through a built-in **MCP endpoint at `/mcp`**
|
||||||
- **RAG** — Semantically relevant notes (≥ 0.60 cosine similarity) auto-injected as context. Notes 0.45–0.60 shown in sidebar as "Suggested."
|
(Bearer-auth with an API key). The **Scribe Claude Code plugin** (shipped in this
|
||||||
- **Attach notes** — Paperclip icon to include specific notes in context.
|
repo) wires it up:
|
||||||
- **RAG scope chip** — Pill above the input bar shows the current note scope. Click to switch: "Orphan notes only" (default — project notes stay out of general chat), any active project, or "All notes." Scope is persisted per conversation. The AI can also call `search_projects` and `set_rag_scope` mid-conversation to switch scope automatically; the chip pulses when this happens.
|
|
||||||
- **Tool calls** — The assistant can create/update notes, tasks, projects, milestones, search the web, check weather, read RSS, query calendar events, and more. Tool calls display inline with confirm/deny for creates.
|
|
||||||
- **Thinking mode** — Toggle extended reasoning for complex questions.
|
|
||||||
- **Abort** — Stop button cancels in-flight generation.
|
|
||||||
- **Message queue** — Messages sent while generation is in progress are queued and drained sequentially.
|
|
||||||
- **Save to note** — Save any assistant reply directly as a note.
|
|
||||||
- **Bulk delete** — Select and delete multiple conversations.
|
|
||||||
- **Retention** — Conversations auto-pruned after configurable days (default 90).
|
|
||||||
|
|
||||||
## Daily Journal
|
- a `SessionStart` hook that injects the operator's always-on rules + active-project
|
||||||
|
context so Scribe surfaces without being asked (fail-open if Scribe is unreachable);
|
||||||
|
- universal process-skills — writing-plans, systematic-debugging, verification,
|
||||||
|
brainstorming — that route their output into Scribe;
|
||||||
|
- your saved Processes auto-surfaced as skills.
|
||||||
|
|
||||||
`/journal` is a conversational daily surface — each day is a chat-style conversation seeded with an LLM-generated daily prep as the first assistant message. The prep pulls together today's tasks, calendar events, weather, recent moments, and active projects in flowing prose, then invites the user to continue the conversation throughout the day.
|
See [API Keys & MCP](api-keys-and-mcp.md).
|
||||||
|
|
||||||
**Schedule** — Daily prep generates at a configurable time (default 5:00am). The "day rollover hour" controls when the journal switches to a new day (default 4am — late-night entries 1–3am still count as the previous day). Scheduler catches up missed runs on startup.
|
|
||||||
|
|
||||||
**Right rail** — The journal view shows current weather conditions and upcoming events for the next two weeks alongside the conversation. Both surfaces draw from the same data the prep references.
|
|
||||||
|
|
||||||
**Configuration** — Settings → Profile:
|
|
||||||
- *Locations* section: home and work place-name inputs (geocoded on blur via Nominatim) and a temperature unit toggle (C/F)
|
|
||||||
- *Journal* section: prep auto-generate toggle, prep generation time, day rollover hour
|
|
||||||
- *About You* / *Interests* / *Work Schedule* / *Response Preferences* feed personalization into the prep's system prompt
|
|
||||||
|
|
||||||
**Weather** — Location-based forecast via Open-Meteo. Up to two named locations (home, work). Cached rows auto-refresh in the background when the journal page loads.
|
|
||||||
|
|
||||||
**What the assistant has learned** — The assistant maintains a per-user observation log + consolidated summary, generated from journal and chat conversations. The summary is included in the journal's system prompt so the daily prep can reference what it knows about you over time.
|
|
||||||
|
|
||||||
## Web Research
|
|
||||||
|
|
||||||
The assistant can search the web (SearXNG) and fetch pages, synthesising findings into a structured multi-note research output: an index note with an executive summary and links to focused section notes. Each section covers a distinct aspect of the topic with cited sources. Falls back to a single note when outline generation fails. A lightweight `search_web` tool answers quick questions inline without saving. Requires `SEARXNG_URL` to be configured.
|
|
||||||
|
|
||||||
## Calendar
|
|
||||||
|
|
||||||
`/calendar` shows a full FullCalendar view (month, week, day). Click an empty slot to create an event; click an existing event to edit or delete it via a slide-over panel.
|
|
||||||
|
|
||||||
**Internal events store** — Events are stored in the app database (`events` table), making them available without any external calendar. Fields: title, description, start/end datetime, all-day toggle, location, colour.
|
|
||||||
|
|
||||||
**AI tools** — `create_event`, `list_events`, `search_events`, `update_event`, `delete_event` all operate on the internal store. Tool-call result cards in chat are clickable and open the same EventSlideOver for editing.
|
|
||||||
|
|
||||||
**HomeView widget** — The dashboard shows today's and the next 7 days' events as clickable cards above the hero project.
|
|
||||||
|
|
||||||
**CalDAV sync (optional)** — Connect an external CalDAV server (Nextcloud, Radicale, etc.) in Settings → Integrations. Events sync bidirectionally via a `caldav_uid` field.
|
|
||||||
|
|
||||||
## Sharing and Collaboration
|
## Sharing and Collaboration
|
||||||
|
|
||||||
**Share** — Share any project or note/task with users or groups at `viewer`/`editor`/`admin` permission levels. Share button in the viewer/project toolbar opens a dialog.
|
- **Share** — Share any project, note, or task with users or groups at
|
||||||
|
`viewer`/`editor`/`admin` levels from the viewer/project toolbar.
|
||||||
|
- **Groups** — Admins create platform-wide groups and assign `member`/`owner` roles;
|
||||||
|
share a resource with a group in one action.
|
||||||
|
- **Shared with me** — `/shared` lists incoming shares with permission badges.
|
||||||
|
- **Notifications** — An in-app bell (unread count, polled) fires when a project or
|
||||||
|
note is shared with you or you're added to a group.
|
||||||
|
|
||||||
**Groups** — Admins create platform-wide groups and assign users `member`/`owner` roles. Share a resource with a group in one action.
|
Every read and mutation is scoped by owner + direct shares + group shares.
|
||||||
|
|
||||||
**Shared with me** — `/shared` lists all incoming shared projects and notes with permission badges.
|
|
||||||
|
|
||||||
**Notifications** — Bell icon in nav shows unread count (60s polling). Notifications generated for: project shared, note shared, added to group. Click navigates to the resource.
|
|
||||||
|
|
||||||
**Push notifications** — Web Push (VAPID) notifies when AI generation completes, even in another tab. Works over HTTPS only. Configurable per-user.
|
|
||||||
|
|
||||||
## Quick Capture
|
|
||||||
|
|
||||||
Quick capture from the Android app routes to the intent classifier. It creates notes, tasks, or projects based on content — using the user's configured model, not the hardcoded default.
|
|
||||||
|
|
||||||
## Data Export and Backup
|
## Data Export and Backup
|
||||||
|
|
||||||
- **Personal export** — Settings → Data: download all notes/tasks as a Markdown ZIP (with YAML frontmatter) or JSON array.
|
- **Personal export** — download all your notes/tasks as a Markdown ZIP (YAML
|
||||||
- **Admin backup** — Full application backup (version 2): includes projects, milestones, task logs, AI drafts, note versions, push subscriptions. ID remapping on restore for cross-instance migration.
|
frontmatter) or a JSON array.
|
||||||
|
- **Admin backup** — full application backup/restore (format v4) with ID remapping on
|
||||||
|
restore for cross-instance migration.
|
||||||
|
|
||||||
## PWA
|
## Progressive Web App
|
||||||
|
|
||||||
Installable as a desktop or mobile app. Service worker caches the shell; push notifications are suppressed when the relevant tab is already focused. Works over HTTPS only in Firefox.
|
Installable as a desktop or mobile app; a service worker caches the shell.
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Native email + password, plus optional **OIDC** sign-in (Authentik, Keycloak, etc.)
|
||||||
|
that links to a matching local account. Invite links, a registration toggle, password
|
||||||
|
reset, and session invalidation are included. See [SSO / OAuth](sso-oauth.md).
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
|
|
||||||
Settings are tabbed:
|
|
||||||
|
|
||||||
| Tab | Contents |
|
| Tab | Contents |
|
||||||
|-----|----------|
|
|-----|----------|
|
||||||
| General | Assistant name, default model, model management (pull/delete) |
|
| General | Instance preferences (key/value) |
|
||||||
| Account | Email change, password change, session invalidation |
|
| Account | Email change, password change, session invalidation |
|
||||||
| Notifications | Push notification subscription, journal prep push toggle |
|
| Profile | Per-user profile fields |
|
||||||
| Profile | About you, response preferences, interests, work schedule, locations + temperature unit, journal prep schedule, learned observations |
|
| Integrations | SearXNG status |
|
||||||
| Integrations | CalDAV configuration, SearXNG status |
|
| Data | Personal export; backup / restore (admin) |
|
||||||
| Data | Personal export, backup/restore (admin) |
|
| API Keys | Create/revoke `fmcp_` keys for the MCP endpoint |
|
||||||
| API Keys | Create/revoke API keys, Fable MCP download and install |
|
| Config (admin) | Base URL, SMTP, DB-maintenance schedule |
|
||||||
| Config (admin) | Base URL, SMTP, OIDC settings |
|
|
||||||
| Users (admin) | User list, invite links, registration toggle |
|
| Users (admin) | User list, invite links, registration toggle |
|
||||||
| Logs (admin) | Error, audit, and usage logs with search |
|
| Logs (admin) | Error, audit, and usage logs with search |
|
||||||
| Groups (admin) | Create/manage groups and membership |
|
| Groups (admin) | Create/manage groups and membership |
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
- Email integration (read/send via IMAP/SMTP tools in chat)
|
|
||||||
- Session invalidation on user deletion
|
|
||||||
|
|
||||||
## Keyboard Shortcuts
|
## Keyboard Shortcuts
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
|-----|--------|
|
|-----|--------|
|
||||||
| `g` + `h` | Go to Home |
|
| `g` + `h` | Home (dashboard) |
|
||||||
| `g` + `n` | Go to Notes |
|
| `g` + `n` | Notes |
|
||||||
| `g` + `t` | Go to Tasks |
|
| `g` + `t` | Knowledge (tasks) |
|
||||||
| `g` + `p` | Go to Projects |
|
| `g` + `p` | Projects |
|
||||||
| `g` + `c` | Go to Chat |
|
| `g` + `r` | Rulebooks |
|
||||||
| `g` (bare) | Go to Graph |
|
| `g` (bare) | Graph |
|
||||||
|
| `g` + `x` | Trash |
|
||||||
| `n` | New note |
|
| `n` | New note |
|
||||||
| `t` | New task |
|
| `t` | New task |
|
||||||
| `c` | Focus chat input |
|
| `/` | Focus search |
|
||||||
| `e` | Edit current item |
|
|
||||||
| `/` | Search |
|
|
||||||
| `?` | Show shortcuts panel |
|
| `?` | Show shortcuts panel |
|
||||||
| `j` / `k` | Navigate list items |
|
| `j` / `k` | Navigate list items |
|
||||||
| `Enter` | Open selected item |
|
| `Enter` | Open selected item |
|
||||||
| `Escape` | Close panel / blur / go home (progressive) |
|
| `e` | Edit current item |
|
||||||
|
| `Esc` | Close panel / blur / go home (progressive) |
|
||||||
| `Ctrl+S` | Save in editor |
|
| `Ctrl+S` | Save in editor |
|
||||||
|
|||||||
Reference in New Issue
Block a user