SDK

@actana/sdk is the Core client for Actana Control, and the core-link wire protocol it speaks: frame schema, protocol version, codec, transport. Node 22 or newer. Published with provenance on the same tag as the images — the SDK, CLI, and images of one release move together.

npm install @actana/sdk

Source and the longer README: github.com/actana/control/tree/main/packages/sdk.

Never log credentials. A registration blob holds clientKey, PEMs, and the bearer. Treat it like a private key. The blob is what a paired client holds, not what a human carries.

Pairing

Enrollment is a short pairing code from actana pair new on the Core — not a pasted blob. pairWithCore from @actana/sdk/core-pairing redeems it: fingerprint compared before the code is sent, private key generated locally and never sent. The full walkthrough, including fetchCorePairingIdentity for showing a fingerprint before anything is spent, is SDK Pairing.

Two layers, one socket

import { CoreClient } from "@actana/sdk/core-client";
import { CoreSession } from "@actana/sdk/core-session";

const client = CoreClient.fromRegistrationBlob(blob, { connectTimeoutMs: 15_000 });
await client.connect();

const session = await CoreSession.start(client, {
  projectId,
  cwd,
  harness: "claude-code",
  prompt: "summarise this repo",
});
await session.waitForIdle({ timeoutMs: 300_000 });
console.log(session.screen());

CoreClient connects, authenticates, and correlates frames. It reconnects nothing. A long-lived consumer wants @actana/sdk/durable-core-client (heartbeat, backoff, event cursor). CoreSession starts a Session, lets the Core deliver the prompt, and reads the result. I/O is programmatic — send(text), onData(…), screen() — never a TTY.

Project files are project.files.list / .upload / .download: HTTPS on the same origin, certificate, and bearer as the socket, not the socket itself. Ask client.canUseFileRoutes() first.

See also

Built by Qcentic