@b0xs/recorder 1.0.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 +89 -0
- package/dist/api/client.d.ts +111 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +186 -0
- package/dist/api/client.js.map +1 -0
- package/dist/cli/commands/init.d.ts +7 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +104 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/login.d.ts +7 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +154 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/record.d.ts +14 -0
- package/dist/cli/commands/record.d.ts.map +1 -0
- package/dist/cli/commands/record.js +244 -0
- package/dist/cli/commands/record.js.map +1 -0
- package/dist/core/chunk-uploader.d.ts +52 -0
- package/dist/core/chunk-uploader.d.ts.map +1 -0
- package/dist/core/chunk-uploader.js +180 -0
- package/dist/core/chunk-uploader.js.map +1 -0
- package/dist/core/pty-manager.d.ts +72 -0
- package/dist/core/pty-manager.d.ts.map +1 -0
- package/dist/core/pty-manager.js +205 -0
- package/dist/core/pty-manager.js.map +1 -0
- package/dist/core/recorder.d.ts +104 -0
- package/dist/core/recorder.d.ts.map +1 -0
- package/dist/core/recorder.js +330 -0
- package/dist/core/recorder.js.map +1 -0
- package/dist/core/stream-client.d.ts +62 -0
- package/dist/core/stream-client.d.ts.map +1 -0
- package/dist/core/stream-client.js +185 -0
- package/dist/core/stream-client.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/auth-store.d.ts +37 -0
- package/dist/storage/auth-store.d.ts.map +1 -0
- package/dist/storage/auth-store.js +168 -0
- package/dist/storage/auth-store.js.map +1 -0
- package/dist/storage/config-store.d.ts +74 -0
- package/dist/storage/config-store.d.ts.map +1 -0
- package/dist/storage/config-store.js +164 -0
- package/dist/storage/config-store.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @b0xs/recorder
|
|
2
|
+
|
|
3
|
+
CLI tool for recording terminal sessions to the BOXS platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @b0xs/recorder
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### First-time Setup
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Authenticate with your API key
|
|
17
|
+
boxs login
|
|
18
|
+
|
|
19
|
+
# Initialize config (optional)
|
|
20
|
+
boxs init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Recording a Session
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Start recording
|
|
27
|
+
boxs record
|
|
28
|
+
|
|
29
|
+
# Record with a specific title
|
|
30
|
+
boxs record --title "My pentesting session"
|
|
31
|
+
|
|
32
|
+
# Record and run a specific command
|
|
33
|
+
boxs record "nmap -sV scanme.nmap.org"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Options
|
|
37
|
+
|
|
38
|
+
- `--title` - Session title
|
|
39
|
+
- `--description` - Session description
|
|
40
|
+
- `--visibility` - Session visibility (public, private, unlisted)
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
- **Real-time upload** - Chunks uploaded every 60 seconds
|
|
45
|
+
- **Offline mode** - Continue recording without network, auto-upload when reconnected
|
|
46
|
+
- **Command detection** - Automatically detect and mark commands in timeline
|
|
47
|
+
- **Crash recovery** - Resume incomplete sessions after crashes
|
|
48
|
+
- **Secure auth** - API keys stored in OS keychain
|
|
49
|
+
|
|
50
|
+
## Configuration
|
|
51
|
+
|
|
52
|
+
Config file: `~/.boxs/config.json`
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"apiUrl": "https://boxs.sh",
|
|
57
|
+
"defaults": {
|
|
58
|
+
"visibility": "private",
|
|
59
|
+
"chunkDuration": 60000
|
|
60
|
+
},
|
|
61
|
+
"recorder": {
|
|
62
|
+
"promptPatterns": ["\\\\$\\\\s$", "#\\\\s$"],
|
|
63
|
+
"maxBufferedChunks": 10,
|
|
64
|
+
"uploadRetries": 5
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## How It Works
|
|
70
|
+
|
|
71
|
+
1. **Captures terminal** - Uses PTY to capture all terminal I/O
|
|
72
|
+
2. **Encodes with BoxsBinary** - Compresses data using custom binary format
|
|
73
|
+
3. **Uploads chunks** - Sends 60-second chunks to BOXS platform
|
|
74
|
+
4. **Detects commands** - Marks command execution for timeline
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
|
79
|
+
|
|
80
|
+
## Related Packages
|
|
81
|
+
|
|
82
|
+
- [`@b0xs/binary`](https://www.npmjs.com/package/@b0xs/binary) - Binary format encoder/decoder
|
|
83
|
+
- [`@b0xs/termbox`](https://www.npmjs.com/package/@b0xs/termbox) - React player component
|
|
84
|
+
|
|
85
|
+
## Links
|
|
86
|
+
|
|
87
|
+
- [GitHub](https://github.com/ozipi/recorder)
|
|
88
|
+
- [Documentation](https://boxs.sh/docs)
|
|
89
|
+
- [Website](https://boxs.sh)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Client for BOXS Platform
|
|
3
|
+
*
|
|
4
|
+
* Handles all HTTP requests to the BOXS API with authentication
|
|
5
|
+
*/
|
|
6
|
+
export interface CreateSessionRequest {
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
visibility?: 'public' | 'private' | 'unlisted' | 'team';
|
|
10
|
+
}
|
|
11
|
+
export interface CreateSessionResponse {
|
|
12
|
+
id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
visibility: string;
|
|
16
|
+
status: string;
|
|
17
|
+
userId: string;
|
|
18
|
+
createdAt: string;
|
|
19
|
+
uploadEndpoint: string;
|
|
20
|
+
}
|
|
21
|
+
export interface UploadChunkResponse {
|
|
22
|
+
chunk: {
|
|
23
|
+
index: number;
|
|
24
|
+
url: string;
|
|
25
|
+
pathname: string;
|
|
26
|
+
size: number;
|
|
27
|
+
offset: number;
|
|
28
|
+
duration: number;
|
|
29
|
+
frameCount: number;
|
|
30
|
+
eventCount: number;
|
|
31
|
+
};
|
|
32
|
+
totalChunks: number;
|
|
33
|
+
}
|
|
34
|
+
export interface UpdateSessionRequest {
|
|
35
|
+
status?: 'recording' | 'completed' | 'failed';
|
|
36
|
+
title?: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
visibility?: 'public' | 'private' | 'unlisted' | 'team';
|
|
39
|
+
}
|
|
40
|
+
export interface APIClientOptions {
|
|
41
|
+
apiKey: string;
|
|
42
|
+
baseUrl?: string;
|
|
43
|
+
timeout?: number;
|
|
44
|
+
}
|
|
45
|
+
export declare class APIClient {
|
|
46
|
+
private client;
|
|
47
|
+
private apiKey;
|
|
48
|
+
private baseUrl;
|
|
49
|
+
constructor(options: APIClientOptions);
|
|
50
|
+
/**
|
|
51
|
+
* Validate API key by making a test request
|
|
52
|
+
*/
|
|
53
|
+
validateApiKey(): Promise<boolean>;
|
|
54
|
+
/**
|
|
55
|
+
* Create a new recording session
|
|
56
|
+
*/
|
|
57
|
+
createSession(request: CreateSessionRequest): Promise<CreateSessionResponse>;
|
|
58
|
+
/**
|
|
59
|
+
* Upload a chunk to a session
|
|
60
|
+
*/
|
|
61
|
+
uploadChunk(sessionId: string, chunkData: Buffer): Promise<UploadChunkResponse>;
|
|
62
|
+
/**
|
|
63
|
+
* Update session metadata or status
|
|
64
|
+
*/
|
|
65
|
+
updateSession(sessionId: string, updates: UpdateSessionRequest): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Get session details
|
|
68
|
+
*/
|
|
69
|
+
getSession(sessionId: string): Promise<any>;
|
|
70
|
+
/**
|
|
71
|
+
* Get the full session URL for sharing
|
|
72
|
+
*/
|
|
73
|
+
getSessionUrl(sessionId: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Start streaming session (get WebSocket token)
|
|
76
|
+
*/
|
|
77
|
+
startStream(sessionId: string): Promise<{
|
|
78
|
+
streamToken: string;
|
|
79
|
+
wsUrl: string;
|
|
80
|
+
}>;
|
|
81
|
+
/**
|
|
82
|
+
* Stop streaming session
|
|
83
|
+
*/
|
|
84
|
+
stopStream(sessionId: string): Promise<void>;
|
|
85
|
+
}
|
|
86
|
+
export declare class APIError extends Error {
|
|
87
|
+
statusCode?: number | undefined;
|
|
88
|
+
constructor(message: string, statusCode?: number | undefined);
|
|
89
|
+
}
|
|
90
|
+
export declare class AuthenticationError extends APIError {
|
|
91
|
+
constructor(message: string);
|
|
92
|
+
}
|
|
93
|
+
export declare class ForbiddenError extends APIError {
|
|
94
|
+
constructor(message: string);
|
|
95
|
+
}
|
|
96
|
+
export declare class NotFoundError extends APIError {
|
|
97
|
+
constructor(message: string);
|
|
98
|
+
}
|
|
99
|
+
export declare class ConflictError extends APIError {
|
|
100
|
+
constructor(message: string);
|
|
101
|
+
}
|
|
102
|
+
export declare class RateLimitError extends APIError {
|
|
103
|
+
constructor(message: string);
|
|
104
|
+
}
|
|
105
|
+
export declare class ServerError extends APIError {
|
|
106
|
+
constructor(message: string);
|
|
107
|
+
}
|
|
108
|
+
export declare class NetworkError extends APIError {
|
|
109
|
+
constructor(message: string);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* API Client for BOXS Platform
|
|
4
|
+
*
|
|
5
|
+
* Handles all HTTP requests to the BOXS API with authentication
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.NetworkError = exports.ServerError = exports.RateLimitError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.AuthenticationError = exports.APIError = exports.APIClient = void 0;
|
|
12
|
+
const axios_1 = __importDefault(require("axios"));
|
|
13
|
+
class APIClient {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.apiKey = options.apiKey;
|
|
16
|
+
this.baseUrl = options.baseUrl || 'https://boxs.sh';
|
|
17
|
+
this.client = axios_1.default.create({
|
|
18
|
+
baseURL: this.baseUrl,
|
|
19
|
+
timeout: options.timeout || 30000,
|
|
20
|
+
headers: {
|
|
21
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
// Add response interceptor for error handling
|
|
26
|
+
this.client.interceptors.response.use((response) => response, (error) => {
|
|
27
|
+
if (error.response) {
|
|
28
|
+
const status = error.response.status;
|
|
29
|
+
const data = error.response.data;
|
|
30
|
+
switch (status) {
|
|
31
|
+
case 401:
|
|
32
|
+
throw new AuthenticationError('Invalid API key. Run: boxs login');
|
|
33
|
+
case 403:
|
|
34
|
+
throw new ForbiddenError('Access forbidden');
|
|
35
|
+
case 404:
|
|
36
|
+
throw new NotFoundError(data.error || 'Resource not found');
|
|
37
|
+
case 409:
|
|
38
|
+
throw new ConflictError(data.error || 'Conflict');
|
|
39
|
+
case 429:
|
|
40
|
+
throw new RateLimitError('Rate limit exceeded. Please try again later.');
|
|
41
|
+
case 500:
|
|
42
|
+
case 502:
|
|
43
|
+
case 503:
|
|
44
|
+
throw new ServerError('Server error. Retrying...');
|
|
45
|
+
default:
|
|
46
|
+
throw new APIError(data.error || 'Unknown API error', status);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else if (error.request) {
|
|
50
|
+
throw new NetworkError('Network error. Check your connection.');
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
throw new APIError(error.message);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Validate API key by making a test request
|
|
59
|
+
*/
|
|
60
|
+
async validateApiKey() {
|
|
61
|
+
try {
|
|
62
|
+
await this.client.get('/api/users/me');
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error instanceof AuthenticationError) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a new recording session
|
|
74
|
+
*/
|
|
75
|
+
async createSession(request) {
|
|
76
|
+
const response = await this.client.post('/api/sessions', {
|
|
77
|
+
title: request.title,
|
|
78
|
+
description: request.description,
|
|
79
|
+
visibility: request.visibility || 'private',
|
|
80
|
+
});
|
|
81
|
+
return response.data;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Upload a chunk to a session
|
|
85
|
+
*/
|
|
86
|
+
async uploadChunk(sessionId, chunkData) {
|
|
87
|
+
const response = await this.client.post(`/api/sessions/${sessionId}/chunks`, chunkData, {
|
|
88
|
+
headers: {
|
|
89
|
+
'Content-Type': 'application/octet-stream',
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
return response.data;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Update session metadata or status
|
|
96
|
+
*/
|
|
97
|
+
async updateSession(sessionId, updates) {
|
|
98
|
+
await this.client.patch(`/api/sessions/${sessionId}`, updates);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get session details
|
|
102
|
+
*/
|
|
103
|
+
async getSession(sessionId) {
|
|
104
|
+
const response = await this.client.get(`/api/sessions/${sessionId}`);
|
|
105
|
+
return response.data;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the full session URL for sharing
|
|
109
|
+
*/
|
|
110
|
+
getSessionUrl(sessionId) {
|
|
111
|
+
return `${this.baseUrl}/sessions/${sessionId}`;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Start streaming session (get WebSocket token)
|
|
115
|
+
*/
|
|
116
|
+
async startStream(sessionId) {
|
|
117
|
+
const response = await this.client.post(`/api/sessions/${sessionId}/start-stream`);
|
|
118
|
+
return response.data;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Stop streaming session
|
|
122
|
+
*/
|
|
123
|
+
async stopStream(sessionId) {
|
|
124
|
+
await this.client.post(`/api/sessions/${sessionId}/stop-stream`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.APIClient = APIClient;
|
|
128
|
+
// Custom error classes
|
|
129
|
+
class APIError extends Error {
|
|
130
|
+
constructor(message, statusCode) {
|
|
131
|
+
super(message);
|
|
132
|
+
this.statusCode = statusCode;
|
|
133
|
+
this.name = 'APIError';
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.APIError = APIError;
|
|
137
|
+
class AuthenticationError extends APIError {
|
|
138
|
+
constructor(message) {
|
|
139
|
+
super(message, 401);
|
|
140
|
+
this.name = 'AuthenticationError';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.AuthenticationError = AuthenticationError;
|
|
144
|
+
class ForbiddenError extends APIError {
|
|
145
|
+
constructor(message) {
|
|
146
|
+
super(message, 403);
|
|
147
|
+
this.name = 'ForbiddenError';
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.ForbiddenError = ForbiddenError;
|
|
151
|
+
class NotFoundError extends APIError {
|
|
152
|
+
constructor(message) {
|
|
153
|
+
super(message, 404);
|
|
154
|
+
this.name = 'NotFoundError';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
exports.NotFoundError = NotFoundError;
|
|
158
|
+
class ConflictError extends APIError {
|
|
159
|
+
constructor(message) {
|
|
160
|
+
super(message, 409);
|
|
161
|
+
this.name = 'ConflictError';
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.ConflictError = ConflictError;
|
|
165
|
+
class RateLimitError extends APIError {
|
|
166
|
+
constructor(message) {
|
|
167
|
+
super(message, 429);
|
|
168
|
+
this.name = 'RateLimitError';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.RateLimitError = RateLimitError;
|
|
172
|
+
class ServerError extends APIError {
|
|
173
|
+
constructor(message) {
|
|
174
|
+
super(message, 500);
|
|
175
|
+
this.name = 'ServerError';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.ServerError = ServerError;
|
|
179
|
+
class NetworkError extends APIError {
|
|
180
|
+
constructor(message) {
|
|
181
|
+
super(message);
|
|
182
|
+
this.name = 'NetworkError';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.NetworkError = NetworkError;
|
|
186
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAgEjD"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Init Command
|
|
4
|
+
*
|
|
5
|
+
* Initialize configuration file with user preferences
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.initCommand = initCommand;
|
|
45
|
+
const readline = __importStar(require("readline"));
|
|
46
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
47
|
+
const config_store_1 = require("../../storage/config-store");
|
|
48
|
+
async function initCommand() {
|
|
49
|
+
console.log(chalk_1.default.cyan('\n⚙️ BOXS Recorder Configuration\n'));
|
|
50
|
+
const configStore = new config_store_1.ConfigStore();
|
|
51
|
+
const rl = readline.createInterface({
|
|
52
|
+
input: process.stdin,
|
|
53
|
+
output: process.stdout,
|
|
54
|
+
});
|
|
55
|
+
const question = (prompt, defaultValue) => {
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
const promptText = defaultValue
|
|
58
|
+
? `${prompt} ${chalk_1.default.gray(`(default: ${defaultValue})`)}: `
|
|
59
|
+
: `${prompt}: `;
|
|
60
|
+
rl.question(promptText, (answer) => {
|
|
61
|
+
resolve(answer || defaultValue || '');
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
try {
|
|
66
|
+
// API URL
|
|
67
|
+
const currentApiUrl = configStore.getApiUrl();
|
|
68
|
+
const apiUrl = await question('API URL', currentApiUrl);
|
|
69
|
+
if (apiUrl && apiUrl !== currentApiUrl) {
|
|
70
|
+
configStore.setApiUrl(apiUrl);
|
|
71
|
+
}
|
|
72
|
+
// Default visibility
|
|
73
|
+
const currentVisibility = configStore.getDefaultVisibility();
|
|
74
|
+
console.log(chalk_1.default.gray('\nVisibility options: public, private, unlisted, team'));
|
|
75
|
+
const visibility = await question('Default visibility', currentVisibility);
|
|
76
|
+
if (visibility && ['public', 'private', 'unlisted', 'team'].includes(visibility)) {
|
|
77
|
+
configStore.setDefaultVisibility(visibility);
|
|
78
|
+
}
|
|
79
|
+
// Chunk duration
|
|
80
|
+
const currentDuration = configStore.getChunkDuration();
|
|
81
|
+
const duration = await question('Chunk duration (ms)', currentDuration.toString());
|
|
82
|
+
if (duration) {
|
|
83
|
+
const durationNum = parseInt(duration);
|
|
84
|
+
if (!isNaN(durationNum)) {
|
|
85
|
+
try {
|
|
86
|
+
configStore.setChunkDuration(durationNum);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.log(chalk_1.default.yellow(`\n⚠ ${error.message}`));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
rl.close();
|
|
94
|
+
console.log(chalk_1.default.green('\n✓ Configuration saved!'));
|
|
95
|
+
console.log(chalk_1.default.gray(`\nConfig file: ${configStore.getConfigPath()}`));
|
|
96
|
+
console.log(chalk_1.default.gray('\nYou can edit this file directly or run this command again.\n'));
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
rl.close();
|
|
100
|
+
console.log(chalk_1.default.red(`\n✗ Error: ${error.message}\n`));
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CA+DlD"}
|