@ai-hands/gateway-sdk
v0.1.1
Published
TypeScript SDK for AI Hands Gateway
Readme
AI Hands Gateway TypeScript SDK
TypeScript/Node.js SDK for interacting with the AI Hands Gateway.
Installation
From npm (when published)
npm install @ai-hands/gateway-sdk
# or
yarn add @ai-hands/gateway-sdk
# or
pnpm add @ai-hands/gateway-sdkFrom source (development)
# Clone the repository
git clone https://github.com/ChainbotAI/ai-hands-gateway.git
cd ai-hands-gateway/sdk/typescript
# Install dependencies
npm install
# Build
npm run build
# Link for local development
npm link
# In your project
npm link @ai-hands/gateway-sdkUsage
Basic Usage
import { GatewayClient } from '@ai-hands/gateway-sdk';
// Create client
const client = new GatewayClient({
endpoint: 'gateway.example.com:8443',
auth: {
username: 'admin',
password: 'secret',
},
});
// List online devices
const devices = await client.listDevices();
console.log('Online devices:', devices);
// Execute command on a device
const result = await client.exec({
deviceId: 'device-uuid-here',
command: 'echo "Hello, World!"',
});
console.log('Output:', result.stdout.toString());
console.log('Exit code:', result.exitCode);
// Close client when done
client.close();Device Binding Flow
The device binding flow allows users to securely bind devices to their accounts:
import { GatewayClient } from '@ai-hands/gateway-sdk';
const client = new GatewayClient({
endpoint: 'gateway.example.com:8443',
auth: { username: 'admin', password: 'secret' },
});
// Bind a device using the binding code displayed on the device
const bindResult = await client.bindDevice({
bindingCode: 'ABCD-1234-EFGH', // Code shown on device terminal
userId: 'user-123',
deviceName: 'My MacBook Pro', // Optional friendly name
});
if (bindResult.ok) {
console.log('Device bound successfully!');
console.log('Device ID:', bindResult.deviceId);
console.log('Short ID:', bindResult.shortId); // e.g., "a1b2c3d4"
} else {
console.error('Binding failed:', bindResult.error);
}
// List user's devices
const userDevices = await client.listUserDevices({
userId: 'user-123',
includeOffline: true,
});
console.log('User devices:', userDevices.devices);
console.log('Online status:', userDevices.online);
// Unbind a device
await client.unbindDevice({
deviceId: 'a1b2c3d4', // Can use short_id or full device_id
userId: 'user-123',
});
// Delete a device completely
await client.deleteDevice({
deviceId: 'a1b2c3d4',
userId: 'user-123',
});File Operations
// Read a file from a device
const content = await client.readFile({
deviceId: 'device-uuid',
path: '/etc/hostname',
});
console.log('File content:', content.toString());
// Write a file to a device
const writeResult = await client.writeFile({
deviceId: 'device-uuid',
path: '/tmp/hello.txt',
data: Buffer.from('Hello, World!\n'),
mode: 0o644,
});
if (writeResult.ok) {
console.log('File written, SHA256:', writeResult.sha256);
} else {
console.error('Write failed:', writeResult.error);
}Next.js API Route Example
// app/api/devices/route.ts
import { NextResponse } from 'next/server';
import { GatewayClient } from '@ai-hands/gateway-sdk';
const client = new GatewayClient({
endpoint: process.env.GATEWAY_ENDPOINT!,
auth: {
username: process.env.GATEWAY_USERNAME!,
password: process.env.GATEWAY_PASSWORD!,
},
});
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const userId = searchParams.get('userId');
if (!userId) {
return NextResponse.json({ error: 'userId required' }, { status: 400 });
}
try {
const result = await client.listUserDevices({
userId,
includeOffline: true,
});
return NextResponse.json(result);
} catch (error) {
return NextResponse.json({ error: String(error) }, { status: 500 });
}
}
// POST /api/devices/bind
export async function POST(request: Request) {
const body = await request.json();
const { bindingCode, userId, deviceName } = body;
try {
const result = await client.bindDevice({
bindingCode,
userId,
deviceName,
});
return NextResponse.json(result);
} catch (error) {
return NextResponse.json({ error: String(error) }, { status: 500 });
}
}API Reference
GatewayClient
Constructor
new GatewayClient(config: GatewayClientConfig)endpoint: Gateway address (host:port)auth: Optional Basic Auth credentialsuseTls: Use TLS (default: auto-detect from endpoint)timeoutMs: Request timeout (default: 30000)
Methods
| Method | Description |
|--------|-------------|
| listDevices(tags?) | List all online devices |
| exec(request) | Execute a command on a device |
| readFile(request) | Read a file from a device |
| writeFile(request) | Write a file to a device |
| bindDevice(request) | Bind a device using binding code |
| unbindDevice(request) | Unbind a device from user |
| deleteDevice(request) | Delete a device completely |
| listUserDevices(request) | List devices for a user |
| close() | Close the client connection |
Environment Variables
When using with Next.js, set these in your .env.local:
GATEWAY_ENDPOINT=gateway.example.com:8443
GATEWAY_USERNAME=admin
GATEWAY_PASSWORD=your-secret-passwordPublishing (Maintainers)
SDK 版本号跟随 Gateway 的「主.次」版本,「补丁」版本独立维护。
Setup (First time)
- Create npm organization
ai-handsat https://www.npmjs.com/org/create - Configure OIDC trusted publishing on npm:
- Go to package settings on npmjs.com
- Add trusted publisher with:
- Repository:
ChainbotAI/ai-hands-gateway - Workflow:
publish-ts-sdk.yml - Environment: (leave empty)
- Repository:
Release
# Tag format: sdk/v{major}.{minor}.{patch}
git tag sdk/v0.1.0
git push origin sdk/v0.1.0GitHub Actions will automatically build and publish to npm via OIDC (no token management needed).
License
MIT
