Normalize the topology so web/desktop/mobile clients communicate only with Convex. Convex admits durable commands, dispatches private Flue turns through FLUE_URL, and stores the product-facing result before clients observe it. - Normalized relational schema: organizations, projects, conversations/turns/ messages/attachments, signals/sources/constraints, works/events/attachments. - Conversation turns queued in Convex; the agent runAction dispatches to Flue and persists assistant response, signals, and proposed work back into Convex. - Browser chat moved off the Flue transport: use-chat-agent now reads reactive Convex rows and sends through conversationMessages.send. - Fixed signed-in blank screen: gate all product queries on useConvexAuth (isAuthenticated && !isRefreshing) plus personal-org bootstrap. - Pinned react/react-dom to 19.2.8 via catalog to fix SSR dual-React crash. - Removed ~16.6k net lines: daemon, AgentOS/Orb, project issues/runs/artifacts, todos, browser Flue transport, mobile execution views, smoke scripts. Verified end-to-end on cheaptricks: connect repo, send actionable message, Flue turn completes, Signal + proposed Work created with exact provenance, persists across refresh.
19 lines
734 B
TypeScript
19 lines
734 B
TypeScript
import { parseAgentEnv } from "@code/env/agent";
|
|
import type { AgentRouteHandler } from "@flue/runtime";
|
|
|
|
/** Only Convex may invoke or observe the organization-scoped Flue agent. */
|
|
export const convexAgentRoute: AgentRouteHandler = async (context, next) => {
|
|
const env = parseAgentEnv(process.env);
|
|
const authorization = context.req.header("authorization");
|
|
if (authorization !== `Bearer ${env.FLUE_DB_TOKEN}`) {
|
|
return context.json({ error: "Unauthorized" }, 401);
|
|
}
|
|
|
|
const organizationId = context.req.header("x-zopu-organization-id");
|
|
if (!organizationId || organizationId !== context.req.param("id")) {
|
|
return context.json({ error: "Forbidden" }, 403);
|
|
}
|
|
|
|
return await next().then(() => context.res);
|
|
};
|