React SDK
TL;DR
The @cmdop/react package provides React hooks and components for CMDOP integration. Wrap your app with CmdopProvider, then use hooks like useMachines, useMachine, useCommand, useTerminal, useFiles, and useRealtime for machine management, command execution, file browsing, and real-time status monitoring. Includes a pre-built Terminal component with dark theme support. Full TypeScript types included.
React hooks and components for Cmdop integration.
How do I set up the React provider?
Wrap your app with CmdopProvider:
import { CmdopProvider } from '@cmdop/react';
// Wrap your entire app to provide CMDOP context to all child components
function App() {
return (
<CmdopProvider apiKey={process.env.NEXT_PUBLIC_CMDOP_API_KEY}>
<YourApp />
</CmdopProvider>
);
}What hooks are available?
How do I list all machines with useMachines?
List all machines:
import { useMachines } from '@cmdop/react';
function MachineList() {
// Fetch all registered machines with loading and error states
const { machines, loading, error, refetch } = useMachines();
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<ul>
{machines.map((machine) => (
<li key={machine.id}>
{machine.name} - {machine.status}
</li>
))}
</ul>
);
}How do I get a single machine with useMachine?
Get single machine:
import { useMachine } from '@cmdop/react';
function MachineDetail({ id }: { id: string }) {
// Fetch a single machine by its ID
const { machine, loading, error } = useMachine(id);
if (loading) return <div>Loading...</div>;
if (!machine) return <div>Not found</div>;
return (
<div>
<h2>{machine.name}</h2>
<p>Status: {machine.status}</p>
<p>OS: {machine.os}</p>
</div>
);
}How do I execute commands with useCommand?
Execute commands:
import { useCommand } from '@cmdop/react';
function CommandRunner({ machineId }: { machineId: string }) {
// Hook returns execute function, result, loading state, and error
const { execute, result, loading, error } = useCommand(machineId);
const handleRun = async () => {
// Execute a shell command on the specified machine
await execute('ls -la');
};
return (
<div>
<button onClick={handleRun} disabled={loading}>
Run Command
</button>
{result && (
<pre>{result.stdout}</pre>
)}
</div>
);
}How do I create an interactive terminal with useTerminal?
Interactive terminal:
import { useTerminal } from '@cmdop/react';
function Terminal({ machineId }: { machineId: string }) {
// Hook manages terminal output buffer, send function, and connection state
const {
output,
send,
clear,
connected
} = useTerminal(machineId);
return (
<div>
<pre>{output}</pre>
<input
onKeyDown={(e) => {
// Send command when Enter is pressed, then clear the input
if (e.key === 'Enter') {
send(e.currentTarget.value);
e.currentTarget.value = '';
}
}}
/>
</div>
);
}How do I browse files with useFiles?
File operations:
import { useFiles } from '@cmdop/react';
function FileExplorer({ machineId }: { machineId: string }) {
// Hook provides file listing, current path, navigation, and loading state
const {
files,
path,
navigate,
loading
} = useFiles(machineId, '/home'); // Start browsing at /home
return (
<div>
<p>Current: {path}</p>
<ul>
{files.map((file) => (
<li
key={file.name}
onClick={() => file.isDirectory && navigate(file.path)}
>
{file.isDirectory ? '📁' : '📄'} {file.name}
</li>
))}
</ul>
</div>
);
}How do I subscribe to real-time updates with useRealtime?
Real-time subscriptions:
import { useRealtime } from '@cmdop/react';
function StatusMonitor({ machineId }: { machineId: string }) {
// Subscribe to real-time machine status updates via WebSocket
const { status, lastUpdate } = useRealtime(machineId);
return (
<div>
<p>Status: {status}</p>
<p>Updated: {lastUpdate?.toLocaleTimeString()}</p>
</div>
);
}What pre-built components are available?
How do I use the Terminal component?
Pre-built terminal component:
import { Terminal } from '@cmdop/react';
// Drop-in terminal component with configurable height and theme
function App() {
return (
<Terminal
machineId="your-machine-id"
height={400} // Terminal height in pixels
theme="dark" // "dark" or "light" theme
/>
);
}How do I use TypeScript types?
Full type support:
// Import types directly from the package for type-safe component props
import { Machine, CommandResult } from '@cmdop/react';
function MachineCard({ machine }: { machine: Machine }) {
return <div>{machine.name}</div>;
}Last updated on