Skip to content

SDKs

If you want to wire your own tools into Clessira, the official SDKs take care of HMAC signing, nonce handling, and error mapping. There are two packages — both are thin wrappers around the HTTP API:

  • @clessira/sdk on npm — TypeScript, ESM + CJS, runs on Node ≥ 20, Bun, and Deno.
  • clessira-sdk on PyPI — Python ≥ 3.10, with both a sync and an async client; the only runtime dependency is httpx.

Both SDKs talk over the HTTP API, so you need to enable it first — see HTTP API. Pass the token and port to the constructor, or set them as environment variables:

Terminal window
export CLESSIRA_TOKEN=""
export CLESSIRA_PORT=39847 # optional, default

Install:

Terminal window
npm install @clessira/sdk

Example:

import { ClessiraClient } from "@clessira/sdk";
const client = new ClessiraClient();
await client.healthcheck();
const status = await client.getStatus();
console.log(
status.isTracking
? `${status.currentActivity?.activityName} running (${status.todaySeconds}s today)`
: "Nothing running.",
);
await client.startActivity({ name: "Refactor", createIfMissing: true });
await client.logEntry({
name: "Standup",
durationMinutes: 15,
note: "Daily",
createIfMissing: true,
});
await client.stopActivity();
await client.notifyBranchChange({
branch: "feature/sdk-rewrite",
repo: "clessiramac",
previousBranch: "main",
});

Browser usage is intentionally unsupported — the listener binds to loopback, and most browsers refuse CORS to 127.0.0.1.

Install:

Terminal window
pip install clessira-sdk

Sync client:

from clessira import ClessiraClient
with ClessiraClient() as client:
client.healthcheck()
status = client.get_status()
if status.is_tracking and status.current_activity:
print(f"{status.current_activity.activity_name} running ({status.today_seconds}s today)")
else:
print("Nothing running.")
client.start_activity(name="Refactor", create_if_missing=True)
client.log_entry(
name="Standup",
duration_minutes=15,
note="Daily",
create_if_missing=True,
)
client.stop_activity()
client.notify_branch_change(
branch="feature/sdk-rewrite",
repo="clessiramac",
previous_branch="main",
)

For async, use AsyncClessiraClient:

import asyncio
from clessira import AsyncClessiraClient
async def main() -> None:
async with AsyncClessiraClient() as client:
current = await client.get_current()
print(current)
asyncio.run(main())

Both SDKs cover the same eight endpoints:

Method (JS / Python)Endpoint
healthcheck() / healthcheck()GET /healthcheck
getCurrent() / get_current()GET /current
getStatus() / get_status()GET /status
searchActivities(q) / search_activities(q)GET /activities/search
startActivity({…}) / start_activity(…)POST /activities/start
stopActivity() / stop_activity()POST /activities/stop
logEntry({…}) / log_entry(…)POST /entries
notifyBranchChange({…}) / notify_branch_change(…)POST /branch-changed

All HTTP failures map to typed exceptions that inherit from ClessiraError:

StatusClassTypical cause
400ClessiraValidationErrorBad payload (e.g. empty branch, durationMinutes ≤ 0).
401ClessiraAuthErrorWrong or missing token, or bad signature.
404ClessiraNotFoundErrorActivity UUID or name unknown.
409ClessiraReplayErrorNonce already used in the last 180 s.
423ClessiraHttpErrorClessira is locked (no valid license).
503ClessiraUnavailableErrorEndpoint handler not wired in the app.
otherClessiraHttpErrorAnything else (incl. 5xx).

Both SDKs live in the Clessira/sdk monorepo and are published to npm / PyPI from GitHub Actions on tag. File bugs and feature requests there.