From b0aef542499163676081fdfe01b306b37a98231f Mon Sep 17 00:00:00 2001 From: sai karthik Date: Thu, 23 Jul 2026 00:50:08 +0530 Subject: [PATCH] Apply the bracketed Convex API module references required by the kebab-case module rename --- apps/daemon/src/agent-os.ts | 3 + .../projects/project-workspace-page.tsx | 445 ++++++++++++++++++ apps/web/src/hooks/use-project-workspace.ts | 113 +++++ apps/web/src/root.tsx | 5 +- apps/web/src/routes/_app.dashboard.tsx | 23 +- bun.lock | 188 +++----- packages/agents/package.json | 1 + packages/agents/src/agents/project-manager.ts | 30 ++ packages/agents/src/sandboxes/agent-os.ts | 234 +++++++++ packages/agents/src/tools/project.ts | 70 +++ packages/backend/CLAUDE.md | 13 + .../convex/_generated/ai/ai-files.state.json | 2 +- .../convex/_generated/ai/guidelines.md | 12 +- packages/backend/convex/_generated/api.d.ts | 12 + packages/backend/convex/agent-workspace.ts | 174 +++++++ .../{artifactModel.ts => artifact-model.ts} | 34 +- packages/backend/convex/authz.ts | 4 +- packages/backend/convex/daemonCommands.ts | 5 + ...ojectArtifacts.ts => project-artifacts.ts} | 0 .../{projectIssues.ts => project-issues.ts} | 40 +- packages/backend/convex/projects.ts | 96 ++-- packages/backend/convex/schema.ts | 21 +- packages/backend/skills-lock.json | 41 ++ packages/env/src/agent.ts | 3 + 24 files changed, 1330 insertions(+), 239 deletions(-) create mode 100644 apps/web/src/components/projects/project-workspace-page.tsx create mode 100644 apps/web/src/hooks/use-project-workspace.ts create mode 100644 packages/agents/src/agents/project-manager.ts create mode 100644 packages/agents/src/sandboxes/agent-os.ts create mode 100644 packages/agents/src/tools/project.ts create mode 100644 packages/backend/CLAUDE.md create mode 100644 packages/backend/convex/agent-workspace.ts rename packages/backend/convex/{artifactModel.ts => artifact-model.ts} (63%) rename packages/backend/convex/{projectArtifacts.ts => project-artifacts.ts} (100%) rename packages/backend/convex/{projectIssues.ts => project-issues.ts} (92%) create mode 100644 packages/backend/skills-lock.json diff --git a/apps/daemon/src/agent-os.ts b/apps/daemon/src/agent-os.ts index 1e1dcfb..6a68f62 100644 --- a/apps/daemon/src/agent-os.ts +++ b/apps/daemon/src/agent-os.ts @@ -43,6 +43,9 @@ export const makeAgentOsRuntime = Effect.gen(function* () { catch: (cause) => new AgentOsCommandError({ method: command.method, cause }), }).pipe( + Effect.map((result) => + result instanceof Uint8Array ? result.slice().buffer : result + ), Effect.tap((result) => controlPlane.recordEvent({ commandId: command._id, diff --git a/apps/web/src/components/projects/project-workspace-page.tsx b/apps/web/src/components/projects/project-workspace-page.tsx new file mode 100644 index 0000000..6d9a7cd --- /dev/null +++ b/apps/web/src/components/projects/project-workspace-page.tsx @@ -0,0 +1,445 @@ +import type { Doc, Id } from "@code/backend/convex/_generated/dataModel"; +import { Button } from "@code/ui/components/button"; +import { Input } from "@code/ui/components/input"; +import { Textarea } from "@code/ui/components/textarea"; +import { + Bot, + ExternalLink, + FileText, + GitFork, + GitPullRequest, + Play, + Plus, +} from "lucide-react"; + +import UserMenu from "@/components/user-menu"; +import { useProjectWorkspace } from "@/hooks/use-project-workspace"; + +const statusStyle: Record["status"], string> = { + completed: + "border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300", + failed: "border-destructive/40 bg-destructive/10 text-destructive", + "needs-input": + "border-orange-500/40 bg-orange-500/10 text-orange-700 dark:text-orange-300", + open: "border-border text-muted-foreground", + queued: + "border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-300", + working: "border-blue-500/40 bg-blue-500/10 text-blue-700 dark:text-blue-300", +}; + +interface RepositoryFormProps { + readonly busy: boolean; + readonly onChange: (value: string) => void; + readonly onSubmit: () => Promise; + readonly value: string; +} + +const RepositoryForm = ({ + busy, + onChange, + onSubmit, + value, +}: RepositoryFormProps) => ( +
{ + event.preventDefault(); + void onSubmit(); + }} + > +
+ +

+ Connect with an owner/name slug or repository URL. +

+
+ onChange(event.target.value)} + placeholder="rivet-dev/rivet" + required + value={value} + /> + +
+); + +interface ProjectListProps { + readonly projects: readonly Doc<"projects">[] | undefined; + readonly selectedId: Id<"projects"> | null; + readonly onSelect: (projectId: Id<"projects">) => void; +} + +const ProjectList = ({ projects, selectedId, onSelect }: ProjectListProps) => { + const renderContent = () => { + if (projects === undefined) { + return ( +

Loading projects...

+ ); + } + if (projects.length === 0) { + return ( +

+ Connect a repository to create its project artifacts and issue queue. +

+ ); + } + return ( +
+ {projects.map((project) => ( + + ))} +
+ ); + }; + + return ( + + ); +}; + +interface ArtifactGridProps { + readonly artifacts: readonly Doc<"projectArtifacts">[] | undefined; +} + +const ArtifactGrid = ({ artifacts }: ArtifactGridProps) => ( +
+
+

+ Project artifacts +

+

+ Canonical context staged into every issue workspace. +

+
+ {artifacts === undefined ? ( +

Loading artifacts...

+ ) : ( +
+ {artifacts.map((artifact) => ( +
+
+
+ +

+ {artifact.path} +

+
+ + r{artifact.revision} + +
+

+ {artifact.content} +

+
+ ))} +
+ )} +
+); + +interface IssueComposerProps { + readonly body: string; + readonly busy: boolean; + readonly onBodyChange: (value: string) => void; + readonly onSubmit: () => Promise; + readonly onTitleChange: (value: string) => void; + readonly title: string; +} + +const IssueComposer = ({ + body, + busy, + onBodyChange, + onSubmit, + onTitleChange, + title, +}: IssueComposerProps) => ( +
{ + event.preventDefault(); + void onSubmit(); + }} + > +
+

Raise an issue

+

+ The issue becomes the identity for one Flue agent and AgentOS workspace. +

+
+
+ + onTitleChange(event.target.value)} + required + value={title} + /> +
+
+ +