@displaydev/cli 0.17.0 → 0.19.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.
@@ -63,39 +63,27 @@ function _object_spread(target) {
63
63
  }
64
64
  return target;
65
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);
66
+ function ownKeys(object, enumerableOnly) {
67
+ var keys = Object.keys(object);
80
68
  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];
69
+ var symbols = Object.getOwnPropertySymbols(object);
70
+ if (enumerableOnly) {
71
+ symbols = symbols.filter(function(sym) {
72
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
73
+ });
87
74
  }
75
+ keys.push.apply(keys, symbols);
88
76
  }
89
- return target;
77
+ return keys;
90
78
  }
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];
79
+ function _object_spread_props(target, source) {
80
+ source = source != null ? source : {};
81
+ if (Object.getOwnPropertyDescriptors) {
82
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
83
+ } else {
84
+ ownKeys(Object(source)).forEach(function(key) {
85
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
86
+ });
99
87
  }
100
88
  return target;
101
89
  }
@@ -624,24 +612,29 @@ export function registerTools(server, api) {
624
612
  });
625
613
  })();
626
614
  });
627
- server.tool('find', 'Search for artifacts in the organization', {
628
- query: z.string().optional().describe('Search by artifact name'),
629
- published_by: z.string().optional().describe('Filter by publisher email'),
630
- mine: z.boolean().optional().describe('Limit results to your own artifacts'),
631
- since: z.string().optional().describe('Filter by updated since ISO date'),
615
+ 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.', {
616
+ query: z.string().optional().describe('Search by artifact name (case-insensitive substring). Omit to list all artifacts.'),
617
+ 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.'),
618
+ visibility: z.array(z.enum([
619
+ 'public',
620
+ 'company',
621
+ 'private'
622
+ ])).optional().describe('Filter by one or more visibility levels. NOTE: "private" is creator-scoped — only your own private artifacts are returned, not org-wide.'),
623
+ since: z.string().optional().describe('ISO timestamp; only artifacts updated on or after this point.'),
632
624
  sort: z.enum([
633
625
  'updated_at',
634
626
  'view_count',
635
627
  'name'
636
- ]).optional().describe('Sort column'),
628
+ ]).optional().describe('Sort column. Defaults to updated_at.'),
637
629
  dir: z.enum([
638
630
  'asc',
639
631
  'desc'
640
- ]).optional().describe('Sort direction'),
641
- limit: z.number().optional().describe('Max results to return (1-100)')
632
+ ]).optional().describe('Sort direction. Defaults: desc for updated_at and view_count, asc for name.'),
633
+ 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.'),
634
+ limit: z.number().int().min(1).max(100).optional().describe('Max results per page (1–100, default 50).')
642
635
  }, function(args) {
643
636
  return _async_to_generator(function() {
644
- var publishedBy, rest, results, err;
637
+ var result, err;
645
638
  return _ts_generator(this, function(_state) {
646
639
  switch(_state.label){
647
640
  case 0:
@@ -651,25 +644,15 @@ export function registerTools(server, api) {
651
644
  ,
652
645
  3
653
646
  ]);
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
647
  return [
663
648
  4,
664
- api.find(_object_spread({}, rest, publishedBy !== undefined ? {
665
- publishedBy: publishedBy
666
- } : {}))
649
+ api.find(args)
667
650
  ];
668
651
  case 1:
669
- results = _state.sent();
652
+ result = _state.sent();
670
653
  return [
671
654
  2,
672
- okResponse(results)
655
+ okResponse(result)
673
656
  ];
674
657
  case 2:
675
658
  err = _state.sent();
@@ -1129,4 +1112,446 @@ export function registerTools(server, api) {
1129
1112
  });
1130
1113
  })();
1131
1114
  });
1115
+ registerCommentTools(server, api);
1116
+ }
1117
+ /**
1118
+ * Comment tools (feat-comments §3) — stdio transport mirror of the
1119
+ * eight HTTP MCP tools in `api/src/mcp/comment-tools.ts`. KB-page
1120
+ * subjects return `subject_type_not_implemented` here too; the
1121
+ * polymorphic shape is part of the public contract so the CLI's MCP
1122
+ * surface accepts the same input even when the wire path 501s.
1123
+ */ function registerCommentTools(server, api) {
1124
+ function rejectKbPage() {
1125
+ return {
1126
+ content: [
1127
+ {
1128
+ type: 'text',
1129
+ text: JSON.stringify({
1130
+ error: 'subject_type_not_implemented',
1131
+ message: 'KB-page subjects are not yet supported. Pass subject_type="artifact".',
1132
+ status: 501
1133
+ })
1134
+ }
1135
+ ],
1136
+ isError: true
1137
+ };
1138
+ }
1139
+ function requireShortId(args) {
1140
+ if (!args.short_id) {
1141
+ return {
1142
+ content: [
1143
+ {
1144
+ type: 'text',
1145
+ text: JSON.stringify({
1146
+ error: 'validation_error',
1147
+ message: 'short_id is required for subject_type=artifact',
1148
+ status: 400
1149
+ })
1150
+ }
1151
+ ],
1152
+ isError: true
1153
+ };
1154
+ }
1155
+ return args.short_id;
1156
+ }
1157
+ var subjectArgs = {
1158
+ subject_type: z.enum([
1159
+ 'artifact',
1160
+ 'kb_page'
1161
+ ]).describe('Subject discriminator'),
1162
+ short_id: z.string().optional().describe('Artifact shortId (subject_type=artifact)'),
1163
+ kb_name: z.string().optional().describe('KB name (subject_type=kb_page; not yet supported)'),
1164
+ file_path: z.string().optional().describe('KB page path (subject_type=kb_page; not yet supported)')
1165
+ };
1166
+ var anchorSchema = z.object({
1167
+ textQuote: z.object({
1168
+ prefix: z.string(),
1169
+ exact: z.string(),
1170
+ suffix: z.string()
1171
+ }),
1172
+ cssPath: z.string(),
1173
+ textPosition: z.object({
1174
+ start: z.number().int(),
1175
+ end: z.number().int()
1176
+ }).optional()
1177
+ }).optional();
1178
+ server.tool('add_comment', 'Post a root comment or reply on an artifact. Root: pass `anchor` and omit `parent_id`. Reply: pass `parent_id` (the root comment id) and omit `anchor` (replies inherit the root anchor).', _object_spread_props(_object_spread({}, subjectArgs), {
1179
+ body: z.string().min(1).max(10000).describe('Comment body (≤10k chars)'),
1180
+ parent_id: z.string().optional().describe('Root comment id when posting a reply'),
1181
+ anchor: anchorSchema
1182
+ }), function(args) {
1183
+ return _async_to_generator(function() {
1184
+ var shortIdOrErr, result, err;
1185
+ return _ts_generator(this, function(_state) {
1186
+ switch(_state.label){
1187
+ case 0:
1188
+ if (args.subject_type === 'kb_page') {
1189
+ return [
1190
+ 2,
1191
+ rejectKbPage()
1192
+ ];
1193
+ }
1194
+ shortIdOrErr = requireShortId(args);
1195
+ if (typeof shortIdOrErr !== 'string') {
1196
+ return [
1197
+ 2,
1198
+ shortIdOrErr
1199
+ ];
1200
+ }
1201
+ _state.label = 1;
1202
+ case 1:
1203
+ _state.trys.push([
1204
+ 1,
1205
+ 3,
1206
+ ,
1207
+ 4
1208
+ ]);
1209
+ return [
1210
+ 4,
1211
+ api.addComment(shortIdOrErr, {
1212
+ body: args.body,
1213
+ anchor: args.anchor,
1214
+ parentId: args.parent_id
1215
+ })
1216
+ ];
1217
+ case 2:
1218
+ result = _state.sent();
1219
+ return [
1220
+ 2,
1221
+ okResponse(result)
1222
+ ];
1223
+ case 3:
1224
+ err = _state.sent();
1225
+ return [
1226
+ 2,
1227
+ errorResponse(err)
1228
+ ];
1229
+ case 4:
1230
+ return [
1231
+ 2
1232
+ ];
1233
+ }
1234
+ });
1235
+ })();
1236
+ });
1237
+ server.tool('list_comments', 'List comment threads on a subject. Reads from Postgres (not the KV widget cache).', _object_spread_props(_object_spread({}, subjectArgs), {
1238
+ status: z.enum([
1239
+ 'open',
1240
+ 'resolved',
1241
+ 'all'
1242
+ ]).optional().describe('Defaults to "open"'),
1243
+ since: z.string().optional().describe('ISO-8601 — return only threads with activity at or after this timestamp')
1244
+ }), function(args) {
1245
+ return _async_to_generator(function() {
1246
+ var shortIdOrErr, result, err;
1247
+ return _ts_generator(this, function(_state) {
1248
+ switch(_state.label){
1249
+ case 0:
1250
+ if (args.subject_type === 'kb_page') {
1251
+ return [
1252
+ 2,
1253
+ rejectKbPage()
1254
+ ];
1255
+ }
1256
+ shortIdOrErr = requireShortId(args);
1257
+ if (typeof shortIdOrErr !== 'string') {
1258
+ return [
1259
+ 2,
1260
+ shortIdOrErr
1261
+ ];
1262
+ }
1263
+ _state.label = 1;
1264
+ case 1:
1265
+ _state.trys.push([
1266
+ 1,
1267
+ 3,
1268
+ ,
1269
+ 4
1270
+ ]);
1271
+ return [
1272
+ 4,
1273
+ api.listComments(shortIdOrErr, {
1274
+ status: args.status,
1275
+ since: args.since
1276
+ })
1277
+ ];
1278
+ case 2:
1279
+ result = _state.sent();
1280
+ return [
1281
+ 2,
1282
+ okResponse(result)
1283
+ ];
1284
+ case 3:
1285
+ err = _state.sent();
1286
+ return [
1287
+ 2,
1288
+ errorResponse(err)
1289
+ ];
1290
+ case 4:
1291
+ return [
1292
+ 2
1293
+ ];
1294
+ }
1295
+ });
1296
+ })();
1297
+ });
1298
+ server.tool('edit_comment', 'Edit your own comment within the 5-minute author window. After 5 minutes the body is locked.', {
1299
+ comment_id: z.string(),
1300
+ body: z.string().min(1).max(10000)
1301
+ }, function(args) {
1302
+ return _async_to_generator(function() {
1303
+ var result, err;
1304
+ return _ts_generator(this, function(_state) {
1305
+ switch(_state.label){
1306
+ case 0:
1307
+ _state.trys.push([
1308
+ 0,
1309
+ 2,
1310
+ ,
1311
+ 3
1312
+ ]);
1313
+ return [
1314
+ 4,
1315
+ api.editComment(args.comment_id, args.body)
1316
+ ];
1317
+ case 1:
1318
+ result = _state.sent();
1319
+ return [
1320
+ 2,
1321
+ okResponse(result)
1322
+ ];
1323
+ case 2:
1324
+ err = _state.sent();
1325
+ return [
1326
+ 2,
1327
+ errorResponse(err)
1328
+ ];
1329
+ case 3:
1330
+ return [
1331
+ 2
1332
+ ];
1333
+ }
1334
+ });
1335
+ })();
1336
+ });
1337
+ server.tool('delete_comment', 'Soft-delete a comment. Author / artifact creator / org admin. Replies remain visible; body becomes "[deleted]".', {
1338
+ comment_id: z.string()
1339
+ }, function(args) {
1340
+ return _async_to_generator(function() {
1341
+ var err;
1342
+ return _ts_generator(this, function(_state) {
1343
+ switch(_state.label){
1344
+ case 0:
1345
+ _state.trys.push([
1346
+ 0,
1347
+ 2,
1348
+ ,
1349
+ 3
1350
+ ]);
1351
+ return [
1352
+ 4,
1353
+ api.deleteComment(args.comment_id)
1354
+ ];
1355
+ case 1:
1356
+ _state.sent();
1357
+ return [
1358
+ 2,
1359
+ okResponse({
1360
+ deleted: true
1361
+ })
1362
+ ];
1363
+ case 2:
1364
+ err = _state.sent();
1365
+ return [
1366
+ 2,
1367
+ errorResponse(err)
1368
+ ];
1369
+ case 3:
1370
+ return [
1371
+ 2
1372
+ ];
1373
+ }
1374
+ });
1375
+ })();
1376
+ });
1377
+ server.tool('resolve_thread', 'Mark a thread resolved (root comment id). Thread participant / artifact creator / org admin.', {
1378
+ comment_id: z.string()
1379
+ }, function(args) {
1380
+ return _async_to_generator(function() {
1381
+ var result, err;
1382
+ return _ts_generator(this, function(_state) {
1383
+ switch(_state.label){
1384
+ case 0:
1385
+ _state.trys.push([
1386
+ 0,
1387
+ 2,
1388
+ ,
1389
+ 3
1390
+ ]);
1391
+ return [
1392
+ 4,
1393
+ api.resolveThread(args.comment_id)
1394
+ ];
1395
+ case 1:
1396
+ result = _state.sent();
1397
+ return [
1398
+ 2,
1399
+ okResponse(result)
1400
+ ];
1401
+ case 2:
1402
+ err = _state.sent();
1403
+ return [
1404
+ 2,
1405
+ errorResponse(err)
1406
+ ];
1407
+ case 3:
1408
+ return [
1409
+ 2
1410
+ ];
1411
+ }
1412
+ });
1413
+ })();
1414
+ });
1415
+ server.tool('reopen_thread', 'Reopen a resolved thread. Any authenticated user with view access on the artifact.', {
1416
+ comment_id: z.string()
1417
+ }, function(args) {
1418
+ return _async_to_generator(function() {
1419
+ var result, err;
1420
+ return _ts_generator(this, function(_state) {
1421
+ switch(_state.label){
1422
+ case 0:
1423
+ _state.trys.push([
1424
+ 0,
1425
+ 2,
1426
+ ,
1427
+ 3
1428
+ ]);
1429
+ return [
1430
+ 4,
1431
+ api.reopenThread(args.comment_id)
1432
+ ];
1433
+ case 1:
1434
+ result = _state.sent();
1435
+ return [
1436
+ 2,
1437
+ okResponse(result)
1438
+ ];
1439
+ case 2:
1440
+ err = _state.sent();
1441
+ return [
1442
+ 2,
1443
+ errorResponse(err)
1444
+ ];
1445
+ case 3:
1446
+ return [
1447
+ 2
1448
+ ];
1449
+ }
1450
+ });
1451
+ })();
1452
+ });
1453
+ server.tool('watch', 'Watch the subject for comment notifications. Per-user; service-account API keys cannot subscribe.', subjectArgs, function(args) {
1454
+ return _async_to_generator(function() {
1455
+ var shortIdOrErr, result, err;
1456
+ return _ts_generator(this, function(_state) {
1457
+ switch(_state.label){
1458
+ case 0:
1459
+ if (args.subject_type === 'kb_page') {
1460
+ return [
1461
+ 2,
1462
+ rejectKbPage()
1463
+ ];
1464
+ }
1465
+ shortIdOrErr = requireShortId(args);
1466
+ if (typeof shortIdOrErr !== 'string') {
1467
+ return [
1468
+ 2,
1469
+ shortIdOrErr
1470
+ ];
1471
+ }
1472
+ _state.label = 1;
1473
+ case 1:
1474
+ _state.trys.push([
1475
+ 1,
1476
+ 3,
1477
+ ,
1478
+ 4
1479
+ ]);
1480
+ return [
1481
+ 4,
1482
+ api.watchArtifact(shortIdOrErr)
1483
+ ];
1484
+ case 2:
1485
+ result = _state.sent();
1486
+ return [
1487
+ 2,
1488
+ okResponse(result)
1489
+ ];
1490
+ case 3:
1491
+ err = _state.sent();
1492
+ return [
1493
+ 2,
1494
+ errorResponse(err)
1495
+ ];
1496
+ case 4:
1497
+ return [
1498
+ 2
1499
+ ];
1500
+ }
1501
+ });
1502
+ })();
1503
+ });
1504
+ server.tool('unwatch', 'Unwatch the subject. Per-user; service-account API keys cannot subscribe.', subjectArgs, function(args) {
1505
+ return _async_to_generator(function() {
1506
+ var shortIdOrErr, err;
1507
+ return _ts_generator(this, function(_state) {
1508
+ switch(_state.label){
1509
+ case 0:
1510
+ if (args.subject_type === 'kb_page') {
1511
+ return [
1512
+ 2,
1513
+ rejectKbPage()
1514
+ ];
1515
+ }
1516
+ shortIdOrErr = requireShortId(args);
1517
+ if (typeof shortIdOrErr !== 'string') {
1518
+ return [
1519
+ 2,
1520
+ shortIdOrErr
1521
+ ];
1522
+ }
1523
+ _state.label = 1;
1524
+ case 1:
1525
+ _state.trys.push([
1526
+ 1,
1527
+ 3,
1528
+ ,
1529
+ 4
1530
+ ]);
1531
+ return [
1532
+ 4,
1533
+ api.unwatchArtifact(shortIdOrErr)
1534
+ ];
1535
+ case 2:
1536
+ _state.sent();
1537
+ return [
1538
+ 2,
1539
+ okResponse({
1540
+ watching: false
1541
+ })
1542
+ ];
1543
+ case 3:
1544
+ err = _state.sent();
1545
+ return [
1546
+ 2,
1547
+ errorResponse(err)
1548
+ ];
1549
+ case 4:
1550
+ return [
1551
+ 2
1552
+ ];
1553
+ }
1554
+ });
1555
+ })();
1556
+ });
1132
1557
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@displaydev/cli",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "dsp": "dist/main.js"