From cb7484912c409da8267c36472d3147a830c303bb Mon Sep 17 00:00:00 2001 From: puter Date: Mon, 27 Jul 2026 16:03:36 +0000 Subject: [PATCH] Convex-only Slice 1: clients talk to Convex, Flue is a private worker (#20) --- .env.example | 5 +- apps/web/package.json | 6 +- apps/web/react-router.config.ts | 4 +- .../src/components/chat/chat-attachments.tsx | 4 +- apps/web/src/components/chat/chat-message.tsx | 36 +- .../src/components/chat/chat-tool-call.tsx | 60 - .../mobile-workspace/mobile-flow-page.tsx | 200 --- .../components/slice-one/slice-one-page.tsx | 146 ++- .../web/src/hooks/chat/use-chat-agent.test.ts | 79 -- apps/web/src/hooks/chat/use-chat-agent.ts | 107 +- apps/web/src/hooks/chat/use-chat-images.ts | 7 +- apps/web/src/hooks/slice-one/use-slice-one.ts | 11 +- .../src/hooks/use-mobile-project-workspace.ts | 126 -- apps/web/src/hooks/use-mobile-work-stack.ts | 66 - apps/web/src/hooks/use-mobile-workspace.ts | 98 -- .../src/hooks/use-personal-organization.ts | 10 +- apps/web/src/hooks/use-project-workspace.ts | 194 --- apps/web/src/index.css | 13 + apps/web/src/lib/auth.server.ts | 64 + apps/web/src/lib/chat/attachments.test.ts | 10 +- apps/web/src/lib/chat/attachments.ts | 19 - apps/web/src/lib/chat/constants.ts | 13 +- apps/web/src/lib/chat/conversation.test.ts | 44 + apps/web/src/lib/chat/conversation.ts | 50 + apps/web/src/lib/chat/transforms.test.ts | 39 +- apps/web/src/lib/chat/transforms.ts | 27 +- apps/web/src/lib/chat/types.ts | 50 +- apps/web/src/lib/flue-transport.test.ts | 152 --- apps/web/src/lib/flue-transport.ts | 120 -- .../build-mobile-workspace-view.ts | 191 --- .../mobile-status-message.test.ts | 23 - .../mobile-workspace/mobile-status-message.ts | 25 - .../src/lib/projects/project-evidence.test.ts | 91 -- apps/web/src/lib/projects/project-evidence.ts | 315 ----- .../src/lib/slice-one/presentation.test.ts | 18 +- apps/web/src/lib/slice-one/presentation.ts | 18 +- apps/web/src/root.tsx | 90 +- apps/web/src/routes.ts | 11 +- apps/web/src/routes/app/layout.tsx | 33 +- apps/web/src/routes/app/mobile/chat/page.tsx | 12 - .../src/routes/app/mobile/chat/work/page.tsx | 15 - apps/web/src/routes/app/mobile/layout.tsx | 9 - .../src/routes/app/mobile/work-list/page.tsx | 15 - apps/web/src/routes/app/mobile/work/page.tsx | 15 - apps/web/src/routes/app/todos/page.tsx | 123 -- apps/web/src/routes/auth/layout.tsx | 24 +- apps/web/src/routes/auth/login/page.tsx | 12 +- apps/web/vite.config.ts | 6 +- bun.lock | 168 +-- deploy/zopu-runtime/.env.template | 5 +- deploy/zopu-runtime/caddy/Caddyfile | 14 +- docs/TECH.md | 84 +- package.json | 8 +- packages/agents/package.json | 11 +- .../agents/scripts/agentos-adapter-test.ts | 91 -- .../agents/scripts/agentos-sandbox-ref.ts | 142 --- .../src/actions/finalize-gitea-lifecycle.ts | 223 ---- packages/agents/src/agents/project-manager.ts | 32 - packages/agents/src/agents/zopu-dev.ts | 51 - packages/agents/src/agents/zopu.ts | 4 +- packages/agents/src/app.ts | 3 - packages/agents/src/auth.ts | 327 +---- packages/agents/src/git/gitea.test.ts | 155 --- packages/agents/src/git/gitea.ts | 307 ----- packages/agents/src/orb/README.md | 105 -- packages/agents/src/orb/context-pack.ts | 109 -- .../agents/src/orb/docker-sandbox.test.ts | 170 --- packages/agents/src/orb/docker-sandbox.ts | 118 -- packages/agents/src/orb/domain.test.ts | 132 -- packages/agents/src/orb/domain.ts | 259 ---- packages/agents/src/orb/events.test.ts | 134 -- packages/agents/src/orb/events.ts | 216 ---- packages/agents/src/orb/git-adapter.ts | 81 -- packages/agents/src/orb/index.ts | 13 - .../agents/src/orb/opencode-config.test.ts | 82 -- packages/agents/src/orb/opencode-config.ts | 76 -- packages/agents/src/orb/orb-adapter.ts | 132 -- .../src/orb/orb-project-manager.live.test.ts | 132 -- .../src/orb/orb-project-manager.test.ts | 709 ----------- .../agents/src/orb/orb-project-manager.ts | 636 ---------- .../agents/src/orb/permission-policy.test.ts | 107 -- packages/agents/src/orb/permission-policy.ts | 90 -- packages/agents/src/orb/ports.ts | 136 --- .../agents/src/orb/project-events.test.ts | 123 -- packages/agents/src/orb/project-events.ts | 171 --- packages/agents/src/orb/runtime.test.ts | 125 -- packages/agents/src/orb/runtime.ts | 763 ------------ packages/agents/src/project-request.ts | 162 --- packages/agents/src/sandboxes/agent-os.ts | 312 ----- packages/agents/src/sandboxes/agentos.ts | 121 -- .../sandboxes/host-repository-bridge.test.ts | 297 ----- .../src/sandboxes/host-repository-bridge.ts | 506 -------- packages/agents/src/skills/paseo/SKILL.md | 143 --- packages/agents/src/tools/git-remote.ts | 119 -- packages/agents/src/tools/paseo.ts | 43 - packages/agents/src/tools/project.ts | 70 -- packages/agents/src/tools/signals.ts | 368 ------ packages/agents/src/tools/workflow.ts | 37 - packages/auth/package.json | 4 +- packages/auth/src/web/auth-client.ts | 6 +- packages/auth/src/web/auth-provider.tsx | 14 +- packages/backend/CLAUDE.md | 13 - packages/backend/convex/README.md | 22 +- packages/backend/convex/_generated/api.d.ts | 22 - .../backend/convex/_generated/server.d.ts | 1 + packages/backend/convex/agentWorkspace.ts | 388 ------ packages/backend/convex/artifactModel.ts | 71 -- packages/backend/convex/auth.ts | 3 +- .../convex/conversationIngress.smoke.test.ts | 90 -- .../convex/conversationMessages.test.ts | 328 ++--- .../backend/convex/conversationMessages.ts | 545 ++++++--- packages/backend/convex/convex.config.ts | 1 + packages/backend/convex/daemonCommands.ts | 204 ---- packages/backend/convex/daemonRuntime.ts | 107 -- packages/backend/convex/daemons.ts | 60 - packages/backend/convex/linkedSignals.test.ts | 387 ------ packages/backend/convex/projectArtifacts.ts | 19 - packages/backend/convex/projectEvents.test.ts | 285 ----- .../convex/projectIssueRequests.smoke.test.ts | 177 --- packages/backend/convex/projectIssues.ts | 211 ---- packages/backend/convex/projectStore.ts | 430 ------- packages/backend/convex/projects.ts | 291 ++--- packages/backend/convex/schema.ts | 343 ++---- packages/backend/convex/signalRouting.test.ts | 610 +--------- packages/backend/convex/signalRouting.ts | 825 ++----------- packages/backend/convex/signals.test.ts | 620 ---------- packages/backend/convex/signals.ts | 505 -------- packages/backend/convex/todos.ts | 43 - packages/backend/convex/workflows.ts | 64 - packages/backend/convex/works.test.ts | 239 +--- packages/backend/convex/works.ts | 37 +- packages/env/package.json | 1 - packages/env/src/smoke.ts | 55 - packages/env/src/vite-env.d.ts | 3 +- packages/env/src/web.ts | 4 +- packages/primitives/src/project-issue.test.ts | 11 + packages/primitives/src/project-issue.ts | 8 +- packages/ui/package.json | 4 +- .../standalone-chat/standalone-chat-page.tsx | 0 .../web}/routes/standalone/chat/page.tsx | 0 scripts/zopu-smoke.ts | 1080 ----------------- 141 files changed, 1547 insertions(+), 17812 deletions(-) delete mode 100644 apps/web/src/components/chat/chat-tool-call.tsx delete mode 100644 apps/web/src/components/mobile-workspace/mobile-flow-page.tsx delete mode 100644 apps/web/src/hooks/chat/use-chat-agent.test.ts delete mode 100644 apps/web/src/hooks/use-mobile-project-workspace.ts delete mode 100644 apps/web/src/hooks/use-mobile-work-stack.ts delete mode 100644 apps/web/src/hooks/use-mobile-workspace.ts delete mode 100644 apps/web/src/hooks/use-project-workspace.ts create mode 100644 apps/web/src/lib/auth.server.ts create mode 100644 apps/web/src/lib/chat/conversation.test.ts create mode 100644 apps/web/src/lib/chat/conversation.ts delete mode 100644 apps/web/src/lib/flue-transport.test.ts delete mode 100644 apps/web/src/lib/flue-transport.ts delete mode 100644 apps/web/src/lib/mobile-workspace/build-mobile-workspace-view.ts delete mode 100644 apps/web/src/lib/mobile-workspace/mobile-status-message.test.ts delete mode 100644 apps/web/src/lib/mobile-workspace/mobile-status-message.ts delete mode 100644 apps/web/src/lib/projects/project-evidence.test.ts delete mode 100644 apps/web/src/lib/projects/project-evidence.ts delete mode 100644 apps/web/src/routes/app/mobile/chat/page.tsx delete mode 100644 apps/web/src/routes/app/mobile/chat/work/page.tsx delete mode 100644 apps/web/src/routes/app/mobile/layout.tsx delete mode 100644 apps/web/src/routes/app/mobile/work-list/page.tsx delete mode 100644 apps/web/src/routes/app/mobile/work/page.tsx delete mode 100644 apps/web/src/routes/app/todos/page.tsx delete mode 100644 packages/agents/scripts/agentos-adapter-test.ts delete mode 100644 packages/agents/scripts/agentos-sandbox-ref.ts delete mode 100644 packages/agents/src/actions/finalize-gitea-lifecycle.ts delete mode 100644 packages/agents/src/agents/project-manager.ts delete mode 100644 packages/agents/src/agents/zopu-dev.ts delete mode 100644 packages/agents/src/git/gitea.test.ts delete mode 100644 packages/agents/src/git/gitea.ts delete mode 100644 packages/agents/src/orb/README.md delete mode 100644 packages/agents/src/orb/context-pack.ts delete mode 100644 packages/agents/src/orb/docker-sandbox.test.ts delete mode 100644 packages/agents/src/orb/docker-sandbox.ts delete mode 100644 packages/agents/src/orb/domain.test.ts delete mode 100644 packages/agents/src/orb/domain.ts delete mode 100644 packages/agents/src/orb/events.test.ts delete mode 100644 packages/agents/src/orb/events.ts delete mode 100644 packages/agents/src/orb/git-adapter.ts delete mode 100644 packages/agents/src/orb/index.ts delete mode 100644 packages/agents/src/orb/opencode-config.test.ts delete mode 100644 packages/agents/src/orb/opencode-config.ts delete mode 100644 packages/agents/src/orb/orb-adapter.ts delete mode 100644 packages/agents/src/orb/orb-project-manager.live.test.ts delete mode 100644 packages/agents/src/orb/orb-project-manager.test.ts delete mode 100644 packages/agents/src/orb/orb-project-manager.ts delete mode 100644 packages/agents/src/orb/permission-policy.test.ts delete mode 100644 packages/agents/src/orb/permission-policy.ts delete mode 100644 packages/agents/src/orb/ports.ts delete mode 100644 packages/agents/src/orb/project-events.test.ts delete mode 100644 packages/agents/src/orb/project-events.ts delete mode 100644 packages/agents/src/orb/runtime.test.ts delete mode 100644 packages/agents/src/orb/runtime.ts delete mode 100644 packages/agents/src/project-request.ts delete mode 100644 packages/agents/src/sandboxes/agent-os.ts delete mode 100644 packages/agents/src/sandboxes/agentos.ts delete mode 100644 packages/agents/src/sandboxes/host-repository-bridge.test.ts delete mode 100644 packages/agents/src/sandboxes/host-repository-bridge.ts delete mode 100644 packages/agents/src/skills/paseo/SKILL.md delete mode 100644 packages/agents/src/tools/git-remote.ts delete mode 100644 packages/agents/src/tools/paseo.ts delete mode 100644 packages/agents/src/tools/project.ts delete mode 100644 packages/agents/src/tools/signals.ts delete mode 100644 packages/agents/src/tools/workflow.ts delete mode 100644 packages/backend/CLAUDE.md delete mode 100644 packages/backend/convex/agentWorkspace.ts delete mode 100644 packages/backend/convex/artifactModel.ts delete mode 100644 packages/backend/convex/conversationIngress.smoke.test.ts delete mode 100644 packages/backend/convex/daemonCommands.ts delete mode 100644 packages/backend/convex/daemonRuntime.ts delete mode 100644 packages/backend/convex/daemons.ts delete mode 100644 packages/backend/convex/linkedSignals.test.ts delete mode 100644 packages/backend/convex/projectArtifacts.ts delete mode 100644 packages/backend/convex/projectEvents.test.ts delete mode 100644 packages/backend/convex/projectIssueRequests.smoke.test.ts delete mode 100644 packages/backend/convex/projectIssues.ts delete mode 100644 packages/backend/convex/projectStore.ts delete mode 100644 packages/backend/convex/signals.test.ts delete mode 100644 packages/backend/convex/signals.ts delete mode 100644 packages/backend/convex/todos.ts delete mode 100644 packages/backend/convex/workflows.ts delete mode 100644 packages/env/src/smoke.ts rename {apps/web/src => repos/web}/components/standalone-chat/standalone-chat-page.tsx (100%) rename {apps/web/src => repos/web}/routes/standalone/chat/page.tsx (100%) delete mode 100644 scripts/zopu-smoke.ts diff --git a/.env.example b/.env.example index ca400ee..d65d729 100644 --- a/.env.example +++ b/.env.example @@ -6,10 +6,8 @@ SITE_URL=http://localhost:5173 NATIVE_APP_URL=code:// # Browser and native public endpoints +VITE_AUTH_URL=http://localhost:5173 VITE_CONVEX_URL=https://example.convex.cloud -VITE_CONVEX_SITE_URL=https://example.convex.site -# For phone testing, replace localhost with this machine's Tailscale IPv4 address. -VITE_FLUE_URL=http://localhost:3583 EXPO_PUBLIC_CONVEX_URL=https://example.convex.cloud EXPO_PUBLIC_CONVEX_SITE_URL=https://example.convex.site @@ -23,6 +21,7 @@ DAEMON_COMMAND_LEASE_MS=60000 # Flue persistence adapter FLUE_DB_TOKEN=replace-with-a-long-random-token +FLUE_URL=http://localhost:3583 # Agent model provider AGENT_MODEL_PROVIDER=xiaomi diff --git a/apps/web/package.json b/apps/web/package.json index bc779f4..67dc49e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -15,8 +15,6 @@ "@code/env": "workspace:*", "@code/primitives": "workspace:*", "@code/ui": "workspace:*", - "@flue/react": "1.0.0-beta.9", - "@flue/sdk": "1.0.0-beta.9", "@react-router/fs-routes": "^8.1.0", "@react-router/node": "^8.1.0", "@react-router/serve": "^8.1.0", @@ -24,8 +22,8 @@ "isbot": "^5.1.44", "lucide-react": "catalog:", "next-themes": "catalog:", - "react": "^19.2.7", - "react-dom": "^19.2.7", + "react": "catalog:", + "react-dom": "catalog:", "react-router": "^8.1.0", "sonner": "catalog:", "streamdown": "2.5.0" diff --git a/apps/web/react-router.config.ts b/apps/web/react-router.config.ts index 4539207..72df924 100644 --- a/apps/web/react-router.config.ts +++ b/apps/web/react-router.config.ts @@ -1,7 +1,7 @@ import type { Config } from "@react-router/dev/config"; export default { - // Desktop addons package static web assets; SSR output cannot be bundled - ssr: false, appDirectory: "src", + + ssr: true, } satisfies Config; diff --git a/apps/web/src/components/chat/chat-attachments.tsx b/apps/web/src/components/chat/chat-attachments.tsx index df8b2a0..208e610 100644 --- a/apps/web/src/components/chat/chat-attachments.tsx +++ b/apps/web/src/components/chat/chat-attachments.tsx @@ -9,13 +9,13 @@ import { AttachmentMedia, AttachmentTitle, } from "@code/ui/components/attachment"; -import type { FlueConversationPart } from "@flue/react"; import { ImageIcon, X } from "lucide-react"; import { useEffect, useState } from "react"; import type { PendingChatImage } from "@/lib/chat/attachments"; +import type { ConversationPart } from "@/lib/chat/types"; -type FilePart = Extract; +type FilePart = Extract; const isDirectlyRenderableUrl = (url: string): boolean => url.startsWith("blob:") || url.startsWith("data:"); diff --git a/apps/web/src/components/chat/chat-message.tsx b/apps/web/src/components/chat/chat-message.tsx index e487e69..647d3c7 100644 --- a/apps/web/src/components/chat/chat-message.tsx +++ b/apps/web/src/components/chat/chat-message.tsx @@ -7,12 +7,10 @@ import { MobileChatBubble, MobileChatMessage, } from "@code/ui/components/mobile-chat"; -import type { FlueConversationMessage } from "@flue/react"; import { getMessageText, getReasoningText, - hasToolActivity, isReasoningStreaming, isMessageStreaming, } from "@/lib/chat/transforms"; @@ -23,7 +21,6 @@ import type { import { AssistantIdentity } from "./assistant-identity"; import { MessageAttachments } from "./chat-attachments"; -import { ChatToolCall } from "./chat-tool-call"; const ReasoningTrace = ({ isStreaming, @@ -96,27 +93,7 @@ const assistantState = ( return isStreaming ? "writing" : undefined; }; -const ToolActivity = ({ - hidden, - message, -}: { - readonly hidden: boolean; - readonly message: FlueConversationMessage; -}) => { - if (hidden) { - return null; - } - return message.parts.map((part) => - part.type === "dynamic-tool" ? ( - - ) : null - ); -}; - -export const ChatMessage = ({ - hideToolActivity = false, - message, -}: ChatMessageProps) => { +export const ChatMessage = ({ message }: ChatMessageProps) => { const isUser = message.role === "user"; const isStreaming = isMessageStreaming(message); const text = getMessageText(message); @@ -124,16 +101,6 @@ export const ChatMessage = ({ const reasoningStreaming = isReasoningStreaming(message); const fileParts = message.parts.filter((part) => part.type === "file"); - if ( - hideToolActivity && - !isUser && - hasToolActivity(message) && - !text && - !reasoning - ) { - return null; - } - if (message.parts.length === 0 && !isStreaming) { return null; } @@ -167,7 +134,6 @@ export const ChatMessage = ({ text={reasoning} /> )} -