@displaydev/cli 0.4.0 → 0.6.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 CHANGED
@@ -52,12 +52,25 @@ Extraction pattern: `/Your verification code is: (\d{6})/`.
52
52
  ## Usage
53
53
 
54
54
  ```bash
55
- # Publish a file
55
+ # Publish a file (defaults to company auth)
56
56
  dsp publish ./report.html --name "Q1 Report"
57
57
 
58
- # Update an existing artifact
58
+ # Publish as public (no login required to view)
59
+ dsp publish ./report.html --name "Q1 Report" --public
60
+
61
+ # Share with external recipients (repeatable)
62
+ dsp publish ./proposal.html --name "Q1 Proposal" \
63
+ --share bob@partner.com --share alice@client.com
64
+
65
+ # Update an existing artifact (keeps current visibility/shares if not specified)
59
66
  dsp publish ./report.html --id abc123
60
67
 
68
+ # Change an existing artifact back to company auth
69
+ dsp publish ./report.html --id abc123 --company
70
+
71
+ # Remove all guest shares from an existing artifact
72
+ dsp publish ./report.html --id abc123 --clear-shares
73
+
61
74
  # Search artifacts
62
75
  dsp find
63
76
  dsp find "quarterly" --by alice@acme.com
@@ -72,6 +85,20 @@ dsp delete abc123 --confirm
72
85
  dsp mcp
73
86
  ```
74
87
 
88
+ ### Publish flags
89
+
90
+ | Flag | Effect |
91
+ |---|---|
92
+ | `--name <name>` | Artifact display name. Required for new artifacts. |
93
+ | `--id <shortId>` | Update an existing artifact (publishes a new version). |
94
+ | `--public` | Set visibility to public (no auth required to view). |
95
+ | `--company` | Set visibility to company auth (default for new artifacts). |
96
+ | `--share <email>` | Grant guest access to an external email (repeatable). |
97
+ | `--clear-shares` | Remove all guest shares. Only valid with `--id`. |
98
+ | `--theme <theme>` | Markdown rendering theme. |
99
+
100
+ Visibility and share flags **default to "keep current"** on update: omitting `--public`/`--company` leaves visibility unchanged, and omitting `--share`/`--clear-shares` leaves the guest list unchanged. `--public`/`--company` are mutually exclusive; `--share`/`--clear-shares` are mutually exclusive.
101
+
75
102
  ## MCP
76
103
 
77
104
  The CLI doubles as an MCP server over stdio. Add to your MCP client config:
@@ -265,9 +265,58 @@ export var ApiClient = /*#__PURE__*/ function() {
265
265
  }
266
266
  }
267
267
  }
268
+ if (params.clearShares) {
269
+ form.append('clearGuestEmails', 'true');
270
+ }
271
+ if (params.showBranding) {
272
+ form.append('showBranding', params.showBranding);
273
+ }
268
274
  return form;
269
275
  }
270
276
  },
277
+ {
278
+ key: "getOrgBranding",
279
+ value: function getOrgBranding() {
280
+ return _async_to_generator(function() {
281
+ return _ts_generator(this, function(_state) {
282
+ return [
283
+ 2,
284
+ this.request('GET', '/v1/org/branding')
285
+ ];
286
+ });
287
+ }).call(this);
288
+ }
289
+ },
290
+ {
291
+ key: "setOrgBranding",
292
+ value: function setOrgBranding(showBranding) {
293
+ return _async_to_generator(function() {
294
+ return _ts_generator(this, function(_state) {
295
+ return [
296
+ 2,
297
+ this.request('PUT', '/v1/org/branding', {
298
+ showBranding: showBranding
299
+ })
300
+ ];
301
+ });
302
+ }).call(this);
303
+ }
304
+ },
305
+ {
306
+ key: "setArtifactBranding",
307
+ value: function setArtifactBranding(shortId, showBranding) {
308
+ return _async_to_generator(function() {
309
+ return _ts_generator(this, function(_state) {
310
+ return [
311
+ 2,
312
+ this.request('POST', "/v1/artifacts/".concat(shortId, "/branding"), {
313
+ showBranding: showBranding
314
+ })
315
+ ];
316
+ });
317
+ }).call(this);
318
+ }
319
+ },
271
320
  {
272
321
  key: "find",
273
322
  value: function find(params) {
package/dist/main.js CHANGED
@@ -287,10 +287,26 @@ var program = new Command().name('dsp').description('display.dev CLI — publish
287
287
  function collectEmails(value, prev) {
288
288
  return prev.concat(value);
289
289
  }
290
+ var SHOW_BRANDING_VALUES = new Set([
291
+ 'show',
292
+ 'hide',
293
+ 'inherit'
294
+ ]);
295
+ function parseShowBrandingFlag(raw) {
296
+ if (!raw) {
297
+ return undefined;
298
+ }
299
+ var normalized = raw.toLowerCase();
300
+ if (!SHOW_BRANDING_VALUES.has(normalized)) {
301
+ console.error("Invalid --show-branding: ".concat(raw, ". Use show, hide, or inherit."));
302
+ process.exit(1);
303
+ }
304
+ return normalized;
305
+ }
290
306
  // --- publish ---
291
- program.command('publish <path>').description('Publish an HTML or Markdown file').option('--name <name>', 'Artifact display name').option('--id <shortId>', 'Update existing artifact (new version)').option('--public', 'Make artifact publicly accessible').option('--share <email>', 'Share with guest email (repeatable)', collectEmails, []).option('--theme <theme>', 'Markdown theme (default: github)').action(function(filePath, opts) {
307
+ program.command('publish <path>').description('Publish an HTML or Markdown file').option('--name <name>', 'Artifact display name').option('--id <shortId>', 'Update existing artifact (new version)').option('--public', 'Make artifact publicly accessible').option('--company', 'Restrict artifact to company auth (default for new artifacts)').option('--share <email>', 'Share with guest email (repeatable)', collectEmails, []).option('--clear-shares', 'Remove all guest email shares (update only)').option('--theme <theme>', 'Markdown theme (default: github)').option('--show-branding <mode>', 'display.dev bar override: show, hide, or inherit (paid plans only)').action(function(filePath, opts) {
292
308
  return _async_to_generator(function() {
293
- var auth, client, ext, content, format, visibility, share, result, verb;
309
+ var showBranding, auth, client, ext, content, format, visibility, share, result, err, msg, verb;
294
310
  return _ts_generator(this, function(_state) {
295
311
  switch(_state.label){
296
312
  case 0:
@@ -298,6 +314,19 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
298
314
  console.error('--name is required for new artifacts. Use --id to update an existing one.');
299
315
  process.exit(1);
300
316
  }
317
+ if (opts.public && opts.company) {
318
+ console.error('Use --public or --company, not both.');
319
+ process.exit(1);
320
+ }
321
+ if (opts.clearShares && opts.share.length > 0) {
322
+ console.error('Use --share or --clear-shares, not both.');
323
+ process.exit(1);
324
+ }
325
+ if (opts.clearShares && !opts.id) {
326
+ console.error('--clear-shares only applies when updating (--id).');
327
+ process.exit(1);
328
+ }
329
+ showBranding = parseShowBrandingFlag(opts.showBranding);
301
330
  return [
302
331
  4,
303
332
  resolveAuthOrConfig()
@@ -317,11 +346,23 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
317
346
  case 2:
318
347
  content = _state.sent();
319
348
  format = ext === '.md' ? 'md' : 'html';
320
- visibility = opts.public ? 'public' : undefined;
349
+ if (opts.public) {
350
+ visibility = 'public';
351
+ } else if (opts.company) {
352
+ visibility = 'company';
353
+ }
321
354
  share = opts.share.length > 0 ? opts.share : undefined;
355
+ _state.label = 3;
356
+ case 3:
357
+ _state.trys.push([
358
+ 3,
359
+ 8,
360
+ ,
361
+ 9
362
+ ]);
322
363
  if (!opts.id) return [
323
364
  3,
324
- 4
365
+ 5
325
366
  ];
326
367
  return [
327
368
  4,
@@ -331,16 +372,18 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
331
372
  name: opts.name,
332
373
  theme: opts.theme,
333
374
  share: share,
334
- visibility: visibility
375
+ clearShares: opts.clearShares,
376
+ visibility: visibility,
377
+ showBranding: showBranding
335
378
  })
336
379
  ];
337
- case 3:
380
+ case 4:
338
381
  result = _state.sent();
339
382
  return [
340
383
  3,
341
- 6
384
+ 7
342
385
  ];
343
- case 4:
386
+ case 5:
344
387
  return [
345
388
  4,
346
389
  client.publish({
@@ -349,13 +392,32 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
349
392
  format: format,
350
393
  theme: opts.theme,
351
394
  share: share,
352
- visibility: visibility
395
+ visibility: visibility,
396
+ showBranding: showBranding
353
397
  })
354
398
  ];
355
- case 5:
356
- result = _state.sent();
357
- _state.label = 6;
358
399
  case 6:
400
+ result = _state.sent();
401
+ _state.label = 7;
402
+ case 7:
403
+ return [
404
+ 3,
405
+ 9
406
+ ];
407
+ case 8:
408
+ err = _state.sent();
409
+ msg = _instanceof(err, Error) ? err.message : String(err);
410
+ if (/paid plan|upgrade/i.test(msg)) {
411
+ console.error('Error: Hiding display.dev branding requires a paid plan. See https://display.dev/billing');
412
+ } else {
413
+ console.error(msg);
414
+ }
415
+ process.exit(1);
416
+ return [
417
+ 3,
418
+ 9
419
+ ];
420
+ case 9:
359
421
  console.log(result.url);
360
422
  verb = opts.id ? 'Updated' : 'Published';
361
423
  console.log("".concat(verb, " ").concat(result.name, " (").concat(result.shortId, ") v").concat(result.version));
@@ -1004,6 +1066,65 @@ program.command('login').description('Authenticate with display.dev').option('--
1004
1066
  });
1005
1067
  })();
1006
1068
  });
1069
+ // --- branding ---
1070
+ program.command('branding <shortId> <mode>').description('Override display.dev branding for an existing artifact without re-publishing (show|hide|inherit)').action(function(shortId, modeRaw) {
1071
+ return _async_to_generator(function() {
1072
+ var mode, auth, client, result, err, msg;
1073
+ return _ts_generator(this, function(_state) {
1074
+ switch(_state.label){
1075
+ case 0:
1076
+ mode = parseShowBrandingFlag(modeRaw);
1077
+ if (!mode) {
1078
+ console.error('mode is required');
1079
+ process.exit(1);
1080
+ }
1081
+ return [
1082
+ 4,
1083
+ resolveAuthOrConfig()
1084
+ ];
1085
+ case 1:
1086
+ auth = _state.sent();
1087
+ client = createClient(auth);
1088
+ _state.label = 2;
1089
+ case 2:
1090
+ _state.trys.push([
1091
+ 2,
1092
+ 4,
1093
+ ,
1094
+ 5
1095
+ ]);
1096
+ return [
1097
+ 4,
1098
+ client.setArtifactBranding(shortId, mode)
1099
+ ];
1100
+ case 3:
1101
+ result = _state.sent();
1102
+ console.log("".concat(result.shortId, " branding=").concat(result.showBranding === null ? 'inherit' : result.showBranding ? 'show' : 'hide'));
1103
+ return [
1104
+ 3,
1105
+ 5
1106
+ ];
1107
+ case 4:
1108
+ err = _state.sent();
1109
+ msg = _instanceof(err, Error) ? err.message : String(err);
1110
+ if (/paid plan|upgrade/i.test(msg)) {
1111
+ console.error('Error: Hiding display.dev branding requires a paid plan. See https://display.dev/billing');
1112
+ } else {
1113
+ console.error(msg);
1114
+ }
1115
+ process.exit(1);
1116
+ return [
1117
+ 3,
1118
+ 5
1119
+ ];
1120
+ case 5:
1121
+ return [
1122
+ 2
1123
+ ];
1124
+ }
1125
+ });
1126
+ })();
1127
+ });
1007
1128
  // --- mcp ---
1008
1129
  program.command('mcp').description('Start MCP server over stdin/stdout').action(function() {
1009
1130
  return _async_to_generator(function() {
@@ -27,6 +27,14 @@ function _async_to_generator(fn) {
27
27
  });
28
28
  };
29
29
  }
30
+ function _instanceof(left, right) {
31
+ "@swc/helpers - instanceof";
32
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
33
+ return !!right[Symbol.hasInstance](left);
34
+ } else {
35
+ return left instanceof right;
36
+ }
37
+ }
30
38
  function _ts_generator(thisArg, body) {
31
39
  var f, y, t, _ = {
32
40
  label: 0,
@@ -170,11 +178,17 @@ function registerTools(server, api) {
170
178
  'md'
171
179
  ]).default('html').describe('Content format'),
172
180
  theme: z.string().optional().describe('Theme for Markdown rendering'),
173
- share: z.array(z.string()).optional().describe('Email addresses to share with'),
181
+ share: z.array(z.string()).optional().describe('Email addresses to share with. Omit to keep current shares on update.'),
182
+ clear_shares: z.boolean().optional().describe('Set true to remove all guest shares (update only, mutually exclusive with share).'),
174
183
  visibility: z.enum([
175
184
  'public',
176
185
  'company'
177
- ]).default('company').describe('Artifact visibility')
186
+ ]).optional().describe('Artifact visibility. Omit to keep current on update; defaults to "company" on create.'),
187
+ show_branding: z.enum([
188
+ 'show',
189
+ 'hide',
190
+ 'inherit'
191
+ ]).optional().describe('display.dev attribution bar override. Paid tier only; defaults to org setting when omitted.')
178
192
  }, function(args) {
179
193
  return _async_to_generator(function() {
180
194
  var _args_name, content, hasContent, hasFilePath, absPath, result, _args_name1;
@@ -198,6 +212,40 @@ function registerTools(server, api) {
198
212
  }
199
213
  ];
200
214
  }
215
+ if (args.share && args.clear_shares) {
216
+ return [
217
+ 2,
218
+ {
219
+ content: [
220
+ {
221
+ type: 'text',
222
+ text: JSON.stringify({
223
+ error: 'conflicting_params',
224
+ message: 'Pass share or clear_shares, not both'
225
+ })
226
+ }
227
+ ],
228
+ isError: true
229
+ }
230
+ ];
231
+ }
232
+ if (args.clear_shares && !args.short_id) {
233
+ return [
234
+ 2,
235
+ {
236
+ content: [
237
+ {
238
+ type: 'text',
239
+ text: JSON.stringify({
240
+ error: 'clear_shares_requires_short_id',
241
+ message: 'clear_shares only applies when updating an existing artifact (short_id)'
242
+ })
243
+ }
244
+ ],
245
+ isError: true
246
+ }
247
+ ];
248
+ }
201
249
  hasContent = args.content !== undefined;
202
250
  hasFilePath = args.file_path !== undefined;
203
251
  if (hasContent && hasFilePath) {
@@ -266,7 +314,9 @@ function registerTools(server, api) {
266
314
  name: ((_args_name1 = args.name) === null || _args_name1 === void 0 ? void 0 : _args_name1.trim()) || undefined,
267
315
  theme: args.theme,
268
316
  share: args.share,
269
- visibility: args.visibility
317
+ clearShares: args.clear_shares,
318
+ visibility: args.visibility,
319
+ showBranding: args.show_branding
270
320
  })
271
321
  ];
272
322
  case 4:
@@ -284,7 +334,8 @@ function registerTools(server, api) {
284
334
  format: args.format,
285
335
  theme: args.theme,
286
336
  share: args.share,
287
- visibility: args.visibility
337
+ visibility: args.visibility,
338
+ showBranding: args.show_branding
288
339
  })
289
340
  ];
290
341
  case 6:
@@ -425,4 +476,130 @@ function registerTools(server, api) {
425
476
  });
426
477
  })();
427
478
  });
479
+ // Agent-native parity for the artifact-detail per-artifact toggle.
480
+ // Metadata-only: does NOT bump the artifact version. Use the `publish`
481
+ // tool (with `show_branding`) when you're changing content at the same
482
+ // time so both writes happen in one transaction.
483
+ server.tool('artifact_set_branding', 'Override display.dev branding for an existing artifact without re-publishing. Paid tiers only (free-tier orgs must keep inherit).', {
484
+ short_id: z.string().describe('Artifact shortId'),
485
+ show_branding: z.enum([
486
+ 'show',
487
+ 'hide',
488
+ 'inherit'
489
+ ]).describe('show = force branding on; hide = force off; inherit = follow org default')
490
+ }, function(args) {
491
+ return _async_to_generator(function() {
492
+ var result, err, msg;
493
+ return _ts_generator(this, function(_state) {
494
+ switch(_state.label){
495
+ case 0:
496
+ _state.trys.push([
497
+ 0,
498
+ 2,
499
+ ,
500
+ 3
501
+ ]);
502
+ return [
503
+ 4,
504
+ api.setArtifactBranding(args.short_id, args.show_branding)
505
+ ];
506
+ case 1:
507
+ result = _state.sent();
508
+ return [
509
+ 2,
510
+ {
511
+ content: [
512
+ {
513
+ type: 'text',
514
+ text: JSON.stringify(result)
515
+ }
516
+ ]
517
+ }
518
+ ];
519
+ case 2:
520
+ err = _state.sent();
521
+ msg = _instanceof(err, Error) ? err.message : String(err);
522
+ return [
523
+ 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
+ }
536
+ ];
537
+ case 3:
538
+ return [
539
+ 2
540
+ ];
541
+ }
542
+ });
543
+ })();
544
+ });
545
+ // Agent-native parity for the Settings → Branding dashboard toggle.
546
+ // Pairs with `publish`'s `show_branding` param: this tool controls the
547
+ // default; that param overrides it per-artifact.
548
+ server.tool('org_set_branding', 'Enable or disable display.dev branding for every artifact in the org (paid tiers only). Per-artifact overrides keep precedence.', {
549
+ enabled: z.boolean().describe('true to show the bar by default; false to hide it')
550
+ }, function(args) {
551
+ return _async_to_generator(function() {
552
+ var result, err, msg;
553
+ return _ts_generator(this, function(_state) {
554
+ switch(_state.label){
555
+ case 0:
556
+ _state.trys.push([
557
+ 0,
558
+ 2,
559
+ ,
560
+ 3
561
+ ]);
562
+ return [
563
+ 4,
564
+ api.setOrgBranding(args.enabled)
565
+ ];
566
+ case 1:
567
+ result = _state.sent();
568
+ return [
569
+ 2,
570
+ {
571
+ content: [
572
+ {
573
+ type: 'text',
574
+ text: JSON.stringify(result)
575
+ }
576
+ ]
577
+ }
578
+ ];
579
+ case 2:
580
+ err = _state.sent();
581
+ msg = _instanceof(err, Error) ? err.message : String(err);
582
+ return [
583
+ 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
+ }
596
+ ];
597
+ case 3:
598
+ return [
599
+ 2
600
+ ];
601
+ }
602
+ });
603
+ })();
604
+ });
428
605
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@displaydev/cli",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "dsp": "dist/main.js"