4runr-os 2.8.0 → 2.8.2
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-client.d.ts","sourceRoot":"","sources":["../src/gateway-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"gateway-client.d.ts","sourceRoot":"","sources":["../src/gateway-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IACpE,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,UAAU,CAAS;IAE3B,SAAgB,IAAI,EAAE;QACpB,MAAM,EAAE,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,QAAQ,CAAA;SAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QAClE,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;KACzE,CAAC;gBAEU,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IA2F3F,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC;IAKtB,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;CAI9B"}
|
package/dist/gateway-client.js
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* Self-contained client for connecting to 4Runr Gateway
|
|
4
4
|
*/
|
|
5
5
|
import axios from 'axios';
|
|
6
|
+
import { validateGatewayUrl } from './security/ssrf-protection.js';
|
|
6
7
|
export class GatewayClient {
|
|
7
8
|
http;
|
|
8
9
|
gatewayUrl;
|
|
9
10
|
runs;
|
|
10
11
|
constructor(config) {
|
|
11
12
|
// SECURITY: Validate gateway URL to prevent SSRF
|
|
12
|
-
const { validateGatewayUrl } = require('./security/ssrf-protection.js');
|
|
13
13
|
const validation = validateGatewayUrl(config.gatewayUrl);
|
|
14
14
|
if (!validation.valid) {
|
|
15
15
|
throw new Error(`Invalid gateway URL: ${validation.error}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-client.js","sourceRoot":"","sources":["../src/gateway-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"gateway-client.js","sourceRoot":"","sources":["../src/gateway-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAiCnE,MAAM,OAAO,aAAa;IAChB,IAAI,CAAgB;IACpB,UAAU,CAAS;IAEX,IAAI,CAKlB;IAEF,YAAY,MAAqF;QAC/F,iDAAiD;QACjD,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAEzD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,wBAAwB,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAEpC,mCAAmC;QACnC,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,0BAA0B;QAC1B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QACvC,CAAC;QAED,+BAA+B;QAC/B,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,CAAC,SAAS,EAAE,CAAC;QAC1D,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;YAErE,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;YACnC,CAAC;iBAAM,IAAI,QAAQ,EAAE,CAAC;gBACpB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,QAAQ,EAAE,CAAC;YAClD,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,MAAM,CAAC,UAAU;YAC1B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK,EAAE,qCAAqC;YACvE,OAAO;SACR,CAAC,CAAC;QAEH,0DAA0D;QAC1D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;YACxC,sBAAsB;YACtB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAChC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAClB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CACjC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EACtB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CACjC,CAAC;QACJ,CAAC;QAED,kBAAkB;QAClB,IAAI,CAAC,IAAI,GAAG;YACV,MAAM,EAAE,KAAK,EAAE,IAAuC,EAAE,EAAE;gBACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;gBACzD,OAAO,QAAQ,CAAC,IAAI,CAAC;YACvB,CAAC;YACD,KAAK,EAAE,KAAK,EAAE,EAAU,EAAE,EAAE;gBAC1B,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YAChD,CAAC;YACD,GAAG,EAAE,KAAK,EAAE,EAAU,EAAE,EAAE;gBACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;gBACxD,OAAO,QAAQ,CAAC,IAAI,CAAC;YACvB,CAAC;YACD,IAAI,EAAE,KAAK,EAAE,OAA6C,EAAE,EAAE;gBAC5D,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;gBACrC,IAAI,OAAO,EAAE,KAAK;oBAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACrE,IAAI,OAAO,EAAE,MAAM;oBAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC7D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBAEvE,qDAAqD;gBACrD,uDAAuD;gBACvD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjC,OAAO,QAAQ,CAAC,IAAI,CAAC;gBACvB,CAAC;gBACD,IAAI,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC5B,CAAC;gBAED,uDAAuD;gBACvD,OAAO,CAAC,IAAI,CAAC,4DAA4D,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC1F,OAAO,EAAE,CAAC;YACZ,CAAC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAChD,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -39,23 +39,45 @@ pub fn render(f: &mut Frame, state: &AppState) {
|
|
|
39
39
|
// Split portal into sections
|
|
40
40
|
use ratatui::layout::{Constraint, Direction, Layout};
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
// Dynamic layout based on error state
|
|
43
|
+
let has_error = state.connection_portal.error.is_some();
|
|
44
|
+
let constraints = if has_error {
|
|
45
|
+
vec![
|
|
45
46
|
Constraint::Length(3), // Header
|
|
46
47
|
Constraint::Length(4), // Description
|
|
47
48
|
Constraint::Length(7), // Input fields
|
|
48
49
|
Constraint::Length(3), // Status
|
|
50
|
+
Constraint::Length(8), // Error box (when error exists)
|
|
49
51
|
Constraint::Min(1), // Spacer
|
|
50
52
|
Constraint::Length(3), // Actions
|
|
51
|
-
]
|
|
53
|
+
]
|
|
54
|
+
} else {
|
|
55
|
+
vec![
|
|
56
|
+
Constraint::Length(3), // Header
|
|
57
|
+
Constraint::Length(4), // Description
|
|
58
|
+
Constraint::Length(7), // Input fields
|
|
59
|
+
Constraint::Length(3), // Status
|
|
60
|
+
Constraint::Min(1), // Spacer
|
|
61
|
+
Constraint::Length(3), // Actions
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
let chunks = Layout::default()
|
|
66
|
+
.direction(Direction::Vertical)
|
|
67
|
+
.constraints(constraints)
|
|
52
68
|
.split(portal_area);
|
|
53
69
|
|
|
54
70
|
render_header(f, chunks[0], state);
|
|
55
71
|
render_description(f, chunks[1]);
|
|
56
72
|
render_input_fields(f, chunks[2], state);
|
|
57
73
|
render_status(f, chunks[3], state);
|
|
58
|
-
|
|
74
|
+
|
|
75
|
+
if has_error {
|
|
76
|
+
render_error_box(f, chunks[4], state);
|
|
77
|
+
render_actions(f, chunks[6], state);
|
|
78
|
+
} else {
|
|
79
|
+
render_actions(f, chunks[5], state);
|
|
80
|
+
}
|
|
59
81
|
}
|
|
60
82
|
|
|
61
83
|
fn render_header(f: &mut Frame, area: Rect, state: &AppState) {
|
|
@@ -178,8 +200,8 @@ fn render_status(f: &mut Frame, area: Rect, state: &AppState) {
|
|
|
178
200
|
|
|
179
201
|
let portal = &state.connection_portal;
|
|
180
202
|
|
|
181
|
-
let (status_text, status_color) = if
|
|
182
|
-
(
|
|
203
|
+
let (status_text, status_color) = if portal.error.is_some() {
|
|
204
|
+
("Connection failed".to_string(), ERROR_RED)
|
|
183
205
|
} else if portal.connecting {
|
|
184
206
|
("Connecting...".to_string(), AMBER_WARN)
|
|
185
207
|
} else {
|
|
@@ -197,6 +219,111 @@ fn render_status(f: &mut Frame, area: Rect, state: &AppState) {
|
|
|
197
219
|
f.render_widget(paragraph, inner);
|
|
198
220
|
}
|
|
199
221
|
|
|
222
|
+
fn render_error_box(f: &mut Frame, area: Rect, state: &AppState) {
|
|
223
|
+
let portal = &state.connection_portal;
|
|
224
|
+
|
|
225
|
+
if let Some(error) = &portal.error {
|
|
226
|
+
let block = Block::default()
|
|
227
|
+
.title(" ⚠️ ERROR ")
|
|
228
|
+
.borders(Borders::ALL)
|
|
229
|
+
.border_style(Style::default().fg(ERROR_RED))
|
|
230
|
+
.style(Style::default().bg(BG_PANEL));
|
|
231
|
+
|
|
232
|
+
let inner = block.inner(area);
|
|
233
|
+
f.render_widget(block, area);
|
|
234
|
+
|
|
235
|
+
// Parse error and provide helpful hints
|
|
236
|
+
let (error_message, troubleshooting) = parse_error_message(error);
|
|
237
|
+
|
|
238
|
+
let mut text = vec![
|
|
239
|
+
Line::from(""),
|
|
240
|
+
Line::from(Span::styled(
|
|
241
|
+
format!(" {}", error_message),
|
|
242
|
+
Style::default().fg(ERROR_RED).bold()
|
|
243
|
+
)),
|
|
244
|
+
Line::from(""),
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
if !troubleshooting.is_empty() {
|
|
248
|
+
text.push(Line::from(Span::styled(
|
|
249
|
+
" Troubleshooting:",
|
|
250
|
+
Style::default().fg(AMBER_WARN).bold()
|
|
251
|
+
)));
|
|
252
|
+
text.push(Line::from(""));
|
|
253
|
+
|
|
254
|
+
for hint in troubleshooting {
|
|
255
|
+
text.push(Line::from(Span::styled(
|
|
256
|
+
format!(" • {}", hint),
|
|
257
|
+
Style::default().fg(TEXT_PRIMARY)
|
|
258
|
+
)));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let paragraph = Paragraph::new(text)
|
|
263
|
+
.wrap(Wrap { trim: false })
|
|
264
|
+
.alignment(Alignment::Left);
|
|
265
|
+
|
|
266
|
+
f.render_widget(paragraph, inner);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
fn parse_error_message(error: &str) -> (String, Vec<String>) {
|
|
271
|
+
let error_lower = error.to_lowercase();
|
|
272
|
+
|
|
273
|
+
// Parse common errors and provide helpful hints
|
|
274
|
+
if error_lower.contains("econnrefused") || error_lower.contains("connection refused") {
|
|
275
|
+
(
|
|
276
|
+
"Cannot connect to Gateway server. The server is not running or not reachable.".to_string(),
|
|
277
|
+
vec![
|
|
278
|
+
"Verify Gateway server is running".to_string(),
|
|
279
|
+
"Check Gateway URL is correct".to_string(),
|
|
280
|
+
"To start Gateway: cd apps/gateway && npm start".to_string(),
|
|
281
|
+
"Check firewall settings".to_string(),
|
|
282
|
+
]
|
|
283
|
+
)
|
|
284
|
+
} else if error_lower.contains("timeout") || error_lower.contains("timed out") {
|
|
285
|
+
(
|
|
286
|
+
"Connection timeout. The Gateway server may be slow or unreachable.".to_string(),
|
|
287
|
+
vec![
|
|
288
|
+
"Check Gateway server is running".to_string(),
|
|
289
|
+
"Check network connection".to_string(),
|
|
290
|
+
"Verify Gateway URL is correct".to_string(),
|
|
291
|
+
"Try increasing connection timeout".to_string(),
|
|
292
|
+
]
|
|
293
|
+
)
|
|
294
|
+
} else if error_lower.contains("require") || error_lower.contains("is not defined") {
|
|
295
|
+
(
|
|
296
|
+
format!("Backend error: {}", error),
|
|
297
|
+
vec![
|
|
298
|
+
"This is a code error in the backend".to_string(),
|
|
299
|
+
"Check backend console for full error details".to_string(),
|
|
300
|
+
"Verify all dependencies are installed".to_string(),
|
|
301
|
+
"Check backend code for syntax errors".to_string(),
|
|
302
|
+
]
|
|
303
|
+
)
|
|
304
|
+
} else if error_lower.contains("network") || error_lower.contains("dns") {
|
|
305
|
+
(
|
|
306
|
+
"Network error. Cannot reach Gateway server.".to_string(),
|
|
307
|
+
vec![
|
|
308
|
+
"Check internet connection".to_string(),
|
|
309
|
+
"Verify Gateway URL is correct".to_string(),
|
|
310
|
+
"Check DNS resolution".to_string(),
|
|
311
|
+
"Check firewall/proxy settings".to_string(),
|
|
312
|
+
]
|
|
313
|
+
)
|
|
314
|
+
} else {
|
|
315
|
+
// Generic error - show full message
|
|
316
|
+
(
|
|
317
|
+
format!("Connection failed: {}", error),
|
|
318
|
+
vec![
|
|
319
|
+
"Verify Gateway server is running".to_string(),
|
|
320
|
+
"Check Gateway URL is correct".to_string(),
|
|
321
|
+
"Check backend logs for details".to_string(),
|
|
322
|
+
]
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
200
327
|
fn render_actions(f: &mut Frame, area: Rect, state: &AppState) {
|
|
201
328
|
let block = Block::default()
|
|
202
329
|
.title(" ⌨️ Actions ")
|
package/mk3-tui/src/ui/layout.rs
CHANGED
|
@@ -127,7 +127,7 @@ fn render_header(f: &mut Frame, area: Rect, state: &AppState) {
|
|
|
127
127
|
|
|
128
128
|
// Line 1: Brand + version + mode + uptime - Bug 3 fix: Use "4Runr." with dot (matches brand logo)
|
|
129
129
|
// Use npm package version (2.7.0) - matches package.json
|
|
130
|
-
const PACKAGE_VERSION: &str = "2.8.
|
|
130
|
+
const PACKAGE_VERSION: &str = "2.8.2";
|
|
131
131
|
let brand_line = Line::from(vec![
|
|
132
132
|
Span::styled("4Runr.", Style::default().fg(BRAND_PURPLE).add_modifier(Modifier::BOLD)),
|
|
133
133
|
Span::styled(" AI AGENT OS", Style::default().fg(BRAND_VIOLET)),
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "4runr-os",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.2",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.8.
|
|
5
|
+
"description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.8.2: Step 5 & 7 Complete - Full agent management integration + Connection Portal with improved error display. Fixed ES module import issue in Gateway client. Create, view, select, and delete agents through TUI. Dynamic mode switching (Local ↔ Connected) with Gateway connection. Enhanced error messages with full visibility and troubleshooting hints. Agent Builder, Agent List, Connection Portal fully functional. Built with Rust + Ratatui. ⚠️ Pre-MVP / Development Phase",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"4runr": "dist/index.js",
|