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

# Give a personal agent a Chert identity

> Verified CLI and SDK surfaces, safe integration steps, and the capabilities that are still pending.

This guide is for persistent personal-agent products such as OpenClaw, Hermes,
and Muse. A coding agent may integrate Chert into one of those projects; it is
not the personal agent. Chert does not currently provide a universal personal-
agent plugin, always-on host, or unified iMessage/FaceTime identity.

For the temporary integration fallback, see [trychert.com/setup](https://trychert.com/setup).

> [!WARNING]
>
> The beta.10 line-allocation checks were fixture-based, not a live allocation.
> The shared pool was still pending line qualification in the release evidence.
> Do not claim an account, assigned line, delivery, or working call until the
> service response and an explicitly authorized real-world check confirm it.

## Capability status

This YAML is the machine-readable summary for agents. “Verified” describes the
published package/help/fixture or loopback checks listed below; it does not mean
that a real customer line, message, or call was exercised.

```yaml theme={null}
guide_version: 1
audience: persistent-personal-agent-integrator
cli_package: "@trychert/facetime@0.1.0-beta.10"
sdk_package: "@trychert/sdk@0.1.0"
available:
  cli_commands: [login, onboard, new, doctor, dev, "guide fix"]
  sdk_cli: [context, imessage-send, facetime-status, facetime-lines, facetime-workers]
  sdk_imessage_send: "queued receipt; no automatic retry or delivery guarantee"
  facetime_dev: "foreground incoming-call connector; Ctrl+C requests graceful release that must be confirmed"
pending_or_unverified:
  live_owner_verification: true
  live_shared_line_allocation: true
  always_on_personal_agent_service: true
  automatic_restart_and_resume: true
  imessage_watch_or_receive_command: true
  outbound_facetime_start_watch_end: true
  chert_managed_owner_contact_policy: true
  line_allocation_release_command: true
```

## Prerequisites and bootstrap

* A macOS or Linux host and access to the intended Chert project. Native Windows
  is unsupported.
* Node.js 22.12+ (22.x), 24.x, or 26.x for the CLI when using npm/pnpm/npx;
  the bundled starter supports Node 22.23.2 or 24.x. Bun 1.4.0 package commands
  were exercised locally.
* For voice, a registered LiveKit agent and its existing LiveKit project values.
* For the SDK channels, separate iMessage and FaceTime service credentials. A
  shared `CHERT_PROJECT_ID` is context; it does not bind or authorize the two
  credentials together.
* Explicit owner approval before browser/device sign-in, phone verification,
  paid provider activity, messages, or calls.

The following package-resolution and help commands were exercised against the
published packages. At review, npm's `beta` tag pointed to beta.10 while `latest`
pointed to beta.6. Use `@beta` intentionally in npm/Bun commands; do not omit
the tag. The tested `pnpm add @trychert/facetime@beta` resolved beta.6, so the
pnpm example pins beta.10 explicitly.

```bash theme={null}
npm install @trychert/facetime@beta @trychert/sdk@0.1.0
pnpm add @trychert/facetime@0.1.0-beta.10 @trychert/sdk@0.1.0
bun add @trychert/facetime@beta @trychert/sdk@0.1.0
npx --yes --package @trychert/facetime@beta chert --help
bunx --yes --package @trychert/facetime@beta chert --help
npx --yes --package @trychert/sdk@0.1.0 chert-sdk --help
bunx --yes --package @trychert/sdk@0.1.0 chert-sdk --help
```

The Chert CLI includes these supported entry points:

```bash theme={null}
bunx --yes --package @trychert/facetime@beta chert login
bunx --yes --package @trychert/facetime@beta chert onboard --skip-demo --no-browser --json --wait 0
bunx --yes --package @trychert/facetime@beta chert new my-agent
bunx --yes --package @trychert/facetime@beta chert doctor --json
bunx --yes --package @trychert/facetime@beta chert dev --agent AGENT_NAME --json
bunx --yes --package @trychert/facetime@beta chert guide fix
```

`login` approves one project for this computer. Use it for an existing project.
Use `onboard` only for a new setup after the owner approves the phone-verification
step. A human must complete the browser and send any displayed verification
code; an agent must not send it, ask the owner to paste it into chat, or claim
verification succeeded while the command is pending. `--skip-demo` skips the
hosted demo request, not verification or line allocation. If the service cannot
allocate a line, stop and report that exact result. Do not create a second
onboarding to retry an uncertain request.

`new` creates a generic LiveKit voice-agent starter; it does not integrate an
existing OpenClaw, Hermes, Muse, or other personal-agent runtime. It refuses to
overwrite a non-empty target. A clean starter's `npm start` is separate from
`chert dev`; neither command installs an always-on service.

## Temporary generated wrapper

Until a universal personal-agent CLI ships, an integrating coding agent may
create a project-local wrapper in a new, empty directory. The names below are
**commands generated in that project**, not commands supplied by Chert:

| Local wrapper command | Safe contract |
| - | - |
| `setup` | Inspect the explicit brief and relevant project files, summarize the intended files and behavior, and wait for approval before writing. Reuse the authenticated project, assigned line, and existing LiveKit environment. |
| `start` | Start the selected personal-agent runtime and the foreground `chert dev` connector only after setup and health checks. It is not an always-on supervisor. |
| `health` | Run read-only `chert doctor --json` and available SDK identity/line/worker reads. Report identity separately from media readiness. |
| `message` | Send only after explicit approval of recipient and body. Use `ChertClient.sendText` or `chert-sdk imessage send`; a `queued` receipt is not delivery. |
| `call` | No outbound call method is available in the published SDK. Return a structured `capability_pending` result; never invent an endpoint or start a call. Incoming calls are handled by `chert dev` when a ready line exists. |
| `watch` / `status` | `status` may report `doctor`, identity, lines, workers, and local process state. A wrapper may relay events from its own `chert dev --json` process for incoming FaceTime calls; there is no SDK iMessage inbox watcher or remote FaceTime call watch API. |
| `stop` | Send one SIGINT to wrapper-owned `chert dev`, then wait for confirmed binding release. `release_failed` or retained cleanup is not a release. This does not unassign the phone number/shared allocation. |

`chert dev --json` emits newline-delimited JSON records with
`schema_version: 1` and `command: "dev"`. Call events include `call_incoming`,
`call_accepted`, `call_declined`, `call_ended`, `call_media`, and
`call_bridge_ready`. The last means Chert wrote the bridge-ready room signal;
it is not proof that audio/video worked or that the caller heard the agent.
Session records include `dev_ready`, `dev_stopped`, `cleanup_pending`, and
`release_failed`. On shutdown, a second interrupt reports that release is still
underway; a third can exit without releasing. Do not claim cleanup until the
terminal record confirms it.

The wrapper should use a project-local `chert-agent` executable (for example,
`./chert-agent health`) and emit JSON Lines with a documented schema. That output
schema is local to the generated project, not a Chert API guarantee. Persist only
non-secret project/line/agent identifiers and stable idempotency keys in an
owner-only state file. Reuse `~/.chert` and the same onboarding intent. Automatic
service restart, durable message watching, and recovery after host reboot remain
unverified; do not promise them or invent a supervisor integration.

## Secrets, consent, and identity

Create or edit `.env.local` locally and require mode `0600`. Add `.env.local` and
`.env*` to `.gitignore` before writing secrets. Keep `LIVEKIT_API_SECRET`,
`OPENAI_API_KEY`, `CHERT_API_KEY`, `CHERT_FACETIME_TOKEN`, and all login/device
credentials out of prompts, command arguments, stdout/stderr, screenshots, logs,
and version control. Never print an env file to diagnose it; report variable
names and whether values are present, not their values.

The CLI login credential, iMessage API key, FaceTime token, and LiveKit API
secret are different credentials. The SDK's project ID is context only for the
iMessage client. No Chert-managed owner-contact allowlist or cross-channel
consent policy is currently provided. The personal-agent application must derive
its persona and handlers from the owner's explicit brief and relevant repository,
and enforce the approved recipient/contact policy locally.

Before every real outbound message or call, show the exact recipient, content or
call purpose, and expected cost/impact, then wait for that action's explicit
confirmation. Setup consent is not send/call consent. `doctor --agent` dispatches
a real agent job; ask before using it. Do not test against a real person or line
without approval.

## Project, line, and LiveKit lifecycle

Choose the project the owner approved. `chert login` signs this computer into
that project. `chert-sdk facetime lines` and `workers` inspect existing access;
they do not assign a line. `chert doctor --json` checks readiness predicates,
but a healthy response does not prove two-way media. A project must already have
the eligible line and worker required by `chert dev`.

Run the personal agent using its own supported host/runtime. Put its LiveKit
values in the same project's `.env.local`; Chert does not start or deploy the
personal agent. Start the foreground connector with `chert dev --agent NAME --json`. It handles incoming calls on an assigned line. It is not an outbound
FaceTime call command and is not a background service. The owner must accept or
place a real test call only after explicit confirmation. Audio/video success must
be confirmed during the call, not inferred from identity, health, or connection
status.

For shutdown, send SIGINT/Ctrl+C to the wrapper-owned `chert dev` process and
wait for its terminal `dev_stopped` record. Preserve state if it reports
`cleanup_pending` or `release_failed`. This drains the connector when cleanup is
confirmed; it does not release the project allocation or phone number. There is
no verified CLI command to release that allocation; ask the project owner/admin.

## iMessage and FaceTime API boundaries

The SDK CLI reads existing FaceTime identity, lines, and workers:

```bash theme={null}
chert-sdk context
chert-sdk facetime status
chert-sdk facetime lines
chert-sdk facetime workers
```

`facetime status` checks identity, not media readiness. There is no published
SDK call-start, call-watch, or call-end method. `chert dev` is the supported
incoming-call connector path when its line is ready.

An explicitly approved iMessage send may use:

```bash theme={null}
chert-sdk imessage send --phone +15555550123 --body "Approved message" --idempotency-key stable-request-id
```

This returns a strict HTTP 202 `queued` receipt. It means accepted for queueing,
not sent, delivered, or read. The client does not retry automatically. On timeout
or an unconfirmed response, preserve the same idempotency key and reconcile with
the service/operator before trying again. The published CLI has no generic
iMessage `watch` or `receive` command; do not poll guessed endpoints or infer
delivery from queue acceptance.

## Structured output and recovery

`chert --json` emits one JSON record per line with `schema_version: 1` and
`command`; `chert dev --json` is an event stream. Errors go to stderr as
structured codes/actions. SDK channel commands emit JSON objects by default and
sanitize errors. The local wrapper should preserve these streams, never parse
human prose as a success signal, and keep its own stdout schema separate.

| Error/state | Action |
| - | - |
| `login_required` | Pause for owner browser/device approval; do not request or store a browser token in chat. |
| `forbidden` | Check `chert whoami`; ask the project owner/admin to grant the correct role. |
| `line_in_use`, `line_in_call` | Wait for the current holder/call. Do not use takeover without explicit admin approval. |
| `line_paused`, `shared_line_paused`, `shared_allocation_inactive`, `worker_unavailable` | Stop and ask the owner/admin to resolve readiness. Preserve onboarding state; do not create another allocation or force a call. |
| `cleanup_pending`, `release_failed` | Preserve local state and stop new calls; ask the owner/admin to verify cleanup. |
| `unconfirmed_text_outcome` | Do not send again automatically. Reconcile the original request with its same idempotency key. |

For diagnostics, begin with `chert guide fix` and `chert doctor --json`. Capture
timestamps, command names, project/line IDs only when safe, error codes, and
redacted event records. Redact phone numbers, message bodies, tokens, URLs with
credentials, `.env.local`, and provider responses. Never attach raw process
environments or unfiltered logs.

## Ready-to-paste integrator prompt

```text theme={null}
Integrate Chert as an identity/communications layer for my persistent personal
agent. The personal agent (for example OpenClaw, Hermes, or Muse) is the product;
you are only the one-time coding integrator. Use only my explicit brief and the
relevant repository. Do not scrape unrelated conversation, environment files,
credentials, or absolute project paths. First inspect the target: if it is not
empty, make an additive integration plan and do not overwrite files. If it is
empty, show me the planned files and behavior and wait for approval before
writing a project-local `chert-agent` wrapper CLI.

Use the verified packages only: `@trychert/facetime@beta` for `login`,
`onboard`, `new`, `doctor`, and `dev`; use `@trychert/sdk` for its existing
iMessage send and FaceTime identity/line/worker methods. Do not claim the SDK
provides iMessage receive/watch or FaceTime call start/watch/end. The generated
wrapper must expose `setup`, `start`, `health`, `message`, `call`, `status`,
`watch`, and `stop`; unsupported call/watch behavior must return a structured
pending result without contacting an invented endpoint.

Reuse the owner's existing Chert project, assigned line, and LiveKit project.
Use `chert login` for an existing project. Start `chert onboard --skip-demo`
only after I approve browser/phone verification; stop for me to complete any
human step, and resume the same onboarding rather than creating another. If no
line is actually returned and healthy, stop and report that. Do not infer
allocation from a successful install or fixture result.

Derive persona, contact policy, and handlers only from my explicit brief and
relevant project files. Keep the personal agent's existing runtime and identity.
Create `.env.local` only after showing planned files; enforce mode 0600 and
`.gitignore`. I will enter LiveKit/OpenAI/Chert secrets locally. Never print,
echo, log, transmit, screenshot, commit, or ask me to paste secrets into chat.
Persist only non-secret project/line/agent state and stable idempotency keys;
preserve `~/.chert` and recover the same onboarding after timeouts.

Require a fresh explicit confirmation immediately before each real outbound
message or call, showing exact recipient and content/purpose. A queued message is
not delivery. Do not retry an uncertain send automatically. `chert dev` only
connects an existing LiveKit agent for incoming calls; it is foreground, not an
always-on service. Do not invent service-manager, inbox-watcher, outbound-call,
or line-release commands. Run read-only health checks first, preserve structured
JSON/events, redact logs, and report every capability that remains pending.
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.