NEXUS is Slack-native — there is no public REST API in v1 (see docs/ROADMAP.md for the planned /api/* surface backing the dashboard). This document covers the Slack-facing surface and the internal service contracts.
All commands are subcommands of a single /nexus entry point.
| Command | Description | Example |
|---|---|---|
/nexus ask <question> |
AI chat, one-off | /nexus ask what's on my plate today? |
/nexus task add <title> [by <date>] |
Create a task | /nexus task add Finish deck by Friday |
/nexus task list |
List your open tasks | /nexus task list |
/nexus task done <title fragment> |
Mark a task complete (fuzzy match) | /nexus task done deck |
/nexus remind me to <text> at <time> |
Create a reminder | /nexus remind me to call the client at 3pm tomorrow |
/nexus prep <meeting title> |
Meeting prep briefing | /nexus prep Acme renewal call |
/nexus digest |
On-demand productivity digest | /nexus digest |
/nexus note <text> |
Save a note to personal memory | /nexus note client wants ROI-focused proposal |
/nexus search <query> |
Search notes/PDFs/history | /nexus search acme proposal |
All responses are ephemeral by default (only visible to the requester) except /nexus ask, which posts in_channel so teammates can see AI answers shared in a channel.
| Slack event | Handler | Purpose |
|---|---|---|
message.im |
chat.controller.ts::handleDirectMessage |
Free-form AI chat via DM |
message.channels |
deadline.controller.ts::handleChannelMessageForDeadlines |
Passive deadline detection |
file_shared |
meetingPrepAndPdf.controller.ts::handleFileSharedForPdf |
Auto-summarize shared PDFs |
block_actions (add_detected_task, dismiss_detected_task) |
deadline.controller.ts |
Confirm/dismiss a detected deadline |
These are the pure-logic boundaries — the layer unit tests target (see docs/TESTING.md).
groq.service.tscompleteChat(messages: ChatMessage[], options?): Promise<string>
summarizeText(text: string, context: string): Promise<string>
task.service.tscreateTask(input: CreateTaskInput): Promise<Task>
listTasks(userUuid: string, status?: TaskStatus): Promise<Task[]>
getTasksDueBetween(userUuid: string, start: Date, end: Date): Promise<Task[]>
getOverdueTasks(userUuid: string): Promise<Task[]>
updateTaskStatus(taskId: string, status: TaskStatus): Promise<void>
reminder.service.tscreateReminder(workspaceUuid: string, userUuid: string, message: string, remindAt: Date): Promise<Reminder>
getDueReminders(withinMinutes?: number): Promise<Reminder[]>
markReminderDelivered(id: string): Promise<void>
getUpcomingReminders(userUuid: string, hours?: number): Promise<Reminder[]>
memory.service.tssaveMemory(workspaceUuid: string, userUuid: string, content: string, sourceType: MemoryEntry["sourceType"]): Promise<MemoryEntry>
searchMemory(userUuid: string, query: string, limit?: number): Promise<MemoryEntry[]>
deadline.service.tsextractDeadline(messageText: string, referenceDateIso: string): Promise<DeadlineExtraction>
meetingPrep.service.tsprepareMeeting(userUuid: string, meetingTitle: string): Promise<MeetingPrepResult>
digest.service.tsbuildDailyDigest(userUuid: string): Promise<DailyDigest>
Not implemented in this hackathon build; the dashboard currently ships with realistic mock data and gracefully falls back if these aren’t reachable (see frontend/public/assets/js/dashboard.js).
GET /api/tasks -> Task[]
GET /api/digest -> DailyDigest
GET /api/notifications -> Notification[]
POST /api/chat -> { reply: string }
Auth for this surface will use Slack’s OAuth “Sign in with Slack” flow rather than a separate password system — consistent with the “Slack is the identity provider” principle in docs/ARCHITECTURE.md.