@displaydev/cli 0.6.0 → 0.8.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.
@@ -139,21 +139,88 @@ import { resolve } from 'node:path';
139
139
  import { z } from 'zod';
140
140
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
141
141
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
142
+ import { ApiError } from './api-client.js';
143
+ var FILE_ERROR_CODES = new Set([
144
+ 'ENOENT',
145
+ 'EACCES',
146
+ 'EISDIR',
147
+ 'ENOTDIR',
148
+ 'EMFILE'
149
+ ]);
150
+ function isFileError(err) {
151
+ if (!_instanceof(err, Error)) {
152
+ return false;
153
+ }
154
+ var code = err.code;
155
+ return typeof code === 'string' && FILE_ERROR_CODES.has(code);
156
+ }
157
+ function errorResponse(err) {
158
+ var body;
159
+ if (_instanceof(err, ApiError)) {
160
+ body = {
161
+ error: 'request_failed',
162
+ message: err.message,
163
+ status: err.status
164
+ };
165
+ } else if (isFileError(err)) {
166
+ body = {
167
+ error: 'file_error',
168
+ code: err.code,
169
+ message: err.message
170
+ };
171
+ } else {
172
+ var message = _instanceof(err, Error) ? err.message : String(err);
173
+ body = {
174
+ error: 'request_failed',
175
+ message: message
176
+ };
177
+ }
178
+ return {
179
+ content: [
180
+ {
181
+ type: 'text',
182
+ text: JSON.stringify(body)
183
+ }
184
+ ],
185
+ isError: true
186
+ };
187
+ }
188
+ function okResponse(result) {
189
+ return {
190
+ content: [
191
+ {
192
+ type: 'text',
193
+ text: JSON.stringify(result)
194
+ }
195
+ ]
196
+ };
197
+ }
142
198
  /**
143
199
  * Starts an MCP server over stdin/stdout.
144
200
  * Tools call the display.dev REST API via the ApiClient.
145
- */ export function startMcpServer(apiClient) {
146
- return _async_to_generator(function() {
147
- var server, transport;
201
+ */ export function startMcpServer(_0) {
202
+ return _async_to_generator(function(apiClient) {
203
+ var options, _options_mode, _options_transport, mode, server, transport;
204
+ var _arguments = arguments;
148
205
  return _ts_generator(this, function(_state) {
149
206
  switch(_state.label){
150
207
  case 0:
208
+ options = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
209
+ mode = (_options_mode = options.mode) !== null && _options_mode !== void 0 ? _options_mode : 'authenticated';
151
210
  server = new McpServer({
152
211
  name: 'display',
153
212
  version: '1.0.0'
154
213
  });
155
- registerTools(server, apiClient);
156
- transport = new StdioServerTransport();
214
+ if (mode === 'public') {
215
+ registerPublicTools(server, apiClient);
216
+ } else {
217
+ registerTools(server, apiClient);
218
+ }
219
+ transport = (_options_transport = options.transport) !== null && _options_transport !== void 0 ? _options_transport : new StdioServerTransport();
220
+ // The MCP SDK's connect() accepts any transport implementing the shared
221
+ // interface; tests pass an InMemoryTransport and production passes the
222
+ // stdio transport. Typing is loose here to avoid re-exporting the
223
+ // transport interface type from the SDK just for this seam.
157
224
  return [
158
225
  4,
159
226
  server.connect(transport)
@@ -161,13 +228,123 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
161
228
  case 1:
162
229
  _state.sent();
163
230
  return [
164
- 2
231
+ 2,
232
+ {
233
+ server: server
234
+ }
165
235
  ];
166
236
  }
167
237
  });
168
- })();
238
+ }).apply(this, arguments);
239
+ }
240
+ export function registerPublicTools(server, api) {
241
+ server.tool('publish', 'Publish an anonymous HTML or Markdown artifact. Returns a preview URL (anyone can view) and a one-shot claim URL the user visits to move it into their display.dev organization.', {
242
+ content: z.string().optional().describe('HTML or Markdown content to publish'),
243
+ file_path: z.string().optional().describe('Path to a local file to publish'),
244
+ name: z.string().optional().describe('Optional display name (defaults to filename stem)'),
245
+ format: z.enum([
246
+ 'html',
247
+ 'md'
248
+ ]).default('html').describe('Content format')
249
+ }, function(args) {
250
+ return _async_to_generator(function() {
251
+ var hasContent, hasFilePath, content, _tmp, result, err;
252
+ return _ts_generator(this, function(_state) {
253
+ switch(_state.label){
254
+ case 0:
255
+ hasContent = args.content !== undefined;
256
+ hasFilePath = args.file_path !== undefined;
257
+ if (hasContent && hasFilePath) {
258
+ return [
259
+ 2,
260
+ {
261
+ content: [
262
+ {
263
+ type: 'text',
264
+ text: JSON.stringify({
265
+ error: 'ambiguous_input',
266
+ message: 'Provide either content or file_path, not both'
267
+ })
268
+ }
269
+ ],
270
+ isError: true
271
+ }
272
+ ];
273
+ }
274
+ if (!hasContent && !hasFilePath) {
275
+ return [
276
+ 2,
277
+ {
278
+ content: [
279
+ {
280
+ type: 'text',
281
+ text: JSON.stringify({
282
+ error: 'missing_content',
283
+ message: 'Either content or file_path is required'
284
+ })
285
+ }
286
+ ],
287
+ isError: true
288
+ }
289
+ ];
290
+ }
291
+ _state.label = 1;
292
+ case 1:
293
+ _state.trys.push([
294
+ 1,
295
+ 6,
296
+ ,
297
+ 7
298
+ ]);
299
+ if (!hasFilePath) return [
300
+ 3,
301
+ 3
302
+ ];
303
+ return [
304
+ 4,
305
+ readFile(resolve(args.file_path), 'utf-8')
306
+ ];
307
+ case 2:
308
+ _tmp = _state.sent();
309
+ return [
310
+ 3,
311
+ 4
312
+ ];
313
+ case 3:
314
+ _tmp = args.content;
315
+ _state.label = 4;
316
+ case 4:
317
+ content = _tmp;
318
+ return [
319
+ 4,
320
+ api.publishPublic({
321
+ content: content,
322
+ name: args.name,
323
+ format: args.format
324
+ })
325
+ ];
326
+ case 5:
327
+ result = _state.sent();
328
+ return [
329
+ 2,
330
+ okResponse(result)
331
+ ];
332
+ case 6:
333
+ err = _state.sent();
334
+ return [
335
+ 2,
336
+ errorResponse(err)
337
+ ];
338
+ case 7:
339
+ return [
340
+ 2
341
+ ];
342
+ }
343
+ });
344
+ })();
345
+ });
169
346
  }
170
- function registerTools(server, api) {
347
+ export function registerTools(server, api) {
171
348
  server.tool('publish', 'Publish an HTML or Markdown artifact behind company auth', {
172
349
  content: z.string().optional().describe('HTML or Markdown content to publish'),
173
350
  file_path: z.string().optional().describe('Path to a local file to publish'),
@@ -191,7 +368,7 @@ function registerTools(server, api) {
191
368
  ]).optional().describe('display.dev attribution bar override. Paid tier only; defaults to org setting when omitted.')
192
369
  }, function(args) {
193
370
  return _async_to_generator(function() {
194
- var _args_name, content, hasContent, hasFilePath, absPath, result, _args_name1;
371
+ var _args_name, hasContent, hasFilePath, _args_name1, content, _tmp, result, _tmp1, err;
195
372
  return _ts_generator(this, function(_state) {
196
373
  switch(_state.label){
197
374
  case 0:
@@ -265,25 +442,7 @@ function registerTools(server, api) {
265
442
  }
266
443
  ];
267
444
  }
268
- if (!hasFilePath) return [
269
- 3,
270
- 2
271
- ];
272
- absPath = resolve(args.file_path);
273
- return [
274
- 4,
275
- readFile(absPath, 'utf-8')
276
- ];
277
- case 1:
278
- content = _state.sent();
279
- return [
280
- 3,
281
- 3
282
- ];
283
- case 2:
284
- if (hasContent) {
285
- content = args.content;
286
- } else {
445
+ if (!hasContent && !hasFilePath) {
287
446
  return [
288
447
  2,
289
448
  {
@@ -300,11 +459,36 @@ function registerTools(server, api) {
300
459
  }
301
460
  ];
302
461
  }
303
- _state.label = 3;
462
+ _state.label = 1;
463
+ case 1:
464
+ _state.trys.push([
465
+ 1,
466
+ 9,
467
+ ,
468
+ 10
469
+ ]);
470
+ if (!hasFilePath) return [
471
+ 3,
472
+ 3
473
+ ];
474
+ return [
475
+ 4,
476
+ readFile(resolve(args.file_path), 'utf-8')
477
+ ];
478
+ case 2:
479
+ _tmp = _state.sent();
480
+ return [
481
+ 3,
482
+ 4
483
+ ];
304
484
  case 3:
485
+ _tmp = args.content;
486
+ _state.label = 4;
487
+ case 4:
488
+ content = _tmp;
305
489
  if (!args.short_id) return [
306
490
  3,
307
- 5
491
+ 6
308
492
  ];
309
493
  return [
310
494
  4,
@@ -319,13 +503,13 @@ function registerTools(server, api) {
319
503
  showBranding: args.show_branding
320
504
  })
321
505
  ];
322
- case 4:
323
- result = _state.sent();
506
+ case 5:
507
+ _tmp1 = _state.sent();
324
508
  return [
325
509
  3,
326
- 7
510
+ 8
327
511
  ];
328
- case 5:
512
+ case 6:
329
513
  return [
330
514
  4,
331
515
  api.publish({
@@ -338,20 +522,24 @@ function registerTools(server, api) {
338
522
  showBranding: args.show_branding
339
523
  })
340
524
  ];
341
- case 6:
342
- result = _state.sent();
343
- _state.label = 7;
344
525
  case 7:
526
+ _tmp1 = _state.sent();
527
+ _state.label = 8;
528
+ case 8:
529
+ result = _tmp1;
530
+ return [
531
+ 2,
532
+ okResponse(result)
533
+ ];
534
+ case 9:
535
+ err = _state.sent();
345
536
  return [
346
537
  2,
347
- {
348
- content: [
349
- {
350
- type: 'text',
351
- text: JSON.stringify(result)
352
- }
353
- ]
354
- }
538
+ errorResponse(err)
539
+ ];
540
+ case 10:
541
+ return [
542
+ 2
355
543
  ];
356
544
  }
357
545
  });
@@ -374,10 +562,16 @@ function registerTools(server, api) {
374
562
  limit: z.number().optional().describe('Max results to return (1-100)')
375
563
  }, function(args) {
376
564
  return _async_to_generator(function() {
377
- var results;
565
+ var results, err;
378
566
  return _ts_generator(this, function(_state) {
379
567
  switch(_state.label){
380
568
  case 0:
569
+ _state.trys.push([
570
+ 0,
571
+ 2,
572
+ ,
573
+ 3
574
+ ]);
381
575
  return [
382
576
  4,
383
577
  api.find(args)
@@ -386,14 +580,17 @@ function registerTools(server, api) {
386
580
  results = _state.sent();
387
581
  return [
388
582
  2,
389
- {
390
- content: [
391
- {
392
- type: 'text',
393
- text: JSON.stringify(results)
394
- }
395
- ]
396
- }
583
+ okResponse(results)
584
+ ];
585
+ case 2:
586
+ err = _state.sent();
587
+ return [
588
+ 2,
589
+ errorResponse(err)
590
+ ];
591
+ case 3:
592
+ return [
593
+ 2
397
594
  ];
398
595
  }
399
596
  });
@@ -404,10 +601,16 @@ function registerTools(server, api) {
404
601
  include: z.array(z.string()).optional().describe('Include additional data (e.g. "versions")')
405
602
  }, function(args) {
406
603
  return _async_to_generator(function() {
407
- var result;
604
+ var result, err;
408
605
  return _ts_generator(this, function(_state) {
409
606
  switch(_state.label){
410
607
  case 0:
608
+ _state.trys.push([
609
+ 0,
610
+ 2,
611
+ ,
612
+ 3
613
+ ]);
411
614
  return [
412
615
  4,
413
616
  api.get(args.short_id, args.include)
@@ -416,14 +619,17 @@ function registerTools(server, api) {
416
619
  result = _state.sent();
417
620
  return [
418
621
  2,
419
- {
420
- content: [
421
- {
422
- type: 'text',
423
- text: JSON.stringify(result)
424
- }
425
- ]
426
- }
622
+ okResponse(result)
623
+ ];
624
+ case 2:
625
+ err = _state.sent();
626
+ return [
627
+ 2,
628
+ errorResponse(err)
629
+ ];
630
+ case 3:
631
+ return [
632
+ 2
427
633
  ];
428
634
  }
429
635
  });
@@ -434,7 +640,7 @@ function registerTools(server, api) {
434
640
  confirm: z.boolean().describe('Must be true to confirm deletion')
435
641
  }, function(args) {
436
642
  return _async_to_generator(function() {
437
- var result;
643
+ var result, err;
438
644
  return _ts_generator(this, function(_state) {
439
645
  switch(_state.label){
440
646
  case 0:
@@ -455,22 +661,33 @@ function registerTools(server, api) {
455
661
  }
456
662
  ];
457
663
  }
664
+ _state.label = 1;
665
+ case 1:
666
+ _state.trys.push([
667
+ 1,
668
+ 3,
669
+ ,
670
+ 4
671
+ ]);
458
672
  return [
459
673
  4,
460
674
  api.delete(args.short_id)
461
675
  ];
462
- case 1:
676
+ case 2:
463
677
  result = _state.sent();
464
678
  return [
465
679
  2,
466
- {
467
- content: [
468
- {
469
- type: 'text',
470
- text: JSON.stringify(result)
471
- }
472
- ]
473
- }
680
+ okResponse(result)
681
+ ];
682
+ case 3:
683
+ err = _state.sent();
684
+ return [
685
+ 2,
686
+ errorResponse(err)
687
+ ];
688
+ case 4:
689
+ return [
690
+ 2
474
691
  ];
475
692
  }
476
693
  });
@@ -489,7 +706,7 @@ function registerTools(server, api) {
489
706
  ]).describe('show = force branding on; hide = force off; inherit = follow org default')
490
707
  }, function(args) {
491
708
  return _async_to_generator(function() {
492
- var result, err, msg;
709
+ var result, err;
493
710
  return _ts_generator(this, function(_state) {
494
711
  switch(_state.label){
495
712
  case 0:
@@ -507,32 +724,13 @@ function registerTools(server, api) {
507
724
  result = _state.sent();
508
725
  return [
509
726
  2,
510
- {
511
- content: [
512
- {
513
- type: 'text',
514
- text: JSON.stringify(result)
515
- }
516
- ]
517
- }
727
+ okResponse(result)
518
728
  ];
519
729
  case 2:
520
730
  err = _state.sent();
521
- msg = _instanceof(err, Error) ? err.message : String(err);
522
731
  return [
523
732
  2,
524
- {
525
- content: [
526
- {
527
- type: 'text',
528
- text: JSON.stringify({
529
- error: 'request_failed',
530
- message: msg
531
- })
532
- }
533
- ],
534
- isError: true
535
- }
733
+ errorResponse(err)
536
734
  ];
537
735
  case 3:
538
736
  return [
@@ -549,7 +747,7 @@ function registerTools(server, api) {
549
747
  enabled: z.boolean().describe('true to show the bar by default; false to hide it')
550
748
  }, function(args) {
551
749
  return _async_to_generator(function() {
552
- var result, err, msg;
750
+ var result, err;
553
751
  return _ts_generator(this, function(_state) {
554
752
  switch(_state.label){
555
753
  case 0:
@@ -567,32 +765,13 @@ function registerTools(server, api) {
567
765
  result = _state.sent();
568
766
  return [
569
767
  2,
570
- {
571
- content: [
572
- {
573
- type: 'text',
574
- text: JSON.stringify(result)
575
- }
576
- ]
577
- }
768
+ okResponse(result)
578
769
  ];
579
770
  case 2:
580
771
  err = _state.sent();
581
- msg = _instanceof(err, Error) ? err.message : String(err);
582
772
  return [
583
773
  2,
584
- {
585
- content: [
586
- {
587
- type: 'text',
588
- text: JSON.stringify({
589
- error: 'request_failed',
590
- message: msg
591
- })
592
- }
593
- ],
594
- isError: true
595
- }
774
+ errorResponse(err)
596
775
  ];
597
776
  case 3:
598
777
  return [
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@displaydev/cli",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "dsp": "dist/main.js"
7
7
  },
8
8
  "files": [
9
9
  "dist",
10
- "!dist/*.spec.js"
10
+ "!dist/*.spec.js",
11
+ "!dist/test-helpers.js"
11
12
  ],
12
13
  "scripts": {
13
14
  "build": "swc src -d dist --strip-leading-paths",