feat: journal dashboard widgets, agent polish, and edit-mode live previews
CI / checks (push) Failing after 2m7s
CI / build (push) Successful in 4m36s

Journal dashboard widgets and quick-add; rich-text quick-add dialogs.

Dashboard draft sync for live edit previews; assistant bubble + API tools.

Journal UX: stress slider, mood grid, query cap fix.
This commit is contained in:
ginnoir
2026-07-04 22:03:45 -05:00
parent 4a924a4107
commit a09747c314
76 changed files with 4594 additions and 611 deletions
+50 -1
View File
@@ -1,10 +1,13 @@
import { z } from "zod";
import { apiError, apiJson } from "@/lib/api-handler";
import { resolveApiAuth } from "@/lib/api-auth";
import { getAssistantEnabled } from "@/lib/assistant-preference";
import { isLlmConfigured } from "@/lib/llm";
import { encodeSseEvent } from "@/modules/agent/server/progress";
import { runAgentChat } from "@/modules/agent/server/run";
const chatInput = z.object({
stream: z.boolean().optional(),
messages: z
.array(
z.object({
@@ -18,10 +21,15 @@ const chatInput = z.object({
export async function POST(request: Request) {
const auth = await resolveApiAuth(request);
if (!auth) {
if (!auth?.userId) {
return apiError("Unauthorized", 401);
}
const assistantEnabled = await getAssistantEnabled(auth.userId);
if (!assistantEnabled) {
return apiError("Assistant not enabled", 403);
}
let body: unknown;
try {
body = await request.json();
@@ -34,6 +42,47 @@ export async function POST(request: Request) {
return apiError(parsed.error.issues[0]?.message ?? "Validation error", 400);
}
if (parsed.data.stream) {
const stream = new ReadableStream<Uint8Array>({
async start(controller) {
const encoder = new TextEncoder();
const send = (event: Parameters<typeof encodeSseEvent>[0]) => {
controller.enqueue(encoder.encode(encodeSseEvent(event)));
};
try {
const result = await runAgentChat({
messages: parsed.data.messages,
request,
onProgress: send,
});
send({
type: "done",
message: {
role: "assistant",
content: result.message.content,
},
toolCalls: result.toolCalls,
});
} catch (err) {
const message = err instanceof Error ? err.message : "Agent request failed";
send({ type: "error", message });
} finally {
controller.close();
}
},
});
return new Response(stream, {
headers: {
"Content-Type": "text/event-stream; charset=utf-8",
"Cache-Control": "no-cache, no-transform",
Connection: "keep-alive",
},
});
}
try {
const result = await runAgentChat({
messages: parsed.data.messages,