@displaydev/cli 0.1.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.
@@ -0,0 +1,418 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ function _ts_generator(thisArg, body) {
31
+ var f, y, t, _ = {
32
+ label: 0,
33
+ sent: function() {
34
+ if (t[0] & 1) throw t[1];
35
+ return t[1];
36
+ },
37
+ trys: [],
38
+ ops: []
39
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
40
+ return d(g, "next", {
41
+ value: verb(0)
42
+ }), d(g, "throw", {
43
+ value: verb(1)
44
+ }), d(g, "return", {
45
+ value: verb(2)
46
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
47
+ value: function() {
48
+ return this;
49
+ }
50
+ }), g;
51
+ function verb(n) {
52
+ return function(v) {
53
+ return step([
54
+ n,
55
+ v
56
+ ]);
57
+ };
58
+ }
59
+ function step(op) {
60
+ if (f) throw new TypeError("Generator is already executing.");
61
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
62
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
63
+ if (y = 0, t) op = [
64
+ op[0] & 2,
65
+ t.value
66
+ ];
67
+ switch(op[0]){
68
+ case 0:
69
+ case 1:
70
+ t = op;
71
+ break;
72
+ case 4:
73
+ _.label++;
74
+ return {
75
+ value: op[1],
76
+ done: false
77
+ };
78
+ case 5:
79
+ _.label++;
80
+ y = op[1];
81
+ op = [
82
+ 0
83
+ ];
84
+ continue;
85
+ case 7:
86
+ op = _.ops.pop();
87
+ _.trys.pop();
88
+ continue;
89
+ default:
90
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
91
+ _ = 0;
92
+ continue;
93
+ }
94
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
95
+ _.label = op[1];
96
+ break;
97
+ }
98
+ if (op[0] === 6 && _.label < t[1]) {
99
+ _.label = t[1];
100
+ t = op;
101
+ break;
102
+ }
103
+ if (t && _.label < t[2]) {
104
+ _.label = t[2];
105
+ _.ops.push(op);
106
+ break;
107
+ }
108
+ if (t[2]) _.ops.pop();
109
+ _.trys.pop();
110
+ continue;
111
+ }
112
+ op = body.call(thisArg, _);
113
+ } catch (e) {
114
+ op = [
115
+ 6,
116
+ e
117
+ ];
118
+ y = 0;
119
+ } finally{
120
+ f = t = 0;
121
+ }
122
+ if (op[0] & 5) throw op[1];
123
+ return {
124
+ value: op[0] ? op[1] : void 0,
125
+ done: true
126
+ };
127
+ }
128
+ }
129
+ import { readFile } from 'node:fs/promises';
130
+ import { resolve } from 'node:path';
131
+ import { z } from 'zod';
132
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
133
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
134
+ /**
135
+ * Starts an MCP server over stdin/stdout.
136
+ * Tools call the display.dev REST API via the ApiClient.
137
+ */ export function startMcpServer(apiClient) {
138
+ return _async_to_generator(function() {
139
+ var server, transport;
140
+ return _ts_generator(this, function(_state) {
141
+ switch(_state.label){
142
+ case 0:
143
+ server = new McpServer({
144
+ name: 'display',
145
+ version: '1.0.0'
146
+ });
147
+ registerTools(server, apiClient);
148
+ transport = new StdioServerTransport();
149
+ return [
150
+ 4,
151
+ server.connect(transport)
152
+ ];
153
+ case 1:
154
+ _state.sent();
155
+ return [
156
+ 2
157
+ ];
158
+ }
159
+ });
160
+ })();
161
+ }
162
+ function registerTools(server, api) {
163
+ server.tool('publish', 'Publish an HTML or Markdown artifact behind company auth', {
164
+ content: z.string().optional().describe('HTML or Markdown content to publish'),
165
+ file_path: z.string().optional().describe('Path to a local file to publish'),
166
+ name: z.string().optional().describe('Name for the artifact (required for new artifacts)'),
167
+ short_id: z.string().optional().describe('Short ID of existing artifact to update (publishes new version)'),
168
+ format: z.enum([
169
+ 'html',
170
+ 'md'
171
+ ]).default('html').describe('Content format'),
172
+ theme: z.string().optional().describe('Theme for Markdown rendering'),
173
+ share: z.array(z.string()).optional().describe('Email addresses to share with'),
174
+ visibility: z.enum([
175
+ 'public',
176
+ 'company'
177
+ ]).default('company').describe('Artifact visibility')
178
+ }, function(args) {
179
+ return _async_to_generator(function() {
180
+ var _args_name, content, hasContent, hasFilePath, absPath, result, _args_name1;
181
+ return _ts_generator(this, function(_state) {
182
+ switch(_state.label){
183
+ case 0:
184
+ if (!args.short_id && !((_args_name = args.name) === null || _args_name === void 0 ? void 0 : _args_name.trim())) {
185
+ return [
186
+ 2,
187
+ {
188
+ content: [
189
+ {
190
+ type: 'text',
191
+ text: JSON.stringify({
192
+ error: 'missing_name',
193
+ message: 'name is required for new artifacts (omit short_id), or provide short_id to update an existing artifact'
194
+ })
195
+ }
196
+ ],
197
+ isError: true
198
+ }
199
+ ];
200
+ }
201
+ hasContent = args.content !== undefined;
202
+ hasFilePath = args.file_path !== undefined;
203
+ if (hasContent && hasFilePath) {
204
+ return [
205
+ 2,
206
+ {
207
+ content: [
208
+ {
209
+ type: 'text',
210
+ text: JSON.stringify({
211
+ error: 'ambiguous_input',
212
+ message: 'Provide either content or file_path, not both'
213
+ })
214
+ }
215
+ ],
216
+ isError: true
217
+ }
218
+ ];
219
+ }
220
+ if (!hasFilePath) return [
221
+ 3,
222
+ 2
223
+ ];
224
+ absPath = resolve(args.file_path);
225
+ return [
226
+ 4,
227
+ readFile(absPath, 'utf-8')
228
+ ];
229
+ case 1:
230
+ content = _state.sent();
231
+ return [
232
+ 3,
233
+ 3
234
+ ];
235
+ case 2:
236
+ if (hasContent) {
237
+ content = args.content;
238
+ } else {
239
+ return [
240
+ 2,
241
+ {
242
+ content: [
243
+ {
244
+ type: 'text',
245
+ text: JSON.stringify({
246
+ error: 'missing_content',
247
+ message: 'Either content or file_path is required'
248
+ })
249
+ }
250
+ ],
251
+ isError: true
252
+ }
253
+ ];
254
+ }
255
+ _state.label = 3;
256
+ case 3:
257
+ if (!args.short_id) return [
258
+ 3,
259
+ 5
260
+ ];
261
+ return [
262
+ 4,
263
+ api.publishVersion(args.short_id, {
264
+ content: content,
265
+ format: args.format,
266
+ name: ((_args_name1 = args.name) === null || _args_name1 === void 0 ? void 0 : _args_name1.trim()) || undefined,
267
+ theme: args.theme,
268
+ share: args.share,
269
+ visibility: args.visibility
270
+ })
271
+ ];
272
+ case 4:
273
+ result = _state.sent();
274
+ return [
275
+ 3,
276
+ 7
277
+ ];
278
+ case 5:
279
+ return [
280
+ 4,
281
+ api.publish({
282
+ content: content,
283
+ name: args.name.trim(),
284
+ format: args.format,
285
+ theme: args.theme,
286
+ share: args.share,
287
+ visibility: args.visibility
288
+ })
289
+ ];
290
+ case 6:
291
+ result = _state.sent();
292
+ _state.label = 7;
293
+ case 7:
294
+ return [
295
+ 2,
296
+ {
297
+ content: [
298
+ {
299
+ type: 'text',
300
+ text: JSON.stringify(result)
301
+ }
302
+ ]
303
+ }
304
+ ];
305
+ }
306
+ });
307
+ })();
308
+ });
309
+ server.tool('find', 'Search for artifacts in the organization', {
310
+ query: z.string().optional().describe('Search by artifact name'),
311
+ published_by: z.string().optional().describe('Filter by publisher email'),
312
+ since: z.string().optional().describe('Filter by updated since ISO date'),
313
+ limit: z.number().optional().describe('Max results to return')
314
+ }, function(args) {
315
+ return _async_to_generator(function() {
316
+ var results;
317
+ return _ts_generator(this, function(_state) {
318
+ switch(_state.label){
319
+ case 0:
320
+ return [
321
+ 4,
322
+ api.find(args)
323
+ ];
324
+ case 1:
325
+ results = _state.sent();
326
+ return [
327
+ 2,
328
+ {
329
+ content: [
330
+ {
331
+ type: 'text',
332
+ text: JSON.stringify(results)
333
+ }
334
+ ]
335
+ }
336
+ ];
337
+ }
338
+ });
339
+ })();
340
+ });
341
+ server.tool('get', 'Get full details of a specific artifact', {
342
+ short_id: z.string().describe('Artifact shortId'),
343
+ include: z.array(z.string()).optional().describe('Include additional data (e.g. "versions")')
344
+ }, function(args) {
345
+ return _async_to_generator(function() {
346
+ var result;
347
+ return _ts_generator(this, function(_state) {
348
+ switch(_state.label){
349
+ case 0:
350
+ return [
351
+ 4,
352
+ api.get(args.short_id, args.include)
353
+ ];
354
+ case 1:
355
+ result = _state.sent();
356
+ return [
357
+ 2,
358
+ {
359
+ content: [
360
+ {
361
+ type: 'text',
362
+ text: JSON.stringify(result)
363
+ }
364
+ ]
365
+ }
366
+ ];
367
+ }
368
+ });
369
+ })();
370
+ });
371
+ server.tool('delete', 'Delete an artifact permanently', {
372
+ short_id: z.string().describe('Artifact shortId to delete'),
373
+ confirm: z.boolean().describe('Must be true to confirm deletion')
374
+ }, function(args) {
375
+ return _async_to_generator(function() {
376
+ var result;
377
+ return _ts_generator(this, function(_state) {
378
+ switch(_state.label){
379
+ case 0:
380
+ if (!args.confirm) {
381
+ return [
382
+ 2,
383
+ {
384
+ content: [
385
+ {
386
+ type: 'text',
387
+ text: JSON.stringify({
388
+ error: 'confirm_required',
389
+ message: 'Set confirm to true to delete'
390
+ })
391
+ }
392
+ ],
393
+ isError: true
394
+ }
395
+ ];
396
+ }
397
+ return [
398
+ 4,
399
+ api.delete(args.short_id)
400
+ ];
401
+ case 1:
402
+ result = _state.sent();
403
+ return [
404
+ 2,
405
+ {
406
+ content: [
407
+ {
408
+ type: 'text',
409
+ text: JSON.stringify(result)
410
+ }
411
+ ]
412
+ }
413
+ ];
414
+ }
415
+ });
416
+ })();
417
+ });
418
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@displaydev/cli",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "dsp": "./dist/main.js"
7
+ },
8
+ "files": [
9
+ "dist",
10
+ "!dist/*.spec.js"
11
+ ],
12
+ "scripts": {
13
+ "build": "swc src -d dist --strip-leading-paths",
14
+ "typecheck": "tsgo --project tsconfig.json --noEmit",
15
+ "test": "vitest run"
16
+ },
17
+ "dependencies": {
18
+ "@modelcontextprotocol/sdk": "^1.29.0",
19
+ "commander": "^14.0.3",
20
+ "zod": "^4.3.6"
21
+ },
22
+ "devDependencies": {
23
+ "@swc/cli": "^0.7.10",
24
+ "@swc/core": "^1.15.24",
25
+ "@types/node": "^24.12.2",
26
+ "vitest": "^4.1.2"
27
+ }
28
+ }