#!/usr/bin/env node import { mkdtemp, copyFile } from "node:fs/promises"; import { existsSync } from "node:fs"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { createRequire } from "node:module"; const rootDir = process.cwd(); const scriptDir = path.dirname(fileURLToPath(import.meta.url)); const require = createRequire(import.meta.url); const jiti = require("jiti")(fileURLToPath(import.meta.url), { alias: { "@/": `${path.join(rootDir, "src")}/`, }, }); const tempDir = await mkdtemp(path.join(os.tmpdir(), "boss-attachment-model-")); const tempStateFile = path.join(tempDir, "boss-state.json"); const sourceStateFile = path.join(rootDir, "data", "boss-state.json"); if (!existsSync(sourceStateFile)) { throw new Error(`Missing state file: ${sourceStateFile}`); } await copyFile(sourceStateFile, tempStateFile); process.env.BOSS_STATE_FILE = tempStateFile; process.env.BOSS_RUNTIME_ROOT = rootDir; const { getAttachmentStorageConfig, readState, writeState } = jiti(path.join(scriptDir, "..", "src", "lib", "boss-data.ts")); const config = await getAttachmentStorageConfig("krisolo"); if (config.mode !== "server_file") { throw new Error(`Expected default storage mode server_file, got ${config.mode}`); } if (!config.updatedAt || typeof config.updatedAt !== "string") { throw new Error("Expected updatedAt to be populated"); } const state = await readState(); const messageId = "script-attachment-message"; state.projects[0].messages.unshift({ id: messageId, sender: "user", senderLabel: "测试用户", body: "Attachment round-trip", sentAt: "2026-03-29T00:00:00+08:00", kind: "attachment", attachments: [ { attachmentId: "att-001", fileName: "demo.txt", mimeType: "text/plain", fileSizeBytes: 12, attachmentKind: "text", storageBackend: "server_file", storagePath: "/tmp/demo.txt", previewAvailable: true, uploadedAt: "2026-03-29T00:00:00+08:00", uploadedBy: "krisolo", analysisState: "not_applicable", }, ], }); await writeState(state); const reread = await readState(); const message = reread.projects[0].messages.find((item) => item.id === messageId); if (!message?.attachments?.length) { throw new Error("Expected message attachments to round-trip through state"); } if (message.attachments[0].attachmentId !== "att-001") { throw new Error("Expected attachment metadata to persist"); } if (message.attachments[0].storageBackend !== "server_file") { throw new Error("Expected attachment storage backend to persist"); } console.log("OK");