> ## Documentation Index
> Fetch the complete documentation index at: https://checkfu.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Personal assistant

> A poke-shaped assistant you reach over a messaging channel.

A personal assistant reached over a messaging channel, built exclusively on the public API the way any customer would build one (D115). Every insufficiency it hits is recorded as a public-API gap rather than closed with a private hook.

Source: `examples/personal-assistant` in the repository. The index at `examples/README.md` compares all eight side by side.

## Golden journeys

* Bind an external conversation and connect an app
* Use it safely through draft-then-confirm approvals
* Keep personal memory that stays clamped to its place

## Platform surfaces exercised

Conversation bindings, External identities, `ingestConversation`, ActionApprovals, Budgets, Memory.

## From the source

Reading a parked approval off the event stream — the draft-then-confirm turn starts from a durable event, not from a response body:

```ts path=examples/personal-assistant/src/draft.ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const readRequiresActionApproval = (
	event: SessionEvent,
): { readonly approvalId: string; readonly toolUseId: string } | null => {
	if (event.type !== "run.requires_action") return null
	const payload = event.payload
	if (!isJsonRecord(payload)) return null
	const record = payload.action
	if (!isJsonRecord(record)) return null
	if (jsonField(record, "kind") !== "action_approval") return null
	const approvalId = jsonField(record, "action_approval")
	const toolUseId = jsonField(record, "tool_use_id")
	if (typeof approvalId !== "string" || typeof toolUseId !== "string") return null
	return { approvalId, toolUseId }
}
```

This block is quoted from the file, not retyped: `pnpm agent-docs:check` fails if it drifts.

## Honest gaps

Recorded in `examples/personal-assistant/README.md`. Counts are deliberately not repeated here — they differ per tree, and `examples/README.md` carries them with the sha they were measured at.
