/** * `sessionMetadata` — typed session metadata. Mirrors * `agent-core-v2/session/sessionMetadata/sessionMetadata.ts`. The `ready` * promise property is excluded (not a wire method). */ import { z } from 'zod'; import { noResult } from '../helpers.js'; import type { ServiceContract } from '../types.js'; export const agentMetaSchema = z.object({ homedir: z.string().optional(), type: z.enum(['main', 'sub', 'independent']).optional(), parentAgentId: z.union([z.string(), z.null()]).optional(), forkedFrom: z.string().optional(), labels: z.record(z.string(), z.string()).optional(), swarmItem: z.string().optional(), }); export const sessionMetaSchema = z.object({ id: z.string(), version: z.number().optional(), title: z.string().optional(), titleKind: z.enum(['replaceable', 'generated', 'custom']).optional(), lastPrompt: z.string().optional(), createdAt: z.number(), updatedAt: z.number(), archived: z.boolean(), archivedAt: z.number().optional(), cwd: z.string().optional(), forkedFrom: z.string().optional(), agents: z.record(z.string(), agentMetaSchema).optional(), custom: z.record(z.string(), z.unknown()).optional(), lastTurnReason: z.enum(['completed', 'cancelled', 'failed']).optional(), }); /** `Partial>` — every key optional. */ export const sessionMetaPatchSchema = z.object({ version: z.number().optional(), title: z.string().optional(), titleKind: z.enum(['replaceable', 'generated', 'custom']).optional(), lastPrompt: z.string().optional(), updatedAt: z.number().optional(), archived: z.boolean().optional(), archivedAt: z.number().optional(), cwd: z.string().optional(), forkedFrom: z.string().optional(), agents: z.record(z.string(), agentMetaSchema).optional(), custom: z.record(z.string(), z.unknown()).optional(), lastTurnReason: z.enum(['completed', 'cancelled', 'failed']).optional(), }); /** `keyof SessionMeta` — keep in sync with `sessionMetaSchema`. */ export const sessionMetaKeySchema = z.enum([ 'id', 'version', 'title', 'titleKind', 'lastPrompt', 'createdAt', 'updatedAt', 'archived', 'archivedAt', 'cwd', 'forkedFrom', 'agents', 'custom', 'lastTurnReason', ]); export const sessionMetadataChangedEventSchema = z.object({ changed: z.array(sessionMetaKeySchema), }); export const sessionMetadataContract = { read: { input: z.tuple([]), output: sessionMetaSchema }, update: { input: z.tuple([sessionMetaPatchSchema]), output: noResult }, setTitle: { input: z.tuple([z.string()]), output: noResult }, setArchived: { input: z.tuple([z.boolean()]), output: noResult }, registerAgent: { input: z.tuple([z.string(), agentMetaSchema]), output: noResult }, } satisfies ServiceContract;