# CLI and SDK

Use BytesMap over HTTP or through a native local host.

BytesMap has one operation catalogue and one implementation behind its HTTP SDK,
native SDK, CLI and MCP tools. See [architecture](https://github.com/oblien/bytesmap/blob/main/docs/architecture.md) for ownership.

## Install the CLI

```sh
npm install -g bytesmap
bytesmap --help
```

The CLI needs Bun 1.3.1+; npm installation also needs Node.js 22+ and npm 11+.
Use `npm install -g npm@11` to upgrade an older npm version. npm 10 can fail
while resolving the package's optional peer dependencies.
On macOS or Linux, the one-line installer installs the CLI and supplies a
verified private Bun runtime when a compatible one is not already available:

```sh
curl -fsSL https://get.bytesmap.com | sh
```

The installer uses the public `bytesmap` npm package. It installs into
`~/.bytesmap/install`, links the command in `~/.local/bin` if that path is free,
and prints a PATH instruction when needed. It does not alter shell profiles,
workspace data, or system runtimes. A failed package install preserves the
previous working release. Set `BYTESMAP_VERSION` on `sh` to pin a release:

```sh
curl -fsSL https://get.bytesmap.com | BYTESMAP_VERSION=0.1.1 sh
```

`BYTESMAP_INSTALL_DIR` and `BYTESMAP_BIN_DIR` accept absolute custom paths.
`BYTESMAP_PACKAGE_FILE` accepts a locally built `.tgz` for release verification.

## Build or use the CLI in this checkout

Use the Bun version in `.bun-version` and Node 22+ for dashboard/package checks.

```sh
bun install --frozen-lockfile
bun run cli dashboards list --schema
bun run build:sdk
bun run --cwd packages/bytesmap test:package
```

`packages/bytesmap` builds the distributable `bytesmap` package. A local release
build produces `dist/release/bytesmap-<version>.tgz`, installable with
`bun install -g /path/to/archive.tgz`. No npm publication is required to use it.

## Remote workspace

Create an API key in Settings, granting the resources/actions the integration needs.
Pipe the key to login using your secret manager or set `BYTESMAP_API_TOKEN`:

```sh
bytesmap login --name production --url https://api.example.com --token-stdin
bytesmap context list
bytesmap context use production
bytesmap dashboards list
bytesmap queries create --schema
bytesmap queries create --input query.json
bytesmap queries run --input run.json
bytesmap audit list --input activity-filter.json
```

Each catalogue module is a CLI group; camelCase methods use kebab-case command
names. `--input -` reads JSON from stdin. `--schema` prints accepted input without
opening any connection. JSON output follows the SDK contract; report exports
include filename, content type and base64 content. Ctrl+C cancels the active call.

Global `--context`, `--url`, and `--organization` select the connection/scope.
Environment alternatives are `BYTESMAP_API_URL`, `BYTESMAP_API_TOKEN`, and
`BYTESMAP_ORGANIZATION_ID`. Overriding the API URL cannot send a saved key to a
different origin. Remote URLs require HTTPS; loopback permits HTTP.

Config defaults to `~/.bytesmap/cli.json` (override with
`BYTESMAP_CLI_CONFIG`) and is written atomically with private permissions. Context
listing omits credentials. `bytesmap logout [name]` removes a saved connection;
revoke its API key in Settings to invalidate the credential itself.

API keys remain workspace-bound and intersect with the owner's current access.
They cannot manage team/account/key authority or outbound notification settings.
Those methods require an authenticated account/device session, even though the
catalogue lists them. Remote CLI browser sign-in is not implemented yet.

## Connect an agent to the running desktop

Create a **Selected resources** API key in Desktop Settings, including **MCP
connection → View** and an expiry. Then save it without a key in the arguments:

```sh
bytesmap login --desktop --name desktop-agent --token-stdin
bytesmap --context desktop-agent mcp --desktop
```

The second command serves newline-delimited MCP over stdin/stdout. Configure it
as an MCP stdio command in your client; it is not an interactive command prompt.
The CLI verifies the current desktop identity before sending its scoped key and
tracks port changes through the private discovery record. The saved context
contains no transient port or desktop owner capability. Remote/native contexts
are separate; desktop contexts do not open REST/account routes or the metadata
store. See [MCP](https://bytesmap.com/docs/agents/mcp.md#desktop-clients-using-stdio) for client configuration,
limits, restart behavior and revocation.

## Local workspace without HTTP

```sh
bytesmap native init --name local --directory /absolute/path/to/new-workspace
bytesmap dashboards list
bytesmap native connect --name existing --directory /absolute/path/to/existing-workspace
```

Initialization requires a new directory. It saves the host encryption secret in
`bytesmap-host.json`, creates metadata under `data/`, applies migrations, and pins
the local user. Back up both the host file and data together. Logging out never
deletes either. Reopening a store never silently chooses or promotes another user.

Embedded PGlite is exclusive to one process. To use several clients concurrently,
run an API and connect over HTTP; use PostgreSQL metadata for separate API/worker
processes. Native CLI commands close their engine/store after each call. Scheduled
workflow runs and dashboard deliveries require a long-lived API scheduler or report worker.

## HTTP SDK

```ts
import { createClient } from 'bytesmap'

const client = createClient({
  baseURL: 'https://api.example.com',
  token: () => process.env.BYTESMAP_API_TOKEN!,
})
const { dashboards } = await client.dashboards.list()
const controller = new AbortController()
const result = await client.queries.run({ id: 'saved-query-id' }, { signal: controller.signal })
```

Browser sessions can use `credentials: 'include'`. `client.scope(workspaceId)`
selects an allowed workspace; it cannot widen a key's binding. Methods accept
typed input and return the same public JSON as native calls. `BytesMapError`
contains `code`, `params` and HTTP `status`.

For a SaaS integration, connect directly to the owning API and set `projectId`
alongside your workspace-scoped token. Project scope can also be supplied per call.
Keep account/API tokens on your server; browser event ingestion uses the separate
dataset append-only key from `bytesmap/events`. The SDK does not follow HTTP
redirects or automatically retry mutations. Point it at the final API origin and
reuse the same request key when retrying an idempotent workflow operation.

## Native SDK in a trusted host

```ts
import { openLocalHost, createNativeClient } from 'bytesmap/native'

const local = await openLocalHost({
  directory: metadataDirectory,
  secret: persistedHostSecret,
})
try {
  const client = createNativeClient({
    platform: local.host,
    identity: { resolve: verifyHostSession },
  }).scope({ identity: sessionHandle, organizationId: selectedWorkspaceId })
  const { queries } = await client.queries.list()
} finally {
  await local.close()
}
```

`verifyHostSession` is host code that verifies the supplied assertion and returns
a `VerifiedIdentity` on every operation. It cannot trust renderer-supplied users,
roles or organization claims. The CLI's local device adapter lives in the trusted
process; do not expose that adapter directly to a renderer or model.

Hosts with an already-open metadata database can use `createNativeHost` after
migration. Host-specific secrets, invitation delivery and mail adapters are
injectable. Both clients expose sources, servers, queries, charts, dashboards,
flows, actions, views, schedules, reports, reporting, notifications, permissions, tokens and audit.
CLI and MCP discovery expose one canonical Views authoring family. The retained `panels.*`
SDK methods and `/api/panels` routes are compatibility aliases over the same stored definitions.

Saving or editing definitions never runs data queries. Run, preview, report export
and refresh remain separate operations with source execution checks. Discovery
and connection tests contact the source as their own explicit operations.

The desktop shell and Mindwire UI/runtime are later consumers of this boundary.
See [MCP](https://bytesmap.com/docs/agents/mcp.md), [identity](https://bytesmap.com/docs/workspace/access.md) and [releases](https://github.com/oblien/bytesmap/blob/main/docs/releases.md).
