@cplace/mcp-server 1.9.1 → 1.10.6

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 (235) hide show
  1. package/README.md +12 -13
  2. package/dist/index.js +4 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/plugins/app-catalog.js +1 -1
  5. package/dist/plugins/app-catalog.js.map +1 -1
  6. package/dist/plugins/application-settings.d.ts.map +1 -1
  7. package/dist/plugins/application-settings.js +6 -3
  8. package/dist/plugins/application-settings.js.map +1 -1
  9. package/dist/plugins/core/widget-specifications/cf.cplace.platform.tableWidget/columns.md +6 -0
  10. package/dist/plugins/core.d.ts.map +1 -1
  11. package/dist/plugins/core.js +25 -13
  12. package/dist/plugins/core.js.map +1 -1
  13. package/dist/plugins/forms-wizard.js +2 -2
  14. package/dist/plugins/forms-wizard.js.map +1 -1
  15. package/dist/plugins/history.d.ts.map +1 -1
  16. package/dist/plugins/history.js +6 -3
  17. package/dist/plugins/history.js.map +1 -1
  18. package/dist/plugins/jobs.js +2 -2
  19. package/dist/plugins/jobs.js.map +1 -1
  20. package/dist/plugins/layouts.d.ts.map +1 -1
  21. package/dist/plugins/layouts.js +17 -8
  22. package/dist/plugins/layouts.js.map +1 -1
  23. package/dist/plugins/low-code.d.ts.map +1 -1
  24. package/dist/plugins/low-code.js +48 -17
  25. package/dist/plugins/low-code.js.map +1 -1
  26. package/dist/plugins/project-planning.d.ts.map +1 -1
  27. package/dist/plugins/project-planning.js +6 -3
  28. package/dist/plugins/project-planning.js.map +1 -1
  29. package/dist/plugins/resource-management.d.ts.map +1 -1
  30. package/dist/plugins/resource-management.js +6 -3
  31. package/dist/plugins/resource-management.js.map +1 -1
  32. package/dist/plugins/solution-management.d.ts.map +1 -1
  33. package/dist/plugins/solution-management.js +6 -3
  34. package/dist/plugins/solution-management.js.map +1 -1
  35. package/dist/plugins/types-write.d.ts.map +1 -1
  36. package/dist/plugins/types-write.js +6 -3
  37. package/dist/plugins/types-write.js.map +1 -1
  38. package/dist/plugins/widget-specifications.d.ts.map +1 -1
  39. package/dist/plugins/widget-specifications.js +2 -2
  40. package/dist/plugins/widget-specifications.js.map +1 -1
  41. package/dist/plugins/workspace-admin.d.ts.map +1 -1
  42. package/dist/plugins/workspace-admin.js +6 -3
  43. package/dist/plugins/workspace-admin.js.map +1 -1
  44. package/dist/str-replace-utils.js +1 -1
  45. package/dist/str-replace-utils.js.map +1 -1
  46. package/dist/tools/apps-catalog.d.ts +1 -1
  47. package/dist/tools/apps-catalog.d.ts.map +1 -1
  48. package/dist/tools/apps-catalog.js +16 -12
  49. package/dist/tools/apps-catalog.js.map +1 -1
  50. package/dist/tools/board-widget.d.ts +2 -2
  51. package/dist/tools/board-widget.d.ts.map +1 -1
  52. package/dist/tools/board-widget.js +354 -201
  53. package/dist/tools/board-widget.js.map +1 -1
  54. package/dist/tools/change-listeners.d.ts +2 -2
  55. package/dist/tools/change-listeners.d.ts.map +1 -1
  56. package/dist/tools/change-listeners.js +125 -57
  57. package/dist/tools/change-listeners.js.map +1 -1
  58. package/dist/tools/common-schemas.d.ts +1 -1
  59. package/dist/tools/common-schemas.d.ts.map +1 -1
  60. package/dist/tools/common-schemas.js +5 -3
  61. package/dist/tools/common-schemas.js.map +1 -1
  62. package/dist/tools/csv-export.d.ts +2 -2
  63. package/dist/tools/csv-export.d.ts.map +1 -1
  64. package/dist/tools/csv-export.js +29 -24
  65. package/dist/tools/csv-export.js.map +1 -1
  66. package/dist/tools/documents.d.ts +2 -2
  67. package/dist/tools/documents.d.ts.map +1 -1
  68. package/dist/tools/documents.js +34 -14
  69. package/dist/tools/documents.js.map +1 -1
  70. package/dist/tools/expert-settings.d.ts +3 -3
  71. package/dist/tools/expert-settings.d.ts.map +1 -1
  72. package/dist/tools/expert-settings.js +97 -38
  73. package/dist/tools/expert-settings.js.map +1 -1
  74. package/dist/tools/get-operations.d.ts +2 -2
  75. package/dist/tools/get-operations.d.ts.map +1 -1
  76. package/dist/tools/get-operations.js +29 -21
  77. package/dist/tools/get-operations.js.map +1 -1
  78. package/dist/tools/job-schedule-trigger.d.ts +2 -2
  79. package/dist/tools/job-schedule-trigger.d.ts.map +1 -1
  80. package/dist/tools/job-schedule-trigger.js +19 -10
  81. package/dist/tools/job-schedule-trigger.js.map +1 -1
  82. package/dist/tools/job-scripts.d.ts +2 -2
  83. package/dist/tools/job-scripts.d.ts.map +1 -1
  84. package/dist/tools/job-scripts.js +119 -55
  85. package/dist/tools/job-scripts.js.map +1 -1
  86. package/dist/tools/jobs.d.ts +2 -2
  87. package/dist/tools/jobs.d.ts.map +1 -1
  88. package/dist/tools/jobs.js +68 -38
  89. package/dist/tools/jobs.js.map +1 -1
  90. package/dist/tools/layout-richstring-shared.d.ts +24 -1
  91. package/dist/tools/layout-richstring-shared.d.ts.map +1 -1
  92. package/dist/tools/layout-richstring-shared.js +99 -1
  93. package/dist/tools/layout-richstring-shared.js.map +1 -1
  94. package/dist/tools/layout-richstring-widgets.d.ts +94 -2
  95. package/dist/tools/layout-richstring-widgets.d.ts.map +1 -1
  96. package/dist/tools/layout-richstring-widgets.js +247 -25
  97. package/dist/tools/layout-richstring-widgets.js.map +1 -1
  98. package/dist/tools/layout.d.ts +5 -4
  99. package/dist/tools/layout.d.ts.map +1 -1
  100. package/dist/tools/layout.js +235 -124
  101. package/dist/tools/layout.js.map +1 -1
  102. package/dist/tools/linting.d.ts +2 -2
  103. package/dist/tools/linting.d.ts.map +1 -1
  104. package/dist/tools/linting.js +5 -5
  105. package/dist/tools/linting.js.map +1 -1
  106. package/dist/tools/page-action-simulation.d.ts +18 -0
  107. package/dist/tools/page-action-simulation.d.ts.map +1 -0
  108. package/dist/tools/page-action-simulation.js +88 -0
  109. package/dist/tools/page-action-simulation.js.map +1 -0
  110. package/dist/tools/page-actions.d.ts +60 -0
  111. package/dist/tools/page-actions.d.ts.map +1 -0
  112. package/dist/tools/page-actions.js +284 -0
  113. package/dist/tools/page-actions.js.map +1 -0
  114. package/dist/tools/pages.d.ts +3 -3
  115. package/dist/tools/pages.d.ts.map +1 -1
  116. package/dist/tools/pages.js +237 -112
  117. package/dist/tools/pages.js.map +1 -1
  118. package/dist/tools/ppt-export-schemas.d.ts +1 -1
  119. package/dist/tools/ppt-export-schemas.d.ts.map +1 -1
  120. package/dist/tools/ppt-export-schemas.js +269 -122
  121. package/dist/tools/ppt-export-schemas.js.map +1 -1
  122. package/dist/tools/ppt-export.d.ts +2 -2
  123. package/dist/tools/ppt-export.d.ts.map +1 -1
  124. package/dist/tools/ppt-export.js +82 -43
  125. package/dist/tools/ppt-export.js.map +1 -1
  126. package/dist/tools/profile-management.d.ts +2 -2
  127. package/dist/tools/profile-management.d.ts.map +1 -1
  128. package/dist/tools/profile-management.js +109 -82
  129. package/dist/tools/profile-management.js.map +1 -1
  130. package/dist/tools/references.d.ts +2 -2
  131. package/dist/tools/references.d.ts.map +1 -1
  132. package/dist/tools/references.js +36 -24
  133. package/dist/tools/references.js.map +1 -1
  134. package/dist/tools/resource-planner-widget.d.ts +2 -2
  135. package/dist/tools/resource-planner-widget.d.ts.map +1 -1
  136. package/dist/tools/resource-planner-widget.js +334 -138
  137. package/dist/tools/resource-planner-widget.js.map +1 -1
  138. package/dist/tools/richstring-marker-resolver.d.ts +16 -0
  139. package/dist/tools/richstring-marker-resolver.d.ts.map +1 -0
  140. package/dist/tools/richstring-marker-resolver.js +47 -0
  141. package/dist/tools/richstring-marker-resolver.js.map +1 -0
  142. package/dist/tools/richstring-widgets.d.ts +6 -16
  143. package/dist/tools/richstring-widgets.d.ts.map +1 -1
  144. package/dist/tools/richstring-widgets.js +184 -129
  145. package/dist/tools/richstring-widgets.js.map +1 -1
  146. package/dist/tools/schedule.d.ts +2 -2
  147. package/dist/tools/schedule.d.ts.map +1 -1
  148. package/dist/tools/schedule.js +23 -14
  149. package/dist/tools/schedule.js.map +1 -1
  150. package/dist/tools/script-logs.d.ts +2 -2
  151. package/dist/tools/script-logs.d.ts.map +1 -1
  152. package/dist/tools/script-logs.js +71 -32
  153. package/dist/tools/script-logs.js.map +1 -1
  154. package/dist/tools/script.d.ts +2 -2
  155. package/dist/tools/script.d.ts.map +1 -1
  156. package/dist/tools/script.js +44 -26
  157. package/dist/tools/script.js.map +1 -1
  158. package/dist/tools/search.d.ts +2 -2
  159. package/dist/tools/search.d.ts.map +1 -1
  160. package/dist/tools/search.js +139 -102
  161. package/dist/tools/search.js.map +1 -1
  162. package/dist/tools/solution-packages.d.ts +2 -2
  163. package/dist/tools/solution-packages.d.ts.map +1 -1
  164. package/dist/tools/solution-packages.js +149 -61
  165. package/dist/tools/solution-packages.js.map +1 -1
  166. package/dist/tools/system.d.ts +2 -2
  167. package/dist/tools/system.d.ts.map +1 -1
  168. package/dist/tools/system.js +43 -21
  169. package/dist/tools/system.js.map +1 -1
  170. package/dist/tools/type-layouts.d.ts +2 -2
  171. package/dist/tools/type-layouts.d.ts.map +1 -1
  172. package/dist/tools/type-layouts.js +67 -31
  173. package/dist/tools/type-layouts.js.map +1 -1
  174. package/dist/tools/type-management.d.ts +86 -70
  175. package/dist/tools/type-management.d.ts.map +1 -1
  176. package/dist/tools/type-management.js +407 -138
  177. package/dist/tools/type-management.js.map +1 -1
  178. package/dist/tools/url-resolution.d.ts +2 -2
  179. package/dist/tools/url-resolution.d.ts.map +1 -1
  180. package/dist/tools/url-resolution.js +16 -12
  181. package/dist/tools/url-resolution.js.map +1 -1
  182. package/dist/tools/users.d.ts +2 -2
  183. package/dist/tools/users.d.ts.map +1 -1
  184. package/dist/tools/users.js +24 -14
  185. package/dist/tools/users.js.map +1 -1
  186. package/dist/tools/validators.d.ts +2 -2
  187. package/dist/tools/validators.d.ts.map +1 -1
  188. package/dist/tools/validators.js +68 -35
  189. package/dist/tools/validators.js.map +1 -1
  190. package/dist/tools/version-check.d.ts +2 -2
  191. package/dist/tools/version-check.d.ts.map +1 -1
  192. package/dist/tools/version-check.js +36 -30
  193. package/dist/tools/version-check.js.map +1 -1
  194. package/dist/tools/version-history.d.ts +2 -2
  195. package/dist/tools/version-history.d.ts.map +1 -1
  196. package/dist/tools/version-history.js +72 -41
  197. package/dist/tools/version-history.js.map +1 -1
  198. package/dist/tools/widget-simulation.d.ts +5 -6
  199. package/dist/tools/widget-simulation.d.ts.map +1 -1
  200. package/dist/tools/widget-simulation.js +60 -42
  201. package/dist/tools/widget-simulation.js.map +1 -1
  202. package/dist/tools/widget-tool-helpers.d.ts +17 -1
  203. package/dist/tools/widget-tool-helpers.d.ts.map +1 -1
  204. package/dist/tools/widget-tool-helpers.js +41 -6
  205. package/dist/tools/widget-tool-helpers.js.map +1 -1
  206. package/dist/tools/widgets.d.ts +2 -2
  207. package/dist/tools/widgets.d.ts.map +1 -1
  208. package/dist/tools/widgets.js +62 -43
  209. package/dist/tools/widgets.js.map +1 -1
  210. package/dist/tools/wizards.d.ts +2 -2
  211. package/dist/tools/wizards.d.ts.map +1 -1
  212. package/dist/tools/wizards.js +378 -182
  213. package/dist/tools/wizards.js.map +1 -1
  214. package/dist/tools/workflow-execution.d.ts +2 -2
  215. package/dist/tools/workflow-execution.d.ts.map +1 -1
  216. package/dist/tools/workflow-execution.js +27 -19
  217. package/dist/tools/workflow-execution.js.map +1 -1
  218. package/dist/tools/workflow-scripts.d.ts +2 -2
  219. package/dist/tools/workflow-scripts.d.ts.map +1 -1
  220. package/dist/tools/workflow-scripts.js +168 -81
  221. package/dist/tools/workflow-scripts.js.map +1 -1
  222. package/dist/tools/workflow.d.ts +2 -2
  223. package/dist/tools/workflow.d.ts.map +1 -1
  224. package/dist/tools/workflow.js +185 -74
  225. package/dist/tools/workflow.js.map +1 -1
  226. package/dist/tools/workspace-admin.d.ts +2 -2
  227. package/dist/tools/workspace-admin.d.ts.map +1 -1
  228. package/dist/tools/workspace-admin.js +82 -40
  229. package/dist/tools/workspace-admin.js.map +1 -1
  230. package/dist/tools/workspace-core.d.ts +2 -2
  231. package/dist/tools/workspace-core.d.ts.map +1 -1
  232. package/dist/tools/workspace-core.js +93 -53
  233. package/dist/tools/workspace-core.js.map +1 -1
  234. package/dist/utils/dateValidation.js.map +1 -1
  235. package/package.json +9 -4
@@ -1,63 +1,102 @@
1
- import { z } from "zod";
2
- import { debugLogWithTag } from "../logger.js";
1
+ import { z } from 'zod';
2
+ import { debugLogWithTag } from '../logger.js';
3
3
  import { LayoutContextSchema } from './layout.js';
4
- import { findWidgetById, buildUpdateRequestBody, determineApiEndpoint, buildRequestParams } from './widget-tool-helpers.js';
4
+ import { findWidgetById, buildUpdateRequestBody, determineApiEndpoint, buildRequestParams, } from './widget-tool-helpers.js';
5
5
  const TOOL_BOARD_GET_CONFIGURATION = 'cplace_board_get_configuration';
6
6
  const TOOL_BOARD_CONFIGURE_CARDS = 'cplace_board_configure_cards';
7
7
  const TOOL_BOARD_CONFIGURE_COLUMNS = 'cplace_board_configure_columns';
8
8
  const TOOL_BOARD_CONFIGURE_SWIMLANES = 'cplace_board_configure_swimlanes';
9
9
  const TOOL_BOARD_CONFIGURE_VISUAL = 'cplace_board_configure_visual';
10
10
  const BOARD_WIDGET_TYPE = 'cf.cplace.cboard.main.board';
11
- const CardDisplaySchema = z.object({
12
- dateAttribute: z.string().optional().describe("Attribute for date shown in card footer (e.g., 'cf.myType.dueDate')"),
13
- tagAttributes: z.array(z.string()).optional().describe("Attributes for colored tag badges on cards (e.g., ['cf.myType.category'])"),
14
- colorAttribute: z.object({
15
- attribute: z.string().describe("Enumeration attribute for dynamic left-border color (e.g., 'cf.myType.status')"),
16
- colorMapping: z.record(z.string()).describe("Map of enumeration values to hex colors (e.g., {\"Open\": \"#4CAF50\", \"Closed\": \"#F44336\"})")
17
- }).optional().describe("Dynamic card border color based on an enumeration attribute"),
18
- iconAttributes: z.array(z.object({
19
- attribute: z.string().describe("Attribute name for icon indicator"),
20
- enabled: z.boolean().optional().default(true).describe("Whether this icon is active (default: true)")
21
- })).optional().describe("Attributes shown as icon indicators on cards")
22
- }).optional();
11
+ const CardDisplaySchema = z
12
+ .object({
13
+ dateAttribute: z
14
+ .string()
15
+ .optional()
16
+ .describe("Attribute for date shown in card footer (e.g., 'cf.myType.dueDate')"),
17
+ tagAttributes: z
18
+ .array(z.string())
19
+ .optional()
20
+ .describe("Attributes for colored tag badges on cards (e.g., ['cf.myType.category'])"),
21
+ colorAttribute: z
22
+ .object({
23
+ attribute: z
24
+ .string()
25
+ .describe("Enumeration attribute for dynamic left-border color (e.g., 'cf.myType.status')"),
26
+ colorMapping: z
27
+ .record(z.string())
28
+ .describe('Map of enumeration values to hex colors (e.g., {"Open": "#4CAF50", "Closed": "#F44336"})'),
29
+ })
30
+ .optional()
31
+ .describe('Dynamic card border color based on an enumeration attribute'),
32
+ iconAttributes: z
33
+ .array(z.object({
34
+ attribute: z.string().describe('Attribute name for icon indicator'),
35
+ enabled: z
36
+ .boolean()
37
+ .optional()
38
+ .default(true)
39
+ .describe('Whether this icon is active (default: true)'),
40
+ }))
41
+ .optional()
42
+ .describe('Attributes shown as icon indicators on cards'),
43
+ })
44
+ .optional();
23
45
  const CardConfigurationSchema = z.object({
24
- searchId: z.string().describe("Unique identifier for this card source - used to link columns/swimlanes"),
25
- search: z.string().describe("WARNING: Do not manually construct! Use cplaceJson from cplace_search_pages response. Must have 'filters' array, e.g., {\"filters\":[{\"relativeSpace\":\"true\"},{\"types\":[\"cf.myType\"]}]}"),
26
- typeId: z.string().optional().describe("Explicit page type (optional, inferred from search)"),
27
- cardDisplay: CardDisplaySchema
46
+ searchId: z
47
+ .string()
48
+ .describe('Unique identifier for this card source - used to link columns/swimlanes'),
49
+ search: z
50
+ .string()
51
+ .describe('WARNING: Do not manually construct! Use cplaceJson from cplace_search_pages response. Must have \'filters\' array, e.g., {"filters":[{"relativeSpace":"true"},{"types":["cf.myType"]}]}'),
52
+ typeId: z.string().optional().describe('Explicit page type (optional, inferred from search)'),
53
+ cardDisplay: CardDisplaySchema,
28
54
  });
29
- const CardsInputSchema = z.array(CardConfigurationSchema)
55
+ const CardsInputSchema = z
56
+ .array(CardConfigurationSchema)
30
57
  .min(1)
31
- .describe("Array of card source configurations. Order determines display priority.");
58
+ .describe('Array of card source configurations. Order determines display priority.');
32
59
  const LocalizedNamesSchema = z.object({
33
- en: z.string().describe("English name"),
34
- de: z.string().optional().describe("German name (optional)")
60
+ en: z.string().describe('English name'),
61
+ de: z.string().optional().describe('German name (optional)'),
35
62
  });
36
63
  const MappingSchema = z.object({
37
- searchId: z.string().describe("Must match a searchId from card configurations"),
64
+ searchId: z.string().describe('Must match a searchId from card configurations'),
38
65
  attribute: z.string().describe("Attribute determining placement (e.g., 'cf.myType.status')"),
39
- values: z.array(z.string()).optional().describe("Enumeration attribute values mapping to this column/swimlane"),
40
- referenceValues: z.array(z.string()).optional().describe("Reference attribute values as page UIDs (e.g., '6a0pydt3gd31ea3d42hdhqf4t')"),
41
- dateRange: z.object({
66
+ values: z
67
+ .array(z.string())
68
+ .optional()
69
+ .describe('Enumeration attribute values mapping to this column/swimlane'),
70
+ referenceValues: z
71
+ .array(z.string())
72
+ .optional()
73
+ .describe("Reference attribute values as page UIDs (e.g., '6a0pydt3gd31ea3d42hdhqf4t')"),
74
+ dateRange: z
75
+ .object({
42
76
  start: z.string(),
43
- end: z.string()
44
- }).optional().describe("Date range for date-type attribute mapping")
77
+ end: z.string(),
78
+ })
79
+ .optional()
80
+ .describe('Date range for date-type attribute mapping'),
45
81
  });
46
82
  const StaticColumnSchema = z.object({
47
- columnId: z.string().describe("Unique identifier for this column"),
83
+ columnId: z.string().describe('Unique identifier for this column'),
48
84
  names: LocalizedNamesSchema,
49
- mappings: z.array(MappingSchema).min(1).describe("Value mappings per card source")
85
+ mappings: z.array(MappingSchema).min(1).describe('Value mappings per card source'),
50
86
  });
51
87
  const StaticSwimlaneSchema = z.object({
52
- swimlaneId: z.string().describe("Unique identifier for this swimlane"),
88
+ swimlaneId: z.string().describe('Unique identifier for this swimlane'),
53
89
  names: LocalizedNamesSchema,
54
- mappings: z.array(MappingSchema).min(1).describe("Value mappings per card source")
90
+ mappings: z.array(MappingSchema).min(1).describe('Value mappings per card source'),
55
91
  });
56
92
  const DynamicConfigSchema = z.object({
57
- mappedAttributes: z.array(z.object({
93
+ mappedAttributes: z
94
+ .array(z.object({
58
95
  searchId: z.string(),
59
- attribute: z.string()
60
- })).min(1).describe("Attribute mappings per card source. Dynamic mode requires enumeration attributes.")
96
+ attribute: z.string(),
97
+ }))
98
+ .min(1)
99
+ .describe('Attribute mappings per card source. Dynamic mode requires enumeration attributes.'),
61
100
  });
62
101
  const BOARD_TOOL_DEFINITIONS = {
63
102
  [TOOL_BOARD_GET_CONFIGURATION]: {
@@ -72,9 +111,9 @@ Returns the current state of:
72
111
  WORKFLOW: Use this tool first, then modify the relevant section and pass to the corresponding configure tool.`,
73
112
  inputSchema: {
74
113
  context: LayoutContextSchema,
75
- widgetId: z.string().describe("The board widget ID (e.g., 'id_abc123')")
114
+ widgetId: z.string().describe("The board widget ID (e.g., 'id_abc123')"),
76
115
  },
77
- annotations: { title: "Get Board Configuration" }
116
+ annotations: { title: 'Get Board Configuration' },
78
117
  },
79
118
  [TOOL_BOARD_CONFIGURE_CARDS]: {
80
119
  description: `Configure card sources for a board widget. Declares the complete set of card sources - existing sources not in the array will be removed.
@@ -104,10 +143,10 @@ WORKFLOW:
104
143
  3. Call this tool with the complete desired cards array`,
105
144
  inputSchema: {
106
145
  context: LayoutContextSchema,
107
- widgetId: z.string().describe("The board widget ID"),
108
- cards: CardsInputSchema
146
+ widgetId: z.string().describe('The board widget ID'),
147
+ cards: CardsInputSchema,
109
148
  },
110
- annotations: { title: "Configure Board Cards" }
149
+ annotations: { title: 'Configure Board Cards' },
111
150
  },
112
151
  [TOOL_BOARD_CONFIGURE_COLUMNS]: {
113
152
  description: `Configure column structure for a board widget. Declares the complete column configuration.
@@ -137,12 +176,15 @@ WORKFLOW:
137
176
  4. Call this tool with complete desired state`,
138
177
  inputSchema: {
139
178
  context: LayoutContextSchema,
140
- widgetId: z.string().describe("The board widget ID"),
141
- mode: z.enum(["static", "dynamic"]).describe("Column generation mode"),
142
- columns: z.array(StaticColumnSchema).optional().describe("Static column definitions (required for static mode)"),
143
- dynamicConfig: DynamicConfigSchema.optional().describe("Dynamic column configuration (required for dynamic mode)")
179
+ widgetId: z.string().describe('The board widget ID'),
180
+ mode: z.enum(['static', 'dynamic']).describe('Column generation mode'),
181
+ columns: z
182
+ .array(StaticColumnSchema)
183
+ .optional()
184
+ .describe('Static column definitions (required for static mode)'),
185
+ dynamicConfig: DynamicConfigSchema.optional().describe('Dynamic column configuration (required for dynamic mode)'),
144
186
  },
145
- annotations: { title: "Configure Board Columns" }
187
+ annotations: { title: 'Configure Board Columns' },
146
188
  },
147
189
  [TOOL_BOARD_CONFIGURE_SWIMLANES]: {
148
190
  description: `Configure swimlane structure for a board widget. Swimlanes create horizontal groupings within columns.
@@ -170,13 +212,16 @@ WORKFLOW:
170
212
  4. Call this tool with complete desired state`,
171
213
  inputSchema: {
172
214
  context: LayoutContextSchema,
173
- widgetId: z.string().describe("The board widget ID"),
174
- enabled: z.boolean().describe("false = no swimlanes (flat board)"),
175
- mode: z.enum(["static", "dynamic"]).optional().describe("Swimlane generation mode (required when enabled)"),
176
- swimlanes: z.array(StaticSwimlaneSchema).optional().describe("Static swimlane definitions"),
177
- dynamicConfig: DynamicConfigSchema.optional().describe("Dynamic swimlane configuration")
215
+ widgetId: z.string().describe('The board widget ID'),
216
+ enabled: z.boolean().describe('false = no swimlanes (flat board)'),
217
+ mode: z
218
+ .enum(['static', 'dynamic'])
219
+ .optional()
220
+ .describe('Swimlane generation mode (required when enabled)'),
221
+ swimlanes: z.array(StaticSwimlaneSchema).optional().describe('Static swimlane definitions'),
222
+ dynamicConfig: DynamicConfigSchema.optional().describe('Dynamic swimlane configuration'),
178
223
  },
179
- annotations: { title: "Configure Board Swimlanes" }
224
+ annotations: { title: 'Configure Board Swimlanes' },
180
225
  },
181
226
  [TOOL_BOARD_CONFIGURE_VISUAL]: {
182
227
  description: `Configure visual settings for a board widget. Controls UI features and display options.
@@ -193,37 +238,61 @@ Available settings:
193
238
  Omitted settings retain their current values (this tool does partial updates for visual settings).`,
194
239
  inputSchema: {
195
240
  context: LayoutContextSchema,
196
- widgetId: z.string().describe("The board widget ID"),
197
- showCardCount: z.boolean().optional().describe("Show card count in column headers"),
241
+ widgetId: z.string().describe('The board widget ID'),
242
+ showCardCount: z.boolean().optional().describe('Show card count in column headers'),
198
243
  enableQuickAdd: z.boolean().optional().describe("Show '+' button to create new cards"),
199
- showUnmappedContainer: z.boolean().optional().describe("Show container for cards without valid column mapping"),
200
- unmappedContainerNames: LocalizedNamesSchema.optional().describe("Localized names for unmapped container"),
201
- enableCardDetailsView: z.boolean().optional().describe("Show card details inline instead of navigation"),
202
- showSpaceAfterLastColumn: z.boolean().optional().describe("Add visual spacing after last column"),
203
- enableRecentHistory: z.boolean().optional().describe("Show button to highlight recently changed cards"),
204
- recentHistoryWeeks: z.number().optional().describe("Time range for 'recent' cards (default: 2)")
244
+ showUnmappedContainer: z
245
+ .boolean()
246
+ .optional()
247
+ .describe('Show container for cards without valid column mapping'),
248
+ unmappedContainerNames: LocalizedNamesSchema.optional().describe('Localized names for unmapped container'),
249
+ enableCardDetailsView: z
250
+ .boolean()
251
+ .optional()
252
+ .describe('Show card details inline instead of navigation'),
253
+ showSpaceAfterLastColumn: z
254
+ .boolean()
255
+ .optional()
256
+ .describe('Add visual spacing after last column'),
257
+ enableRecentHistory: z
258
+ .boolean()
259
+ .optional()
260
+ .describe('Show button to highlight recently changed cards'),
261
+ recentHistoryWeeks: z
262
+ .number()
263
+ .optional()
264
+ .describe("Time range for 'recent' cards (default: 2)"),
205
265
  },
206
- annotations: { title: "Configure Board Visual Settings" }
207
- }
266
+ annotations: { title: 'Configure Board Visual Settings' },
267
+ },
208
268
  };
209
269
  function extractWidgetConfiguration(widget) {
210
270
  const config = {};
211
271
  const CBOARD_PREFIX = 'cf.cplace.cboard.';
212
- const KNOWN_ATTRS = ['searchConfigurations', 'columnMapping', 'swimlaneMapping', 'visualComponents'];
272
+ const KNOWN_ATTRS = [
273
+ 'searchConfigurations',
274
+ 'columnMapping',
275
+ 'swimlaneMapping',
276
+ 'visualComponents',
277
+ ];
213
278
  const parseSearchConfigurations = (value) => {
214
- return (value || []).map((v) => {
279
+ return (value || [])
280
+ .map((v) => {
215
281
  try {
216
282
  return JSON.parse(v);
217
283
  }
218
284
  catch {
219
285
  return null;
220
286
  }
221
- }).filter((v) => v !== null);
287
+ })
288
+ .filter((v) => v !== null);
222
289
  };
223
290
  const getShortName = (name) => {
224
291
  return name.startsWith(CBOARD_PREFIX) ? name.slice(CBOARD_PREFIX.length) : name;
225
292
  };
226
- if (widget.configuration && typeof widget.configuration === 'object' && !Array.isArray(widget.configuration)) {
293
+ if (widget.configuration &&
294
+ typeof widget.configuration === 'object' &&
295
+ !Array.isArray(widget.configuration)) {
227
296
  for (const [key, value] of Object.entries(widget.configuration)) {
228
297
  const shortName = getShortName(key);
229
298
  if (shortName === 'searchConfigurations') {
@@ -247,12 +316,12 @@ function extractWidgetConfiguration(widget) {
247
316
  return config;
248
317
  }
249
318
  function validateSearchIdReferences(referencedIds, availableIds, contextDescription) {
250
- const invalidIds = referencedIds.filter(id => !availableIds.includes(id));
319
+ const invalidIds = referencedIds.filter((id) => !availableIds.includes(id));
251
320
  if (invalidIds.length > 0) {
252
321
  return {
253
322
  valid: false,
254
- error: `${contextDescription} references unknown searchId(s): ${invalidIds.map(id => `'${id}'`).join(', ')}. ` +
255
- `Available searchIds: [${availableIds.map(id => `'${id}'`).join(', ')}]`
323
+ error: `${contextDescription} references unknown searchId(s): ${invalidIds.map((id) => `'${id}'`).join(', ')}. ` +
324
+ `Available searchIds: [${availableIds.map((id) => `'${id}'`).join(', ')}]`,
256
325
  };
257
326
  }
258
327
  return { valid: true };
@@ -262,7 +331,7 @@ function transformRawToFriendly(rawConfig) {
262
331
  const card = {
263
332
  searchId: sc.searchId,
264
333
  search: sc.search,
265
- typeId: sc.typeId
334
+ typeId: sc.typeId,
266
335
  };
267
336
  const hasCardDisplay = sc.visibleDateAttribute || sc.attributeTags || sc.colorAttribute || sc.customIconAttributes;
268
337
  if (hasCardDisplay) {
@@ -276,13 +345,13 @@ function transformRawToFriendly(rawConfig) {
276
345
  if (sc.colorAttribute) {
277
346
  card.cardDisplay.colorAttribute = {
278
347
  attribute: sc.colorAttribute.attributeSimpleName,
279
- colorMapping: sc.colorAttribute.selection || {}
348
+ colorMapping: sc.colorAttribute.selection || {},
280
349
  };
281
350
  }
282
351
  if (sc.customIconAttributes?.length) {
283
352
  card.cardDisplay.iconAttributes = sc.customIconAttributes.map((cia) => ({
284
353
  attribute: cia.attributeSimpleName,
285
- enabled: cia.enabled
354
+ enabled: cia.enabled,
286
355
  }));
287
356
  }
288
357
  }
@@ -336,28 +405,29 @@ function transformMappingToFriendly(raw, elementType) {
336
405
  }
337
406
  if (raw.dynamic) {
338
407
  return {
339
- mode: "dynamic",
408
+ mode: 'dynamic',
340
409
  ...(elementType === 'swimlane' && { enabled: true }),
341
410
  dynamicConfig: {
342
411
  mappedAttributes: raw.mappedAttributes?.map((ma) => ({
343
412
  searchId: ma.searchId,
344
- attribute: ma.attributeSimpleName
413
+ attribute: ma.attributeSimpleName,
345
414
  })),
346
415
  timeGranularity: raw.timeGranularity?.toLowerCase(),
347
416
  dateRange: raw.dateRange,
348
- dateFormatId: raw.dateFormatId
349
- }
417
+ dateFormatId: raw.dateFormatId,
418
+ },
350
419
  };
351
420
  }
352
421
  return {
353
- mode: "static",
422
+ mode: 'static',
354
423
  ...(elementType === 'swimlane' && { enabled: true }),
355
424
  [pluralField]: raw.elements?.map((el) => ({
356
425
  [idField]: el.id,
357
426
  names: el.localizedNames,
358
427
  mappings: el.mappedValues?.map((mv) => ({
359
428
  searchId: mv.searchId,
360
- attribute: raw.mappedAttributes?.find((ma) => ma.searchId === mv.searchId)?.attributeSimpleName,
429
+ attribute: raw.mappedAttributes?.find((ma) => ma.searchId === mv.searchId)
430
+ ?.attributeSimpleName,
361
431
  values: mv.values?.length ? mv.values : undefined,
362
432
  referenceValues: mv.referenceValues?.length
363
433
  ? mv.referenceValues.map((rv) => {
@@ -365,9 +435,9 @@ function transformMappingToFriendly(raw, elementType) {
365
435
  return uid.startsWith('page/') ? uid.slice(5) : uid;
366
436
  })
367
437
  : undefined,
368
- dateRange: mv.dateRange || undefined
369
- }))
370
- }))
438
+ dateRange: mv.dateRange || undefined,
439
+ })),
440
+ })),
371
441
  };
372
442
  }
373
443
  function transformVisualToFriendly(raw) {
@@ -379,15 +449,15 @@ function transformVisualToFriendly(raw) {
379
449
  enableCardDetailsView: raw.cardDetailsViewEnabled,
380
450
  showSpaceAfterLastColumn: raw.spaceAfterLastColumnEnabled,
381
451
  enableRecentHistory: raw.recentHistoryButtonEnabled,
382
- recentHistoryWeeks: raw.recentHistoryTimeRangeWeeks
452
+ recentHistoryWeeks: raw.recentHistoryTimeRangeWeeks,
383
453
  };
384
454
  }
385
455
  function transformCardsToRaw(cards) {
386
- return cards.map(card => {
456
+ return cards.map((card) => {
387
457
  const raw = {
388
458
  searchId: card.searchId,
389
459
  search: card.search,
390
- typeId: card.typeId
460
+ typeId: card.typeId,
391
461
  };
392
462
  if (card.cardDisplay) {
393
463
  if (card.cardDisplay.dateAttribute) {
@@ -399,13 +469,13 @@ function transformCardsToRaw(cards) {
399
469
  if (card.cardDisplay.colorAttribute) {
400
470
  raw.colorAttribute = {
401
471
  attributeSimpleName: card.cardDisplay.colorAttribute.attribute,
402
- selection: card.cardDisplay.colorAttribute.colorMapping
472
+ selection: card.cardDisplay.colorAttribute.colorMapping,
403
473
  };
404
474
  }
405
475
  if (card.cardDisplay.iconAttributes) {
406
476
  raw.customIconAttributes = card.cardDisplay.iconAttributes.map((ia) => ({
407
477
  enabled: ia.enabled !== false,
408
- attributeSimpleName: ia.attribute
478
+ attributeSimpleName: ia.attribute,
409
479
  }));
410
480
  }
411
481
  }
@@ -419,8 +489,8 @@ function transformMappedValuesToRaw(mapping) {
419
489
  referenceValues: (mapping.referenceValues || []).map((uid) => ({
420
490
  linkUid: uid.startsWith('page/') ? uid : `page/${uid}`,
421
491
  linkName: '',
422
- linkIcon: ''
423
- }))
492
+ linkIcon: '',
493
+ })),
424
494
  };
425
495
  if (mapping.dateRange) {
426
496
  raw.dateRange = mapping.dateRange;
@@ -428,14 +498,14 @@ function transformMappedValuesToRaw(mapping) {
428
498
  return raw;
429
499
  }
430
500
  function transformColumnsToRaw(columnsConfig) {
431
- if (columnsConfig.mode === "dynamic") {
501
+ if (columnsConfig.mode === 'dynamic') {
432
502
  return JSON.stringify({
433
503
  dynamic: true,
434
504
  mappedAttributes: columnsConfig.dynamicConfig.mappedAttributes.map((ma) => ({
435
505
  searchId: ma.searchId,
436
- attributeSimpleName: ma.attribute
506
+ attributeSimpleName: ma.attribute,
437
507
  })),
438
- elements: []
508
+ elements: [],
439
509
  });
440
510
  }
441
511
  const mappedAttributesMap = new Map();
@@ -448,13 +518,13 @@ function transformColumnsToRaw(columnsConfig) {
448
518
  dynamic: false,
449
519
  mappedAttributes: Array.from(mappedAttributesMap.entries()).map(([searchId, attr]) => ({
450
520
  searchId,
451
- attributeSimpleName: attr
521
+ attributeSimpleName: attr,
452
522
  })),
453
523
  elements: columnsConfig.columns.map((col) => ({
454
524
  id: col.columnId,
455
525
  localizedNames: col.names,
456
- mappedValues: col.mappings.map(transformMappedValuesToRaw)
457
- }))
526
+ mappedValues: col.mappings.map(transformMappedValuesToRaw),
527
+ })),
458
528
  });
459
529
  }
460
530
  function transformSwimlanesToRaw(swimlanesConfig) {
@@ -462,17 +532,17 @@ function transformSwimlanesToRaw(swimlanesConfig) {
462
532
  return JSON.stringify({
463
533
  dynamic: false,
464
534
  mappedAttributes: [],
465
- elements: []
535
+ elements: [],
466
536
  });
467
537
  }
468
- if (swimlanesConfig.mode === "dynamic") {
538
+ if (swimlanesConfig.mode === 'dynamic') {
469
539
  return JSON.stringify({
470
540
  dynamic: true,
471
541
  mappedAttributes: swimlanesConfig.dynamicConfig.mappedAttributes.map((ma) => ({
472
542
  searchId: ma.searchId,
473
- attributeSimpleName: ma.attribute
543
+ attributeSimpleName: ma.attribute,
474
544
  })),
475
- elements: []
545
+ elements: [],
476
546
  });
477
547
  }
478
548
  const mappedAttributesMap = new Map();
@@ -485,13 +555,13 @@ function transformSwimlanesToRaw(swimlanesConfig) {
485
555
  dynamic: false,
486
556
  mappedAttributes: Array.from(mappedAttributesMap.entries()).map(([searchId, attr]) => ({
487
557
  searchId,
488
- attributeSimpleName: attr
558
+ attributeSimpleName: attr,
489
559
  })),
490
560
  elements: swimlanesConfig.swimlanes.map((sl) => ({
491
561
  id: sl.swimlaneId,
492
562
  localizedNames: sl.names,
493
- mappedValues: sl.mappings.map(transformMappedValuesToRaw)
494
- }))
563
+ mappedValues: sl.mappings.map(transformMappedValuesToRaw),
564
+ })),
495
565
  });
496
566
  }
497
567
  function transformVisualToRaw(friendlyVisual) {
@@ -503,7 +573,7 @@ function transformVisualToRaw(friendlyVisual) {
503
573
  enableCardDetailsView: 'cardDetailsViewEnabled',
504
574
  showSpaceAfterLastColumn: 'spaceAfterLastColumnEnabled',
505
575
  enableRecentHistory: 'recentHistoryButtonEnabled',
506
- recentHistoryWeeks: 'recentHistoryTimeRangeWeeks'
576
+ recentHistoryWeeks: 'recentHistoryTimeRangeWeeks',
507
577
  };
508
578
  const raw = {};
509
579
  for (const [friendlyName, rawName] of Object.entries(fieldMapping)) {
@@ -529,11 +599,13 @@ async function getCurrentBoardConfig(client, context, widgetId) {
529
599
  const friendlyConfig = transformRawToFriendly(rawConfig);
530
600
  return {
531
601
  cards: friendlyConfig.cards,
532
- visualComponents: friendlyConfig.visualComponents
602
+ visualComponents: friendlyConfig.visualComponents,
533
603
  };
534
604
  }
535
605
  catch (error) {
536
- return { error: `Failed to get current configuration: ${error instanceof Error ? error.message : String(error)}` };
606
+ return {
607
+ error: `Failed to get current configuration: ${error instanceof Error ? error.message : String(error)}`,
608
+ };
537
609
  }
538
610
  }
539
611
  export function registerBoardWidgetTools(server, client) {
@@ -546,154 +618,203 @@ export function registerBoardWidgetTools(server, client) {
546
618
  const widget = findWidgetById(layoutResult.rows, widgetId);
547
619
  if (!widget) {
548
620
  return {
549
- content: [{ type: "text", text: `Board widget with ID '${widgetId}' not found in layout` }],
550
- isError: true
621
+ content: [
622
+ { type: 'text', text: `Board widget with ID '${widgetId}' not found in layout` },
623
+ ],
624
+ isError: true,
551
625
  };
552
626
  }
553
627
  if (widget.widgetType !== BOARD_WIDGET_TYPE) {
554
628
  return {
555
- content: [{ type: "text", text: `Widget '${widgetId}' is not a board widget (found: ${widget.widgetType})` }],
556
- isError: true
629
+ content: [
630
+ {
631
+ type: 'text',
632
+ text: `Widget '${widgetId}' is not a board widget (found: ${widget.widgetType})`,
633
+ },
634
+ ],
635
+ isError: true,
557
636
  };
558
637
  }
559
638
  const rawConfig = extractWidgetConfiguration(widget);
560
- const isUnconfigured = (!rawConfig.searchConfigurations || rawConfig.searchConfigurations.length === 0)
561
- && !rawConfig.columnMapping
562
- && !rawConfig.swimlaneMapping;
639
+ const isUnconfigured = (!rawConfig.searchConfigurations || rawConfig.searchConfigurations.length === 0) &&
640
+ !rawConfig.columnMapping &&
641
+ !rawConfig.swimlaneMapping;
563
642
  if (isUnconfigured) {
564
643
  debugLogWithTag('BOARD', `Board widget ${widgetId} is unconfigured (no card sources or mappings)`);
565
644
  return {
566
- content: [{ type: "text", text: JSON.stringify({
645
+ content: [
646
+ {
647
+ type: 'text',
648
+ text: JSON.stringify({
567
649
  context,
568
650
  widgetId,
569
651
  configuration: {
570
- status: "unconfigured",
652
+ status: 'unconfigured',
571
653
  cards: [],
572
654
  columns: null,
573
655
  swimlanes: null,
574
- visualComponents: null
575
- }
576
- }, null, 2) }]
656
+ visualComponents: null,
657
+ },
658
+ }, null, 2),
659
+ },
660
+ ],
577
661
  };
578
662
  }
579
663
  const friendlyConfig = transformRawToFriendly(rawConfig);
580
664
  debugLogWithTag('BOARD', `Successfully retrieved board configuration with ${friendlyConfig.cards?.length || 0} card sources`);
581
665
  return {
582
- content: [{ type: "text", text: JSON.stringify({
666
+ content: [
667
+ {
668
+ type: 'text',
669
+ text: JSON.stringify({
583
670
  context,
584
671
  widgetId,
585
672
  configuration: {
586
- status: "configured",
587
- ...friendlyConfig
588
- }
589
- }, null, 2) }]
673
+ status: 'configured',
674
+ ...friendlyConfig,
675
+ },
676
+ }, null, 2),
677
+ },
678
+ ],
590
679
  };
591
680
  }
592
681
  catch (error) {
593
682
  debugLogWithTag('BOARD', `Error getting board configuration: ${error instanceof Error ? error.message : String(error)}`);
594
683
  return {
595
- content: [{ type: "text", text: `Failed to get board configuration: ${error instanceof Error ? error.message : String(error)}` }],
596
- isError: true
684
+ content: [
685
+ {
686
+ type: 'text',
687
+ text: `Failed to get board configuration: ${error instanceof Error ? error.message : String(error)}`,
688
+ },
689
+ ],
690
+ isError: true,
597
691
  };
598
692
  }
599
693
  });
600
694
  server.registerTool(TOOL_BOARD_CONFIGURE_CARDS, BOARD_TOOL_DEFINITIONS[TOOL_BOARD_CONFIGURE_CARDS], async ({ context, widgetId, cards }) => {
601
695
  debugLogWithTag('BOARD', `Configuring ${cards.length} card sources for widget ${widgetId}`);
602
696
  try {
603
- const searchIds = cards.map(c => c.searchId);
697
+ const searchIds = cards.map((c) => c.searchId);
604
698
  const duplicates = searchIds.filter((id, i) => searchIds.indexOf(id) !== i);
605
699
  if (duplicates.length > 0) {
606
700
  return {
607
- content: [{ type: "text", text: `Duplicate searchId(s) found: ${[...new Set(duplicates)].join(', ')}. Each searchId must be unique.` }],
608
- isError: true
701
+ content: [
702
+ {
703
+ type: 'text',
704
+ text: `Duplicate searchId(s) found: ${[...new Set(duplicates)].join(', ')}. Each searchId must be unique.`,
705
+ },
706
+ ],
707
+ isError: true,
609
708
  };
610
709
  }
611
710
  const rawSearchConfigurations = transformCardsToRaw(cards);
612
711
  const endpoint = determineApiEndpoint(context);
613
- const searchConfigurationsValue = rawSearchConfigurations.map(sc => JSON.stringify(sc));
712
+ const searchConfigurationsValue = rawSearchConfigurations.map((sc) => JSON.stringify(sc));
614
713
  debugLogWithTag('BOARD', `searchConfigurationsValue: ${JSON.stringify(searchConfigurationsValue)}`);
615
714
  const requestBody = buildUpdateRequestBody(context, widgetId, {
616
- 'cf.cplace.cboard.searchConfigurations': searchConfigurationsValue
715
+ 'cf.cplace.cboard.searchConfigurations': searchConfigurationsValue,
617
716
  });
618
717
  await client.makeApiRequest(endpoint, 'PATCH', undefined, requestBody);
619
718
  debugLogWithTag('BOARD', `Successfully configured ${cards.length} card sources`);
620
719
  return {
621
- content: [{ type: "text", text: JSON.stringify({
622
- operation: "CONFIGURE_CARDS",
623
- status: "SUCCESS",
720
+ content: [
721
+ {
722
+ type: 'text',
723
+ text: JSON.stringify({
724
+ operation: 'CONFIGURE_CARDS',
725
+ status: 'SUCCESS',
624
726
  context,
625
727
  widgetId,
626
728
  cardCount: cards.length,
627
729
  searchIds: searchIds,
628
- message: `Board cards configured successfully with ${cards.length} source(s)`
629
- }, null, 2) }]
730
+ message: `Board cards configured successfully with ${cards.length} source(s)`,
731
+ }, null, 2),
732
+ },
733
+ ],
630
734
  };
631
735
  }
632
736
  catch (error) {
633
737
  debugLogWithTag('BOARD', `Error configuring cards: ${error instanceof Error ? error.message : String(error)}`);
634
738
  return {
635
- content: [{ type: "text", text: `Failed to configure board cards: ${error instanceof Error ? error.message : String(error)}` }],
636
- isError: true
739
+ content: [
740
+ {
741
+ type: 'text',
742
+ text: `Failed to configure board cards: ${error instanceof Error ? error.message : String(error)}`,
743
+ },
744
+ ],
745
+ isError: true,
637
746
  };
638
747
  }
639
748
  });
640
749
  server.registerTool(TOOL_BOARD_CONFIGURE_COLUMNS, BOARD_TOOL_DEFINITIONS[TOOL_BOARD_CONFIGURE_COLUMNS], async ({ context, widgetId, mode, columns, dynamicConfig }) => {
641
750
  debugLogWithTag('BOARD', `Configuring columns (${mode} mode) for widget ${widgetId}`);
642
751
  try {
643
- if (mode === "static" && (!columns || columns.length === 0)) {
752
+ if (mode === 'static' && (!columns || columns.length === 0)) {
644
753
  return {
645
- content: [{ type: "text", text: "Static mode requires at least one column definition" }],
646
- isError: true
754
+ content: [
755
+ { type: 'text', text: 'Static mode requires at least one column definition' },
756
+ ],
757
+ isError: true,
647
758
  };
648
759
  }
649
- if (mode === "dynamic" && !dynamicConfig) {
760
+ if (mode === 'dynamic' && !dynamicConfig) {
650
761
  return {
651
- content: [{ type: "text", text: "Dynamic mode requires dynamicConfig" }],
652
- isError: true
762
+ content: [{ type: 'text', text: 'Dynamic mode requires dynamicConfig' }],
763
+ isError: true,
653
764
  };
654
765
  }
655
766
  const currentConfig = await getCurrentBoardConfig(client, context, widgetId);
656
767
  if (currentConfig.error) {
657
768
  return {
658
- content: [{ type: "text", text: currentConfig.error }],
659
- isError: true
769
+ content: [{ type: 'text', text: currentConfig.error }],
770
+ isError: true,
660
771
  };
661
772
  }
662
773
  const availableSearchIds = currentConfig.cards?.map((c) => c.searchId) || [];
663
- const referencedIds = mode === "static"
664
- ? [...new Set(columns.flatMap(col => col.mappings.map(m => m.searchId)))]
665
- : (dynamicConfig?.mappedAttributes || []).map(ma => ma.searchId);
666
- const validation = validateSearchIdReferences(referencedIds, availableSearchIds, "Column configuration");
774
+ const referencedIds = mode === 'static'
775
+ ? [...new Set(columns.flatMap((col) => col.mappings.map((m) => m.searchId)))]
776
+ : (dynamicConfig?.mappedAttributes || []).map((ma) => ma.searchId);
777
+ const validation = validateSearchIdReferences(referencedIds, availableSearchIds, 'Column configuration');
667
778
  if (!validation.valid) {
668
779
  return {
669
- content: [{ type: "text", text: validation.error }],
670
- isError: true
780
+ content: [{ type: 'text', text: validation.error }],
781
+ isError: true,
671
782
  };
672
783
  }
673
784
  const rawColumnMapping = transformColumnsToRaw({ mode, columns, dynamicConfig });
674
785
  const endpoint = determineApiEndpoint(context);
675
786
  const requestBody = buildUpdateRequestBody(context, widgetId, {
676
- 'cf.cplace.cboard.columnMapping': rawColumnMapping
787
+ 'cf.cplace.cboard.columnMapping': rawColumnMapping,
677
788
  });
678
789
  await client.makeApiRequest(endpoint, 'PATCH', undefined, requestBody);
679
790
  debugLogWithTag('BOARD', `Successfully configured columns in ${mode} mode`);
680
791
  return {
681
- content: [{ type: "text", text: JSON.stringify({
682
- operation: "CONFIGURE_COLUMNS",
683
- status: "SUCCESS",
792
+ content: [
793
+ {
794
+ type: 'text',
795
+ text: JSON.stringify({
796
+ operation: 'CONFIGURE_COLUMNS',
797
+ status: 'SUCCESS',
684
798
  context,
685
799
  widgetId,
686
800
  mode,
687
- columnCount: mode === "static" ? columns.length : "dynamic",
688
- message: `Board columns configured successfully (${mode} mode)`
689
- }, null, 2) }]
801
+ columnCount: mode === 'static' ? columns.length : 'dynamic',
802
+ message: `Board columns configured successfully (${mode} mode)`,
803
+ }, null, 2),
804
+ },
805
+ ],
690
806
  };
691
807
  }
692
808
  catch (error) {
693
809
  debugLogWithTag('BOARD', `Error configuring columns: ${error instanceof Error ? error.message : String(error)}`);
694
810
  return {
695
- content: [{ type: "text", text: `Failed to configure board columns: ${error instanceof Error ? error.message : String(error)}` }],
696
- isError: true
811
+ content: [
812
+ {
813
+ type: 'text',
814
+ text: `Failed to configure board columns: ${error instanceof Error ? error.message : String(error)}`,
815
+ },
816
+ ],
817
+ isError: true,
697
818
  };
698
819
  }
699
820
  });
@@ -704,81 +825,103 @@ export function registerBoardWidgetTools(server, client) {
704
825
  const rawSwimlaneMapping = transformSwimlanesToRaw({ enabled: false });
705
826
  const endpoint = determineApiEndpoint(context);
706
827
  const requestBody = buildUpdateRequestBody(context, widgetId, {
707
- 'cf.cplace.cboard.swimlaneMapping': rawSwimlaneMapping
828
+ 'cf.cplace.cboard.swimlaneMapping': rawSwimlaneMapping,
708
829
  });
709
830
  await client.makeApiRequest(endpoint, 'PATCH', undefined, requestBody);
710
831
  return {
711
- content: [{ type: "text", text: JSON.stringify({
712
- operation: "CONFIGURE_SWIMLANES",
713
- status: "SUCCESS",
832
+ content: [
833
+ {
834
+ type: 'text',
835
+ text: JSON.stringify({
836
+ operation: 'CONFIGURE_SWIMLANES',
837
+ status: 'SUCCESS',
714
838
  context,
715
839
  widgetId,
716
840
  enabled: false,
717
- message: "Board swimlanes disabled (flat board)"
718
- }, null, 2) }]
841
+ message: 'Board swimlanes disabled (flat board)',
842
+ }, null, 2),
843
+ },
844
+ ],
719
845
  };
720
846
  }
721
847
  if (!mode) {
722
848
  return {
723
- content: [{ type: "text", text: "Mode is required when swimlanes are enabled" }],
724
- isError: true
849
+ content: [{ type: 'text', text: 'Mode is required when swimlanes are enabled' }],
850
+ isError: true,
725
851
  };
726
852
  }
727
- if (mode === "static" && (!swimlanes || swimlanes.length === 0)) {
853
+ if (mode === 'static' && (!swimlanes || swimlanes.length === 0)) {
728
854
  return {
729
- content: [{ type: "text", text: "Static mode requires at least one swimlane definition" }],
730
- isError: true
855
+ content: [
856
+ { type: 'text', text: 'Static mode requires at least one swimlane definition' },
857
+ ],
858
+ isError: true,
731
859
  };
732
860
  }
733
- if (mode === "dynamic" && !dynamicConfig) {
861
+ if (mode === 'dynamic' && !dynamicConfig) {
734
862
  return {
735
- content: [{ type: "text", text: "Dynamic mode requires dynamicConfig" }],
736
- isError: true
863
+ content: [{ type: 'text', text: 'Dynamic mode requires dynamicConfig' }],
864
+ isError: true,
737
865
  };
738
866
  }
739
867
  const currentConfig = await getCurrentBoardConfig(client, context, widgetId);
740
868
  if (currentConfig.error) {
741
869
  return {
742
- content: [{ type: "text", text: currentConfig.error }],
743
- isError: true
870
+ content: [{ type: 'text', text: currentConfig.error }],
871
+ isError: true,
744
872
  };
745
873
  }
746
874
  const availableSearchIds = currentConfig.cards?.map((c) => c.searchId) || [];
747
- const referencedIds = mode === "static"
748
- ? [...new Set(swimlanes.flatMap(sl => sl.mappings.map(m => m.searchId)))]
749
- : (dynamicConfig?.mappedAttributes || []).map(ma => ma.searchId);
750
- const validation = validateSearchIdReferences(referencedIds, availableSearchIds, "Swimlane configuration");
875
+ const referencedIds = mode === 'static'
876
+ ? [...new Set(swimlanes.flatMap((sl) => sl.mappings.map((m) => m.searchId)))]
877
+ : (dynamicConfig?.mappedAttributes || []).map((ma) => ma.searchId);
878
+ const validation = validateSearchIdReferences(referencedIds, availableSearchIds, 'Swimlane configuration');
751
879
  if (!validation.valid) {
752
880
  return {
753
- content: [{ type: "text", text: validation.error }],
754
- isError: true
881
+ content: [{ type: 'text', text: validation.error }],
882
+ isError: true,
755
883
  };
756
884
  }
757
- const rawSwimlaneMapping = transformSwimlanesToRaw({ enabled: true, mode, swimlanes, dynamicConfig });
885
+ const rawSwimlaneMapping = transformSwimlanesToRaw({
886
+ enabled: true,
887
+ mode,
888
+ swimlanes,
889
+ dynamicConfig,
890
+ });
758
891
  const endpoint = determineApiEndpoint(context);
759
892
  const requestBody = buildUpdateRequestBody(context, widgetId, {
760
- 'cf.cplace.cboard.swimlaneMapping': rawSwimlaneMapping
893
+ 'cf.cplace.cboard.swimlaneMapping': rawSwimlaneMapping,
761
894
  });
762
895
  await client.makeApiRequest(endpoint, 'PATCH', undefined, requestBody);
763
896
  debugLogWithTag('BOARD', `Successfully configured swimlanes in ${mode} mode`);
764
897
  return {
765
- content: [{ type: "text", text: JSON.stringify({
766
- operation: "CONFIGURE_SWIMLANES",
767
- status: "SUCCESS",
898
+ content: [
899
+ {
900
+ type: 'text',
901
+ text: JSON.stringify({
902
+ operation: 'CONFIGURE_SWIMLANES',
903
+ status: 'SUCCESS',
768
904
  context,
769
905
  widgetId,
770
906
  enabled: true,
771
907
  mode,
772
- swimlaneCount: mode === "static" ? swimlanes.length : "dynamic",
773
- message: `Board swimlanes configured successfully (${mode} mode)`
774
- }, null, 2) }]
908
+ swimlaneCount: mode === 'static' ? swimlanes.length : 'dynamic',
909
+ message: `Board swimlanes configured successfully (${mode} mode)`,
910
+ }, null, 2),
911
+ },
912
+ ],
775
913
  };
776
914
  }
777
915
  catch (error) {
778
916
  debugLogWithTag('BOARD', `Error configuring swimlanes: ${error instanceof Error ? error.message : String(error)}`);
779
917
  return {
780
- content: [{ type: "text", text: `Failed to configure board swimlanes: ${error instanceof Error ? error.message : String(error)}` }],
781
- isError: true
918
+ content: [
919
+ {
920
+ type: 'text',
921
+ text: `Failed to configure board swimlanes: ${error instanceof Error ? error.message : String(error)}`,
922
+ },
923
+ ],
924
+ isError: true,
782
925
  };
783
926
  }
784
927
  });
@@ -788,8 +931,8 @@ export function registerBoardWidgetTools(server, client) {
788
931
  const currentConfig = await getCurrentBoardConfig(client, context, widgetId);
789
932
  if (currentConfig.error) {
790
933
  return {
791
- content: [{ type: "text", text: currentConfig.error }],
792
- isError: true
934
+ content: [{ type: 'text', text: currentConfig.error }],
935
+ isError: true,
793
936
  };
794
937
  }
795
938
  const currentVisual = currentConfig.visualComponents || {};
@@ -799,27 +942,37 @@ export function registerBoardWidgetTools(server, client) {
799
942
  const rawVisualComponents = JSON.stringify(mergedRaw);
800
943
  const endpoint = determineApiEndpoint(context);
801
944
  const requestBody = buildUpdateRequestBody(context, widgetId, {
802
- 'cf.cplace.cboard.visualComponents': rawVisualComponents
945
+ 'cf.cplace.cboard.visualComponents': rawVisualComponents,
803
946
  });
804
947
  await client.makeApiRequest(endpoint, 'PATCH', undefined, requestBody);
805
948
  debugLogWithTag('BOARD', `Successfully configured visual settings`);
806
- const appliedSettings = Object.keys(visualSettings).filter(k => visualSettings[k] !== undefined);
949
+ const appliedSettings = Object.keys(visualSettings).filter((k) => visualSettings[k] !== undefined);
807
950
  return {
808
- content: [{ type: "text", text: JSON.stringify({
809
- operation: "CONFIGURE_VISUAL",
810
- status: "SUCCESS",
951
+ content: [
952
+ {
953
+ type: 'text',
954
+ text: JSON.stringify({
955
+ operation: 'CONFIGURE_VISUAL',
956
+ status: 'SUCCESS',
811
957
  context,
812
958
  widgetId,
813
959
  appliedSettings,
814
- message: "Board visual settings configured successfully"
815
- }, null, 2) }]
960
+ message: 'Board visual settings configured successfully',
961
+ }, null, 2),
962
+ },
963
+ ],
816
964
  };
817
965
  }
818
966
  catch (error) {
819
967
  debugLogWithTag('BOARD', `Error configuring visual settings: ${error instanceof Error ? error.message : String(error)}`);
820
968
  return {
821
- content: [{ type: "text", text: `Failed to configure board visual settings: ${error instanceof Error ? error.message : String(error)}` }],
822
- isError: true
969
+ content: [
970
+ {
971
+ type: 'text',
972
+ text: `Failed to configure board visual settings: ${error instanceof Error ? error.message : String(error)}`,
973
+ },
974
+ ],
975
+ isError: true,
823
976
  };
824
977
  }
825
978
  });