---
title: ExecHandle
description: One exec, addressed by its caller-minted id.
---

One exec, addressed by its caller-minted id.

The id is the idempotency key, so a handle survives a process restart: rebuild it through
`Session.exec(execId)` and every method still addresses the same server-side exec.

## Accessors

### execId

#### Get Signature

```ts
get execId(): string;
```

##### Returns

`string`

## Methods

### ack()

```ts
ack(): Promise<ExecResult>;
```

Releases the buffered output and starts the TTL clock.

#### Returns

`Promise`\<[`ExecResult`](/microvms-agentd/reference/typescript/interfaces/execresult/)>

***

### closeStdin()

```ts
closeStdin(): Promise<StdinAck>;
```

Sends EOF. Nothing else closes stdin: the daemon's copy of the pipe outlives the
child's wait, so a child blocked reading stdin hangs until its timeout otherwise.

#### Returns

`Promise`\<[`StdinAck`](/microvms-agentd/reference/typescript/interfaces/stdinack/)>

***

### kill()

```ts
kill(): Promise<boolean>;
```

Signals the whole process group. `false` means nothing was signalled because the
child had already been reaped — which is the outcome a kill wanted.

#### Returns

`Promise`\<`boolean`>

***

### poll()

```ts
poll(): Promise<ExecResult>;
```

Reads current status and output. Read-only server-side; safe to spin on.

#### Returns

`Promise`\<[`ExecResult`](/microvms-agentd/reference/typescript/interfaces/execresult/)>

***

### stream()

```ts
stream(options?: StreamOptionsInput | null): ExecStream;
```

An async iterator over output as it arrives, reconnecting at the last good offset.

`for await (const event of handle.stream())`.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `options?` | [`StreamOptionsInput`](/microvms-agentd/reference/typescript/interfaces/streamoptionsinput/) | `null` |

#### Returns

[`ExecStream`](/microvms-agentd/reference/typescript/classes/execstream/)

***

### wait()

```ts
wait(timeout?: number | null): Promise<ExecResult>;
```

Polls until the exec is done, or rejects with `ERR_TIMEOUT`.

A timeout has not touched the exec — polling is read-only and output lives until it
is acked — so a caller that gives up can come back and poll again.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `timeout?` | `number` | `null` |

#### Returns

`Promise`\<[`ExecResult`](/microvms-agentd/reference/typescript/interfaces/execresult/)>

***

### waitAndAck()

```ts
waitAndAck(timeout?: number | null): Promise<ExecResult>;
```

Wait, then ack, returning the result that carries the output.

Which result comes back matters: the ack response carries the released output and a
poll issued after the ack reports `acked` with none, so returning the wrong one is a
silent empty-output bug. The core sequences it.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `timeout?` | `number` | `null` |

#### Returns

`Promise`\<[`ExecResult`](/microvms-agentd/reference/typescript/interfaces/execresult/)>

***

### writeStdin()

```ts
writeStdin(data: Uint8Array, eof?: boolean | null): Promise<StdinAck>;
```

Writes to the child's stdin. Requires the exec to have been started with
`stdin: true`, or the daemon answers 409.

`eof` in the same call is the common case for feeding a prompt: two round trips would
leave a window where the child has the bytes but not the EOF that says the input is
complete.

#### Parameters

| Parameter | Type |
| ------ | ------ |
| `data` | `Uint8Array` |
| `eof?` | `boolean` | `null` |

#### Returns

`Promise`\<[`StdinAck`](/microvms-agentd/reference/typescript/interfaces/stdinack/)>

## Provenance

This page is generated from `bindings/microvms-js/index.d.ts` by TypeDoc 0.28.20 and typedoc-plugin-markdown 4.13.1, run from `site/scripts/gen-reference.mjs` on every `pnpm run sync`, so an edit made here is overwritten by the next run.

To change the page, change the doc comment in the binding's Rust source, then regenerate the declarations with `mise run dts`. `mise run dts:check` fails when the committed file no longer matches the source.