repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | // API client for admin endpoints |
| #2 | // Authentication is handled by Cloudflare Access (JWT in cookies) |
| #3 | |
| #4 | const API_BASE = '/api/admin'; |
| #5 | |
| #6 | export interface PendingDevice { |
| #7 | requestId: string; |
| #8 | deviceId: string; |
| #9 | displayName?: string; |
| #10 | platform?: string; |
| #11 | clientId?: string; |
| #12 | clientMode?: string; |
| #13 | role?: string; |
| #14 | roles?: string[]; |
| #15 | scopes?: string[]; |
| #16 | remoteIp?: string; |
| #17 | ts: number; |
| #18 | } |
| #19 | |
| #20 | export interface PairedDevice { |
| #21 | deviceId: string; |
| #22 | displayName?: string; |
| #23 | platform?: string; |
| #24 | clientId?: string; |
| #25 | clientMode?: string; |
| #26 | role?: string; |
| #27 | roles?: string[]; |
| #28 | scopes?: string[]; |
| #29 | createdAtMs: number; |
| #30 | approvedAtMs: number; |
| #31 | } |
| #32 | |
| #33 | export interface DeviceListResponse { |
| #34 | pending: PendingDevice[]; |
| #35 | paired: PairedDevice[]; |
| #36 | raw?: string; |
| #37 | stderr?: string; |
| #38 | parseError?: string; |
| #39 | error?: string; |
| #40 | } |
| #41 | |
| #42 | export interface ApproveResponse { |
| #43 | success: boolean; |
| #44 | requestId: string; |
| #45 | message?: string; |
| #46 | stdout?: string; |
| #47 | stderr?: string; |
| #48 | error?: string; |
| #49 | } |
| #50 | |
| #51 | export interface ApproveAllResponse { |
| #52 | approved: string[]; |
| #53 | failed: Array<{ requestId: string; success: boolean; error?: string }>; |
| #54 | message?: string; |
| #55 | error?: string; |
| #56 | } |
| #57 | |
| #58 | export class AuthError extends Error { |
| #59 | constructor(message: string) { |
| #60 | super(message); |
| #61 | this.name = 'AuthError'; |
| #62 | } |
| #63 | } |
| #64 | |
| #65 | async function apiRequest<T>( |
| #66 | path: string, |
| #67 | options: globalThis.RequestInit = {} |
| #68 | ): Promise<T> { |
| #69 | const response = await fetch(`${API_BASE}${path}`, { |
| #70 | ...options, |
| #71 | credentials: 'include', |
| #72 | headers: { |
| #73 | 'Content-Type': 'application/json', |
| #74 | ...options.headers, |
| #75 | }, |
| #76 | } as globalThis.RequestInit); |
| #77 | |
| #78 | if (response.status === 401) { |
| #79 | throw new AuthError('Unauthorized - please log in via Cloudflare Access'); |
| #80 | } |
| #81 | |
| #82 | const data = await response.json() as T & { error?: string }; |
| #83 | |
| #84 | if (!response.ok) { |
| #85 | throw new Error(data.error || `API error: ${response.status}`); |
| #86 | } |
| #87 | |
| #88 | return data; |
| #89 | } |
| #90 | |
| #91 | export async function listDevices(): Promise<DeviceListResponse> { |
| #92 | return apiRequest<DeviceListResponse>('/devices'); |
| #93 | } |
| #94 | |
| #95 | export async function approveDevice(requestId: string): Promise<ApproveResponse> { |
| #96 | return apiRequest<ApproveResponse>(`/devices/${requestId}/approve`, { |
| #97 | method: 'POST', |
| #98 | }); |
| #99 | } |
| #100 | |
| #101 | export async function approveAllDevices(): Promise<ApproveAllResponse> { |
| #102 | return apiRequest<ApproveAllResponse>('/devices/approve-all', { |
| #103 | method: 'POST', |
| #104 | }); |
| #105 | } |
| #106 | |
| #107 | export interface RestartGatewayResponse { |
| #108 | success: boolean; |
| #109 | message?: string; |
| #110 | error?: string; |
| #111 | } |
| #112 | |
| #113 | export async function restartGateway(): Promise<RestartGatewayResponse> { |
| #114 | return apiRequest<RestartGatewayResponse>('/gateway/restart', { |
| #115 | method: 'POST', |
| #116 | }); |
| #117 | } |
| #118 | |
| #119 | export interface StorageStatusResponse { |
| #120 | configured: boolean; |
| #121 | missing?: string[]; |
| #122 | lastSync: string | null; |
| #123 | message: string; |
| #124 | } |
| #125 | |
| #126 | export async function getStorageStatus(): Promise<StorageStatusResponse> { |
| #127 | return apiRequest<StorageStatusResponse>('/storage'); |
| #128 | } |
| #129 | |
| #130 | export interface SyncResponse { |
| #131 | success: boolean; |
| #132 | message?: string; |
| #133 | lastSync?: string; |
| #134 | error?: string; |
| #135 | details?: string; |
| #136 | } |
| #137 | |
| #138 | export async function triggerSync(): Promise<SyncResponse> { |
| #139 | return apiRequest<SyncResponse>('/storage/sync', { |
| #140 | method: 'POST', |
| #141 | }); |
| #142 | } |
| #143 |