feat(HAI-042): add file attachment support for tasks

- Expand MIME type support for text file uploads
- Add --attach flag to CLI task create command
- Surface attachments to triage agent with image content support
- Reference attachments in executor prompt for task execution context
- Add drag-and-drop file upload on dashboard task cards
This commit is contained in:
Dustin Byrne
2026-03-26 00:06:41 -04:00
parent afcd074caa
commit 123c481dfc
13 changed files with 592 additions and 27 deletions

View File

@@ -245,10 +245,29 @@ describe("TaskStore", () => {
expect(content).toEqual(TINY_PNG);
});
it("rejects non-image mime types", async () => {
it("accepts text/plain mime type", async () => {
const task = await createTestTask();
const attachment = await store.addAttachment(task.id, "error.log", Buffer.from("log content"), "text/plain");
expect(attachment.originalName).toBe("error.log");
expect(attachment.mimeType).toBe("text/plain");
});
it("accepts application/json mime type", async () => {
const task = await createTestTask();
const attachment = await store.addAttachment(task.id, "config.json", Buffer.from('{"key":"val"}'), "application/json");
expect(attachment.mimeType).toBe("application/json");
});
it("accepts text/yaml mime type", async () => {
const task = await createTestTask();
const attachment = await store.addAttachment(task.id, "config.yaml", Buffer.from("key: val"), "text/yaml");
expect(attachment.mimeType).toBe("text/yaml");
});
it("rejects unsupported mime types", async () => {
const task = await createTestTask();
await expect(
store.addAttachment(task.id, "file.txt", Buffer.from("hello"), "text/plain"),
store.addAttachment(task.id, "file.bin", Buffer.from("data"), "application/octet-stream"),
).rejects.toThrow("Invalid mime type");
});

View File

@@ -718,6 +718,12 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
"image/jpeg",
"image/gif",
"image/webp",
"text/plain",
"application/json",
"text/yaml",
"text/x-toml",
"text/csv",
"application/xml",
]);
private static MAX_ATTACHMENT_SIZE = 5 * 1024 * 1024; // 5MB