@closedloop-ai/cli 0.2.3 → 0.3.0
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 +106 -258
- package/dist/THIRD_PARTY_NOTICES.txt +24 -0
- package/dist/closedloop.js +156 -0
- package/package.json +31 -62
- package/CONTRIBUTING.md +0 -437
- package/LICENSE +0 -21
- package/docs/CLI_COMMANDS.md +0 -508
- package/packages/cli/dist/__tests__/cli.test.js +0 -37
- package/packages/cli/dist/__tests__/cli.test.js.map +0 -1
- package/packages/cli/dist/__tests__/config.test.js +0 -33
- package/packages/cli/dist/__tests__/config.test.js.map +0 -1
- package/packages/cli/dist/__tests__/errors.test.js +0 -109
- package/packages/cli/dist/__tests__/errors.test.js.map +0 -1
- package/packages/cli/dist/__tests__/setup.js +0 -20
- package/packages/cli/dist/__tests__/setup.js.map +0 -1
- package/packages/cli/dist/__tests__/validation.test.js +0 -124
- package/packages/cli/dist/__tests__/validation.test.js.map +0 -1
- package/packages/cli/dist/api/auth.js +0 -27
- package/packages/cli/dist/api/auth.js.map +0 -1
- package/packages/cli/dist/api/feedback.js +0 -70
- package/packages/cli/dist/api/feedback.js.map +0 -1
- package/packages/cli/dist/api/input.js +0 -60
- package/packages/cli/dist/api/input.js.map +0 -1
- package/packages/cli/dist/api/team.js +0 -45
- package/packages/cli/dist/api/team.js.map +0 -1
- package/packages/cli/dist/api/usage.js +0 -49
- package/packages/cli/dist/api/usage.js.map +0 -1
- package/packages/cli/dist/cli.js +0 -163
- package/packages/cli/dist/cli.js.map +0 -1
- package/packages/cli/dist/commands/config.js +0 -186
- package/packages/cli/dist/commands/config.js.map +0 -1
- package/packages/cli/dist/commands/feedback.js +0 -234
- package/packages/cli/dist/commands/feedback.js.map +0 -1
- package/packages/cli/dist/commands/input.js +0 -370
- package/packages/cli/dist/commands/input.js.map +0 -1
- package/packages/cli/dist/commands/list.js +0 -81
- package/packages/cli/dist/commands/list.js.map +0 -1
- package/packages/cli/dist/commands/status.js +0 -93
- package/packages/cli/dist/commands/status.js.map +0 -1
- package/packages/cli/dist/commands/submit.js +0 -225
- package/packages/cli/dist/commands/submit.js.map +0 -1
- package/packages/cli/dist/commands/team.js +0 -44
- package/packages/cli/dist/commands/team.js.map +0 -1
- package/packages/cli/dist/commands/usage.js +0 -168
- package/packages/cli/dist/commands/usage.js.map +0 -1
- package/packages/cli/dist/config/constants.js +0 -37
- package/packages/cli/dist/config/constants.js.map +0 -1
- package/packages/cli/dist/config/index.js +0 -84
- package/packages/cli/dist/config/index.js.map +0 -1
- package/packages/cli/dist/types/index.js +0 -3
- package/packages/cli/dist/types/index.js.map +0 -1
- package/packages/cli/dist/utils/config.js +0 -55
- package/packages/cli/dist/utils/config.js.map +0 -1
- package/packages/cli/dist/utils/errors.js +0 -70
- package/packages/cli/dist/utils/errors.js.map +0 -1
- package/packages/cli/dist/utils/validation.js +0 -133
- package/packages/cli/dist/utils/validation.js.map +0 -1
package/docs/CLI_COMMANDS.md
DELETED
|
@@ -1,508 +0,0 @@
|
|
|
1
|
-
# ClosedLoop AI CLI Commands Reference
|
|
2
|
-
|
|
3
|
-
Complete reference for all CLI commands, parameters, and user experience.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Installation](#installation)
|
|
8
|
-
- [Configuration](#configuration)
|
|
9
|
-
- [How to Use API Keys](#how-to-use-api-keys)
|
|
10
|
-
- [Input Commands](#input-commands)
|
|
11
|
-
- [Feedback Commands](#feedback-commands)
|
|
12
|
-
- [General Commands](#general-commands)
|
|
13
|
-
- [Error Handling](#error-handling)
|
|
14
|
-
- [Examples](#examples)
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
### Global Installation (Recommended)
|
|
19
|
-
```bash
|
|
20
|
-
npm install -g @closedloop-ai/cli
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Local Installation
|
|
24
|
-
```bash
|
|
25
|
-
npm install @closedloop-ai/cli
|
|
26
|
-
npx cl --help
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### Verify Installation
|
|
30
|
-
```bash
|
|
31
|
-
cl --version
|
|
32
|
-
# Output: 0.2.0
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Configuration
|
|
36
|
-
|
|
37
|
-
### Set API Key
|
|
38
|
-
```bash
|
|
39
|
-
cl config set --api-key your-api-key-here
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### View Configuration
|
|
43
|
-
```bash
|
|
44
|
-
cl config
|
|
45
|
-
# Output:
|
|
46
|
-
# ⚙️ Configuration:
|
|
47
|
-
# ────────────────────────────────────────
|
|
48
|
-
# API Key: ✓ Configured
|
|
49
|
-
# Config File: /Users/jirikobelka/.closedloop/config.json
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### JSON Configuration
|
|
53
|
-
```bash
|
|
54
|
-
cl config --json
|
|
55
|
-
# Output:
|
|
56
|
-
# {
|
|
57
|
-
# "success": true,
|
|
58
|
-
# "data": {
|
|
59
|
-
# "apiKey": "test-key...",
|
|
60
|
-
# "configFile": "/Users/jirikobelka/.closedloop/config.json",
|
|
61
|
-
# "configured": true
|
|
62
|
-
# }
|
|
63
|
-
# }
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Environment Variable
|
|
67
|
-
```bash
|
|
68
|
-
export CLOSEDLOOP_API_KEY="your-api-key-here"
|
|
69
|
-
cl config # Will use environment variable
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Input Commands
|
|
73
|
-
|
|
74
|
-
### Submit Customer Product Feedback
|
|
75
|
-
|
|
76
|
-
#### Basic Submission
|
|
77
|
-
```bash
|
|
78
|
-
cl input "Your customer product feedback here"
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
#### With Metadata
|
|
82
|
-
```bash
|
|
83
|
-
cl input "The dashboard is confusing and hard to navigate" \
|
|
84
|
-
--title "Dashboard UX Issues" \
|
|
85
|
-
--customer "customer-123" \
|
|
86
|
-
--name "John Doe" \
|
|
87
|
-
--email "john@example.com" \
|
|
88
|
-
--url "https://support.example.com/ticket/456"
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
#### Wait for Processing
|
|
92
|
-
```bash
|
|
93
|
-
cl input "Customer complaint about performance" --wait
|
|
94
|
-
# Shows real-time processing status
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
#### JSON Output
|
|
98
|
-
```bash
|
|
99
|
-
cl input "Great product, love the new features!" --json
|
|
100
|
-
# Output: {"id":"74e3dd87-878f-41cf-8e5a-87527bbf7770","status":"submitted"}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### List Customer Inputs
|
|
104
|
-
|
|
105
|
-
#### Basic List
|
|
106
|
-
```bash
|
|
107
|
-
cl input
|
|
108
|
-
# Shows table of recent inputs
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
#### With Pagination
|
|
112
|
-
```bash
|
|
113
|
-
cl input --page 2 --limit 10
|
|
114
|
-
# Shows page 2 with 10 items per page
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
#### JSON Output
|
|
118
|
-
```bash
|
|
119
|
-
cl input --json
|
|
120
|
-
# Output: {"data":[...],"pagination":{...}}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### View Specific Input
|
|
124
|
-
|
|
125
|
-
#### By ID
|
|
126
|
-
```bash
|
|
127
|
-
cl input 74e3dd87-878f-41cf-8e5a-87527bbf7770
|
|
128
|
-
# Shows detailed input information
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
#### JSON Output
|
|
132
|
-
```bash
|
|
133
|
-
cl input 74e3dd87-878f-41cf-8e5a-87527bbf7770 --json
|
|
134
|
-
# Output: {"id":"...","content":"...","status":"..."}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Input Parameters
|
|
138
|
-
|
|
139
|
-
| Parameter | Type | Required | Description | Example |
|
|
140
|
-
|-----------|------|----------|-------------|---------|
|
|
141
|
-
| `content` | string | Yes | Customer product feedback content | `"The app crashes when uploading files"` |
|
|
142
|
-
| `--title` | string | No | Title for the feedback | `"File Upload Issue"` |
|
|
143
|
-
| `--customer` | string | No | Customer identifier | `"customer-123"` |
|
|
144
|
-
| `--name` | string | No | Reporter name | `"John Doe"` |
|
|
145
|
-
| `--email` | string | No | Reporter email | `"john@example.com"` |
|
|
146
|
-
| `--url` | string | No | Source URL | `"https://support.example.com/ticket/456"` |
|
|
147
|
-
| `--wait` | flag | No | Wait for processing to complete | `--wait` |
|
|
148
|
-
| `--json` | flag | No | Output in JSON format | `--json` |
|
|
149
|
-
| `--page` | number | No | Page number for listing | `--page 2` |
|
|
150
|
-
| `--limit` | number | No | Items per page (max 100) | `--limit 20` |
|
|
151
|
-
|
|
152
|
-
## Feedback Commands
|
|
153
|
-
|
|
154
|
-
### List AI-Generated Insights
|
|
155
|
-
|
|
156
|
-
#### Basic List
|
|
157
|
-
```bash
|
|
158
|
-
cl feedback
|
|
159
|
-
# Shows table of AI-generated insights
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
#### With Pagination
|
|
163
|
-
```bash
|
|
164
|
-
cl feedback --page 2 --limit 5
|
|
165
|
-
# Shows page 2 with 5 items per page
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
#### JSON Output
|
|
169
|
-
```bash
|
|
170
|
-
cl feedback --json
|
|
171
|
-
# Output: {"data":[...],"pagination":{...}}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### View Specific Insight
|
|
175
|
-
|
|
176
|
-
#### By ID
|
|
177
|
-
```bash
|
|
178
|
-
cl feedback 2ea8f556-052b-4f5c-bf86-833780b3d00d
|
|
179
|
-
# Shows detailed insight information
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
#### JSON Output
|
|
183
|
-
```bash
|
|
184
|
-
cl feedback 2ea8f556-052b-4f5c-bf86-833780b3d00d --json
|
|
185
|
-
# Output: {"id":"...","title":"...","content":"..."}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Feedback Parameters
|
|
189
|
-
|
|
190
|
-
| Parameter | Type | Required | Description | Example |
|
|
191
|
-
|-----------|------|----------|-------------|---------|
|
|
192
|
-
| `id` | string | Yes* | Insight ID for detailed view | `2ea8f556-052b-4f5c-bf86-833780b3d00d` |
|
|
193
|
-
| `--page` | number | No | Page number for listing | `--page 2` |
|
|
194
|
-
| `--limit` | number | No | Items per page (max 100) | `--limit 20` |
|
|
195
|
-
| `--json` | flag | No | Output in JSON format | `--json` |
|
|
196
|
-
|
|
197
|
-
*Required only for detailed view
|
|
198
|
-
|
|
199
|
-
## Team Commands
|
|
200
|
-
|
|
201
|
-
### Update Team Website
|
|
202
|
-
|
|
203
|
-
#### Basic Update
|
|
204
|
-
```bash
|
|
205
|
-
cl team website update "https://example.com"
|
|
206
|
-
# Output: Team website updated successfully
|
|
207
|
-
# Website: https://example.com
|
|
208
|
-
# Updated: 2024-01-15T10:30:00Z
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
#### With Validation
|
|
212
|
-
```bash
|
|
213
|
-
cl team website update "https://mycompany.com"
|
|
214
|
-
# Output: Team website updated successfully
|
|
215
|
-
# Website: https://mycompany.com
|
|
216
|
-
# Updated: 2024-01-15T10:30:00Z
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Team Management
|
|
220
|
-
```bash
|
|
221
|
-
cl team
|
|
222
|
-
# Shows available team management commands
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### Team Parameters
|
|
226
|
-
|
|
227
|
-
| Parameter | Type | Required | Description | Example |
|
|
228
|
-
|-----------|------|----------|-------------|---------|
|
|
229
|
-
| `website` | string | Yes | Team website URL (must include http:// or https://) | `"https://example.com"` |
|
|
230
|
-
|
|
231
|
-
### Team Error Handling
|
|
232
|
-
|
|
233
|
-
#### Invalid Website URL
|
|
234
|
-
```bash
|
|
235
|
-
cl team website update "invalid-url"
|
|
236
|
-
# Error: Invalid website URL format. Must include protocol (http:// or https://) and domain
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
#### Missing API Key
|
|
240
|
-
```bash
|
|
241
|
-
cl team website update "https://example.com"
|
|
242
|
-
# Error: API key not configured. Run: cl config set --api-key <key>
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## General Commands
|
|
246
|
-
|
|
247
|
-
### Version
|
|
248
|
-
```bash
|
|
249
|
-
cl --version
|
|
250
|
-
# Output: 0.2.0
|
|
251
|
-
|
|
252
|
-
cl version
|
|
253
|
-
# Output: 0.2.0
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
### Help
|
|
257
|
-
```bash
|
|
258
|
-
cl --help
|
|
259
|
-
# Shows main help
|
|
260
|
-
|
|
261
|
-
cl help
|
|
262
|
-
# Shows main help
|
|
263
|
-
|
|
264
|
-
cl help input
|
|
265
|
-
# Shows input command help
|
|
266
|
-
|
|
267
|
-
cl help feedback
|
|
268
|
-
# Shows feedback command help
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
### Help Parameters
|
|
272
|
-
|
|
273
|
-
| Command | Description | Example |
|
|
274
|
-
|---------|-------------|---------|
|
|
275
|
-
| `cl --help` | Main help with all commands | `cl --help` |
|
|
276
|
-
| `cl help <command>` | Specific command help | `cl help input` |
|
|
277
|
-
|
|
278
|
-
## Error Handling
|
|
279
|
-
|
|
280
|
-
### Common Error Messages
|
|
281
|
-
|
|
282
|
-
#### No API Key
|
|
283
|
-
```bash
|
|
284
|
-
cl input "Test feedback"
|
|
285
|
-
# Error: 🔑 No API key configured!
|
|
286
|
-
#
|
|
287
|
-
# To get started:
|
|
288
|
-
# 1. Go to https://closedloop.sh
|
|
289
|
-
# 2. Sign up for a free account
|
|
290
|
-
# 3. Generate your API key
|
|
291
|
-
# 4. Run: cl config --set-api-key <your-key>
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
#### Invalid API Key
|
|
295
|
-
```bash
|
|
296
|
-
cl input "Test feedback"
|
|
297
|
-
# Error: ❌ Invalid API key. Get your free API key at https://closedloop.sh
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
#### Validation Error
|
|
301
|
-
```bash
|
|
302
|
-
cl input ""
|
|
303
|
-
# Error: ❌ Validation Error: Content cannot be empty
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
#### API Error
|
|
307
|
-
```bash
|
|
308
|
-
cl input "Test feedback"
|
|
309
|
-
# Error: ❌ API Error: 500 - Internal server error
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
### Error Codes
|
|
313
|
-
|
|
314
|
-
| Code | Description | Solution |
|
|
315
|
-
|------|-------------|----------|
|
|
316
|
-
| `NO_API_KEY` | No API key configured | Run `cl config set --api-key <key>` |
|
|
317
|
-
| `INVALID_API_KEY` | API key is invalid | Get new key from https://closedloop.sh |
|
|
318
|
-
| `VALIDATION_ERROR` | Input validation failed | Check input format and requirements |
|
|
319
|
-
| `API_ERROR` | Server error | Check internet connection, try again later |
|
|
320
|
-
| `RATE_LIMITED` | Too many requests | Wait and retry |
|
|
321
|
-
| `NOT_FOUND` | Resource not found | Check ID is correct |
|
|
322
|
-
|
|
323
|
-
## Examples
|
|
324
|
-
|
|
325
|
-
### Basic Workflow
|
|
326
|
-
```bash
|
|
327
|
-
# 1. Configure API key
|
|
328
|
-
cl config set --api-key your-api-key-here
|
|
329
|
-
|
|
330
|
-
# 2. Submit customer product feedback
|
|
331
|
-
cl input "The new dashboard is confusing and hard to navigate"
|
|
332
|
-
|
|
333
|
-
# 3. Wait for AI analysis
|
|
334
|
-
cl input "Customer complaint about performance" --wait
|
|
335
|
-
|
|
336
|
-
# 4. View AI-generated insights
|
|
337
|
-
cl feedback
|
|
338
|
-
|
|
339
|
-
# 5. Get detailed insight
|
|
340
|
-
cl feedback 2ea8f556-052b-4f5c-bf86-833780b3d00d
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### Advanced Workflow
|
|
344
|
-
```bash
|
|
345
|
-
# 1. Submit with full metadata
|
|
346
|
-
cl input "Great product, love the new features!" \
|
|
347
|
-
--title "Positive Feedback" \
|
|
348
|
-
--customer "enterprise-123" \
|
|
349
|
-
--name "Jane Smith" \
|
|
350
|
-
--email "jane@example.com" \
|
|
351
|
-
--url "https://support.example.com/ticket/789"
|
|
352
|
-
|
|
353
|
-
# 2. List all inputs with pagination
|
|
354
|
-
cl input --page 1 --limit 20
|
|
355
|
-
|
|
356
|
-
# 3. Get JSON output for scripting
|
|
357
|
-
cl feedback --json | jq '.data[0].title'
|
|
358
|
-
|
|
359
|
-
# 4. View specific input details
|
|
360
|
-
cl input 74e3dd87-878f-41cf-8e5a-87527bbf7770 --json
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Scripting Examples
|
|
364
|
-
```bash
|
|
365
|
-
#!/bin/bash
|
|
366
|
-
# submit-feedback.sh
|
|
367
|
-
|
|
368
|
-
# Submit feedback and get ID
|
|
369
|
-
ID=$(cl input "$1" --json | jq -r '.id')
|
|
370
|
-
|
|
371
|
-
# Wait for processing
|
|
372
|
-
cl input "$ID" --wait
|
|
373
|
-
|
|
374
|
-
# Show results
|
|
375
|
-
cl feedback
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
```bash
|
|
379
|
-
#!/bin/bash
|
|
380
|
-
# get-insights.sh
|
|
381
|
-
|
|
382
|
-
# Get all insights in JSON format
|
|
383
|
-
cl feedback --json | jq '.data[] | {id: .id, title: .title, status: .status}'
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
## Output Formats
|
|
387
|
-
|
|
388
|
-
### Table Format (Default)
|
|
389
|
-
```
|
|
390
|
-
┌─────────────────────────────────────┬─────────────────────────────┬─────────────┬─────────────┐
|
|
391
|
-
│ ID │ Title │ Status │ Created │
|
|
392
|
-
├─────────────────────────────────────┼─────────────────────────────┼─────────────┼─────────────┤
|
|
393
|
-
│ 74e3dd87-878f-41cf-8e5a-87527bbf7770 │ Dashboard UX Issues │ completed │ 2024-01-15 │
|
|
394
|
-
│ 2ea8f556-052b-4f5c-bf86-833780b3d00d │ Performance Problems │ processing │ 2024-01-15 │
|
|
395
|
-
└─────────────────────────────────────┴─────────────────────────────┴─────────────┴─────────────┘
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
### JSON Format
|
|
399
|
-
```json
|
|
400
|
-
{
|
|
401
|
-
"data": [
|
|
402
|
-
{
|
|
403
|
-
"id": "74e3dd87-878f-41cf-8e5a-87527bbf7770",
|
|
404
|
-
"title": "Dashboard UX Issues",
|
|
405
|
-
"content": "The new dashboard is confusing...",
|
|
406
|
-
"status": "completed",
|
|
407
|
-
"created_at": "2024-01-15T10:30:00Z"
|
|
408
|
-
}
|
|
409
|
-
],
|
|
410
|
-
"pagination": {
|
|
411
|
-
"page": 1,
|
|
412
|
-
"limit": 20,
|
|
413
|
-
"total": 1,
|
|
414
|
-
"pages": 1
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
## Best Practices
|
|
420
|
-
|
|
421
|
-
### 1. Use Descriptive Titles
|
|
422
|
-
```bash
|
|
423
|
-
# Good
|
|
424
|
-
cl input "The app crashes when uploading files" --title "File Upload Crash"
|
|
425
|
-
|
|
426
|
-
# Bad
|
|
427
|
-
cl input "App broken" --title "Issue"
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
### 2. Include Customer Context
|
|
431
|
-
```bash
|
|
432
|
-
# Good
|
|
433
|
-
cl input "Feature request" --customer "enterprise-123" --name "John Doe"
|
|
434
|
-
|
|
435
|
-
# Bad
|
|
436
|
-
cl input "Feature request"
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
### 3. Use JSON for Scripting
|
|
440
|
-
```bash
|
|
441
|
-
# Good
|
|
442
|
-
cl feedback --json | jq '.data[0].title'
|
|
443
|
-
|
|
444
|
-
# Bad
|
|
445
|
-
cl feedback | grep "Title"
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
### 4. Handle Errors Gracefully
|
|
449
|
-
```bash
|
|
450
|
-
#!/bin/bash
|
|
451
|
-
if ! cl input "$1" --wait; then
|
|
452
|
-
echo "Failed to submit feedback"
|
|
453
|
-
exit 1
|
|
454
|
-
fi
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
### 5. Use Pagination for Large Datasets
|
|
458
|
-
```bash
|
|
459
|
-
# Good - increase limit for larger datasets
|
|
460
|
-
cl input --page 1 --limit 50
|
|
461
|
-
|
|
462
|
-
# Also good - use default pagination
|
|
463
|
-
cl input --page 2 # Shows 20 items per page (default)
|
|
464
|
-
|
|
465
|
-
# Bad - trying to show too many at once
|
|
466
|
-
cl input --limit 200 # Will be capped at 100 (max limit)
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
## Troubleshooting
|
|
470
|
-
|
|
471
|
-
### CLI Not Found
|
|
472
|
-
```bash
|
|
473
|
-
# Check if installed globally
|
|
474
|
-
npm list -g @closedloop-ai/cli
|
|
475
|
-
|
|
476
|
-
# Reinstall if needed
|
|
477
|
-
npm install -g @closedloop-ai/cli
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
### Permission Denied
|
|
481
|
-
```bash
|
|
482
|
-
# Fix npm permissions
|
|
483
|
-
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
### API Key Not Working
|
|
487
|
-
```bash
|
|
488
|
-
# Check configuration
|
|
489
|
-
cl config
|
|
490
|
-
|
|
491
|
-
# Reset API key
|
|
492
|
-
cl config set --api-key your-new-key-here
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
### Slow Performance
|
|
496
|
-
```bash
|
|
497
|
-
# Check internet connection
|
|
498
|
-
ping mcp.closedloop.sh
|
|
499
|
-
|
|
500
|
-
# Try with smaller batches
|
|
501
|
-
cl input --limit 10
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
## Support
|
|
505
|
-
|
|
506
|
-
- **Documentation**: [https://docs.closedloop.sh](https://docs.closedloop.sh)
|
|
507
|
-
- **GitHub Issues**: [https://github.com/closed-loop-ai/closedloop-cli/issues](https://github.com/closed-loop-ai/closedloop-cli/issues)
|
|
508
|
-
- **Email**: support@closedloop.sh
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const commander_1 = require("commander");
|
|
4
|
-
// Mock the command handlers
|
|
5
|
-
jest.mock('../commands/input', () => ({
|
|
6
|
-
handleInputCommand: jest.fn()
|
|
7
|
-
}));
|
|
8
|
-
jest.mock('../commands/feedback', () => ({
|
|
9
|
-
handleFeedbackCommand: jest.fn()
|
|
10
|
-
}));
|
|
11
|
-
jest.mock('../commands/config', () => ({
|
|
12
|
-
configCommand: new commander_1.Command('config')
|
|
13
|
-
}));
|
|
14
|
-
describe('CLI Structure', () => {
|
|
15
|
-
it('should have correct command structure', () => {
|
|
16
|
-
// This is a basic smoke test to ensure the CLI can be imported
|
|
17
|
-
// without errors
|
|
18
|
-
expect(() => {
|
|
19
|
-
require('../cli');
|
|
20
|
-
}).not.toThrow();
|
|
21
|
-
});
|
|
22
|
-
it('should handle input command', async () => {
|
|
23
|
-
const { handleInputCommand } = require('../commands/input');
|
|
24
|
-
// Mock successful execution
|
|
25
|
-
handleInputCommand.mockResolvedValue(undefined);
|
|
26
|
-
await handleInputCommand('test content', {});
|
|
27
|
-
expect(handleInputCommand).toHaveBeenCalledWith('test content', {});
|
|
28
|
-
});
|
|
29
|
-
it('should handle feedback command', async () => {
|
|
30
|
-
const { handleFeedbackCommand } = require('../commands/feedback');
|
|
31
|
-
// Mock successful execution
|
|
32
|
-
handleFeedbackCommand.mockResolvedValue(undefined);
|
|
33
|
-
await handleFeedbackCommand('test-id', {});
|
|
34
|
-
expect(handleFeedbackCommand).toHaveBeenCalledWith('test-id', {});
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
//# sourceMappingURL=cli.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../../src/__tests__/cli.test.ts"],"names":[],"mappings":";;AAAA,yCAAoC;AAEpC,4BAA4B;AAC5B,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;IACpC,kBAAkB,EAAE,IAAI,CAAC,EAAE,EAAE;CAC9B,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE;CACjC,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IACrC,aAAa,EAAE,IAAI,mBAAO,CAAC,QAAQ,CAAC;CACrC,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,+DAA+D;QAC/D,iBAAiB;QACjB,MAAM,CAAC,GAAG,EAAE;YACV,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAE5D,4BAA4B;QAC3B,kBAAgC,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE/D,MAAM,kBAAkB,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7C,MAAM,CAAC,kBAAkB,CAAC,CAAC,oBAAoB,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAElE,4BAA4B;QAC3B,qBAAmC,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAElE,MAAM,qBAAqB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,qBAAqB,CAAC,CAAC,oBAAoB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const config_1 = require("../config");
|
|
4
|
-
// Mock the config for testing
|
|
5
|
-
jest.mock('../config', () => ({
|
|
6
|
-
config: {
|
|
7
|
-
get: jest.fn(),
|
|
8
|
-
set: jest.fn(),
|
|
9
|
-
getConfigPath: jest.fn()
|
|
10
|
-
}
|
|
11
|
-
}));
|
|
12
|
-
describe('Config Manager', () => {
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
});
|
|
16
|
-
it('should get config values', () => {
|
|
17
|
-
config_1.config.get.mockReturnValue({ apiKey: 'test-key' });
|
|
18
|
-
const result = config_1.config.get();
|
|
19
|
-
expect(result).toEqual({ apiKey: 'test-key' });
|
|
20
|
-
expect(config_1.config.get).toHaveBeenCalled();
|
|
21
|
-
});
|
|
22
|
-
it('should set config values', () => {
|
|
23
|
-
config_1.config.set.mockImplementation(() => { });
|
|
24
|
-
config_1.config.set('apiKey', 'new-key');
|
|
25
|
-
expect(config_1.config.set).toHaveBeenCalledWith('apiKey', 'new-key');
|
|
26
|
-
});
|
|
27
|
-
it('should get config path', () => {
|
|
28
|
-
config_1.config.getConfigPath.mockReturnValue('/path/to/config.json');
|
|
29
|
-
const result = config_1.config.getConfigPath();
|
|
30
|
-
expect(result).toBe('/path/to/config.json');
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
//# sourceMappingURL=config.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":";;AAAA,sCAAmC;AAEnC,8BAA8B;AAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,MAAM,EAAE;QACN,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE;QACd,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE;QACd,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;KACzB;CACF,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACjC,eAAM,CAAC,GAAiB,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAElE,MAAM,MAAM,GAAG,eAAM,CAAC,GAAG,EAAE,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAC/C,MAAM,CAAC,eAAM,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACjC,eAAM,CAAC,GAAiB,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAEvD,eAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAChC,MAAM,CAAC,eAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAC/B,eAAM,CAAC,aAA2B,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC;QAE5E,MAAM,MAAM,GAAG,eAAM,CAAC,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const errors_1 = require("../utils/errors");
|
|
4
|
-
describe('Error Utils', () => {
|
|
5
|
-
describe('CliError', () => {
|
|
6
|
-
it('should create error with message and code', () => {
|
|
7
|
-
const error = new errors_1.CliError('Test error', errors_1.ERROR_CODES.VALIDATION_ERROR);
|
|
8
|
-
expect(error.message).toBe('Test error');
|
|
9
|
-
expect(error.code).toBe(errors_1.ERROR_CODES.VALIDATION_ERROR);
|
|
10
|
-
expect(error.exitCode).toBe(1);
|
|
11
|
-
});
|
|
12
|
-
it('should create error with custom exit code', () => {
|
|
13
|
-
const error = new errors_1.CliError('Test error', errors_1.ERROR_CODES.VALIDATION_ERROR, 2);
|
|
14
|
-
expect(error.exitCode).toBe(2);
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
describe('handleApiError', () => {
|
|
18
|
-
it('should handle 401 errors', () => {
|
|
19
|
-
const mockError = {
|
|
20
|
-
response: {
|
|
21
|
-
status: 401,
|
|
22
|
-
data: { message: 'Unauthorized' }
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
const result = (0, errors_1.handleApiError)(mockError);
|
|
26
|
-
expect(result.message).toContain('Invalid API key');
|
|
27
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.UNAUTHORIZED);
|
|
28
|
-
});
|
|
29
|
-
it('should handle 404 errors', () => {
|
|
30
|
-
const mockError = {
|
|
31
|
-
response: {
|
|
32
|
-
status: 404,
|
|
33
|
-
data: { message: 'Not found' }
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
const result = (0, errors_1.handleApiError)(mockError);
|
|
37
|
-
expect(result.message).toContain('Resource not found');
|
|
38
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.NOT_FOUND);
|
|
39
|
-
});
|
|
40
|
-
it('should handle 429 errors', () => {
|
|
41
|
-
const mockError = {
|
|
42
|
-
response: {
|
|
43
|
-
status: 429,
|
|
44
|
-
data: { message: 'Rate limited' }
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
const result = (0, errors_1.handleApiError)(mockError);
|
|
48
|
-
expect(result.message).toContain('Rate limit exceeded');
|
|
49
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.RATE_LIMITED);
|
|
50
|
-
});
|
|
51
|
-
it('should handle 500 errors', () => {
|
|
52
|
-
const mockError = {
|
|
53
|
-
response: {
|
|
54
|
-
status: 500,
|
|
55
|
-
data: { message: 'Internal server error' }
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
const result = (0, errors_1.handleApiError)(mockError);
|
|
59
|
-
expect(result.message).toContain('Server error');
|
|
60
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.SERVER_ERROR);
|
|
61
|
-
});
|
|
62
|
-
it('should handle connection errors', () => {
|
|
63
|
-
const mockError = {
|
|
64
|
-
code: 'ENOTFOUND'
|
|
65
|
-
};
|
|
66
|
-
const result = (0, errors_1.handleApiError)(mockError);
|
|
67
|
-
expect(result.message).toContain('Cannot connect to ClosedLoop servers');
|
|
68
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.CONNECTION_ERROR);
|
|
69
|
-
});
|
|
70
|
-
it('should handle timeout errors', () => {
|
|
71
|
-
const mockError = {
|
|
72
|
-
code: 'ETIMEDOUT'
|
|
73
|
-
};
|
|
74
|
-
const result = (0, errors_1.handleApiError)(mockError);
|
|
75
|
-
expect(result.message).toContain('Request timed out');
|
|
76
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.CONNECTION_ERROR);
|
|
77
|
-
});
|
|
78
|
-
it('should handle unknown errors', () => {
|
|
79
|
-
const mockError = {
|
|
80
|
-
message: 'Unknown error'
|
|
81
|
-
};
|
|
82
|
-
const result = (0, errors_1.handleApiError)(mockError);
|
|
83
|
-
expect(result.message).toBe('Unknown error');
|
|
84
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.UNKNOWN_ERROR);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
describe('handleValidationError', () => {
|
|
88
|
-
it('should create validation error', () => {
|
|
89
|
-
const result = (0, errors_1.handleValidationError)('Validation failed');
|
|
90
|
-
expect(result.message).toBe('Validation failed');
|
|
91
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.VALIDATION_ERROR);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
describe('handleInputError', () => {
|
|
95
|
-
it('should create input error', () => {
|
|
96
|
-
const result = (0, errors_1.handleInputError)('Input invalid');
|
|
97
|
-
expect(result.message).toBe('Input invalid');
|
|
98
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.INVALID_INPUT);
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
describe('handleProcessingError', () => {
|
|
102
|
-
it('should create processing error', () => {
|
|
103
|
-
const result = (0, errors_1.handleProcessingError)('Processing failed');
|
|
104
|
-
expect(result.message).toBe('Processing failed');
|
|
105
|
-
expect(result.code).toBe(errors_1.ERROR_CODES.PROCESSING_ERROR);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
//# sourceMappingURL=errors.test.js.map
|