refactor(app): introduce attachment storage layer and draft lifecycle management

Replace inline data-URL image handling with a persistent attachment storage service, add draft lifecycle states (active/abandoned/sent) with generation tracking, and update fetchAgent to return project placement alongside agent snapshots.
This commit is contained in:
Mohamed Boudra
2026-02-22 16:22:21 +07:00
parent 2652bdda2e
commit 0c710b09f5
55 changed files with 2381 additions and 350 deletions
@@ -0,0 +1,23 @@
import { describe, expect, it } from "vitest";
import { SessionInboundMessageSchema } from "./messages";
describe("create_agent_request clientMessageId", () => {
it("accepts clientMessageId for stable initial prompt transfer", () => {
const parsed = SessionInboundMessageSchema.parse({
type: "create_agent_request",
requestId: "req-1",
clientMessageId: "client-msg-1",
config: {
provider: "claude",
cwd: "/tmp/project",
},
initialPrompt: "hello",
});
expect(parsed.type).toBe("create_agent_request");
if (parsed.type !== "create_agent_request") {
throw new Error("Expected create_agent_request");
}
expect(parsed.clientMessageId).toBe("client-msg-1");
});
});
+3 -1
View File
@@ -491,7 +491,7 @@ export const FetchAgentsRequestMessageSchema = z.object({
.optional(),
page: z
.object({
limit: z.number().int().positive().max(1000),
limit: z.number().int().positive().max(200),
cursor: z.string().min(1).optional(),
})
.optional(),
@@ -578,6 +578,7 @@ export const CreateAgentRequestMessageSchema = z.object({
config: AgentSessionConfigSchema,
worktreeName: z.string().optional(),
initialPrompt: z.string().optional(),
clientMessageId: z.string().optional(),
outputSchema: z.record(z.unknown()).optional(),
images: z
.array(
@@ -1469,6 +1470,7 @@ export const FetchAgentResponseMessageSchema = z.object({
payload: z.object({
requestId: z.string(),
agent: AgentSnapshotPayloadSchema.nullable(),
project: ProjectPlacementPayloadSchema.nullable().optional(),
error: z.string().nullable(),
}),
})