@displaydev/cli 0.11.0 → 0.12.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.
@@ -287,12 +287,21 @@ function _ts_generator(thisArg, body) {
287
287
  export var ApiError = /*#__PURE__*/ function(Error1) {
288
288
  "use strict";
289
289
  _inherits(ApiError, Error1);
290
- function ApiError(message, status) {
290
+ function ApiError(message, status, details, /**
291
+ * Top-level discriminator on 402 plan_required (e.g.
292
+ * `'gated_artifact_limit'`). Lets MCP clients and the dashboard
293
+ * pick per-context UX without pattern-matching the message string.
294
+ */ reason, /**
295
+ * Original `error` value from the API body (e.g.
296
+ * `'plan_required'`, `'storage_quota_exceeded'`). Preserved so the
297
+ * MCP `errorResponse` path can mirror the API body verbatim per
298
+ * spec feat-free-tier-gated-artifact-limit §6.2.
299
+ */ apiError) {
291
300
  _class_call_check(this, ApiError);
292
301
  var _this;
293
302
  _this = _call_super(this, ApiError, [
294
303
  message
295
- ]), _define_property(_this, "status", void 0), _this.status = status;
304
+ ]), _define_property(_this, "status", void 0), _define_property(_this, "details", void 0), _define_property(_this, "reason", void 0), _define_property(_this, "apiError", void 0), _this.status = status, _this.details = details, _this.reason = reason, _this.apiError = apiError;
296
305
  _this.name = 'ApiError';
297
306
  return _this;
298
307
  }
@@ -614,7 +623,7 @@ export var ApiClient = /*#__PURE__*/ function() {
614
623
  message: text
615
624
  };
616
625
  }
617
- throw new ApiError((_parsed_message = parsed.message) !== null && _parsed_message !== void 0 ? _parsed_message : "API error ".concat(res.status), res.status);
626
+ throw new ApiError((_parsed_message = parsed.message) !== null && _parsed_message !== void 0 ? _parsed_message : "API error ".concat(res.status), res.status, parsed.details, parsed.reason, parsed.error);
618
627
  case 3:
619
628
  return [
620
629
  4,
@@ -890,7 +899,7 @@ export var ApiClient = /*#__PURE__*/ function() {
890
899
  message: text
891
900
  };
892
901
  }
893
- throw new ApiError((_parsed_message = parsed.message) !== null && _parsed_message !== void 0 ? _parsed_message : "API error ".concat(res.status), res.status);
902
+ throw new ApiError((_parsed_message = parsed.message) !== null && _parsed_message !== void 0 ? _parsed_message : "API error ".concat(res.status), res.status, parsed.details, parsed.reason, parsed.error);
894
903
  case 3:
895
904
  return [
896
905
  2,
package/dist/main.js CHANGED
@@ -256,7 +256,7 @@ program.command('publish <path>').description('Publish an HTML or Markdown file.
256
256
  }).filter(Boolean);
257
257
  }).option('--clear-shares', 'Remove all sharedWith entries (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) {
258
258
  return _async_to_generator(function() {
259
- var _opts_shareWith, showBranding, auth, fromStdin, format, content, inferClient, detail, err, msg, publicClient, publicResult, err1, msg1, client, visibility, mergedShare, share, result, err2, msg2, verb;
259
+ var _opts_shareWith, showBranding, auth, fromStdin, format, content, inferClient, detail, err, msg, publicClient, publicResult, err1, msg1, client, visibility, mergedShare, share, result, err2, _err_details, msg2, verb;
260
260
  return _ts_generator(this, function(_state) {
261
261
  switch(_state.label){
262
262
  case 0:
@@ -506,6 +506,16 @@ program.command('publish <path>').description('Publish an HTML or Markdown file.
506
506
  console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
507
507
  process.exit(1);
508
508
  }
509
+ // 402 plan_required carries a structured upgrade URL — surface the
510
+ // API's message verbatim plus the URL on a second line. Sits above
511
+ // the branding-classifier fallback because the gated-artifact-cap
512
+ // message ("upgrade to Solo …") would otherwise be misrouted into
513
+ // the paid-plan branding branch.
514
+ if (_instanceof(err2, ApiError) && err2.status === 402 && ((_err_details = err2.details) === null || _err_details === void 0 ? void 0 : _err_details.upgrade_url)) {
515
+ console.error(err2.message);
516
+ console.error("Upgrade: ".concat(err2.details.upgrade_url));
517
+ process.exit(1);
518
+ }
509
519
  msg2 = _instanceof(err2, Error) ? err2.message : String(err2);
510
520
  if (classifyBrandingError(msg2) === 'paid-plan') {
511
521
  console.error('Error: Hiding display.dev branding requires a paid plan. See https://display.dev/billing');
@@ -539,7 +549,7 @@ program.command('share <shortId>').description('Change an artifact\'s visibility
539
549
  }).filter(Boolean);
540
550
  }).action(function(shortId, opts) {
541
551
  return _async_to_generator(function() {
542
- var auth, client, result, err, msg;
552
+ var auth, client, result, err, _ref, _err_details, upgradeUrl, msg;
543
553
  return _ts_generator(this, function(_state) {
544
554
  switch(_state.label){
545
555
  case 0:
@@ -584,7 +594,16 @@ program.command('share <shortId>').description('Change an artifact\'s visibility
584
594
  case 4:
585
595
  err = _state.sent();
586
596
  if (_instanceof(err, ApiError) && err.status === 402) {
587
- console.error('Error: Private visibility requires the Pro plan. Upgrade at https://display.dev/pricing');
597
+ ;
598
+ ;
599
+ // 402 plan_required carries either the original "private requires
600
+ // Pro" reason or the new gated-artifact-limit reason — print the
601
+ // API's structured message verbatim plus the upgrade URL on a
602
+ // second line. Avoid hard-coding "Private visibility…" since the
603
+ // free-tier gated-artifact cap also returns 402.
604
+ console.error(err.message);
605
+ upgradeUrl = (_ref = (_err_details = err.details) === null || _err_details === void 0 ? void 0 : _err_details.upgrade_url) !== null && _ref !== void 0 ? _ref : 'https://app.display.dev/billing';
606
+ console.error("Upgrade: ".concat(upgradeUrl));
588
607
  process.exit(1);
589
608
  }
590
609
  if (_instanceof(err, ApiError) && err.status === 404) {
@@ -157,11 +157,22 @@ function isFileError(err) {
157
157
  function errorResponse(err) {
158
158
  var body;
159
159
  if (_instanceof(err, ApiError)) {
160
+ var _err_apiError;
161
+ // Mirror the API body verbatim per spec feat-free-tier-gated-artifact-limit
162
+ // §6.2 (MCP returns structured errors verbatim). Falls back to a generic
163
+ // `request_failed` only when the original API didn't supply an `error`
164
+ // field (e.g. opaque proxy 5xx, non-JSON body).
160
165
  body = {
161
- error: 'request_failed',
166
+ error: (_err_apiError = err.apiError) !== null && _err_apiError !== void 0 ? _err_apiError : 'request_failed',
162
167
  message: err.message,
163
168
  status: err.status
164
169
  };
170
+ if (err.reason) {
171
+ body.reason = err.reason;
172
+ }
173
+ if (err.details) {
174
+ body.details = err.details;
175
+ }
165
176
  } else if (isFileError(err)) {
166
177
  body = {
167
178
  error: 'file_error',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@displaydev/cli",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "dsp": "dist/main.js"