diff --git a/packages/tools/official/unsandbox/block.ts b/packages/tools/official/unsandbox/block.ts index 827f026..5b6a915 100644 --- a/packages/tools/official/unsandbox/block.ts +++ b/packages/tools/official/unsandbox/block.ts @@ -3,10 +3,6 @@ * This file provides metadata for the blocks validator */ import { - addContact, - boostSession, - checkServicePort, - cloneImage, cloneSnapshot, // Service tools createService, @@ -27,20 +23,15 @@ import { executeCodeAsync, executeInService, executeInSession, - exportServiceEnv, - extendSession, freezeService, freezeSession, - getAuditLog, getClusterStatus, getImage, getImageTrustedKeys, // Job tools getJob, - getKeyInfo, // Languages tools getLanguages, - getPoolStats, getService, getServiceEnv, getServiceLogs, @@ -48,55 +39,37 @@ import { getShells, getSnapshot, getSystemStats, - getUpgradeLogs, - getUpgradeProgress, grantImageAccess, // System tools healthCheck, - listContacts, listImages, listJobs, - listOwnedImages, listPools, - listPublicImages, listServices, listSessions, - listSharedImages, listSnapshots, - listTokens, lockImage, lockService, lockSession, lockSnapshot, - mintToken, // Image tools publishImage, redeployService, - removeContact, - restoreService, restoreSession, restoreSnapshot, revokeImageAccess, - revokeToken, run, runAsync, setImageVisibility, setServiceEnv, spawnFromImage, transferImage, - unboostSession, unfreezeService, unfreezeSession, unlockImage, unlockService, unlockSession, unlockSnapshot, - updateContact, - updateKeySettings, - updateService, - updateServiceDomains, - // API Key tools - validateKey, } from './src/index.js'; export const block = { @@ -127,9 +100,6 @@ export const block = { createSessionSnapshot, restoreSession, deleteSession, - extendSession, - boostSession, - unboostSession, // Service tools createService, getService, @@ -146,13 +116,6 @@ export const block = { setServiceEnv, deleteServiceEnv, deleteService, - updateService, - checkServicePort, - getUpgradeProgress, - getUpgradeLogs, - updateServiceDomains, - exportServiceEnv, - restoreService, // Snapshot tools createSnapshot, getSnapshot, @@ -175,29 +138,11 @@ export const block = { spawnFromImage, getImageTrustedKeys, deleteImage, - listOwnedImages, - listSharedImages, - listPublicImages, - cloneImage, // System tools healthCheck, getClusterStatus, getSystemStats, listPools, - getPoolStats, - // API Key tools - validateKey, - getKeyInfo, - updateKeySettings, - listContacts, - addContact, - updateContact, - removeContact, - getAuditLog, - // Live Token tools - mintToken, - revokeToken, - listTokens, }, }; diff --git a/packages/tools/official/unsandbox/package.json b/packages/tools/official/unsandbox/package.json index 386998a..aa3bece 100644 --- a/packages/tools/official/unsandbox/package.json +++ b/packages/tools/official/unsandbox/package.json @@ -126,21 +126,6 @@ "name": "deleteSession", "description": "Delete a session and release all associated resources." }, - { - "name": "extendSession", - "description": "Add additional time to a session's TTL.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "boostSession", - "description": "Increase session vCPU and memory. Each vCPU includes 2GB RAM.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "unboostSession", - "description": "Return session to base vCPU and memory allocation.", - "healthCheck": { "skipExecution": true } - }, { "name": "createService", "description": "Create a long-running service with persistent state, networking, and auto-restart capabilities." @@ -201,41 +186,6 @@ "name": "deleteService", "description": "Delete a service and release all associated resources." }, - { - "name": "updateService", - "description": "Update service settings: vCPU resize, auto-unfreeze on HTTP, or freeze page display.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "checkServicePort", - "description": "Check if a specific port is listening inside the service container.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "getUpgradeProgress", - "description": "Get OS upgrade progress including state, percentage, and version chain.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "getUpgradeLogs", - "description": "Get OS upgrade log output for a service.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "updateServiceDomains", - "description": "Manage custom domain names for a service (replace, add, or remove domains).", - "healthCheck": { "skipExecution": true } - }, - { - "name": "exportServiceEnv", - "description": "Export all environment variables as a .env formatted string.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "restoreService", - "description": "Restore a service to a previous snapshot state.", - "healthCheck": { "skipExecution": true } - }, { "name": "createSnapshot", "description": "Create a snapshot from any source (session, service, or existing snapshot)." @@ -316,23 +266,6 @@ "name": "deleteImage", "description": "Delete an image and free associated storage." }, - { - "name": "listOwnedImages", - "description": "List only images owned by the authenticated API key." - }, - { - "name": "listSharedImages", - "description": "List images shared with you via trusted_keys." - }, - { - "name": "listPublicImages", - "description": "List all public images available in the marketplace." - }, - { - "name": "cloneImage", - "description": "Create a copy of an image owned by you with private visibility.", - "healthCheck": { "skipExecution": true } - }, { "name": "healthCheck", "description": "Check the health status of the Unsandbox API service." @@ -348,64 +281,6 @@ { "name": "listPools", "description": "List available execution pools with their configurations and current status." - }, - { - "name": "getPoolStats", - "description": "Get detailed stats for a specific pool including load, memory, and network breakdown.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "validateKey", - "description": "Validate API key pair and retrieve rate limits, concurrency, and expiration." - }, - { - "name": "getKeyInfo", - "description": "Get metadata for the authenticated API key including email, tier, and contacts." - }, - { - "name": "updateKeySettings", - "description": "Update email or sudo settings for the authenticated API key.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "listContacts", - "description": "List all contacts associated with the authenticated API key." - }, - { - "name": "addContact", - "description": "Add a contact with role (owner, operator, reader). Sends invitation email.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "updateContact", - "description": "Change a contact's role. Only owners can manage contacts.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "removeContact", - "description": "Remove a contact from the API key.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "getAuditLog", - "description": "Retrieve audit log entries for all major operations on the API key." - }, - { - "name": "mintToken", - "description": "Create a short-lived token for client-side use (e.g., browser WebSocket).", - "healthCheck": { - "testParams": {}, - "cleanup": [{ "tool": "revokeToken", "mapping": { "token": "token" } }] - } - }, - { - "name": "revokeToken", - "description": "Immediately invalidate a previously minted live token.", - "healthCheck": { "skipExecution": true } - }, - { - "name": "listTokens", - "description": "List all active live tokens for the authenticated API key." } ] }, diff --git a/packages/tools/official/unsandbox/src/index.ts b/packages/tools/official/unsandbox/src/index.ts index d7f3f46..a3e83b9 100644 --- a/packages/tools/official/unsandbox/src/index.ts +++ b/packages/tools/official/unsandbox/src/index.ts @@ -117,7 +117,7 @@ function computeSignature( * Make an authenticated request to the Unsandbox API */ async function apiRequest( - method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', + method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, body?: unknown ): Promise { @@ -1299,127 +1299,6 @@ export const deleteSession = tool({ }, }); -// ============================================================================ -// Extend Session TTL -// ============================================================================ - -export interface ExtendSessionInput { - session_id: string; - seconds?: number; -} - -export interface ExtendSessionResult { - ttl: number; -} - -/** - * Extend a session's time-to-live. - */ -export const extendSession = tool({ - description: 'Add additional time to a session\'s TTL. Default adds 3600 seconds (1 hour).', - inputSchema: jsonSchema({ - type: 'object', - properties: { - session_id: { type: 'string', description: 'The session ID' }, - seconds: { - type: 'number', - description: 'Seconds to add to TTL. Default: 3600', - }, - }, - required: ['session_id'], - additionalProperties: false, - }), - async execute(input: ExtendSessionInput): Promise { - const body: Record = {}; - if (input.seconds !== undefined) body.seconds = input.seconds; - - return apiRequest( - 'POST', - `/sessions/${encodeURIComponent(input.session_id)}/extend`, - body - ); - }, -}); - -// ============================================================================ -// Boost Session Resources -// ============================================================================ - -export interface BoostSessionInput { - session_id: string; - vcpu?: number; -} - -export interface BoostSessionResult { - success: boolean; - message: string; - session: { - session_id: string; - status: string; - vcpu: number; - }; -} - -/** - * Boost session vCPU and memory. - */ -export const boostSession = tool({ - description: 'Increase session vCPU and memory. Each vCPU includes 2GB RAM. Consumes additional concurrency slots.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - session_id: { type: 'string', description: 'The session ID' }, - vcpu: { - type: 'number', - description: 'Target vCPU count (1-8). Default: 2', - }, - }, - required: ['session_id'], - additionalProperties: false, - }), - async execute(input: BoostSessionInput): Promise { - const body: Record = {}; - if (input.vcpu !== undefined) { - if (input.vcpu < 1 || input.vcpu > 8) { - throw new Error('vCPU must be between 1 and 8'); - } - body.vcpu = input.vcpu; - } - - return apiRequest( - 'POST', - `/sessions/${encodeURIComponent(input.session_id)}/boost`, - body - ); - }, -}); - -// ============================================================================ -// Unboost Session Resources -// ============================================================================ - -/** - * Return session to base resources. - */ -export const unboostSession = tool({ - description: 'Reduce session back to default vCPU and memory allocation.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - session_id: { type: 'string', description: 'The session ID' }, - }, - required: ['session_id'], - additionalProperties: false, - }), - async execute(input: SessionIdInput): Promise { - return apiRequest( - 'POST', - `/sessions/${encodeURIComponent(input.session_id)}/unboost`, - {} - ); - }, -}); - // ============================================================================ // Services // ============================================================================ @@ -1892,318 +1771,6 @@ export const deleteService = tool({ }, }); -// ============================================================================ -// Update Service Settings -// ============================================================================ - -export interface UpdateServiceInput { - service_id: string; - vcpu?: number; - unfreeze_on_demand?: boolean; - show_freeze_page?: boolean; -} - -export interface UpdateServiceResult { - success: boolean; - service_id: string; - vcpu?: number; - unfreeze_on_demand?: boolean; - show_freeze_page?: boolean; -} - -/** - * Update service settings (resize, auto-unfreeze, freeze page). - */ -export const updateService = tool({ - description: 'Update service settings. Supports vCPU resize (1-8, each gets 2GB RAM), auto-unfreeze on HTTP request, and branded freeze page. One setting per request.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - service_id: { type: 'string', description: 'The service ID' }, - vcpu: { - type: 'number', - description: 'Target vCPU count (1-8, each gets 2GB RAM)', - }, - unfreeze_on_demand: { - type: 'boolean', - description: 'Auto-unfreeze on first HTTP request when frozen', - }, - show_freeze_page: { - type: 'boolean', - description: 'Show branded freeze page instead of 502 when frozen', - }, - }, - required: ['service_id'], - additionalProperties: false, - }), - async execute(input: UpdateServiceInput): Promise { - const body: Record = {}; - if (input.vcpu !== undefined) { - if (input.vcpu < 1 || input.vcpu > 8) { - throw new Error('vCPU must be between 1 and 8'); - } - body.vcpu = input.vcpu; - } - if (input.unfreeze_on_demand !== undefined) body.unfreeze_on_demand = input.unfreeze_on_demand; - if (input.show_freeze_page !== undefined) body.show_freeze_page = input.show_freeze_page; - - if (Object.keys(body).length === 0) { - throw new Error('Must provide vcpu, unfreeze_on_demand, or show_freeze_page'); - } - - return apiRequest( - 'PATCH', - `/services/${encodeURIComponent(input.service_id)}`, - body - ); - }, -}); - -// ============================================================================ -// Check Service Port -// ============================================================================ - -export interface CheckServicePortInput { - service_id: string; - port: number; -} - -export interface CheckServicePortResult { - listening: boolean; - port: number; - service_id: string; -} - -/** - * Check if a port is listening inside the service container. - */ -export const checkServicePort = tool({ - description: 'Check if a specific port is listening inside the service container.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - service_id: { type: 'string', description: 'The service ID' }, - port: { - type: 'number', - description: 'Port number to check (1-65535)', - }, - }, - required: ['service_id', 'port'], - additionalProperties: false, - }), - async execute(input: CheckServicePortInput): Promise { - if (input.port < 1 || input.port > 65535) { - throw new Error('Port must be between 1 and 65535'); - } - - return apiRequest( - 'GET', - `/services/${encodeURIComponent(input.service_id)}/port?port=${input.port}`, - undefined - ); - }, -}); - -// ============================================================================ -// Service Upgrade Progress -// ============================================================================ - -export interface UpgradeProgressResult { - upgrading: boolean; - state?: string; - progress?: number; - current_version?: string; - target_version?: string; -} - -/** - * Get OS upgrade progress for a service. - */ -export const getUpgradeProgress = tool({ - description: 'Get OS upgrade progress for a service including state, progress percentage, and version chain.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - service_id: { type: 'string', description: 'The service ID' }, - }, - required: ['service_id'], - additionalProperties: false, - }), - async execute(input: ServiceIdInput): Promise { - return apiRequest( - 'GET', - `/services/${encodeURIComponent(input.service_id)}/upgrade/progress`, - undefined - ); - }, -}); - -// ============================================================================ -// Service Upgrade Logs -// ============================================================================ - -export interface GetUpgradeLogsInput { - service_id: string; - lines?: number; -} - -export interface UpgradeLogsResult { - log: string; - message?: string; -} - -/** - * Get OS upgrade logs for a service. - */ -export const getUpgradeLogs = tool({ - description: 'Get OS upgrade log output for a service. Optionally limit to last N lines.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - service_id: { type: 'string', description: 'The service ID' }, - lines: { - type: 'number', - description: 'Limit to last N lines (default: all)', - }, - }, - required: ['service_id'], - additionalProperties: false, - }), - async execute(input: GetUpgradeLogsInput): Promise { - let path = `/services/${encodeURIComponent(input.service_id)}/upgrade/logs`; - if (input.lines !== undefined) { - path += `?lines=${input.lines}`; - } - - return apiRequest('GET', path, undefined); - }, -}); - -// ============================================================================ -// Update Service Domains -// ============================================================================ - -export interface UpdateServiceDomainsInput { - service_id: string; - custom_domains?: string[]; - add?: string[]; - remove?: string[]; -} - -export interface UpdateServiceDomainsResult { - success: boolean; - service_id: string; - custom_domains: string[]; -} - -/** - * Update custom domains for a service. - */ -export const updateServiceDomains = tool({ - description: 'Manage custom domain names for a service. Use custom_domains to replace all, add to append, or remove to delete specific domains.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - service_id: { type: 'string', description: 'The service ID' }, - custom_domains: { - type: 'array', - items: { type: 'string' }, - description: 'Replace all domains with this list', - }, - add: { - type: 'array', - items: { type: 'string' }, - description: 'Add these domains to existing list', - }, - remove: { - type: 'array', - items: { type: 'string' }, - description: 'Remove these domains from existing list', - }, - }, - required: ['service_id'], - additionalProperties: false, - }), - async execute(input: UpdateServiceDomainsInput): Promise { - const body: Record = {}; - if (input.custom_domains) body.custom_domains = input.custom_domains; - if (input.add) body.add = input.add; - if (input.remove) body.remove = input.remove; - - if (Object.keys(body).length === 0) { - throw new Error('Must provide custom_domains, add, or remove'); - } - - return apiRequest( - 'PUT', - `/services/${encodeURIComponent(input.service_id)}/domains`, - body - ); - }, -}); - -// ============================================================================ -// Export Service Env -// ============================================================================ - -export interface ExportServiceEnvResult { - env: string; -} - -/** - * Export service environment variables as .env format. - */ -export const exportServiceEnv = tool({ - description: 'Export all environment variables as a .env formatted string. Requires HMAC authentication.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - service_id: { type: 'string', description: 'The service ID' }, - }, - required: ['service_id'], - additionalProperties: false, - }), - async execute(input: ServiceIdInput): Promise { - return apiRequest( - 'POST', - `/services/${encodeURIComponent(input.service_id)}/env/export`, - {} - ); - }, -}); - -// ============================================================================ -// Restore Service from Snapshot -// ============================================================================ - -export interface RestoreServiceInput { - service_id: string; - snapshot_id: string; -} - -/** - * Restore a service from a snapshot. - */ -export const restoreService = tool({ - description: 'Restore a service to a previous snapshot state.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - service_id: { type: 'string', description: 'The service ID' }, - snapshot_id: { type: 'string', description: 'The snapshot ID to restore from' }, - }, - required: ['service_id', 'snapshot_id'], - additionalProperties: false, - }), - async execute(input: RestoreServiceInput): Promise { - return apiRequest( - 'POST', - `/services/${encodeURIComponent(input.service_id)}/restore`, - { snapshot_id: input.snapshot_id } - ); - }, -}); - // ============================================================================ // Snapshots // ============================================================================ @@ -2817,104 +2384,6 @@ export const deleteImage = tool({ }, }); -// ============================================================================ -// List Owned Images -// ============================================================================ - -/** - * List images owned by the authenticated API key. - */ -export const listOwnedImages = tool({ - description: 'List only images owned by the authenticated API key. Includes management fields like trusted_keys.', - inputSchema: jsonSchema>({ - type: 'object', - properties: {}, - additionalProperties: false, - }), - async execute(): Promise { - const result = await apiRequest('GET', '/images/owned', undefined); - return { images: result.images || [] }; - }, -}); - -// ============================================================================ -// List Shared Images -// ============================================================================ - -/** - * List images shared with the authenticated API key. - */ -export const listSharedImages = tool({ - description: 'List images shared with you via trusted_keys (images you can use but don\'t own).', - inputSchema: jsonSchema>({ - type: 'object', - properties: {}, - additionalProperties: false, - }), - async execute(): Promise { - const result = await apiRequest('GET', '/images/shared', undefined); - return { images: result.images || [] }; - }, -}); - -// ============================================================================ -// List Public Images -// ============================================================================ - -/** - * List all public images (marketplace). - */ -export const listPublicImages = tool({ - description: 'List all public images available in the marketplace.', - inputSchema: jsonSchema>({ - type: 'object', - properties: {}, - additionalProperties: false, - }), - async execute(): Promise { - const result = await apiRequest('GET', '/images/public', undefined); - return { images: result.images || [] }; - }, -}); - -// ============================================================================ -// Clone Image -// ============================================================================ - -export interface CloneImageInput { - image_id: string; - name?: string; - description?: string; -} - -/** - * Clone an image to create your own copy. - */ -export const cloneImage = tool({ - description: 'Create a copy of an image. The cloned image will be owned by you with private visibility.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - image_id: { type: 'string', description: 'The image ID to clone' }, - name: { type: 'string', description: 'Name for the cloned image (defaults to original + " (copy)")' }, - description: { type: 'string', description: 'Description for the cloned image' }, - }, - required: ['image_id'], - additionalProperties: false, - }), - async execute(input: CloneImageInput): Promise { - const body: Record = {}; - if (input.name) body.name = input.name; - if (input.description) body.description = input.description; - - return apiRequest( - 'POST', - `/images/${encodeURIComponent(input.image_id)}/clone`, - body - ); - }, -}); - // ============================================================================ // System // ============================================================================ @@ -3035,445 +2504,6 @@ export const listPools = tool({ }, }); -// ============================================================================ -// Get Pool Stats -// ============================================================================ - -export interface GetPoolStatsInput { - pool_id: string; -} - -export interface PoolStatsResult { - mode: string; - pool_size: number; - total_containers: number; - available: number; - allocated: number; - spawning: number; - network_mode: string; - load_avg?: { - load1: string; - load5: string; - load15: string; - }; - memory?: { - total_mb: number; - used_mb: number; - available_mb: number; - used_percent: number; - }; - network_breakdown?: { - zerotrust?: { total: number; available: number; allocated: number }; - semitrusted?: { total: number; available: number; allocated: number; services?: number }; - }; -} - -/** - * Get detailed stats for a specific pool. - */ -export const getPoolStats = tool({ - description: 'Get detailed stats for a specific pool including load averages, memory usage, and network breakdown.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - pool_id: { - type: 'string', - description: 'Pool identifier (e.g., ai, cammy)', - }, - }, - required: ['pool_id'], - additionalProperties: false, - }), - async execute(input: GetPoolStatsInput): Promise { - return apiRequest( - 'GET', - `/pools/${encodeURIComponent(input.pool_id)}/stats`, - undefined - ); - }, -}); - -// ============================================================================ -// API Keys - Validate -// ============================================================================ - -export interface ValidateKeyResult { - valid: boolean; - public_key: string; - rate_per_minute: number; - burst: number; - concurrency_limit: number; - expires_at: string | null; - tier: string; -} - -/** - * Validate API key pair. - */ -export const validateKey = tool({ - description: 'Validate your API key pair and retrieve its configuration including rate limits, concurrency limits, and expiration status.', - inputSchema: jsonSchema>({ - type: 'object', - properties: {}, - additionalProperties: false, - }), - async execute(): Promise { - return apiRequest('POST', '/keys/validate', {}); - }, -}); - -// ============================================================================ -// API Keys - Get Self -// ============================================================================ - -export interface KeyInfoResult { - key: string; - email: string; - sudo_required: boolean; - tier: number; - created_at: string; - contacts_count: number; -} - -/** - * Get current API key info. - */ -export const getKeyInfo = tool({ - description: 'Get metadata for the authenticated API key including email, tier, and contacts count.', - inputSchema: jsonSchema>({ - type: 'object', - properties: {}, - additionalProperties: false, - }), - async execute(): Promise { - return apiRequest('GET', '/keys/self', undefined); - }, -}); - -// ============================================================================ -// API Keys - Update Self -// ============================================================================ - -export interface UpdateKeyInput { - email?: string; - sudo_required?: boolean; -} - -export interface UpdateKeyResult { - success: boolean; - key: { - key: string; - email: string; - sudo_required: boolean; - }; -} - -/** - * Update API key settings. - */ -export const updateKeySettings = tool({ - description: 'Update email or sudo settings for the authenticated API key.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - email: { type: 'string', description: 'New email address' }, - sudo_required: { - type: 'boolean', - description: 'Require OTP for destructive operations', - }, - }, - additionalProperties: false, - }), - async execute(input: UpdateKeyInput): Promise { - const body: Record = {}; - if (input.email !== undefined) body.email = input.email; - if (input.sudo_required !== undefined) body.sudo_required = input.sudo_required; - - if (Object.keys(body).length === 0) { - throw new Error('Must provide email or sudo_required'); - } - - return apiRequest('PATCH', '/keys/self', body); - }, -}); - -// ============================================================================ -// API Keys - Contacts -// ============================================================================ - -export interface Contact { - email: string; - role: 'owner' | 'operator' | 'reader'; - verified: boolean; - invited_by?: string; - created_at?: string; -} - -export interface ListContactsResult { - contacts: Contact[]; -} - -/** - * List contacts for the authenticated API key. - */ -export const listContacts = tool({ - description: 'List all contacts associated with the authenticated API key.', - inputSchema: jsonSchema>({ - type: 'object', - properties: {}, - additionalProperties: false, - }), - async execute(): Promise { - return apiRequest('GET', '/keys/self/contacts', undefined); - }, -}); - -// ============================================================================ -// API Keys - Add Contact -// ============================================================================ - -export interface AddContactInput { - email: string; - role?: 'owner' | 'operator' | 'reader'; -} - -export interface AddContactResult { - success: boolean; - contact: Contact; -} - -/** - * Add a contact to the API key. - */ -export const addContact = tool({ - description: 'Add a new contact to the API key. Sends an invitation email. Roles: owner (full control), operator (manage services), reader (view-only).', - inputSchema: jsonSchema({ - type: 'object', - properties: { - email: { type: 'string', description: 'Contact email address' }, - role: { - type: 'string', - enum: ['owner', 'operator', 'reader'], - description: 'Contact role. Default: reader', - }, - }, - required: ['email'], - additionalProperties: false, - }), - async execute(input: AddContactInput): Promise { - const body: Record = { email: input.email }; - if (input.role) body.role = input.role; - - return apiRequest('POST', '/keys/self/contacts', body); - }, -}); - -// ============================================================================ -// API Keys - Update Contact Role -// ============================================================================ - -export interface UpdateContactInput { - email: string; - role: 'owner' | 'operator' | 'reader'; -} - -export interface UpdateContactResult { - success: boolean; - contact: { - email: string; - role: string; - }; -} - -/** - * Update a contact's role. - */ -export const updateContact = tool({ - description: 'Change a contact\'s role. Only owners can manage contacts.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - email: { type: 'string', description: 'Contact email address' }, - role: { - type: 'string', - enum: ['owner', 'operator', 'reader'], - description: 'New role for the contact', - }, - }, - required: ['email', 'role'], - additionalProperties: false, - }), - async execute(input: UpdateContactInput): Promise { - return apiRequest( - 'PATCH', - `/keys/self/contacts/${encodeURIComponent(input.email)}`, - { role: input.role } - ); - }, -}); - -// ============================================================================ -// API Keys - Remove Contact -// ============================================================================ - -export interface RemoveContactInput { - email: string; -} - -export interface RemoveContactResult { - success: boolean; -} - -/** - * Remove a contact from the API key. - */ -export const removeContact = tool({ - description: 'Remove a contact from the API key. Only owners can manage contacts.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - email: { type: 'string', description: 'Contact email to remove' }, - }, - required: ['email'], - additionalProperties: false, - }), - async execute(input: RemoveContactInput): Promise { - return apiRequest( - 'DELETE', - `/keys/self/contacts/${encodeURIComponent(input.email)}`, - undefined - ); - }, -}); - -// ============================================================================ -// API Keys - Audit Log -// ============================================================================ - -export interface AuditLogEntry { - action: string; - resource_type: string; - resource_id: string; - result: 'success' | 'failure'; - client_ip: string; - metadata?: Record; - timestamp: string; -} - -export interface AuditLogResult { - entries: AuditLogEntry[]; - count: number; -} - -/** - * Get audit log for the authenticated API key. - */ -export const getAuditLog = tool({ - description: 'Retrieve audit log entries for the authenticated API key. Logs all major operations: create, destroy, freeze, unfreeze, snapshot, etc.', - inputSchema: jsonSchema>({ - type: 'object', - properties: {}, - additionalProperties: false, - }), - async execute(): Promise { - return apiRequest('GET', '/keys/self/audit-log', undefined); - }, -}); - -// ============================================================================ -// Live Tokens - Mint -// ============================================================================ - -export interface MintTokenInput { - ttl?: number; -} - -export interface MintTokenResult { - token: string; - expires_at: string; -} - -/** - * Mint a short-lived live token. - */ -export const mintToken = tool({ - description: 'Create a short-lived token for client-side use (e.g., browser WebSocket connections). Inherits parent key permissions.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - ttl: { - type: 'number', - description: 'Token TTL in seconds', - }, - }, - additionalProperties: false, - }), - async execute(input: MintTokenInput): Promise { - const body: Record = {}; - if (input.ttl !== undefined) body.ttl = input.ttl; - - return apiRequest('POST', '/mint-token', body); - }, -}); - -// ============================================================================ -// Live Tokens - Revoke -// ============================================================================ - -export interface RevokeTokenInput { - token: string; -} - -export interface RevokeTokenResult { - success: boolean; -} - -/** - * Revoke a live token. - */ -export const revokeToken = tool({ - description: 'Immediately invalidate a previously minted live token.', - inputSchema: jsonSchema({ - type: 'object', - properties: { - token: { type: 'string', description: 'The token to revoke' }, - }, - required: ['token'], - additionalProperties: false, - }), - async execute(input: RevokeTokenInput): Promise { - return apiRequest('POST', '/revoke-token', { token: input.token }); - }, -}); - -// ============================================================================ -// Live Tokens - List -// ============================================================================ - -export interface TokenInfo { - token: string; - expires_at: string; -} - -export interface ListTokensResult { - tokens: TokenInfo[]; -} - -/** - * List active live tokens. - */ -export const listTokens = tool({ - description: 'List all active (non-expired, non-revoked) live tokens for the authenticated API key.', - inputSchema: jsonSchema>({ - type: 'object', - properties: {}, - additionalProperties: false, - }), - async execute(): Promise { - return apiRequest('POST', '/list-tokens', {}); - }, -}); - // ============================================================================ // Default Export // ============================================================================ @@ -3503,9 +2533,6 @@ export default { createSessionSnapshot, restoreSession, deleteSession, - extendSession, - boostSession, - unboostSession, // Services createService, getService, @@ -3522,13 +2549,6 @@ export default { setServiceEnv, deleteServiceEnv, deleteService, - updateService, - checkServicePort, - getUpgradeProgress, - getUpgradeLogs, - updateServiceDomains, - exportServiceEnv, - restoreService, // Snapshots createSnapshot, getSnapshot, @@ -3551,27 +2571,9 @@ export default { spawnFromImage, getImageTrustedKeys, deleteImage, - listOwnedImages, - listSharedImages, - listPublicImages, - cloneImage, // System healthCheck, getClusterStatus, getSystemStats, listPools, - getPoolStats, - // API Keys - validateKey, - getKeyInfo, - updateKeySettings, - listContacts, - addContact, - updateContact, - removeContact, - getAuditLog, - // Live Tokens - mintToken, - revokeToken, - listTokens, };