@cmdop/react 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +271 -0
- package/dist/index.cjs +770 -0
- package/dist/index.d.cts +538 -0
- package/dist/index.d.ts +538 -0
- package/dist/index.js +732 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# @cmdop/react
|
|
2
|
+
|
|
3
|
+
React hooks and components for browser-based CMDOP agent interaction.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @cmdop/react react react-dom
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @cmdop/react react react-dom
|
|
11
|
+
# or
|
|
12
|
+
yarn add @cmdop/react react react-dom
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Peer Dependencies:** React >= 18.0.0
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { CMDOPProvider, WebSocketProvider, useTerminal } from '@cmdop/react';
|
|
21
|
+
|
|
22
|
+
function App() {
|
|
23
|
+
return (
|
|
24
|
+
<CMDOPProvider token="your-jwt-token">
|
|
25
|
+
<WebSocketProvider
|
|
26
|
+
url="wss://ws.cmdop.com/connection/websocket"
|
|
27
|
+
getToken={() => Promise.resolve('your-jwt-token')}
|
|
28
|
+
>
|
|
29
|
+
<Terminal sessionId="session-123" />
|
|
30
|
+
</WebSocketProvider>
|
|
31
|
+
</CMDOPProvider>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function Terminal({ sessionId }: { sessionId: string }) {
|
|
36
|
+
const { isConnected, output, sendInput } = useTerminal({ sessionId });
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div>
|
|
40
|
+
<pre>{output}</pre>
|
|
41
|
+
<input
|
|
42
|
+
onKeyDown={(e) => {
|
|
43
|
+
if (e.key === 'Enter') {
|
|
44
|
+
sendInput(e.currentTarget.value + '\n');
|
|
45
|
+
e.currentTarget.value = '';
|
|
46
|
+
}
|
|
47
|
+
}}
|
|
48
|
+
placeholder={isConnected ? 'Type command...' : 'Connecting...'}
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
### HTTP API Hooks (SWR)
|
|
58
|
+
|
|
59
|
+
Data fetching with caching and revalidation:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { CMDOPProvider, useMachines, useMachine, useWorkspaces } from '@cmdop/react';
|
|
63
|
+
|
|
64
|
+
function MachineList() {
|
|
65
|
+
const { machines, isLoading, error, refetch } = useMachines();
|
|
66
|
+
|
|
67
|
+
if (isLoading) return <div>Loading...</div>;
|
|
68
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<ul>
|
|
72
|
+
{machines?.map((machine) => (
|
|
73
|
+
<li key={machine.id}>{machine.name}</li>
|
|
74
|
+
))}
|
|
75
|
+
</ul>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function MachineDetail({ id }: { id: string }) {
|
|
80
|
+
const { machine, isLoading } = useMachine(id);
|
|
81
|
+
return <div>{machine?.name}</div>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function WorkspaceList() {
|
|
85
|
+
const { workspaces, isLoading } = useWorkspaces();
|
|
86
|
+
return (
|
|
87
|
+
<ul>
|
|
88
|
+
{workspaces?.map((ws) => (
|
|
89
|
+
<li key={ws.id}>{ws.name}</li>
|
|
90
|
+
))}
|
|
91
|
+
</ul>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### WebSocket Terminal Hook
|
|
97
|
+
|
|
98
|
+
Real-time terminal interaction:
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { useTerminal } from '@cmdop/react';
|
|
102
|
+
|
|
103
|
+
function Terminal({ sessionId }: { sessionId: string }) {
|
|
104
|
+
const {
|
|
105
|
+
isConnected,
|
|
106
|
+
isConnecting,
|
|
107
|
+
output,
|
|
108
|
+
status,
|
|
109
|
+
error,
|
|
110
|
+
sendInput,
|
|
111
|
+
resize,
|
|
112
|
+
signal,
|
|
113
|
+
clear,
|
|
114
|
+
} = useTerminal({
|
|
115
|
+
sessionId,
|
|
116
|
+
onOutput: (data) => console.log('Output:', data),
|
|
117
|
+
onStatus: (status) => console.log('Status:', status),
|
|
118
|
+
onError: (err) => console.error('Error:', err),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Send input
|
|
122
|
+
const handleSubmit = (command: string) => {
|
|
123
|
+
sendInput(command + '\n');
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Resize terminal
|
|
127
|
+
const handleResize = () => {
|
|
128
|
+
resize(120, 40);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Send Ctrl+C
|
|
132
|
+
const handleInterrupt = () => {
|
|
133
|
+
signal('SIGINT');
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<div>
|
|
138
|
+
<pre>{output}</pre>
|
|
139
|
+
<button onClick={() => signal('SIGINT')}>Ctrl+C</button>
|
|
140
|
+
<button onClick={clear}>Clear</button>
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### AI Agent Hook
|
|
147
|
+
|
|
148
|
+
Streaming AI agent with tool calls:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { useAgent } from '@cmdop/react';
|
|
152
|
+
|
|
153
|
+
function AgentChat({ sessionId }: { sessionId: string }) {
|
|
154
|
+
const {
|
|
155
|
+
run,
|
|
156
|
+
isRunning,
|
|
157
|
+
streamingText,
|
|
158
|
+
result,
|
|
159
|
+
toolCalls,
|
|
160
|
+
error,
|
|
161
|
+
reset,
|
|
162
|
+
cancel,
|
|
163
|
+
} = useAgent({
|
|
164
|
+
sessionId,
|
|
165
|
+
onToken: (text) => console.log('Token:', text),
|
|
166
|
+
onToolCall: (tool) => console.log('Tool:', tool.name),
|
|
167
|
+
onDone: (result) => console.log('Done:', result),
|
|
168
|
+
onError: (err) => console.error('Error:', err),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const handleSubmit = async (prompt: string) => {
|
|
172
|
+
const response = await run(prompt, {
|
|
173
|
+
mode: 'chat',
|
|
174
|
+
timeoutSeconds: 60,
|
|
175
|
+
});
|
|
176
|
+
console.log('Final response:', response);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div>
|
|
181
|
+
{/* Streaming output */}
|
|
182
|
+
<pre>{streamingText || result}</pre>
|
|
183
|
+
|
|
184
|
+
{/* Active tool calls */}
|
|
185
|
+
{toolCalls.map((tool) => (
|
|
186
|
+
<div key={tool.id}>Running: {tool.name}</div>
|
|
187
|
+
))}
|
|
188
|
+
|
|
189
|
+
{/* Controls */}
|
|
190
|
+
<button onClick={() => handleSubmit('List files')}>
|
|
191
|
+
{isRunning ? 'Running...' : 'Send'}
|
|
192
|
+
</button>
|
|
193
|
+
{isRunning && <button onClick={cancel}>Cancel</button>}
|
|
194
|
+
<button onClick={reset}>Reset</button>
|
|
195
|
+
</div>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### WebSocket Infrastructure
|
|
201
|
+
|
|
202
|
+
Low-level WebSocket hooks for custom implementations:
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
import { useSubscription, useRPC, useWebSocket } from '@cmdop/react';
|
|
206
|
+
|
|
207
|
+
// Access WebSocket client
|
|
208
|
+
function CustomComponent() {
|
|
209
|
+
const { client, isConnected } = useWebSocket();
|
|
210
|
+
// ...
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Subscribe to channel
|
|
214
|
+
function Subscriber() {
|
|
215
|
+
const { data, isSubscribed, error } = useSubscription<MyData>({
|
|
216
|
+
channel: 'my-channel',
|
|
217
|
+
onData: (data) => console.log('Received:', data),
|
|
218
|
+
});
|
|
219
|
+
// ...
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Make RPC calls
|
|
223
|
+
function RPCCaller() {
|
|
224
|
+
const { call, isLoading, error } = useRPC();
|
|
225
|
+
|
|
226
|
+
const handleCall = async () => {
|
|
227
|
+
const result = await call<Request, Response>('method.name', { param: 'value' });
|
|
228
|
+
};
|
|
229
|
+
// ...
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Providers
|
|
234
|
+
|
|
235
|
+
### CMDOPProvider
|
|
236
|
+
|
|
237
|
+
Provides JWT token for HTTP API calls:
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
<CMDOPProvider token="jwt-token" baseUrl="https://api.cmdop.com">
|
|
241
|
+
<App />
|
|
242
|
+
</CMDOPProvider>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### WebSocketProvider
|
|
246
|
+
|
|
247
|
+
Manages WebSocket connection:
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
<WebSocketProvider
|
|
251
|
+
url="wss://ws.cmdop.com/connection/websocket"
|
|
252
|
+
getToken={() => fetchToken()}
|
|
253
|
+
autoConnect={true}
|
|
254
|
+
debug={false}
|
|
255
|
+
>
|
|
256
|
+
<App />
|
|
257
|
+
</WebSocketProvider>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Related Packages
|
|
261
|
+
|
|
262
|
+
- [@cmdop/core](https://www.npmjs.com/package/@cmdop/core) - Shared types and configuration
|
|
263
|
+
- [@cmdop/node](https://www.npmjs.com/package/@cmdop/node) - Node.js SDK with gRPC
|
|
264
|
+
|
|
265
|
+
## Documentation
|
|
266
|
+
|
|
267
|
+
For full documentation, visit [https://cmdop.com/docs](https://cmdop.com/docs)
|
|
268
|
+
|
|
269
|
+
## License
|
|
270
|
+
|
|
271
|
+
MIT
|