coding-tool-x 3.8.6 → 3.8.8

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.
Files changed (134) hide show
  1. package/dist/web/assets/{AgentsDrawer-Db9wAyaZ.js → AgentsDrawer-DRQuwi0m.js} +1 -1
  2. package/dist/web/assets/Analytics-Cf5KwEdj.js +1 -0
  3. package/dist/web/assets/AssetPathField-DyniM0pF.js +1 -0
  4. package/dist/web/assets/{ChatHistoryDrawer-CwzJHyNP.js → ChatHistoryDrawer-CrfS0KYV.js} +1 -1
  5. package/dist/web/assets/{CollapseItem-CTCfSiue.js → CollapseItem-ClMsJuUu.js} +1 -1
  6. package/dist/web/assets/{CommandsDrawer-vDghB1U9.js → CommandsDrawer-CzHelf56.js} +1 -1
  7. package/dist/web/assets/ConfigExportDrawer-BEZ8wTby.js +1 -0
  8. package/dist/web/assets/ConfigTemplates-Crg3xWe5.js +1 -0
  9. package/dist/web/assets/{ConfigTemplatesDrawer-CbsJp76X.js → ConfigTemplatesDrawer-BqM32Im7.js} +1 -1
  10. package/dist/web/assets/{ConfigTemplatesPanel-liMSTh7s.js → ConfigTemplatesPanel-lTdutC8H.js} +1 -1
  11. package/dist/web/assets/{Divider-D28g1gwj.js → Divider-DsdbkHrG.js} +1 -1
  12. package/dist/web/assets/{FavoritesDrawer-D6QSiYaL.js → FavoritesDrawer-DDyWUBJR.js} +1 -1
  13. package/dist/web/assets/Forward-DLCL7aMY.js +1 -0
  14. package/dist/web/assets/{GatewayConvertDrawer-RvET6iNG.js → GatewayConvertDrawer-Rigtt_5J.js} +1 -1
  15. package/dist/web/assets/Home-tCSKmSHV.js +1 -0
  16. package/dist/web/assets/{MarkdownEditor-CYmLGYju.js → MarkdownEditor-BMMUufSc.js} +1 -1
  17. package/dist/web/assets/McpDrawer-CmE-d7VW.js +1 -0
  18. package/dist/web/assets/{McpFormDrawer-BcTlgSpN.js → McpFormDrawer-ByvS18od.js} +1 -1
  19. package/dist/web/assets/{PluginManager-Dh2o0xkZ.js → PluginManager-C4kJlpVX.js} +1 -1
  20. package/dist/web/assets/{PluginsDrawer-deKQ5u3I.js → PluginsDrawer-05R4k15x.js} +1 -1
  21. package/dist/web/assets/PluginsPanel-BCoEs7Og.js +1 -0
  22. package/dist/web/assets/PluginsPanel-CzGMK-Ap.css +1 -0
  23. package/dist/web/assets/ProjectList-BJt1OIaI.js +1 -0
  24. package/dist/web/assets/ProjectList-DG3yu8xZ.css +1 -0
  25. package/dist/web/assets/PromptsDrawer-DnwBf_oW.js +1 -0
  26. package/dist/web/assets/RecentSessionsDrawer-B7d-38wH.js +1 -0
  27. package/dist/web/assets/RecentSessionsDrawer-yrAD4p1A.css +1 -0
  28. package/dist/web/assets/SessionCard-BUgjHQwX.js +1 -0
  29. package/dist/web/assets/SessionList-B-bXZRFk.js +1 -0
  30. package/dist/web/assets/SessionList-qG_XpPBJ.css +1 -0
  31. package/dist/web/assets/{SettingsDrawer-u_vwUuPS.js → SettingsDrawer-BITzjQLl.js} +1 -1
  32. package/dist/web/assets/SkillManager-D9jkNuRM.js +1 -0
  33. package/dist/web/assets/{SkillsDrawer-CkF3BpyC.js → SkillsDrawer-0Z4IefxC.js} +1 -1
  34. package/dist/web/assets/SkillsPanel-BKIVOj7n.js +1 -0
  35. package/dist/web/assets/{SkillsPanel-B3Nm5j32.css → SkillsPanel-C4ke56nF.css} +1 -1
  36. package/dist/web/assets/{SpeedTestDrawer-BgfG1Ked.js → SpeedTestDrawer-Bx1bYf5i.js} +1 -1
  37. package/dist/web/assets/Upload-CzC4rGI4.js +1 -0
  38. package/dist/web/assets/{WorkspaceDrawer-Br5CeCzL.js → WorkspaceDrawer-eujtWpoq.js} +1 -1
  39. package/dist/web/assets/{WorkspaceManager-B2O8-qIw.js → WorkspaceManager-CQ-8Ej68.js} +1 -1
  40. package/dist/web/assets/{WorkspacePanel-5oDKit3c.js → WorkspacePanel-Cql5qE2R.js} +1 -1
  41. package/dist/web/assets/headers-BqDmkMjy.js +1 -0
  42. package/dist/web/assets/{icons-B2Vg-IOC.js → icons-DmFe4b5j.js} +1 -1
  43. package/dist/web/assets/index-Cmmwj3Fx.js +2 -0
  44. package/dist/web/assets/{index-Bi1MQHYX.css → index-Cnbe696C.css} +1 -1
  45. package/dist/web/assets/{light-Cp0t7v32.js → light-0eavxNvt.js} +1 -1
  46. package/dist/web/assets/platforms-BmzzwnSw.js +1 -0
  47. package/dist/web/assets/platforms-DWXgmy2w.js +1 -0
  48. package/dist/web/assets/session-visibility-BAmxh3cK.js +1 -0
  49. package/dist/web/assets/sessions-D4yQtfKb.js +1 -0
  50. package/dist/web/assets/sessions-DqlbocLJ.js +1 -0
  51. package/dist/web/assets/use-message-DqCwefG6.js +1 -0
  52. package/dist/web/assets/{useResponsiveDrawer-jbmqZuJs.js → useResponsiveDrawer-DZd5rNk5.js} +1 -1
  53. package/dist/web/index.html +7 -7
  54. package/package.json +1 -1
  55. package/src/commands/search.js +17 -2
  56. package/src/config/paths.js +2 -0
  57. package/src/platforms/driver-registry.js +9 -1
  58. package/src/platforms/drivers/claude/session-history-adapter.js +72 -1
  59. package/src/platforms/drivers/claude/sessions-implementation.js +49 -7
  60. package/src/platforms/drivers/claude/sessions.js +30 -6
  61. package/src/platforms/drivers/codex/parser.js +57 -1
  62. package/src/platforms/drivers/codex/session-history-adapter.js +8 -2
  63. package/src/platforms/drivers/codex/sessions-implementation.js +25 -3
  64. package/src/platforms/drivers/codex/sessions.js +18 -1
  65. package/src/platforms/drivers/dsh/api-operations.js +396 -0
  66. package/src/platforms/drivers/dsh/channels-implementation.js +458 -0
  67. package/src/platforms/drivers/dsh/channels.js +191 -0
  68. package/src/platforms/drivers/dsh/common.js +571 -0
  69. package/src/platforms/drivers/dsh/native-config.js +93 -0
  70. package/src/platforms/drivers/dsh/native-logs.js +116 -0
  71. package/src/platforms/drivers/dsh/plugin-manager.js +117 -0
  72. package/src/platforms/drivers/dsh/projects.js +23 -0
  73. package/src/platforms/drivers/dsh/proxy-implementation.js +260 -0
  74. package/src/platforms/drivers/dsh/proxy.js +23 -0
  75. package/src/platforms/drivers/dsh/resources.js +346 -0
  76. package/src/platforms/drivers/dsh/sessions.js +587 -0
  77. package/src/platforms/drivers/dsh/statistics-implementation.js +238 -0
  78. package/src/platforms/drivers/dsh/statistics.js +24 -0
  79. package/src/platforms/drivers/gemini/session-history-adapter.js +49 -1
  80. package/src/platforms/drivers/gemini/sessions-implementation.js +46 -1
  81. package/src/platforms/drivers/gemini/sessions.js +2 -1
  82. package/src/platforms/drivers/omp/session-history-adapter.js +42 -1
  83. package/src/platforms/drivers/omp/sessions-implementation.js +51 -3
  84. package/src/platforms/drivers/omp/sessions.js +33 -2
  85. package/src/platforms/drivers/opencode/sessions-implementation.js +89 -9
  86. package/src/platforms/drivers/opencode/sessions.js +37 -1
  87. package/src/platforms/manifest-schema.js +43 -3
  88. package/src/platforms/manifests/dsh.json +542 -0
  89. package/src/platforms/path-resolver.js +2 -0
  90. package/src/platforms/platform-path-context.js +12 -2
  91. package/src/platforms/registry.js +16 -1
  92. package/src/platforms/runtime.js +5 -0
  93. package/src/platforms/session-history-adapters.js +1 -0
  94. package/src/server/api/platform-api-config.js +23 -2
  95. package/src/server/api/platform-route-factory.js +9 -2
  96. package/src/server/api/platforms.js +19 -1
  97. package/src/server/api/plugins.js +108 -13
  98. package/src/server/services/config-registry-service.js +10 -1
  99. package/src/server/services/config-templates-service.js +1 -0
  100. package/src/server/services/plugins-service.js +474 -103
  101. package/src/server/services/session-history-index.js +900 -140
  102. package/src/server/services/session-history-worker.js +3 -1
  103. package/src/server/services/skill-service.js +214 -7
  104. package/src/server/services/usage-log-utils.js +1 -0
  105. package/src/server/services/workspace-service.js +39 -10
  106. package/src/shared/channel-driver.js +80 -5
  107. package/src/shared/driver-factories/api.js +22 -6
  108. package/src/shared/driver-factories/projects.js +8 -0
  109. package/dist/web/assets/Analytics-C4gMzv7g.js +0 -1
  110. package/dist/web/assets/AssetPathField-Bd_nMFu3.js +0 -1
  111. package/dist/web/assets/ConfigExportDrawer-C-XDvlHc.js +0 -1
  112. package/dist/web/assets/ConfigTemplates-CYY8XRED.js +0 -1
  113. package/dist/web/assets/Home-P8eseZcf.js +0 -1
  114. package/dist/web/assets/McpDrawer-Ch3bkKIq.js +0 -1
  115. package/dist/web/assets/PluginsPanel-BofsgQgj.js +0 -1
  116. package/dist/web/assets/PluginsPanel-D6ZqITcR.css +0 -1
  117. package/dist/web/assets/ProjectList-677RLZ8O.css +0 -1
  118. package/dist/web/assets/ProjectList-DhSWJHTA.js +0 -1
  119. package/dist/web/assets/PromptsDrawer-Cfb2FeeU.js +0 -1
  120. package/dist/web/assets/RecentSessionsDrawer-3eXamJhr.js +0 -1
  121. package/dist/web/assets/RecentSessionsDrawer-CKFsOYDM.css +0 -1
  122. package/dist/web/assets/SessionCard-CW0eHURI.js +0 -1
  123. package/dist/web/assets/SessionList-BpYRz1cX.css +0 -1
  124. package/dist/web/assets/SessionList-DQfyDGWU.js +0 -1
  125. package/dist/web/assets/SkillManager-DHMprJLA.js +0 -1
  126. package/dist/web/assets/SkillsPanel-DWE4pFGx.js +0 -1
  127. package/dist/web/assets/Upload-CNwaGOws.js +0 -1
  128. package/dist/web/assets/headers-cf-QapUq.js +0 -1
  129. package/dist/web/assets/index-BMAUPq5K.js +0 -2
  130. package/dist/web/assets/platforms-CBkB45JP.js +0 -1
  131. package/dist/web/assets/platforms-FTpjxAT6.js +0 -1
  132. package/dist/web/assets/sessions-Cmy31slD.js +0 -1
  133. package/dist/web/assets/sessions-yC_oVVh8.js +0 -1
  134. package/dist/web/assets/use-message-DoLM8C1C.js +0 -1
@@ -345,7 +345,33 @@ function getProjectRows() {
345
345
  `);
346
346
  }
347
347
 
348
- function getSessionRowsByProjectId(projectId) {
348
+ function getProjectRowsPage(options = {}) {
349
+ const page = Math.max(1, Number.parseInt(options.page, 10) || 1);
350
+ const limit = Math.max(1, Math.min(100, Number.parseInt(options.limit, 10) || 20));
351
+ const query = String(options.q || options.search || '').trim();
352
+ const like = `%${query}%`;
353
+ const where = query ? 'WHERE p.id LIKE ? OR p.name LIKE ? OR p.worktree LIKE ?' : '';
354
+ const params = query ? [like, like, like] : [];
355
+ const total = Number(_query(`SELECT COUNT(*) AS total FROM project p ${where}`, ...params)[0]?.total) || 0;
356
+ const rows = _query(`
357
+ SELECT
358
+ p.*,
359
+ (SELECT s.directory FROM session s
360
+ WHERE s.project_id = p.id AND s.time_archived IS NULL
361
+ ORDER BY s.time_updated DESC LIMIT 1) AS session_directory,
362
+ (SELECT COUNT(*) FROM session s WHERE s.project_id = p.id AND s.time_archived IS NULL) AS session_count
363
+ FROM project p
364
+ ${where}
365
+ ORDER BY p.time_updated DESC, p.id ASC
366
+ LIMIT ? OFFSET ?
367
+ `, ...params, limit, (page - 1) * limit);
368
+ return { rows, page, limit, total };
369
+ }
370
+
371
+ function getSessionRowsByProjectId(projectId, options = {}) {
372
+ const pagination = options.limit != null
373
+ ? `LIMIT ${Math.max(1, Math.min(100, Number(options.limit) || 20))} OFFSET ${Math.max(0, Number(options.offset) || 0)}`
374
+ : '';
349
375
  return _query(`
350
376
  SELECT
351
377
  s.id,
@@ -384,7 +410,8 @@ function getSessionRowsByProjectId(projectId) {
384
410
  FROM session s
385
411
  WHERE s.project_id = ?
386
412
  AND s.time_archived IS NULL
387
- ORDER BY s.time_updated DESC
413
+ ORDER BY s.time_updated DESC, s.id ASC
414
+ ${pagination}
388
415
  `, projectId);
389
416
  }
390
417
 
@@ -484,8 +511,7 @@ function normalizeSession(session, projectId) {
484
511
  // Public API
485
512
  // ---------------------------------------------------------------------------
486
513
 
487
- function getProjects(_options = {}) {
488
- const projects = getProjectRows().map((project) => {
514
+ function normalizeProjectRow(project) {
489
515
  const fallbackPath = project.worktree && project.worktree !== '/'
490
516
  ? project.worktree
491
517
  : project.session_directory || project.worktree || '/';
@@ -504,12 +530,25 @@ function getProjects(_options = {}) {
504
530
  lastUsed: toIsoTime(project.time_updated),
505
531
  source: 'opencode'
506
532
  };
507
- });
533
+ }
534
+
535
+ function getProjects(_options = {}) {
536
+ const projects = getProjectRows().map(normalizeProjectRow);
508
537
 
509
538
  const order = getProjectOrder();
510
539
  return sortByOrder(projects, order, (a, b) => (b.lastUsed || '').localeCompare(a.lastUsed || ''));
511
540
  }
512
541
 
542
+ function getProjectsPage(options = {}) {
543
+ const { rows, page, limit, total } = getProjectRowsPage(options);
544
+ const projects = rows.map(normalizeProjectRow);
545
+ return {
546
+ projects,
547
+ currentProject: null,
548
+ pagination: { page, limit, total, hasMore: page * limit < total }
549
+ };
550
+ }
551
+
513
552
  function getSessionsByProjectId(projectId, _options = {}) {
514
553
  const sessions = getSessionRowsByProjectId(projectId).map(session => normalizeSession(session, projectId));
515
554
  const order = getSessionOrder(projectId);
@@ -523,13 +562,48 @@ function getSessionsByProjectId(projectId, _options = {}) {
523
562
  );
524
563
  }
525
564
 
526
- function searchSessions(keyword) {
565
+ function getSessionsPage(projectId, options = {}) {
566
+ const page = Math.max(1, Number.parseInt(options.page, 10) || 1);
567
+ const limit = Math.max(1, Math.min(100, Number.parseInt(options.limit, 10) || 20));
568
+ const aggregate = _query(`
569
+ SELECT COUNT(*) AS total,
570
+ COALESCE(SUM(
571
+ COALESCE((SELECT SUM(LENGTH(CAST(m.data AS BLOB))) FROM message m WHERE m.session_id = s.id), 0)
572
+ + COALESCE((SELECT SUM(LENGTH(CAST(p.data AS BLOB))) FROM part p WHERE p.session_id = s.id), 0)
573
+ + COALESCE(LENGTH(CAST(s.title AS BLOB)), 0)
574
+ + COALESCE(LENGTH(CAST(s.slug AS BLOB)), 0)
575
+ + COALESCE(LENGTH(CAST(s.directory AS BLOB)), 0)
576
+ ), 0) AS total_size
577
+ FROM session s
578
+ WHERE s.project_id = ? AND s.time_archived IS NULL
579
+ `, projectId)[0] || {};
580
+ const sessions = getSessionRowsByProjectId(projectId, {
581
+ limit,
582
+ offset: (page - 1) * limit
583
+ }).map(session => normalizeSession(session, projectId));
584
+ const total = Number(aggregate.total) || 0;
585
+ const totalSize = Number(aggregate.total_size) || 0;
586
+ return {
587
+ sessions,
588
+ totalSize,
589
+ projectInfo: { sessionCount: total, totalSize },
590
+ pagination: { page, limit, total, hasMore: page * limit < total }
591
+ };
592
+ }
593
+
594
+ function searchSessions(keyword, options = {}) {
527
595
  if (!keyword || !keyword.trim()) return [];
528
596
  const lowerKeyword = keyword.toLowerCase();
597
+ const projectName = typeof options.projectName === 'string' && options.projectName.trim()
598
+ ? options.projectName.trim()
599
+ : null;
600
+ const contextLength = Math.max(1, Math.min(200, Number(options.contextLength) || 35));
601
+ const limit = Math.max(1, Math.min(200, Number(options.limit) || 100));
529
602
 
530
603
  const allSessions = [];
531
604
  const projects = getProjectRows();
532
605
  for (const project of projects) {
606
+ if (projectName && project.id !== projectName) continue;
533
607
  const sessions = getSessionRowsByProjectId(project.id);
534
608
  for (const session of sessions) {
535
609
  const messages = getMessageRowsBySessionId(session.id);
@@ -563,7 +637,7 @@ function searchSessions(keyword) {
563
637
  matchedMessages.push({
564
638
  messageIndex: i,
565
639
  role: data ? (data.role || 'unknown') : 'unknown',
566
- context: buildContext(text, keyword),
640
+ context: buildContext(text, keyword, contextLength),
567
641
  timestamp: toIsoTime(message.time_created)
568
642
  });
569
643
  }
@@ -577,13 +651,17 @@ function searchSessions(keyword) {
577
651
  firstMessage: session.title || null,
578
652
  matches: matchedMessages,
579
653
  matchCount: matchedMessages.length,
654
+ updatedAt: normalizeTimestampMs(session.time_updated) || 0,
655
+ projectFullPath: project.worktree || null,
580
656
  source: 'opencode'
581
657
  });
582
658
  }
583
659
  }
584
660
  }
585
661
 
586
- return allSessions.sort((a, b) => b.matchCount - a.matchCount);
662
+ return allSessions
663
+ .sort((a, b) => b.updatedAt - a.updatedAt || a.sessionId.localeCompare(b.sessionId))
664
+ .slice(0, limit);
587
665
  }
588
666
 
589
667
  function getRecentSessions(limit = 5) {
@@ -638,7 +716,7 @@ function getSessionMessages(sessionId, options = {}) {
638
716
  const session = getSessionById(sessionId);
639
717
  if (!session) return null;
640
718
  const page = Math.max(1, Number.parseInt(options.page, 10) || 1);
641
- const limit = Math.max(1, Math.min(200, Number.parseInt(options.limit, 10) || 50));
719
+ const limit = Math.max(1, Math.min(200, Number.parseInt(options.limit, 10) || 20));
642
720
  const order = String(options.order || 'desc').toLowerCase() === 'asc' ? 'asc' : 'desc';
643
721
  const ordered = order === 'asc' ? [...session.messages] : [...session.messages].reverse();
644
722
  const offset = (page - 1) * limit;
@@ -907,7 +985,9 @@ module.exports = {
907
985
  getOpenCodeDbPath,
908
986
  isOpenCodeInstalled,
909
987
  getProjects,
988
+ getProjectsPage,
910
989
  getSessionsByProjectId,
990
+ getSessionsPage,
911
991
  getSessionById,
912
992
  getSessionStatus,
913
993
  getSessionMessages,
@@ -12,7 +12,6 @@ function createDriver(context = {}) {
12
12
  methods: {
13
13
  getProjects: 'getProjects',
14
14
  recent: 'getRecentSessions',
15
- search: 'searchSessions',
16
15
  getSessionById: 'getSessionById',
17
16
  delete: 'deleteSession',
18
17
  fork: 'forkSession',
@@ -22,11 +21,48 @@ function createDriver(context = {}) {
22
21
  isAvailable: 'isOpenCodeInstalled'
23
22
  },
24
23
  customMethods: {
24
+ search: (service, requestOrProjectName, keyword, contextLength, options = {}) => {
25
+ if (requestOrProjectName && typeof requestOrProjectName === 'object' && !Array.isArray(requestOrProjectName)) {
26
+ const request = requestOrProjectName;
27
+ const query = request.query || {};
28
+ return service.searchSessions(query.keyword || query.q || '', {
29
+ ...request,
30
+ ...options,
31
+ projectName: request.params?.projectName || null,
32
+ contextLength: Number(query.context) || 15,
33
+ limit: Number.parseInt(query.limit, 10) || 100
34
+ });
35
+ }
36
+ return service.searchSessions(keyword, {
37
+ ...options,
38
+ projectName: requestOrProjectName,
39
+ contextLength,
40
+ limit: options.limit
41
+ });
42
+ },
43
+ searchAcrossProjects: (service, requestOrKeyword, limit, options = {}) => {
44
+ if (requestOrKeyword && typeof requestOrKeyword === 'object' && !Array.isArray(requestOrKeyword)) {
45
+ const request = requestOrKeyword;
46
+ const query = request.query || {};
47
+ return service.searchSessions(query.keyword || query.q || '', {
48
+ ...request,
49
+ ...options,
50
+ projectName: query.projectName || query.project || null,
51
+ limit: Number.parseInt(query.limit, 10) || 35,
52
+ contextLength: Number(query.context) || 35
53
+ });
54
+ }
55
+ return service.searchSessions(requestOrKeyword, { ...options, limit });
56
+ },
25
57
  listSessions: (service, ...args) => {
26
58
  const method = service.getSessionsByProjectId || service.getSessionsByProject;
27
59
  if (typeof method !== 'function') return undefined;
28
60
  return method.apply(service, args);
29
61
  },
62
+ listSessionsPage: (service, projectName, options = {}) => {
63
+ if (typeof service.getSessionsPage !== 'function') return undefined;
64
+ return service.getSessionsPage(projectName, options);
65
+ },
30
66
  messages: (service, sessionId, options) => {
31
67
  if (typeof service.getSessionMessages === 'function') {
32
68
  return service.getSessionMessages(sessionId, options);
@@ -17,7 +17,15 @@ const DRIVER_IDS = new Set([
17
17
  'legacy:opencode',
18
18
  'legacy:omp',
19
19
  'opencode-conversion',
20
- 'claude-health'
20
+ 'claude-health',
21
+ 'dsh-api',
22
+ 'dsh-projects',
23
+ 'dsh-sessions',
24
+ 'dsh-native-config',
25
+ 'dsh-channels',
26
+ 'dsh-proxy',
27
+ 'dsh-statistics',
28
+ 'dsh-native-logs'
21
29
  ]);
22
30
 
23
31
  const PATH_RESOLVER_IDS = new Set([
@@ -26,7 +34,8 @@ const PATH_RESOLVER_IDS = new Set([
26
34
  'codex',
27
35
  'gemini',
28
36
  'opencode',
29
- 'omp'
37
+ 'omp',
38
+ 'dsh'
30
39
  ]);
31
40
 
32
41
  const API_ROUTE_DESCRIPTOR_SCHEMA = {
@@ -46,7 +55,31 @@ const API_ROUTE_DESCRIPTOR_SCHEMA = {
46
55
  const API_ROUTE_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
47
56
 
48
57
  const CAPABILITY_OPERATIONS = Object.freeze({
49
- api: new Set(['getConfig', 'getConfigAuthProviders', 'getConfigCapabilities', 'getConfigResources']),
58
+ api: new Set([
59
+ 'getConfig',
60
+ 'getConfigAuthProviders',
61
+ 'getConfigCapabilities',
62
+ 'getConfigResources',
63
+ 'updateConfig',
64
+ 'listProfiles',
65
+ 'listPlugins',
66
+ 'listProfilePlugins',
67
+ 'listProfileCapabilities',
68
+ 'listProfileMcp',
69
+ 'listProfilePrompts',
70
+ 'installPlugin',
71
+ 'uninstallPlugin',
72
+ 'updatePlugin',
73
+ 'upsertMcp',
74
+ 'deleteMcp',
75
+ 'upsertPrompt',
76
+ 'deletePrompt',
77
+ 'listSkills',
78
+ 'getSkill',
79
+ 'createSkill',
80
+ 'updateSkill',
81
+ 'deleteSkill'
82
+ ]),
50
83
  channels: new Set(['applyToSettings', 'bestForRestore', 'catalogMetadata', 'create', 'current', 'enabled', 'getAuth', 'getAuthQuota', 'list', 'models', 'order', 'poolStatus', 'probeModels', 'remove', 'resetHealth', 'speedTest', 'speedTestAll', 'sync', 'syncLocalAuth', 'update']),
51
84
  health: new Set(['healthCheck']),
52
85
  hooks: new Set(['getHooks', 'saveHooks', 'testHooks']),
@@ -102,6 +135,13 @@ const schema = {
102
135
  }
103
136
  },
104
137
  resourceTypes: { type: 'object', additionalProperties: { type: 'boolean' } },
138
+ resourceActions: {
139
+ type: 'object',
140
+ additionalProperties: {
141
+ type: 'object',
142
+ additionalProperties: { type: 'boolean' }
143
+ }
144
+ },
105
145
  skillActivation: {
106
146
  type: 'object',
107
147
  additionalProperties: false,