| 53 | import type { AgentArtifactsResult } from '../cloud-artifacts.ts'; |
| 54 | |
| 55 | export function createAgentDeviceClient( |
| 56 | config: AgentDeviceClientConfig = {}, |
| 57 | deps: { transport?: AgentDeviceDaemonTransport } = {}, |
| 58 | ): AgentDeviceClient { |
| 59 | const transport = deps.transport ?? sendToDaemon; |
| 60 | |
| 61 | // A non-default responseLevel (digest/full) makes the daemon return a leveled |
| 62 | // shape; the per-command client normalizers assume the default shape, so the |
| 63 | // capture methods pass the leveled payload through unnormalized instead. |
| 64 | const isLeveledResponse = (options: { responseLevel?: ResponseLevel }): boolean => |
| 65 | isNonDefaultResponseLevel(options.responseLevel ?? config.responseLevel); |
| 66 | |
| 67 | const execute = async ( |
| 68 | command: string, |
| 69 | positionals: string[] = [], |
| 70 | options: InternalRequestOptions = {}, |
| 71 | metadataFlags?: Partial<CommandFlags>, |
| 72 | ): Promise<Record<string, unknown>> => { |
| 73 | const merged = mergeClientOptions(config, options); |
| 74 | const response = await transport({ |
| 75 | session: resolveSessionName(merged.session), |
| 76 | command, |
| 77 | positionals, |
| 78 | flags: buildRequestFlags(merged, metadataFlags), |
| 79 | runtime: merged.runtime, |
| 80 | meta: buildMeta(merged), |
| 81 | }); |
| 82 | if (!response.ok) { |
| 83 | throwDaemonError(response.error); |
| 84 | } |
| 85 | return (response.data ?? {}) as Record<string, unknown>; |
| 86 | }; |
| 87 | |
| 88 | const listSessions = async (options = {}) => { |
| 89 | const data = await execute(INTERNAL_COMMANDS.sessionList, [], options); |
| 90 | const sessions = Array.isArray(data.sessions) ? data.sessions : []; |
| 91 | return sessions.map(normalizeSession); |
| 92 | }; |
| 93 | |
| 94 | const executeCommand = async <T>( |
| 95 | command: DaemonCommandName, |
| 96 | options: InternalRequestOptions = {}, |
| 97 | ): Promise<T> => { |
| 98 | const request = prepareDaemonCommandRequest(command, options); |
| 99 | return (await execute( |
| 100 | request.command, |
| 101 | request.positionals, |
| 102 | request.options, |
| 103 | request.metadataFlags, |
| 104 | )) as T; |
| 105 | }; |
| 106 | |
| 107 | const resolveRequestSession = (options: InternalRequestOptions = {}) => |
| 108 | resolveSessionName(mergeClientOptions(config, options).session); |
| 109 | |
| 110 | return { |
| 111 | command: { |
| 112 | wait: async (options) => await executeCommand('wait', options), |