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
+3 -2
View File
@@ -57,8 +57,8 @@ export async function runArchiveCommand(
}
try {
const agent = await client.fetchAgent(agentIdArg)
if (!agent) {
const fetchResult = await client.fetchAgent(agentIdArg)
if (!fetchResult) {
const error: CommandError = {
code: 'AGENT_NOT_FOUND',
message: `Agent not found: ${agentIdArg}`,
@@ -66,6 +66,7 @@ export async function runArchiveCommand(
}
throw error
}
const agent = fetchResult.agent
const agentId = agent.id
// Check if agent is already archived
+3 -3
View File
@@ -118,14 +118,14 @@ export async function runAttachCommand(
}
try {
const agent = await client.fetchAgent(id)
if (!agent) {
const fetchResult = await client.fetchAgent(id)
if (!fetchResult) {
console.error(`Error: No agent found matching: ${id}`)
console.error('Use `paseo ls` to list available agents')
await client.close()
process.exit(1)
}
const resolvedId = agent.id
const resolvedId = fetchResult.agent.id
// Print header
console.log(`Attaching to agent ${resolvedId.substring(0, 7)}...`)
+3 -3
View File
@@ -231,8 +231,8 @@ export async function runInspectCommand(
}
try {
const snapshot = await client.fetchAgent(agentIdArg)
if (!snapshot) {
const fetchResult = await client.fetchAgent(agentIdArg)
if (!fetchResult) {
const error: CommandError = {
code: 'AGENT_NOT_FOUND',
message: `Agent not found: ${agentIdArg}`,
@@ -243,7 +243,7 @@ export async function runInspectCommand(
await client.close()
const inspectData = toInspectData(snapshot)
const inspectData = toInspectData(fetchResult.agent)
return {
type: 'list',
+3 -3
View File
@@ -99,14 +99,14 @@ export async function runLogsCommand(
}
try {
const agent = await client.fetchAgent(id)
if (!agent) {
const fetchResult = await client.fetchAgent(id)
if (!fetchResult) {
console.error(`Error: No agent found matching: ${id}`)
console.error('Use `paseo ls` to list available agents')
await client.close()
process.exit(1)
}
const resolvedId = agent.id
const resolvedId = fetchResult.agent.id
// For follow mode, we stream events continuously
if (options.follow) {
+3 -2
View File
@@ -65,8 +65,8 @@ export async function runModeCommand(
let client: Awaited<ReturnType<typeof connectToDaemon>> | undefined
try {
client = await connectToDaemon({ host: options.host as string | undefined })
const agent = await client.fetchAgent(id)
if (!agent) {
const fetchResult = await client.fetchAgent(id)
if (!fetchResult) {
const error: CommandError = {
code: 'AGENT_NOT_FOUND',
message: `No agent found matching: ${id}`,
@@ -74,6 +74,7 @@ export async function runModeCommand(
}
throw error
}
const agent = fetchResult.agent
const resolvedId = agent.id
if (options.list) {
+3 -3
View File
@@ -71,8 +71,8 @@ export async function runStopCommand(
})
} else if (id) {
// Stop specific agent
const agent = await client.fetchAgent(id)
if (!agent) {
const fetchResult = await client.fetchAgent(id)
if (!fetchResult) {
const error: CommandError = {
code: 'AGENT_NOT_FOUND',
message: `No agent found matching: ${id}`,
@@ -80,7 +80,7 @@ export async function runStopCommand(
}
throw error
}
agents = [agent]
agents = [fetchResult.agent]
}
// Stop each agent
+7 -7
View File
@@ -127,8 +127,8 @@ export async function runUpdateCommand(
}
try {
const agent = await client.fetchAgent(agentIdArg)
if (!agent) {
const fetchResult = await client.fetchAgent(agentIdArg)
if (!fetchResult) {
const error: CommandError = {
code: 'AGENT_NOT_FOUND',
message: `Agent not found: ${agentIdArg}`,
@@ -136,15 +136,15 @@ export async function runUpdateCommand(
}
throw error
}
const agentId = agent.id
const agentId = fetchResult.agent.id
await client.updateAgent(agentId, {
...(name ? { name } : {}),
...(Object.keys(labels).length > 0 ? { labels } : {}),
})
const updated = await client.fetchAgent(agentId)
if (!updated) {
const updatedResult = await client.fetchAgent(agentId)
if (!updatedResult) {
throw new Error(`Agent not found after update: ${agentId}`)
}
@@ -154,8 +154,8 @@ export async function runUpdateCommand(
type: 'single',
data: {
agentId,
name: updated.title,
labels: formatLabels(updated.labels),
name: updatedResult.agent.title,
labels: formatLabels(updatedResult.agent.labels),
},
schema: updateSchema,
}
+3 -2
View File
@@ -79,8 +79,8 @@ export async function runAllowCommand(
}
try {
const agent = await client.fetchAgent(agentIdOrPrefix)
if (!agent) {
const fetchResult = await client.fetchAgent(agentIdOrPrefix)
if (!fetchResult) {
await client.close()
const error: CommandError = {
code: 'AGENT_NOT_FOUND',
@@ -89,6 +89,7 @@ export async function runAllowCommand(
}
throw error
}
const agent = fetchResult.agent
const resolvedAgentId = agent.id
// Get pending permissions for this agent
+3 -2
View File
@@ -45,8 +45,8 @@ export async function runDenyCommand(
}
try {
const agent = await client.fetchAgent(agentIdOrPrefix)
if (!agent) {
const fetchResult = await client.fetchAgent(agentIdOrPrefix)
if (!fetchResult) {
await client.close()
const error: CommandError = {
code: 'AGENT_NOT_FOUND',
@@ -55,6 +55,7 @@ export async function runDenyCommand(
}
throw error
}
const agent = fetchResult.agent
const resolvedAgentId = agent.id
// Get pending permissions for this agent