|
|
||
|---|---|---|
| .. | ||
| codegen_templates | ||
| examples | ||
| include | ||
| src | ||
| tests | ||
| build.rs | ||
| Cargo.toml | ||
| cbindgen.toml | ||
| README.md | ||
agent-desktop-ffi
C-ABI cdylib over PlatformAdapter. Exposes
libagent_desktop_ffi.{dylib,so,dll} to Python (ctypes), Swift, Go (cgo),
Node (ffi-napi), and C++ consumers without spawning a CLI subprocess per call.
Build
cargo build --profile release-ffi -p agent-desktop-ffi
The release-ffi profile keeps panic = "unwind", which is required for the
catch_unwind traps that prevent panics from crossing the extern "C" boundary.
Do not use --release — that profile sets panic = "abort", which silently
defeats every trap.
For the CI / stub-adapter path (no AX permission required):
cargo build --profile release-ffi -p agent-desktop-ffi --features stub-adapter
--features stub-adapter replaces the real platform adapter with a no-op that
returns PLATFORM_NOT_SUPPORTED for every adapter call.
ABI Surface
| Group | Key symbols |
|---|---|
| ABI handshake | ad_abi_version(), ad_init(expected_major) |
| Adapter lifecycle | ad_adapter_create(), ad_adapter_create_with_session(id), ad_adapter_destroy() |
| Command-backed JSON entrypoints | ad_snapshot, ad_execute_by_ref, ad_wait, ad_version, ad_status |
| Log callback | ad_set_log_callback(fn(level, msg)) — unstructured tracing to a callback |
| Structured file trace | Same JSONL contract as CLI, gated by a trace: on session manifest (no ABI change); use session start before creating a session adapter |
| Errno last-error | ad_last_error_code(), ad_last_error_message(), ad_last_error_suggestion(), ad_last_error_platform_detail() |
| Type accessors / size getters | ad_*_size(), ad_*_list_{count,get,free}(), ad_image_buffer_*() |
| Free helpers | ad_free_string(), ad_free_handle(), ad_free_tree(), ad_free_action_result() |
The full declaration list is in include/agent_desktop.h.
Consumers must call ad_init(AD_ABI_VERSION_MAJOR) after dlopen to verify the
loaded dylib matches the header the consumer was built against.
Codegen
The 5 command-backed JSON entrypoints (ad_snapshot, ad_execute_by_ref,
ad_wait, ad_version, ad_status) are generated by build.rs from the
template files in codegen_templates/ into
src/commands/generated.rs. Do not hand-edit generated.rs; edit the
corresponding .rs.in template instead. The build panics if a template file
exists in codegen_templates/ but is not registered in build.rs, so stale
templates cannot silently accumulate.
Thread Safety (macOS)
Every adapter-touching entry point must be called from the process's main
thread. The guard fires at runtime in all build profiles; a worker-thread call
returns AD_RESULT_ERR_INTERNAL with a 'static diagnostic string. Operations
safe from any thread: ad_abi_version, ad_init, adapter create/destroy,
ad_last_error_* readers, and all accessor / free helpers.
Error Model
Every AdResult-returning function sets thread-local last-error state on failure.
Read it with ad_last_error_code() / ad_last_error_message() /
ad_last_error_suggestion(). The pointer returned by ad_last_error_message()
stays valid until the next failing call on the same thread — successful calls
leave it untouched (POSIX errno semantics).
Full Documentation
skills/agent-desktop-ffi/ — build-and-link guide, ownership model, threading
rules, and error-handling patterns.