@displaydev/cli 0.3.0 → 0.5.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,6 +265,9 @@ export var ApiClient = /*#__PURE__*/ function() {
265
265
  }
266
266
  }
267
267
  }
268
+ if (params.clearShares) {
269
+ form.append('clearGuestEmails', 'true');
270
+ }
268
271
  return form;
269
272
  }
270
273
  },
@@ -272,26 +275,44 @@ export var ApiClient = /*#__PURE__*/ function() {
272
275
  key: "find",
273
276
  value: function find(params) {
274
277
  return _async_to_generator(function() {
275
- var searchParams, qs;
278
+ var searchParams, qs, res;
276
279
  return _ts_generator(this, function(_state) {
277
- searchParams = new URLSearchParams();
278
- if (params.query) {
279
- searchParams.set('q', params.query);
280
- }
281
- if (params.published_by) {
282
- searchParams.set('published_by', params.published_by);
283
- }
284
- if (params.since) {
285
- searchParams.set('since', params.since);
286
- }
287
- if (params.limit) {
288
- searchParams.set('limit', String(params.limit));
280
+ switch(_state.label){
281
+ case 0:
282
+ searchParams = new URLSearchParams();
283
+ if (params.query) {
284
+ searchParams.set('q', params.query);
285
+ }
286
+ if (params.mine) {
287
+ searchParams.append('author', 'me');
288
+ }
289
+ if (params.published_by) {
290
+ searchParams.set('published_by', params.published_by);
291
+ }
292
+ if (params.since) {
293
+ searchParams.set('since', params.since);
294
+ }
295
+ if (params.sort) {
296
+ searchParams.set('sort', params.sort);
297
+ }
298
+ if (params.dir) {
299
+ searchParams.set('dir', params.dir);
300
+ }
301
+ if (params.limit) {
302
+ searchParams.set('limit', String(params.limit));
303
+ }
304
+ qs = searchParams.toString();
305
+ return [
306
+ 4,
307
+ this.request('GET', "/v1/artifacts".concat(qs ? "?".concat(qs) : ''))
308
+ ];
309
+ case 1:
310
+ res = _state.sent();
311
+ return [
312
+ 2,
313
+ res.data
314
+ ];
289
315
  }
290
- qs = searchParams.toString();
291
- return [
292
- 2,
293
- this.request('GET', "/v1/artifacts".concat(qs ? "?".concat(qs) : ''))
294
- ];
295
316
  });
296
317
  }).call(this);
297
318
  }
package/dist/main.js CHANGED
@@ -288,7 +288,7 @@ function collectEmails(value, prev) {
288
288
  return prev.concat(value);
289
289
  }
290
290
  // --- 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) {
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('--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)').action(function(filePath, opts) {
292
292
  return _async_to_generator(function() {
293
293
  var auth, client, ext, content, format, visibility, share, result, verb;
294
294
  return _ts_generator(this, function(_state) {
@@ -298,6 +298,18 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
298
298
  console.error('--name is required for new artifacts. Use --id to update an existing one.');
299
299
  process.exit(1);
300
300
  }
301
+ if (opts.public && opts.company) {
302
+ console.error('Use --public or --company, not both.');
303
+ process.exit(1);
304
+ }
305
+ if (opts.clearShares && opts.share.length > 0) {
306
+ console.error('Use --share or --clear-shares, not both.');
307
+ process.exit(1);
308
+ }
309
+ if (opts.clearShares && !opts.id) {
310
+ console.error('--clear-shares only applies when updating (--id).');
311
+ process.exit(1);
312
+ }
301
313
  return [
302
314
  4,
303
315
  resolveAuthOrConfig()
@@ -317,7 +329,11 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
317
329
  case 2:
318
330
  content = _state.sent();
319
331
  format = ext === '.md' ? 'md' : 'html';
320
- visibility = opts.public ? 'public' : undefined;
332
+ if (opts.public) {
333
+ visibility = 'public';
334
+ } else if (opts.company) {
335
+ visibility = 'company';
336
+ }
321
337
  share = opts.share.length > 0 ? opts.share : undefined;
322
338
  if (!opts.id) return [
323
339
  3,
@@ -331,6 +347,7 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
331
347
  name: opts.name,
332
348
  theme: opts.theme,
333
349
  share: share,
350
+ clearShares: opts.clearShares,
334
351
  visibility: visibility
335
352
  })
336
353
  ];
@@ -367,12 +384,26 @@ program.command('publish <path>').description('Publish an HTML or Markdown file'
367
384
  })();
368
385
  });
369
386
  // --- find ---
370
- program.command('find [query]').description('Search for artifacts').option('--by <email>', 'Filter by publisher email').option('--since <date>', 'Filter by date (ISO format)').action(function(query, opts) {
387
+ program.command('find [query]').description('Search for artifacts').option('--by <email>', 'Filter by publisher email').option('--mine', 'Show only artifacts you published').option('--since <date>', 'Filter by date (ISO format)').option('--sort <col>', 'Sort column: updated_at, view_count, name', 'updated_at').option('--dir <direction>', 'Sort direction: asc or desc').option('--limit <n>', 'Max rows to fetch (1-100)', function(v) {
388
+ return parseInt(v, 10);
389
+ }).action(function(query, opts) {
371
390
  return _async_to_generator(function() {
372
391
  var auth, client, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, a;
373
392
  return _ts_generator(this, function(_state) {
374
393
  switch(_state.label){
375
394
  case 0:
395
+ if (opts.sort && ![
396
+ 'updated_at',
397
+ 'view_count',
398
+ 'name'
399
+ ].includes(opts.sort)) {
400
+ console.error("Invalid --sort: ".concat(opts.sort, ". Use updated_at, view_count, or name."));
401
+ process.exit(1);
402
+ }
403
+ if (opts.dir && opts.dir !== 'asc' && opts.dir !== 'desc') {
404
+ console.error("Invalid --dir: ".concat(opts.dir, ". Use asc or desc."));
405
+ process.exit(1);
406
+ }
376
407
  return [
377
408
  4,
378
409
  resolveAuthOrConfig()
@@ -385,7 +416,11 @@ program.command('find [query]').description('Search for artifacts').option('--by
385
416
  client.find({
386
417
  query: query,
387
418
  published_by: opts.by,
388
- since: opts.since
419
+ mine: opts.mine,
420
+ since: opts.since,
421
+ sort: opts.sort,
422
+ dir: opts.dir,
423
+ limit: opts.limit
389
424
  })
390
425
  ];
391
426
  case 2:
@@ -170,11 +170,12 @@ function registerTools(server, api) {
170
170
  'md'
171
171
  ]).default('html').describe('Content format'),
172
172
  theme: z.string().optional().describe('Theme for Markdown rendering'),
173
- share: z.array(z.string()).optional().describe('Email addresses to share with'),
173
+ share: z.array(z.string()).optional().describe('Email addresses to share with. Omit to keep current shares on update.'),
174
+ clear_shares: z.boolean().optional().describe('Set true to remove all guest shares (update only, mutually exclusive with share).'),
174
175
  visibility: z.enum([
175
176
  'public',
176
177
  'company'
177
- ]).default('company').describe('Artifact visibility')
178
+ ]).optional().describe('Artifact visibility. Omit to keep current on update; defaults to "company" on create.')
178
179
  }, function(args) {
179
180
  return _async_to_generator(function() {
180
181
  var _args_name, content, hasContent, hasFilePath, absPath, result, _args_name1;
@@ -198,6 +199,40 @@ function registerTools(server, api) {
198
199
  }
199
200
  ];
200
201
  }
202
+ if (args.share && args.clear_shares) {
203
+ return [
204
+ 2,
205
+ {
206
+ content: [
207
+ {
208
+ type: 'text',
209
+ text: JSON.stringify({
210
+ error: 'conflicting_params',
211
+ message: 'Pass share or clear_shares, not both'
212
+ })
213
+ }
214
+ ],
215
+ isError: true
216
+ }
217
+ ];
218
+ }
219
+ if (args.clear_shares && !args.short_id) {
220
+ return [
221
+ 2,
222
+ {
223
+ content: [
224
+ {
225
+ type: 'text',
226
+ text: JSON.stringify({
227
+ error: 'clear_shares_requires_short_id',
228
+ message: 'clear_shares only applies when updating an existing artifact (short_id)'
229
+ })
230
+ }
231
+ ],
232
+ isError: true
233
+ }
234
+ ];
235
+ }
201
236
  hasContent = args.content !== undefined;
202
237
  hasFilePath = args.file_path !== undefined;
203
238
  if (hasContent && hasFilePath) {
@@ -266,6 +301,7 @@ function registerTools(server, api) {
266
301
  name: ((_args_name1 = args.name) === null || _args_name1 === void 0 ? void 0 : _args_name1.trim()) || undefined,
267
302
  theme: args.theme,
268
303
  share: args.share,
304
+ clearShares: args.clear_shares,
269
305
  visibility: args.visibility
270
306
  })
271
307
  ];
@@ -309,8 +345,18 @@ function registerTools(server, api) {
309
345
  server.tool('find', 'Search for artifacts in the organization', {
310
346
  query: z.string().optional().describe('Search by artifact name'),
311
347
  published_by: z.string().optional().describe('Filter by publisher email'),
348
+ mine: z.boolean().optional().describe('Limit results to your own artifacts'),
312
349
  since: z.string().optional().describe('Filter by updated since ISO date'),
313
- limit: z.number().optional().describe('Max results to return')
350
+ sort: z.enum([
351
+ 'updated_at',
352
+ 'view_count',
353
+ 'name'
354
+ ]).optional().describe('Sort column'),
355
+ dir: z.enum([
356
+ 'asc',
357
+ 'desc'
358
+ ]).optional().describe('Sort direction'),
359
+ limit: z.number().optional().describe('Max results to return (1-100)')
314
360
  }, function(args) {
315
361
  return _async_to_generator(function() {
316
362
  var results;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@displaydev/cli",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "dsp": "dist/main.js"