@displaydev/cli 0.16.0 → 0.18.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/dist/api-client.js +102 -32
- package/dist/main-helpers.js +13 -1
- package/dist/main.js +267 -16
- package/dist/mcp-server.js +152 -87
- package/package.json +1 -1
package/dist/api-client.js
CHANGED
|
@@ -507,48 +507,118 @@ export var ApiClient = /*#__PURE__*/ function() {
|
|
|
507
507
|
}).call(this);
|
|
508
508
|
}
|
|
509
509
|
},
|
|
510
|
+
{
|
|
511
|
+
key: "setOrgLogo",
|
|
512
|
+
value: /**
|
|
513
|
+
* Upload (or replace) the active org's logo. Multipart `file` field;
|
|
514
|
+
* server validates magic bytes, square aspect, dimensions, and size.
|
|
515
|
+
* Returns the new R2 key + content-addressed version.
|
|
516
|
+
*/ function setOrgLogo(params) {
|
|
517
|
+
return _async_to_generator(function() {
|
|
518
|
+
var form, blob;
|
|
519
|
+
return _ts_generator(this, function(_state) {
|
|
520
|
+
form = new FormData();
|
|
521
|
+
blob = new Blob([
|
|
522
|
+
new Uint8Array(params.bytes)
|
|
523
|
+
], {
|
|
524
|
+
type: params.contentType
|
|
525
|
+
});
|
|
526
|
+
form.append('file', blob, params.filename);
|
|
527
|
+
return [
|
|
528
|
+
2,
|
|
529
|
+
this.request('POST', '/v1/org/logo', form)
|
|
530
|
+
];
|
|
531
|
+
});
|
|
532
|
+
}).call(this);
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
key: "clearOrgLogo",
|
|
537
|
+
value: /** Clear the active org's logo. Idempotent — 200 even when no logo is set. */ function clearOrgLogo() {
|
|
538
|
+
return _async_to_generator(function() {
|
|
539
|
+
return _ts_generator(this, function(_state) {
|
|
540
|
+
return [
|
|
541
|
+
2,
|
|
542
|
+
this.request('DELETE', '/v1/org/logo')
|
|
543
|
+
];
|
|
544
|
+
});
|
|
545
|
+
}).call(this);
|
|
546
|
+
}
|
|
547
|
+
},
|
|
510
548
|
{
|
|
511
549
|
key: "find",
|
|
512
550
|
value: function find(params) {
|
|
513
551
|
return _async_to_generator(function() {
|
|
514
|
-
var searchParams,
|
|
552
|
+
var searchParams, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, a, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, v, qs;
|
|
515
553
|
return _ts_generator(this, function(_state) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
searchParams.set('publishedBy', params.publishedBy);
|
|
527
|
-
}
|
|
528
|
-
if (params.since) {
|
|
529
|
-
searchParams.set('since', params.since);
|
|
554
|
+
searchParams = new URLSearchParams();
|
|
555
|
+
if (params.query) {
|
|
556
|
+
searchParams.set('q', params.query);
|
|
557
|
+
}
|
|
558
|
+
if (params.author) {
|
|
559
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
560
|
+
try {
|
|
561
|
+
for(_iterator = params.author[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
562
|
+
a = _step.value;
|
|
563
|
+
searchParams.append('author', a);
|
|
530
564
|
}
|
|
531
|
-
|
|
532
|
-
|
|
565
|
+
} catch (err) {
|
|
566
|
+
_didIteratorError = true;
|
|
567
|
+
_iteratorError = err;
|
|
568
|
+
} finally{
|
|
569
|
+
try {
|
|
570
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
571
|
+
_iterator.return();
|
|
572
|
+
}
|
|
573
|
+
} finally{
|
|
574
|
+
if (_didIteratorError) {
|
|
575
|
+
throw _iteratorError;
|
|
576
|
+
}
|
|
533
577
|
}
|
|
534
|
-
|
|
535
|
-
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
if (params.visibility) {
|
|
581
|
+
_iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
582
|
+
try {
|
|
583
|
+
for(_iterator1 = params.visibility[Symbol.iterator](); !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
584
|
+
v = _step1.value;
|
|
585
|
+
searchParams.append('visibility', v);
|
|
536
586
|
}
|
|
537
|
-
|
|
538
|
-
|
|
587
|
+
} catch (err) {
|
|
588
|
+
_didIteratorError1 = true;
|
|
589
|
+
_iteratorError1 = err;
|
|
590
|
+
} finally{
|
|
591
|
+
try {
|
|
592
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
593
|
+
_iterator1.return();
|
|
594
|
+
}
|
|
595
|
+
} finally{
|
|
596
|
+
if (_didIteratorError1) {
|
|
597
|
+
throw _iteratorError1;
|
|
598
|
+
}
|
|
539
599
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
];
|
|
545
|
-
case 1:
|
|
546
|
-
res = _state.sent();
|
|
547
|
-
return [
|
|
548
|
-
2,
|
|
549
|
-
res.data
|
|
550
|
-
];
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (params.since) {
|
|
603
|
+
searchParams.set('since', params.since);
|
|
551
604
|
}
|
|
605
|
+
if (params.sort) {
|
|
606
|
+
searchParams.set('sort', params.sort);
|
|
607
|
+
}
|
|
608
|
+
if (params.dir) {
|
|
609
|
+
searchParams.set('dir', params.dir);
|
|
610
|
+
}
|
|
611
|
+
if (params.cursor) {
|
|
612
|
+
searchParams.set('cursor', params.cursor);
|
|
613
|
+
}
|
|
614
|
+
if (params.limit !== undefined) {
|
|
615
|
+
searchParams.set('limit', String(params.limit));
|
|
616
|
+
}
|
|
617
|
+
qs = searchParams.toString();
|
|
618
|
+
return [
|
|
619
|
+
2,
|
|
620
|
+
this.request('GET', "/v1/artifacts".concat(qs ? "?".concat(qs) : ''))
|
|
621
|
+
];
|
|
552
622
|
});
|
|
553
623
|
}).call(this);
|
|
554
624
|
}
|
package/dist/main-helpers.js
CHANGED
|
@@ -287,6 +287,17 @@ function _ts_generator(thisArg, body) {
|
|
|
287
287
|
}
|
|
288
288
|
import { extname } from 'node:path';
|
|
289
289
|
export var DEFAULT_API_URL = 'https://api.display.dev';
|
|
290
|
+
export function classifyApiKey(apiKey) {
|
|
291
|
+
// BA mints keys with no separator after the prefix — `sk_live<body>`,
|
|
292
|
+
// not `sk_live_<body>`. Mirrors the live check at api/src/guards/auth.guard.ts.
|
|
293
|
+
if (apiKey.startsWith('sk_live')) {
|
|
294
|
+
return 'user';
|
|
295
|
+
}
|
|
296
|
+
if (apiKey.startsWith('org_live')) {
|
|
297
|
+
return 'org';
|
|
298
|
+
}
|
|
299
|
+
return 'session';
|
|
300
|
+
}
|
|
290
301
|
export var InvalidFlagError = /*#__PURE__*/ function(Error1) {
|
|
291
302
|
"use strict";
|
|
292
303
|
_inherits(InvalidFlagError, Error1);
|
|
@@ -399,7 +410,8 @@ export function resolveAuth(env, config) {
|
|
|
399
410
|
var apiUrl = (_ref = (_env_DISPLAYDEV_API_URL = env.DISPLAYDEV_API_URL) !== null && _env_DISPLAYDEV_API_URL !== void 0 ? _env_DISPLAYDEV_API_URL : config === null || config === void 0 ? void 0 : config.apiUrl) !== null && _ref !== void 0 ? _ref : DEFAULT_API_URL;
|
|
400
411
|
return {
|
|
401
412
|
apiKey: apiKey,
|
|
402
|
-
apiUrl: apiUrl
|
|
413
|
+
apiUrl: apiUrl,
|
|
414
|
+
keyType: classifyApiKey(apiKey)
|
|
403
415
|
};
|
|
404
416
|
}
|
|
405
417
|
export function classifyBrandingError(message) {
|
package/dist/main.js
CHANGED
|
@@ -189,6 +189,7 @@ function _ts_generator(thisArg, body) {
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
import { readFile } from 'node:fs/promises';
|
|
192
|
+
import { basename } from 'node:path';
|
|
192
193
|
import { createInterface } from 'node:readline/promises';
|
|
193
194
|
import { createRequire } from 'node:module';
|
|
194
195
|
import { execFileSync } from 'node:child_process';
|
|
@@ -725,11 +726,24 @@ program.command('rename <shortId>').description('Rename a published artifact. Sl
|
|
|
725
726
|
})();
|
|
726
727
|
});
|
|
727
728
|
// --- find ---
|
|
728
|
-
|
|
729
|
+
function collectAuthor(value, prev) {
|
|
730
|
+
return prev.concat(value);
|
|
731
|
+
}
|
|
732
|
+
function parseVisibilityCsv(raw) {
|
|
733
|
+
return raw.split(',').map(function(v) {
|
|
734
|
+
return v.trim();
|
|
735
|
+
}).filter(Boolean);
|
|
736
|
+
}
|
|
737
|
+
var VISIBILITY_VALUES = new Set([
|
|
738
|
+
'public',
|
|
739
|
+
'company',
|
|
740
|
+
'private'
|
|
741
|
+
]);
|
|
742
|
+
program.command('find [query]').alias('list').description('List or search artifacts. Omit [query] to list every artifact (paginated).').option('--author <a>', 'Filter by author (repeatable). Each value: email, userId, or "me".', collectAuthor, []).option('--visibility <list>', 'CSV of visibility levels: public, company, private. "private" returns only your own.').option('--since <date>', 'Filter by updated since ISO date').option('--sort <col>', 'Sort column: updated_at, view_count, name').option('--dir <direction>', 'Sort direction: asc or desc').option('--cursor <token>', 'Opaque pagination token from a prior response. Drop the cursor when filters change — the wire only validates it against sort/dir, so reusing it after changing --author / --visibility / --since / [query] silently skews results.').option('--limit <n>', 'Max rows to fetch (1-100)', function(v) {
|
|
729
743
|
return parseInt(v, 10);
|
|
730
744
|
}).action(function(query, opts) {
|
|
731
745
|
return _async_to_generator(function() {
|
|
732
|
-
var
|
|
746
|
+
var visibility, tokens, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, v, auth, client, response, err, msg, data, nextCursor, totalCount, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, a;
|
|
733
747
|
return _ts_generator(this, function(_state) {
|
|
734
748
|
switch(_state.label){
|
|
735
749
|
case 0:
|
|
@@ -745,53 +759,126 @@ program.command('find [query]').description('Search for artifacts').option('--by
|
|
|
745
759
|
console.error("Invalid --dir: ".concat(opts.dir, ". Use asc or desc."));
|
|
746
760
|
process.exit(1);
|
|
747
761
|
}
|
|
762
|
+
if (opts.visibility) {
|
|
763
|
+
tokens = parseVisibilityCsv(opts.visibility);
|
|
764
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
765
|
+
try {
|
|
766
|
+
for(_iterator = tokens[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
767
|
+
v = _step.value;
|
|
768
|
+
if (!VISIBILITY_VALUES.has(v)) {
|
|
769
|
+
console.error("Invalid --visibility: ".concat(v, ". Use public, company, or private."));
|
|
770
|
+
process.exit(1);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
} catch (err) {
|
|
774
|
+
_didIteratorError = true;
|
|
775
|
+
_iteratorError = err;
|
|
776
|
+
} finally{
|
|
777
|
+
try {
|
|
778
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
779
|
+
_iterator.return();
|
|
780
|
+
}
|
|
781
|
+
} finally{
|
|
782
|
+
if (_didIteratorError) {
|
|
783
|
+
throw _iteratorError;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
visibility = tokens;
|
|
788
|
+
}
|
|
748
789
|
return [
|
|
749
790
|
4,
|
|
750
791
|
resolveAuthOrConfig()
|
|
751
792
|
];
|
|
752
793
|
case 1:
|
|
753
794
|
auth = _state.sent();
|
|
795
|
+
// The wire silently drops `me` when authenticated with an org API key (no
|
|
796
|
+
// session user → caller id is null in resolveAuthorIds). Catch that at the
|
|
797
|
+
// command layer so the user gets an explicit failure rather than an
|
|
798
|
+
// unfiltered list. Trim each value to mirror the wire — it trims tokens
|
|
799
|
+
// before resolving `me`, so `--author ' me '` would otherwise bypass the
|
|
800
|
+
// guard and re-introduce the silent-broaden bug.
|
|
801
|
+
if (auth.keyType === 'org' && opts.author.some(function(a) {
|
|
802
|
+
return a.trim() === 'me';
|
|
803
|
+
})) {
|
|
804
|
+
console.error('--author me requires a user-scoped credential. Use a user API key or sign in via dashboard.');
|
|
805
|
+
process.exit(1);
|
|
806
|
+
}
|
|
754
807
|
client = createClient(auth);
|
|
808
|
+
_state.label = 2;
|
|
809
|
+
case 2:
|
|
810
|
+
_state.trys.push([
|
|
811
|
+
2,
|
|
812
|
+
4,
|
|
813
|
+
,
|
|
814
|
+
5
|
|
815
|
+
]);
|
|
755
816
|
return [
|
|
756
817
|
4,
|
|
757
818
|
client.find({
|
|
758
819
|
query: query,
|
|
759
|
-
|
|
760
|
-
|
|
820
|
+
author: opts.author.length > 0 ? opts.author : undefined,
|
|
821
|
+
visibility: visibility,
|
|
761
822
|
since: opts.since,
|
|
762
823
|
sort: opts.sort,
|
|
763
824
|
dir: opts.dir,
|
|
825
|
+
cursor: opts.cursor,
|
|
764
826
|
limit: opts.limit
|
|
765
827
|
})
|
|
766
828
|
];
|
|
767
|
-
case
|
|
768
|
-
|
|
769
|
-
|
|
829
|
+
case 3:
|
|
830
|
+
response = _state.sent();
|
|
831
|
+
return [
|
|
832
|
+
3,
|
|
833
|
+
5
|
|
834
|
+
];
|
|
835
|
+
case 4:
|
|
836
|
+
err = _state.sent();
|
|
837
|
+
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
838
|
+
console.error(msg);
|
|
839
|
+
process.exit(1);
|
|
840
|
+
return [
|
|
841
|
+
3,
|
|
842
|
+
5
|
|
843
|
+
];
|
|
844
|
+
case 5:
|
|
845
|
+
data = response.data, nextCursor = response.nextCursor, totalCount = response.totalCount;
|
|
846
|
+
if (data.length === 0) {
|
|
770
847
|
console.log('No artifacts found.');
|
|
771
848
|
return [
|
|
772
849
|
2
|
|
773
850
|
];
|
|
774
851
|
}
|
|
775
|
-
|
|
852
|
+
_iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
776
853
|
try {
|
|
777
|
-
for(
|
|
778
|
-
a =
|
|
854
|
+
for(_iterator1 = data[Symbol.iterator](); !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
855
|
+
a = _step1.value;
|
|
779
856
|
console.log("".concat(a.shortId, " v").concat(a.currentVersion, " ").concat(a.name, " ").concat(a.url));
|
|
780
857
|
}
|
|
781
858
|
} catch (err) {
|
|
782
|
-
|
|
783
|
-
|
|
859
|
+
_didIteratorError1 = true;
|
|
860
|
+
_iteratorError1 = err;
|
|
784
861
|
} finally{
|
|
785
862
|
try {
|
|
786
|
-
if (!
|
|
787
|
-
|
|
863
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
864
|
+
_iterator1.return();
|
|
788
865
|
}
|
|
789
866
|
} finally{
|
|
790
|
-
if (
|
|
791
|
-
throw
|
|
867
|
+
if (_didIteratorError1) {
|
|
868
|
+
throw _iteratorError1;
|
|
792
869
|
}
|
|
793
870
|
}
|
|
794
871
|
}
|
|
872
|
+
// Footer on stderr so pipe consumers (`dsp find | xargs ...`) get clean
|
|
873
|
+
// stdout. Order: count line first, then the next-page hint.
|
|
874
|
+
if (totalCount === -1) {
|
|
875
|
+
process.stderr.write("Showing ".concat(data.length, " matching artifacts (count exceeded the budget; rerun with a tighter filter to get an exact total).\n"));
|
|
876
|
+
} else if (totalCount >= 0) {
|
|
877
|
+
process.stderr.write("Showing ".concat(data.length, "/").concat(totalCount, " matching artifacts.\n"));
|
|
878
|
+
}
|
|
879
|
+
if (nextCursor !== null) {
|
|
880
|
+
process.stderr.write("More results available. Re-run with --cursor ".concat(nextCursor, " to fetch the next page.\n"));
|
|
881
|
+
}
|
|
795
882
|
return [
|
|
796
883
|
2
|
|
797
884
|
];
|
|
@@ -1452,6 +1539,170 @@ program.command('set-branding <shortId> <mode>').description('Override display.d
|
|
|
1452
1539
|
});
|
|
1453
1540
|
})();
|
|
1454
1541
|
});
|
|
1542
|
+
// --- set-logo ---
|
|
1543
|
+
program.command('set-logo <file>').description('Upload or replace the org logo (PNG or WebP, square, 32–1024px, ≤256 KB)').action(function(filePath) {
|
|
1544
|
+
return _async_to_generator(function() {
|
|
1545
|
+
var auth, client, bytes, err, msg, lower, contentType, result, err1, _ref, _err_details, upgradeUrl, msg1;
|
|
1546
|
+
return _ts_generator(this, function(_state) {
|
|
1547
|
+
switch(_state.label){
|
|
1548
|
+
case 0:
|
|
1549
|
+
return [
|
|
1550
|
+
4,
|
|
1551
|
+
resolveAuthOrConfig()
|
|
1552
|
+
];
|
|
1553
|
+
case 1:
|
|
1554
|
+
auth = _state.sent();
|
|
1555
|
+
client = createClient(auth);
|
|
1556
|
+
_state.label = 2;
|
|
1557
|
+
case 2:
|
|
1558
|
+
_state.trys.push([
|
|
1559
|
+
2,
|
|
1560
|
+
4,
|
|
1561
|
+
,
|
|
1562
|
+
5
|
|
1563
|
+
]);
|
|
1564
|
+
return [
|
|
1565
|
+
4,
|
|
1566
|
+
readFile(filePath)
|
|
1567
|
+
];
|
|
1568
|
+
case 3:
|
|
1569
|
+
bytes = _state.sent();
|
|
1570
|
+
return [
|
|
1571
|
+
3,
|
|
1572
|
+
5
|
|
1573
|
+
];
|
|
1574
|
+
case 4:
|
|
1575
|
+
err = _state.sent();
|
|
1576
|
+
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
1577
|
+
console.error(msg);
|
|
1578
|
+
process.exit(1);
|
|
1579
|
+
return [
|
|
1580
|
+
3,
|
|
1581
|
+
5
|
|
1582
|
+
];
|
|
1583
|
+
case 5:
|
|
1584
|
+
lower = filePath.toLowerCase();
|
|
1585
|
+
if (lower.endsWith('.png')) {
|
|
1586
|
+
contentType = 'image/png';
|
|
1587
|
+
} else if (lower.endsWith('.webp')) {
|
|
1588
|
+
contentType = 'image/webp';
|
|
1589
|
+
} else {
|
|
1590
|
+
console.error('Logo must be a .png or .webp file.');
|
|
1591
|
+
process.exit(1);
|
|
1592
|
+
}
|
|
1593
|
+
_state.label = 6;
|
|
1594
|
+
case 6:
|
|
1595
|
+
_state.trys.push([
|
|
1596
|
+
6,
|
|
1597
|
+
8,
|
|
1598
|
+
,
|
|
1599
|
+
9
|
|
1600
|
+
]);
|
|
1601
|
+
return [
|
|
1602
|
+
4,
|
|
1603
|
+
client.setOrgLogo({
|
|
1604
|
+
bytes: bytes,
|
|
1605
|
+
contentType: contentType,
|
|
1606
|
+
filename: basename(filePath)
|
|
1607
|
+
})
|
|
1608
|
+
];
|
|
1609
|
+
case 7:
|
|
1610
|
+
result = _state.sent();
|
|
1611
|
+
console.log("Logo set: ".concat(result.logoContentType, " version=").concat(result.logoVersion));
|
|
1612
|
+
return [
|
|
1613
|
+
3,
|
|
1614
|
+
9
|
|
1615
|
+
];
|
|
1616
|
+
case 8:
|
|
1617
|
+
err1 = _state.sent();
|
|
1618
|
+
if (_instanceof(err1, ApiError) && err1.status === 402) {
|
|
1619
|
+
;
|
|
1620
|
+
;
|
|
1621
|
+
upgradeUrl = (_ref = (_err_details = err1.details) === null || _err_details === void 0 ? void 0 : _err_details.upgrade_url) !== null && _ref !== void 0 ? _ref : 'https://app.display.dev/billing';
|
|
1622
|
+
console.error("Error: Setting an org logo requires a paid plan. See ".concat(upgradeUrl));
|
|
1623
|
+
process.exit(1);
|
|
1624
|
+
}
|
|
1625
|
+
if (_instanceof(err1, ApiError) && err1.status === 401) {
|
|
1626
|
+
console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
|
|
1627
|
+
process.exit(1);
|
|
1628
|
+
}
|
|
1629
|
+
if (_instanceof(err1, ApiError) && (err1.status === 400 || err1.status === 403)) {
|
|
1630
|
+
console.error(err1.message);
|
|
1631
|
+
process.exit(1);
|
|
1632
|
+
}
|
|
1633
|
+
msg1 = _instanceof(err1, Error) ? err1.message : String(err1);
|
|
1634
|
+
console.error(msg1);
|
|
1635
|
+
process.exit(1);
|
|
1636
|
+
return [
|
|
1637
|
+
3,
|
|
1638
|
+
9
|
|
1639
|
+
];
|
|
1640
|
+
case 9:
|
|
1641
|
+
return [
|
|
1642
|
+
2
|
|
1643
|
+
];
|
|
1644
|
+
}
|
|
1645
|
+
});
|
|
1646
|
+
})();
|
|
1647
|
+
});
|
|
1648
|
+
// --- clear-logo ---
|
|
1649
|
+
program.command('clear-logo').description('Remove the org logo (idempotent — succeeds even if no logo is currently set)').action(function() {
|
|
1650
|
+
return _async_to_generator(function() {
|
|
1651
|
+
var auth, client, err, msg;
|
|
1652
|
+
return _ts_generator(this, function(_state) {
|
|
1653
|
+
switch(_state.label){
|
|
1654
|
+
case 0:
|
|
1655
|
+
return [
|
|
1656
|
+
4,
|
|
1657
|
+
resolveAuthOrConfig()
|
|
1658
|
+
];
|
|
1659
|
+
case 1:
|
|
1660
|
+
auth = _state.sent();
|
|
1661
|
+
client = createClient(auth);
|
|
1662
|
+
_state.label = 2;
|
|
1663
|
+
case 2:
|
|
1664
|
+
_state.trys.push([
|
|
1665
|
+
2,
|
|
1666
|
+
4,
|
|
1667
|
+
,
|
|
1668
|
+
5
|
|
1669
|
+
]);
|
|
1670
|
+
return [
|
|
1671
|
+
4,
|
|
1672
|
+
client.clearOrgLogo()
|
|
1673
|
+
];
|
|
1674
|
+
case 3:
|
|
1675
|
+
_state.sent();
|
|
1676
|
+
console.log('Logo removed.');
|
|
1677
|
+
return [
|
|
1678
|
+
3,
|
|
1679
|
+
5
|
|
1680
|
+
];
|
|
1681
|
+
case 4:
|
|
1682
|
+
err = _state.sent();
|
|
1683
|
+
if (_instanceof(err, ApiError) && err.status === 401) {
|
|
1684
|
+
console.error('Your credential is no longer valid. Run: dsp login (or rotate DISPLAYDEV_API_KEY).');
|
|
1685
|
+
process.exit(1);
|
|
1686
|
+
}
|
|
1687
|
+
if (_instanceof(err, ApiError) && err.status === 403) {
|
|
1688
|
+
console.error(err.message);
|
|
1689
|
+
process.exit(1);
|
|
1690
|
+
}
|
|
1691
|
+
msg = _instanceof(err, Error) ? err.message : String(err);
|
|
1692
|
+
console.error(msg);
|
|
1693
|
+
process.exit(1);
|
|
1694
|
+
return [
|
|
1695
|
+
3,
|
|
1696
|
+
5
|
|
1697
|
+
];
|
|
1698
|
+
case 5:
|
|
1699
|
+
return [
|
|
1700
|
+
2
|
|
1701
|
+
];
|
|
1702
|
+
}
|
|
1703
|
+
});
|
|
1704
|
+
})();
|
|
1705
|
+
});
|
|
1455
1706
|
// --- mcp ---
|
|
1456
1707
|
program.command('mcp').description('Start MCP server over stdin/stdout').action(function() {
|
|
1457
1708
|
return _async_to_generator(function() {
|
package/dist/mcp-server.js
CHANGED
|
@@ -27,19 +27,6 @@ function _async_to_generator(fn) {
|
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
|
-
function _define_property(obj, key, value) {
|
|
31
|
-
if (key in obj) {
|
|
32
|
-
Object.defineProperty(obj, key, {
|
|
33
|
-
value: value,
|
|
34
|
-
enumerable: true,
|
|
35
|
-
configurable: true,
|
|
36
|
-
writable: true
|
|
37
|
-
});
|
|
38
|
-
} else {
|
|
39
|
-
obj[key] = value;
|
|
40
|
-
}
|
|
41
|
-
return obj;
|
|
42
|
-
}
|
|
43
30
|
function _instanceof(left, right) {
|
|
44
31
|
"@swc/helpers - instanceof";
|
|
45
32
|
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
@@ -48,57 +35,6 @@ function _instanceof(left, right) {
|
|
|
48
35
|
return left instanceof right;
|
|
49
36
|
}
|
|
50
37
|
}
|
|
51
|
-
function _object_spread(target) {
|
|
52
|
-
for(var i = 1; i < arguments.length; i++){
|
|
53
|
-
var source = arguments[i] != null ? arguments[i] : {};
|
|
54
|
-
var ownKeys = Object.keys(source);
|
|
55
|
-
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
56
|
-
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
57
|
-
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
60
|
-
ownKeys.forEach(function(key) {
|
|
61
|
-
_define_property(target, key, source[key]);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
return target;
|
|
65
|
-
}
|
|
66
|
-
function _object_without_properties(source, excluded) {
|
|
67
|
-
if (source == null) return {};
|
|
68
|
-
var target = {}, sourceKeys, key, i;
|
|
69
|
-
if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
|
|
70
|
-
sourceKeys = Reflect.ownKeys(Object(source));
|
|
71
|
-
for(i = 0; i < sourceKeys.length; i++){
|
|
72
|
-
key = sourceKeys[i];
|
|
73
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
74
|
-
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
75
|
-
target[key] = source[key];
|
|
76
|
-
}
|
|
77
|
-
return target;
|
|
78
|
-
}
|
|
79
|
-
target = _object_without_properties_loose(source, excluded);
|
|
80
|
-
if (Object.getOwnPropertySymbols) {
|
|
81
|
-
sourceKeys = Object.getOwnPropertySymbols(source);
|
|
82
|
-
for(i = 0; i < sourceKeys.length; i++){
|
|
83
|
-
key = sourceKeys[i];
|
|
84
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
85
|
-
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
86
|
-
target[key] = source[key];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return target;
|
|
90
|
-
}
|
|
91
|
-
function _object_without_properties_loose(source, excluded) {
|
|
92
|
-
if (source == null) return {};
|
|
93
|
-
var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
|
|
94
|
-
for(i = 0; i < sourceKeys.length; i++){
|
|
95
|
-
key = sourceKeys[i];
|
|
96
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
97
|
-
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
98
|
-
target[key] = source[key];
|
|
99
|
-
}
|
|
100
|
-
return target;
|
|
101
|
-
}
|
|
102
38
|
function _ts_generator(thisArg, body) {
|
|
103
39
|
var f, y, t, _ = {
|
|
104
40
|
label: 0,
|
|
@@ -199,7 +135,7 @@ function _ts_generator(thisArg, body) {
|
|
|
199
135
|
}
|
|
200
136
|
}
|
|
201
137
|
import { readFile } from 'node:fs/promises';
|
|
202
|
-
import { resolve } from 'node:path';
|
|
138
|
+
import { basename, resolve } from 'node:path';
|
|
203
139
|
import { z } from 'zod';
|
|
204
140
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
205
141
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
@@ -624,24 +560,29 @@ export function registerTools(server, api) {
|
|
|
624
560
|
});
|
|
625
561
|
})();
|
|
626
562
|
});
|
|
627
|
-
server.tool('find', '
|
|
628
|
-
query: z.string().optional().describe('Search by artifact name'),
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
563
|
+
server.tool('find', 'List or search artifacts in the caller\'s organization. Omit `query` to list every artifact (paginated). Filter by name, one-or-more authors, one-or-more visibilities, or update time. Sort by `updated_at` (default), `view_count`, or `name`. Paginate via `cursor` — if the result includes a non-null `nextCursor`, pass it back to fetch the next page; if filters change between calls, drop the cursor. The response also carries `totalCount` (`-1` means the count query exceeded its budget — treat as "many"). `visibility: ["private"]` returns only your own private artifacts, not org-wide.', {
|
|
564
|
+
query: z.string().optional().describe('Search by artifact name (case-insensitive substring). Omit to list all artifacts.'),
|
|
565
|
+
author: z.array(z.string()).optional().describe('Filter by one or more authors. Each value: email, userId, or the literal "me". Multiple values are ORed. "me" requires a user-scoped credential — with an org API key the wire drops it.'),
|
|
566
|
+
visibility: z.array(z.enum([
|
|
567
|
+
'public',
|
|
568
|
+
'company',
|
|
569
|
+
'private'
|
|
570
|
+
])).optional().describe('Filter by one or more visibility levels. NOTE: "private" is creator-scoped — only your own private artifacts are returned, not org-wide.'),
|
|
571
|
+
since: z.string().optional().describe('ISO timestamp; only artifacts updated on or after this point.'),
|
|
632
572
|
sort: z.enum([
|
|
633
573
|
'updated_at',
|
|
634
574
|
'view_count',
|
|
635
575
|
'name'
|
|
636
|
-
]).optional().describe('Sort column'),
|
|
576
|
+
]).optional().describe('Sort column. Defaults to updated_at.'),
|
|
637
577
|
dir: z.enum([
|
|
638
578
|
'asc',
|
|
639
579
|
'desc'
|
|
640
|
-
]).optional().describe('Sort direction'),
|
|
641
|
-
|
|
580
|
+
]).optional().describe('Sort direction. Defaults: desc for updated_at and view_count, asc for name.'),
|
|
581
|
+
cursor: z.string().optional().describe('Opaque pagination token from a prior response. Pass it back to fetch the next page. WARNING: only valid for the same `sort`/`dir`/filter set that issued it — change a filter and drop the cursor, or results will be skewed without an error.'),
|
|
582
|
+
limit: z.number().int().min(1).max(100).optional().describe('Max results per page (1–100, default 50).')
|
|
642
583
|
}, function(args) {
|
|
643
584
|
return _async_to_generator(function() {
|
|
644
|
-
var
|
|
585
|
+
var result, err;
|
|
645
586
|
return _ts_generator(this, function(_state) {
|
|
646
587
|
switch(_state.label){
|
|
647
588
|
case 0:
|
|
@@ -651,25 +592,15 @@ export function registerTools(server, api) {
|
|
|
651
592
|
,
|
|
652
593
|
3
|
|
653
594
|
]);
|
|
654
|
-
// Translate the snake_case MCP arg to the camelCase wire shape that
|
|
655
|
-
// ApiClient.find() forwards to GET /v1/artifacts. MCP convention
|
|
656
|
-
// prefers snake_case in tool schemas; the wire is camelCase
|
|
657
|
-
// (api-conventions §1.2). Without this map, `published_by` was
|
|
658
|
-
// silently dropped on the floor and the filter went unfiltered.
|
|
659
|
-
publishedBy = args.published_by, rest = _object_without_properties(args, [
|
|
660
|
-
"published_by"
|
|
661
|
-
]);
|
|
662
595
|
return [
|
|
663
596
|
4,
|
|
664
|
-
api.find(
|
|
665
|
-
publishedBy: publishedBy
|
|
666
|
-
} : {}))
|
|
597
|
+
api.find(args)
|
|
667
598
|
];
|
|
668
599
|
case 1:
|
|
669
|
-
|
|
600
|
+
result = _state.sent();
|
|
670
601
|
return [
|
|
671
602
|
2,
|
|
672
|
-
okResponse(
|
|
603
|
+
okResponse(result)
|
|
673
604
|
];
|
|
674
605
|
case 2:
|
|
675
606
|
err = _state.sent();
|
|
@@ -995,4 +926,138 @@ export function registerTools(server, api) {
|
|
|
995
926
|
});
|
|
996
927
|
})();
|
|
997
928
|
});
|
|
929
|
+
server.tool('set_logo', 'Upload or replace the org logo (paid tiers only). Used as the favicon on every artifact the org publishes. Stdio variant reads bytes from a local file path.', {
|
|
930
|
+
file_path: z.string().describe('Path to a local PNG or WebP file. Square, 32×32 to 1024×1024, ≤256 KB.'),
|
|
931
|
+
content_type: z.enum([
|
|
932
|
+
'image/png',
|
|
933
|
+
'image/webp'
|
|
934
|
+
]).optional().describe('Optional declared MIME type; inferred from the file extension when omitted.')
|
|
935
|
+
}, function(args) {
|
|
936
|
+
return _async_to_generator(function() {
|
|
937
|
+
var bytes, err, contentType, lower, result, err1;
|
|
938
|
+
return _ts_generator(this, function(_state) {
|
|
939
|
+
switch(_state.label){
|
|
940
|
+
case 0:
|
|
941
|
+
_state.trys.push([
|
|
942
|
+
0,
|
|
943
|
+
2,
|
|
944
|
+
,
|
|
945
|
+
3
|
|
946
|
+
]);
|
|
947
|
+
return [
|
|
948
|
+
4,
|
|
949
|
+
readFile(resolve(args.file_path))
|
|
950
|
+
];
|
|
951
|
+
case 1:
|
|
952
|
+
bytes = _state.sent();
|
|
953
|
+
return [
|
|
954
|
+
3,
|
|
955
|
+
3
|
|
956
|
+
];
|
|
957
|
+
case 2:
|
|
958
|
+
err = _state.sent();
|
|
959
|
+
return [
|
|
960
|
+
2,
|
|
961
|
+
errorResponse(err)
|
|
962
|
+
];
|
|
963
|
+
case 3:
|
|
964
|
+
contentType = args.content_type;
|
|
965
|
+
if (!contentType) {
|
|
966
|
+
lower = args.file_path.toLowerCase();
|
|
967
|
+
if (lower.endsWith('.png')) {
|
|
968
|
+
contentType = 'image/png';
|
|
969
|
+
} else if (lower.endsWith('.webp')) {
|
|
970
|
+
contentType = 'image/webp';
|
|
971
|
+
} else {
|
|
972
|
+
return [
|
|
973
|
+
2,
|
|
974
|
+
{
|
|
975
|
+
content: [
|
|
976
|
+
{
|
|
977
|
+
type: 'text',
|
|
978
|
+
text: JSON.stringify({
|
|
979
|
+
error: 'invalid_input',
|
|
980
|
+
message: 'Unable to infer content_type from file extension; pass content_type explicitly.'
|
|
981
|
+
})
|
|
982
|
+
}
|
|
983
|
+
],
|
|
984
|
+
isError: true
|
|
985
|
+
}
|
|
986
|
+
];
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
_state.label = 4;
|
|
990
|
+
case 4:
|
|
991
|
+
_state.trys.push([
|
|
992
|
+
4,
|
|
993
|
+
6,
|
|
994
|
+
,
|
|
995
|
+
7
|
|
996
|
+
]);
|
|
997
|
+
return [
|
|
998
|
+
4,
|
|
999
|
+
api.setOrgLogo({
|
|
1000
|
+
bytes: bytes,
|
|
1001
|
+
contentType: contentType,
|
|
1002
|
+
filename: basename(args.file_path)
|
|
1003
|
+
})
|
|
1004
|
+
];
|
|
1005
|
+
case 5:
|
|
1006
|
+
result = _state.sent();
|
|
1007
|
+
return [
|
|
1008
|
+
2,
|
|
1009
|
+
okResponse(result)
|
|
1010
|
+
];
|
|
1011
|
+
case 6:
|
|
1012
|
+
err1 = _state.sent();
|
|
1013
|
+
return [
|
|
1014
|
+
2,
|
|
1015
|
+
errorResponse(err1)
|
|
1016
|
+
];
|
|
1017
|
+
case 7:
|
|
1018
|
+
return [
|
|
1019
|
+
2
|
|
1020
|
+
];
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
1023
|
+
})();
|
|
1024
|
+
});
|
|
1025
|
+
server.tool('clear_logo', 'Remove the org logo. Idempotent — succeeds even when no logo is currently set.', {}, function() {
|
|
1026
|
+
return _async_to_generator(function() {
|
|
1027
|
+
var err;
|
|
1028
|
+
return _ts_generator(this, function(_state) {
|
|
1029
|
+
switch(_state.label){
|
|
1030
|
+
case 0:
|
|
1031
|
+
_state.trys.push([
|
|
1032
|
+
0,
|
|
1033
|
+
2,
|
|
1034
|
+
,
|
|
1035
|
+
3
|
|
1036
|
+
]);
|
|
1037
|
+
return [
|
|
1038
|
+
4,
|
|
1039
|
+
api.clearOrgLogo()
|
|
1040
|
+
];
|
|
1041
|
+
case 1:
|
|
1042
|
+
_state.sent();
|
|
1043
|
+
return [
|
|
1044
|
+
2,
|
|
1045
|
+
okResponse({
|
|
1046
|
+
success: true
|
|
1047
|
+
})
|
|
1048
|
+
];
|
|
1049
|
+
case 2:
|
|
1050
|
+
err = _state.sent();
|
|
1051
|
+
return [
|
|
1052
|
+
2,
|
|
1053
|
+
errorResponse(err)
|
|
1054
|
+
];
|
|
1055
|
+
case 3:
|
|
1056
|
+
return [
|
|
1057
|
+
2
|
|
1058
|
+
];
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
1061
|
+
})();
|
|
1062
|
+
});
|
|
998
1063
|
}
|