@hailer/mcp 0.0.1

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 (163) hide show
  1. package/.claude/commands/tool-builder.md +37 -0
  2. package/.claude/commands/ws-pull.md +44 -0
  3. package/.claude/settings.json +8 -0
  4. package/.claude/settings.local.json +49 -0
  5. package/.claude/skills/activity-api/SKILL.md +96 -0
  6. package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
  7. package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
  8. package/.claude/skills/agent-building/SKILL.md +243 -0
  9. package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
  10. package/.claude/skills/agent-building/references/code-examples.md +587 -0
  11. package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
  12. package/.claude/skills/app-api/SKILL.md +219 -0
  13. package/.claude/skills/app-api/references/app-endpoints.md +759 -0
  14. package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
  15. package/.claude/skills/create-app-skill/SKILL.md +1101 -0
  16. package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
  17. package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
  18. package/.claude/skills/hailer-api/SKILL.md +283 -0
  19. package/.claude/skills/hailer-api/references/activities.md +620 -0
  20. package/.claude/skills/hailer-api/references/authentication.md +216 -0
  21. package/.claude/skills/hailer-api/references/datasets.md +437 -0
  22. package/.claude/skills/hailer-api/references/files.md +301 -0
  23. package/.claude/skills/hailer-api/references/insights.md +469 -0
  24. package/.claude/skills/hailer-api/references/workflows.md +720 -0
  25. package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
  26. package/.claude/skills/insight-api/SKILL.md +185 -0
  27. package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
  28. package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
  29. package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
  30. package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
  31. package/.claude/skills/local-first-skill/SKILL.md +570 -0
  32. package/.claude/skills/mcp-tools/SKILL.md +419 -0
  33. package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
  34. package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
  35. package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
  36. package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
  37. package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
  38. package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
  39. package/.claude/skills/remove-app-skill/SKILL.md +985 -0
  40. package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
  41. package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
  42. package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
  43. package/.claude/skills/skill-testing/README.md +137 -0
  44. package/.claude/skills/skill-testing/SKILL.md +348 -0
  45. package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
  46. package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
  47. package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
  48. package/.claude/skills/tool-builder/SKILL.md +328 -0
  49. package/.claude/skills/update-app-skill/SKILL.md +970 -0
  50. package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
  51. package/.env.example +81 -0
  52. package/.mcp.json +13 -0
  53. package/README.md +297 -0
  54. package/dist/app.d.ts +4 -0
  55. package/dist/app.js +74 -0
  56. package/dist/cli.d.ts +3 -0
  57. package/dist/cli.js +5 -0
  58. package/dist/client/adaptive-documentation-bot.d.ts +108 -0
  59. package/dist/client/adaptive-documentation-bot.js +475 -0
  60. package/dist/client/adaptive-documentation-types.d.ts +66 -0
  61. package/dist/client/adaptive-documentation-types.js +9 -0
  62. package/dist/client/agent-activity-bot.d.ts +51 -0
  63. package/dist/client/agent-activity-bot.js +166 -0
  64. package/dist/client/agent-tracker.d.ts +499 -0
  65. package/dist/client/agent-tracker.js +659 -0
  66. package/dist/client/description-updater.d.ts +56 -0
  67. package/dist/client/description-updater.js +259 -0
  68. package/dist/client/log-parser.d.ts +72 -0
  69. package/dist/client/log-parser.js +387 -0
  70. package/dist/client/mcp-client.d.ts +50 -0
  71. package/dist/client/mcp-client.js +532 -0
  72. package/dist/client/message-processor.d.ts +35 -0
  73. package/dist/client/message-processor.js +352 -0
  74. package/dist/client/multi-bot-manager.d.ts +24 -0
  75. package/dist/client/multi-bot-manager.js +74 -0
  76. package/dist/client/providers/anthropic-provider.d.ts +19 -0
  77. package/dist/client/providers/anthropic-provider.js +631 -0
  78. package/dist/client/providers/llm-provider.d.ts +47 -0
  79. package/dist/client/providers/llm-provider.js +367 -0
  80. package/dist/client/providers/openai-provider.d.ts +23 -0
  81. package/dist/client/providers/openai-provider.js +621 -0
  82. package/dist/client/simple-llm-caller.d.ts +19 -0
  83. package/dist/client/simple-llm-caller.js +100 -0
  84. package/dist/client/skill-generator.d.ts +81 -0
  85. package/dist/client/skill-generator.js +386 -0
  86. package/dist/client/test-adaptive-bot.d.ts +9 -0
  87. package/dist/client/test-adaptive-bot.js +82 -0
  88. package/dist/client/token-pricing.d.ts +38 -0
  89. package/dist/client/token-pricing.js +127 -0
  90. package/dist/client/token-tracker.d.ts +232 -0
  91. package/dist/client/token-tracker.js +457 -0
  92. package/dist/client/token-usage-bot.d.ts +53 -0
  93. package/dist/client/token-usage-bot.js +153 -0
  94. package/dist/client/tool-executor.d.ts +69 -0
  95. package/dist/client/tool-executor.js +159 -0
  96. package/dist/client/tool-schema-loader.d.ts +60 -0
  97. package/dist/client/tool-schema-loader.js +178 -0
  98. package/dist/client/types.d.ts +69 -0
  99. package/dist/client/types.js +7 -0
  100. package/dist/config.d.ts +162 -0
  101. package/dist/config.js +296 -0
  102. package/dist/core.d.ts +26 -0
  103. package/dist/core.js +147 -0
  104. package/dist/lib/context-manager.d.ts +111 -0
  105. package/dist/lib/context-manager.js +431 -0
  106. package/dist/lib/logger.d.ts +74 -0
  107. package/dist/lib/logger.js +277 -0
  108. package/dist/lib/materialize.d.ts +3 -0
  109. package/dist/lib/materialize.js +101 -0
  110. package/dist/lib/normalizedName.d.ts +7 -0
  111. package/dist/lib/normalizedName.js +48 -0
  112. package/dist/lib/prompt-length-manager.d.ts +81 -0
  113. package/dist/lib/prompt-length-manager.js +457 -0
  114. package/dist/lib/terminal-prompt.d.ts +9 -0
  115. package/dist/lib/terminal-prompt.js +108 -0
  116. package/dist/mcp/UserContextCache.d.ts +56 -0
  117. package/dist/mcp/UserContextCache.js +163 -0
  118. package/dist/mcp/auth.d.ts +2 -0
  119. package/dist/mcp/auth.js +29 -0
  120. package/dist/mcp/hailer-clients.d.ts +42 -0
  121. package/dist/mcp/hailer-clients.js +246 -0
  122. package/dist/mcp/signal-handler.d.ts +45 -0
  123. package/dist/mcp/signal-handler.js +317 -0
  124. package/dist/mcp/tool-registry.d.ts +100 -0
  125. package/dist/mcp/tool-registry.js +306 -0
  126. package/dist/mcp/tools/activity.d.ts +15 -0
  127. package/dist/mcp/tools/activity.js +955 -0
  128. package/dist/mcp/tools/app.d.ts +20 -0
  129. package/dist/mcp/tools/app.js +1488 -0
  130. package/dist/mcp/tools/discussion.d.ts +19 -0
  131. package/dist/mcp/tools/discussion.js +950 -0
  132. package/dist/mcp/tools/file.d.ts +15 -0
  133. package/dist/mcp/tools/file.js +119 -0
  134. package/dist/mcp/tools/insight.d.ts +17 -0
  135. package/dist/mcp/tools/insight.js +806 -0
  136. package/dist/mcp/tools/skill.d.ts +10 -0
  137. package/dist/mcp/tools/skill.js +279 -0
  138. package/dist/mcp/tools/user.d.ts +10 -0
  139. package/dist/mcp/tools/user.js +108 -0
  140. package/dist/mcp/tools/workflow-template.d.ts +19 -0
  141. package/dist/mcp/tools/workflow-template.js +822 -0
  142. package/dist/mcp/tools/workflow.d.ts +18 -0
  143. package/dist/mcp/tools/workflow.js +1362 -0
  144. package/dist/mcp/utils/api-errors.d.ts +45 -0
  145. package/dist/mcp/utils/api-errors.js +160 -0
  146. package/dist/mcp/utils/data-transformers.d.ts +102 -0
  147. package/dist/mcp/utils/data-transformers.js +194 -0
  148. package/dist/mcp/utils/file-upload.d.ts +33 -0
  149. package/dist/mcp/utils/file-upload.js +148 -0
  150. package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
  151. package/dist/mcp/utils/hailer-api-client.js +323 -0
  152. package/dist/mcp/utils/index.d.ts +13 -0
  153. package/dist/mcp/utils/index.js +39 -0
  154. package/dist/mcp/utils/logger.d.ts +42 -0
  155. package/dist/mcp/utils/logger.js +103 -0
  156. package/dist/mcp/utils/types.d.ts +286 -0
  157. package/dist/mcp/utils/types.js +7 -0
  158. package/dist/mcp/workspace-cache.d.ts +42 -0
  159. package/dist/mcp/workspace-cache.js +97 -0
  160. package/dist/mcp-server.d.ts +42 -0
  161. package/dist/mcp-server.js +280 -0
  162. package/package.json +56 -0
  163. package/tsconfig.json +23 -0
@@ -0,0 +1,1098 @@
1
+ ---
2
+ name: Updating Workflow Fields
3
+ description: Complete guide for modifying Hailer workflow fields - use when updating field properties, keys, or configurations
4
+ ---
5
+
6
+ # Updating Workflow Fields - Complete Guide
7
+
8
+ Complete reference for modifying workflow field properties using the `update_workflow_field` MCP tool.
9
+
10
+ ## Table of Contents
11
+ 1. [Quick Reference](#quick-reference)
12
+ 2. [Overview](#overview)
13
+ 3. [Core Concepts](#core-concepts)
14
+ 4. [Auto-Generated Keys](#auto-generated-keys)
15
+ 5. [Common Use Cases](#common-use-cases)
16
+ 6. [Field Properties Reference](#field-properties-reference)
17
+ 7. [Advanced Updates](#advanced-updates)
18
+ 8. [Multi-Field Updates](#multi-field-updates)
19
+ 9. [Best Practices](#best-practices)
20
+ 10. [Troubleshooting](#troubleshooting)
21
+
22
+ ## Quick Reference
23
+
24
+ **Basic Field Update:**
25
+
26
+ ```javascript
27
+ update_workflow_field({
28
+ workflowId: "68446dc05b30685f67c6fcd4",
29
+ fieldId: "6901ebb64fd57ff171f43338",
30
+ fieldData: {
31
+ label: "Task Title",
32
+ key: "taskTitle"
33
+ }
34
+ })
35
+ ```
36
+
37
+ **Auto-Generate Key from Label:**
38
+
39
+ ```javascript
40
+ update_workflow_field({
41
+ workflowId: "68446dc05b30685f67c6fcd4",
42
+ fieldId: "6901ebb64fd57ff171f43338",
43
+ fieldData: {
44
+ label: "Start Date"
45
+ // key will auto-generate as "startDate"
46
+ }
47
+ })
48
+ ```
49
+
50
+ **Update ActivityLink Targets:**
51
+
52
+ ```javascript
53
+ update_workflow_field({
54
+ workflowId: "68446dc05b30685f67c6fcd4",
55
+ fieldId: "6901ebb64fd57ff171f43339",
56
+ fieldData: {
57
+ data: ["target-workflow-id-1", "target-workflow-id-2"]
58
+ }
59
+ })
60
+ ```
61
+
62
+ **Key Features:**
63
+ - Auto-generates camelCase keys from labels
64
+ - Updates any field property
65
+ - Requires workspace administrator rights
66
+ - Non-destructive (doesn't affect existing activity data)
67
+
68
+ ## Overview
69
+
70
+ The `update_workflow_field` tool allows you to modify properties of existing fields in Hailer workflows. Unlike removing and recreating workflows, this tool lets you update field configurations without losing data.
71
+
72
+ **Think of it as:**
73
+ - ALTER TABLE in SQL (modifying column properties)
74
+ - Schema migration without data loss
75
+ - Field configuration updates
76
+ - Metadata changes
77
+
78
+ **Common Uses:**
79
+ - Add readable keys to fields for better API responses
80
+ - Update field labels for clarity
81
+ - Modify ActivityLink targets
82
+ - Change predefined options in dropdowns
83
+ - Update field descriptions and placeholders
84
+ - Change field requirements (required/optional)
85
+ - Update field editability
86
+
87
+ **What it Does NOT Do:**
88
+ - Does not change existing activity field values
89
+ - Does not delete field data
90
+ - Does not change field type (type changes may be restricted)
91
+ - Does not reorder fields (use workflow update for that)
92
+
93
+ ## Core Concepts
94
+
95
+ ### Field IDs vs Keys
96
+
97
+ **Field ID:**
98
+ - Permanent identifier: `6901ebb64fd57ff171f43338`
99
+ - Generated by Hailer when field created
100
+ - Never changes
101
+ - Used in update_workflow_field tool
102
+
103
+ **Field Key:**
104
+ - Readable name: `taskTitle`, `startDate`, `priority`
105
+ - Optional but recommended
106
+ - Used in API responses with `returnFlat: true`
107
+ - Can be added or changed with this tool
108
+
109
+ ### Field Properties
110
+
111
+ **Updatable Properties:**
112
+ - `label` - Display name in UI
113
+ - `key` - Readable field name for API
114
+ - `description` - Field help text
115
+ - `placeholder` - Input placeholder text
116
+ - `data` - For ActivityLink targets or predefined options
117
+ - `required` - Whether field must be filled
118
+ - `editable` - Whether field can be edited
119
+ - `unit` - Unit for numeric/text unit fields
120
+
121
+ **Properties That May Be Restricted:**
122
+ - `type` - Field type (text, numeric, activitylink, etc.)
123
+ - Type changes may not be allowed or may cause issues
124
+ - Best practice: Don't change type after creation
125
+
126
+ ### Language Support
127
+
128
+ Updates support multiple languages:
129
+ - Default language: `en` (English)
130
+ - Can specify language: `fi`, `sv`, `de`, etc.
131
+ - Each language can have different labels/descriptions
132
+
133
+ ## Auto-Generated Keys
134
+
135
+ The tool automatically generates camelCase keys from field labels if no key is provided.
136
+
137
+ ### Auto-Generation Rules
138
+
139
+ **Pattern:** First word lowercase, subsequent words capitalized
140
+ **Non-word characters removed:** Spaces, punctuation, special chars
141
+
142
+ ### Examples
143
+
144
+ | Label | Auto-Generated Key |
145
+ |-------|-------------------|
146
+ | Start Date | startDate |
147
+ | Due Date | dueDate |
148
+ | Related To | relatedTo |
149
+ | Project Name | projectName |
150
+ | Owner Team | ownerTeam |
151
+ | Priority Level | priorityLevel |
152
+ | Customer Contact | customerContact |
153
+ | Is Active | isActive |
154
+ | Total Amount | totalAmount |
155
+ | Start Date & Time | startDateTime |
156
+
157
+ ### Custom Keys
158
+
159
+ You can override auto-generation by providing explicit key:
160
+
161
+ ```javascript
162
+ update_workflow_field({
163
+ workflowId: "workflow-id",
164
+ fieldId: "field-id",
165
+ fieldData: {
166
+ label: "Customer Name",
167
+ key: "custName" // Custom key instead of auto-generated "customerName"
168
+ }
169
+ })
170
+ ```
171
+
172
+ ### Disabling Auto-Generation
173
+
174
+ ```javascript
175
+ update_workflow_field({
176
+ workflowId: "workflow-id",
177
+ fieldId: "field-id",
178
+ fieldData: {
179
+ label: "New Label"
180
+ },
181
+ autoGenerateKey: false // Don't auto-generate key
182
+ })
183
+ ```
184
+
185
+ ## Common Use Cases
186
+
187
+ ### Use Case 1: Add Keys to Existing Fields
188
+
189
+ **Situation:** Workflow created without keys, want readable API responses.
190
+
191
+ **Solution:**
192
+
193
+ ```javascript
194
+ // 1. Get workflow schema to see fields
195
+ const schema = get_workflow_schema({
196
+ workflowId: "68446dc05b30685f67c6fcd4"
197
+ })
198
+
199
+ // 2. Add key to each field (auto-generated from labels)
200
+ update_workflow_field({
201
+ workflowId: "68446dc05b30685f67c6fcd4",
202
+ fieldId: "field-id-1",
203
+ fieldData: {
204
+ label: "Task Title" // Key auto-generates as "taskTitle"
205
+ }
206
+ })
207
+
208
+ update_workflow_field({
209
+ workflowId: "68446dc05b30685f67c6fcd4",
210
+ fieldId: "field-id-2",
211
+ fieldData: {
212
+ label: "Due Date" // Key auto-generates as "dueDate"
213
+ }
214
+ })
215
+
216
+ // 3. Now use with returnFlat for readable responses
217
+ list_activities({
218
+ workflowId: "68446dc05b30685f67c6fcd4",
219
+ returnFlat: true
220
+ })
221
+ // Returns: { taskTitle: "My Task", dueDate: "2024-12-31" }
222
+ ```
223
+
224
+ ### Use Case 2: Update ActivityLink Targets
225
+
226
+ **Situation:** Need to change which workflows a field links to.
227
+
228
+ **Solution:**
229
+
230
+ ```javascript
231
+ // Current: Field links to one workflow
232
+ // Want: Field links to two workflows
233
+
234
+ update_workflow_field({
235
+ workflowId: "68446dc05b30685f67c6fcd4",
236
+ fieldId: "link-field-id",
237
+ fieldData: {
238
+ data: [
239
+ "target-workflow-id-1",
240
+ "target-workflow-id-2"
241
+ ]
242
+ }
243
+ })
244
+ ```
245
+
246
+ **Example - Link Tasks to Projects or Topics:**
247
+
248
+ ```javascript
249
+ // Before: Tasks link only to Projects
250
+ // After: Tasks can link to Projects OR Topics
251
+
252
+ update_workflow_field({
253
+ workflowId: "tasks-workflow-id",
254
+ fieldId: "related-to-field-id",
255
+ fieldData: {
256
+ label: "Related To",
257
+ key: "relatedTo",
258
+ data: [
259
+ "projects-workflow-id",
260
+ "topics-workflow-id"
261
+ ]
262
+ }
263
+ })
264
+ ```
265
+
266
+ ### Use Case 3: Update Predefined Options
267
+
268
+ **Situation:** Need to add/change dropdown options.
269
+
270
+ **Solution:**
271
+
272
+ ```javascript
273
+ // Before: Priority has ["Low", "Medium", "High"]
274
+ // After: Add "Urgent" option
275
+
276
+ update_workflow_field({
277
+ workflowId: "68446dc05b30685f67c6fcd4",
278
+ fieldId: "priority-field-id",
279
+ fieldData: {
280
+ data: ["Low", "Medium", "High", "Urgent"]
281
+ }
282
+ })
283
+ ```
284
+
285
+ **Example - Update Status Options:**
286
+
287
+ ```javascript
288
+ update_workflow_field({
289
+ workflowId: "workflow-id",
290
+ fieldId: "status-field-id",
291
+ fieldData: {
292
+ label: "Status",
293
+ key: "status",
294
+ data: [
295
+ "Not Started",
296
+ "In Progress",
297
+ "Blocked",
298
+ "Review",
299
+ "Done"
300
+ ]
301
+ }
302
+ })
303
+ ```
304
+
305
+ ### Use Case 4: Change Field Labels
306
+
307
+ **Situation:** Improve clarity of field names.
308
+
309
+ **Solution:**
310
+
311
+ ```javascript
312
+ // Before: "Name" (ambiguous)
313
+ // After: "Customer Name" (clear)
314
+
315
+ update_workflow_field({
316
+ workflowId: "customers-workflow-id",
317
+ fieldId: "name-field-id",
318
+ fieldData: {
319
+ label: "Customer Name",
320
+ key: "customerName"
321
+ }
322
+ })
323
+ ```
324
+
325
+ ### Use Case 5: Add Descriptions and Placeholders
326
+
327
+ **Situation:** Help users understand field purpose.
328
+
329
+ **Solution:**
330
+
331
+ ```javascript
332
+ update_workflow_field({
333
+ workflowId: "workflow-id",
334
+ fieldId: "email-field-id",
335
+ fieldData: {
336
+ label: "Email Address",
337
+ key: "email",
338
+ description: "Primary contact email for this customer",
339
+ placeholder: "user@example.com"
340
+ }
341
+ })
342
+ ```
343
+
344
+ ### Use Case 6: Make Field Required/Optional
345
+
346
+ **Situation:** Change validation requirements.
347
+
348
+ **Solution:**
349
+
350
+ ```javascript
351
+ // Make field required
352
+ update_workflow_field({
353
+ workflowId: "workflow-id",
354
+ fieldId: "field-id",
355
+ fieldData: {
356
+ required: true
357
+ }
358
+ })
359
+
360
+ // Make field optional
361
+ update_workflow_field({
362
+ workflowId: "workflow-id",
363
+ fieldId: "field-id",
364
+ fieldData: {
365
+ required: false
366
+ }
367
+ })
368
+ ```
369
+
370
+ ### Use Case 7: Update Field Editability
371
+
372
+ **Situation:** Control whether field can be edited after creation.
373
+
374
+ **Solution:**
375
+
376
+ ```javascript
377
+ // Make field read-only
378
+ update_workflow_field({
379
+ workflowId: "workflow-id",
380
+ fieldId: "created-date-field-id",
381
+ fieldData: {
382
+ editable: false
383
+ }
384
+ })
385
+
386
+ // Make field editable
387
+ update_workflow_field({
388
+ workflowId: "workflow-id",
389
+ fieldId: "status-field-id",
390
+ fieldData: {
391
+ editable: true
392
+ }
393
+ })
394
+ ```
395
+
396
+ ## Field Properties Reference
397
+
398
+ ### Text Field Properties
399
+
400
+ ```javascript
401
+ update_workflow_field({
402
+ workflowId: "workflow-id",
403
+ fieldId: "field-id",
404
+ fieldData: {
405
+ label: "Customer Name",
406
+ key: "customerName",
407
+ description: "Full legal name of the customer",
408
+ placeholder: "Enter customer name",
409
+ required: true,
410
+ editable: true
411
+ }
412
+ })
413
+ ```
414
+
415
+ ### Text with Predefined Options
416
+
417
+ ```javascript
418
+ update_workflow_field({
419
+ workflowId: "workflow-id",
420
+ fieldId: "field-id",
421
+ fieldData: {
422
+ label: "Priority",
423
+ key: "priority",
424
+ description: "Task priority level",
425
+ data: ["Low", "Medium", "High", "Urgent"], // Options
426
+ required: true
427
+ }
428
+ })
429
+ ```
430
+
431
+ ### Numeric Field Properties
432
+
433
+ ```javascript
434
+ update_workflow_field({
435
+ workflowId: "workflow-id",
436
+ fieldId: "field-id",
437
+ fieldData: {
438
+ label: "Quantity",
439
+ key: "quantity",
440
+ description: "Number of items",
441
+ placeholder: "0",
442
+ required: false
443
+ }
444
+ })
445
+ ```
446
+
447
+ ### Numeric with Unit
448
+
449
+ ```javascript
450
+ update_workflow_field({
451
+ workflowId: "workflow-id",
452
+ fieldId: "field-id",
453
+ fieldData: {
454
+ label: "Weight",
455
+ key: "weight",
456
+ unit: "kg", // Unit
457
+ description: "Package weight in kilograms"
458
+ }
459
+ })
460
+ ```
461
+
462
+ ### ActivityLink Properties
463
+
464
+ ```javascript
465
+ update_workflow_field({
466
+ workflowId: "workflow-id",
467
+ fieldId: "field-id",
468
+ fieldData: {
469
+ label: "Related Project",
470
+ key: "relatedProject",
471
+ description: "Link to parent project",
472
+ data: [
473
+ "projects-workflow-id",
474
+ "topics-workflow-id"
475
+ ], // Target workflows
476
+ required: false
477
+ }
478
+ })
479
+ ```
480
+
481
+ ### Date/DateTime Properties
482
+
483
+ ```javascript
484
+ update_workflow_field({
485
+ workflowId: "workflow-id",
486
+ fieldId: "field-id",
487
+ fieldData: {
488
+ label: "Due Date",
489
+ key: "dueDate",
490
+ description: "Task completion deadline",
491
+ required: true,
492
+ editable: true
493
+ }
494
+ })
495
+ ```
496
+
497
+ ## Advanced Updates
498
+
499
+ ### Batch Update Pattern
500
+
501
+ Update multiple fields efficiently:
502
+
503
+ ```javascript
504
+ // 1. Get schema to identify fields
505
+ const schema = get_workflow_schema({
506
+ workflowId: "workflow-id"
507
+ })
508
+
509
+ // 2. Define updates
510
+ const fieldUpdates = [
511
+ {
512
+ fieldId: "field-id-1",
513
+ data: { label: "Task Title", key: "taskTitle" }
514
+ },
515
+ {
516
+ fieldId: "field-id-2",
517
+ data: { label: "Due Date", key: "dueDate" }
518
+ },
519
+ {
520
+ fieldId: "field-id-3",
521
+ data: { label: "Priority", key: "priority", data: ["Low", "Medium", "High"] }
522
+ }
523
+ ]
524
+
525
+ // 3. Apply updates
526
+ for (const update of fieldUpdates) {
527
+ await update_workflow_field({
528
+ workflowId: "workflow-id",
529
+ fieldId: update.fieldId,
530
+ fieldData: update.data
531
+ })
532
+ }
533
+ ```
534
+
535
+ ### Standardize Keys Across Workflows
536
+
537
+ Ensure consistent naming across related workflows:
538
+
539
+ ```javascript
540
+ // Standard keys for common fields
541
+
542
+ // Update "Name" field in multiple workflows
543
+ const workflows = [
544
+ { id: "projects-workflow-id", fieldId: "name-field-id" },
545
+ { id: "tasks-workflow-id", fieldId: "name-field-id" },
546
+ { id: "topics-workflow-id", fieldId: "name-field-id" }
547
+ ]
548
+
549
+ for (const wf of workflows) {
550
+ await update_workflow_field({
551
+ workflowId: wf.id,
552
+ fieldId: wf.fieldId,
553
+ fieldData: {
554
+ label: "Name",
555
+ key: "name" // Consistent key across workflows
556
+ }
557
+ })
558
+ }
559
+ ```
560
+
561
+ ### Multi-Language Updates
562
+
563
+ Update field labels for different languages:
564
+
565
+ ```javascript
566
+ // English (default)
567
+ update_workflow_field({
568
+ workflowId: "workflow-id",
569
+ fieldId: "field-id",
570
+ fieldData: {
571
+ label: "Customer Name",
572
+ description: "Full name of the customer"
573
+ },
574
+ language: "en"
575
+ })
576
+
577
+ // Finnish
578
+ update_workflow_field({
579
+ workflowId: "workflow-id",
580
+ fieldId: "field-id",
581
+ fieldData: {
582
+ label: "Asiakkaan nimi",
583
+ description: "Asiakkaan koko nimi"
584
+ },
585
+ language: "fi"
586
+ })
587
+
588
+ // Swedish
589
+ update_workflow_field({
590
+ workflowId: "workflow-id",
591
+ fieldId: "field-id",
592
+ fieldData: {
593
+ label: "Kundnamn",
594
+ description: "Kundens fullständiga namn"
595
+ },
596
+ language: "sv"
597
+ })
598
+ ```
599
+
600
+ ### Migrate ActivityLink Targets
601
+
602
+ Update ActivityLinks when restructuring workflows:
603
+
604
+ ```javascript
605
+ // Scenario: Replaced "Old Projects" workflow with "New Projects"
606
+
607
+ // 1. Find all fields linking to old workflow
608
+ const workflows = list_workflows()
609
+
610
+ for (const workflow of workflows) {
611
+ const schema = get_workflow_schema({ workflowId: workflow._id })
612
+
613
+ for (const field of schema.fields) {
614
+ if (field.type === 'activitylink' &&
615
+ field.data.includes('old-projects-workflow-id')) {
616
+
617
+ // 2. Update to link to new workflow
618
+ const newData = field.data.map(id =>
619
+ id === 'old-projects-workflow-id' ? 'new-projects-workflow-id' : id
620
+ )
621
+
622
+ await update_workflow_field({
623
+ workflowId: workflow._id,
624
+ fieldId: field._id,
625
+ fieldData: { data: newData }
626
+ })
627
+ }
628
+ }
629
+ }
630
+ ```
631
+
632
+ ## Multi-Field Updates
633
+
634
+ ### Scenario: Add Keys to All Fields
635
+
636
+ ```javascript
637
+ // 1. Get workflow schema
638
+ const schema = get_workflow_schema({
639
+ workflowId: "68446dc05b30685f67c6fcd4"
640
+ })
641
+
642
+ // 2. Filter fields without keys
643
+ const fieldsNeedingKeys = schema.fields.filter(field =>
644
+ !field.key && field.type !== 'subheader'
645
+ )
646
+
647
+ // 3. Update each field (auto-generate keys from labels)
648
+ for (const field of fieldsNeedingKeys) {
649
+ await update_workflow_field({
650
+ workflowId: "68446dc05b30685f67c6fcd4",
651
+ fieldId: field._id,
652
+ fieldData: {
653
+ label: field.label // Key auto-generates from label
654
+ }
655
+ })
656
+
657
+ console.log(`Added key to field: ${field.label}`)
658
+ }
659
+ ```
660
+
661
+ ### Scenario: Update All ActivityLinks
662
+
663
+ ```javascript
664
+ // Update all ActivityLink fields to include new target workflow
665
+
666
+ const schema = get_workflow_schema({
667
+ workflowId: "tasks-workflow-id"
668
+ })
669
+
670
+ const activityLinkFields = schema.fields.filter(f => f.type === 'activitylink')
671
+
672
+ for (const field of activityLinkFields) {
673
+ await update_workflow_field({
674
+ workflowId: "tasks-workflow-id",
675
+ fieldId: field._id,
676
+ fieldData: {
677
+ data: [...field.data, "new-target-workflow-id"] // Add new target
678
+ }
679
+ })
680
+ }
681
+ ```
682
+
683
+ ### Scenario: Make All Date Fields Optional
684
+
685
+ ```javascript
686
+ const schema = get_workflow_schema({
687
+ workflowId: "workflow-id"
688
+ })
689
+
690
+ const dateFields = schema.fields.filter(f =>
691
+ ['date', 'datetime', 'daterange', 'datetimerange'].includes(f.type)
692
+ )
693
+
694
+ for (const field of dateFields) {
695
+ if (field.required) {
696
+ await update_workflow_field({
697
+ workflowId: "workflow-id",
698
+ fieldId: field._id,
699
+ fieldData: {
700
+ required: false
701
+ }
702
+ })
703
+
704
+ console.log(`Made field optional: ${field.label}`)
705
+ }
706
+ }
707
+ ```
708
+
709
+ ## Best Practices
710
+
711
+ ### 1. Always Use Keys
712
+
713
+ **Bad:**
714
+ ```javascript
715
+ // Field without key
716
+ update_workflow_field({
717
+ workflowId: "workflow-id",
718
+ fieldId: "field-id",
719
+ fieldData: {
720
+ label: "Customer Email"
721
+ // No key - API responses use field ID
722
+ }
723
+ })
724
+ ```
725
+
726
+ **Good:**
727
+ ```javascript
728
+ // Field with key
729
+ update_workflow_field({
730
+ workflowId: "workflow-id",
731
+ fieldId: "field-id",
732
+ fieldData: {
733
+ label: "Customer Email",
734
+ key: "customerEmail" // Or let it auto-generate
735
+ }
736
+ })
737
+ ```
738
+
739
+ ### 2. Use Descriptive Labels
740
+
741
+ **Bad:**
742
+ ```javascript
743
+ { label: "Date" } // Which date?
744
+ ```
745
+
746
+ **Good:**
747
+ ```javascript
748
+ { label: "Due Date", key: "dueDate" }
749
+ { label: "Start Date", key: "startDate" }
750
+ { label: "Created Date", key: "createdDate" }
751
+ ```
752
+
753
+ ### 3. Provide Helpful Descriptions
754
+
755
+ ```javascript
756
+ update_workflow_field({
757
+ workflowId: "workflow-id",
758
+ fieldId: "field-id",
759
+ fieldData: {
760
+ label: "Budget",
761
+ key: "budget",
762
+ description: "Total project budget in USD, including all costs and contingency"
763
+ }
764
+ })
765
+ ```
766
+
767
+ ### 4. Use Clear Placeholders
768
+
769
+ ```javascript
770
+ update_workflow_field({
771
+ workflowId: "workflow-id",
772
+ fieldId: "field-id",
773
+ fieldData: {
774
+ label: "Phone Number",
775
+ key: "phoneNumber",
776
+ placeholder: "+1 (555) 123-4567"
777
+ }
778
+ })
779
+ ```
780
+
781
+ ### 5. Verify Updates with get_workflow_schema
782
+
783
+ ```javascript
784
+ // 1. Update field
785
+ update_workflow_field({
786
+ workflowId: "workflow-id",
787
+ fieldId: "field-id",
788
+ fieldData: { key: "newKey" }
789
+ })
790
+
791
+ // 2. Verify change
792
+ const schema = get_workflow_schema({
793
+ workflowId: "workflow-id"
794
+ })
795
+
796
+ const field = schema.fields.find(f => f._id === "field-id")
797
+ console.log("Updated field key:", field.key)
798
+ ```
799
+
800
+ ### 6. Update Related Documentation
801
+
802
+ After field updates:
803
+ - Update team documentation
804
+ - Update API integration code
805
+ - Update training materials
806
+ - Notify users of changes
807
+
808
+ ### 7. Consider Backward Compatibility
809
+
810
+ When updating keys used in existing code:
811
+
812
+ ```javascript
813
+ // Option 1: Keep old key, add new property
814
+ // Don't change existing key if code depends on it
815
+
816
+ // Option 2: Update key and update all code
817
+ // Search codebase for old key usage
818
+ // Update create_activity and update_activity calls
819
+ ```
820
+
821
+ ### 8. Test with returnFlat
822
+
823
+ After adding keys, test with returnFlat:
824
+
825
+ ```javascript
826
+ // 1. Add keys
827
+ update_workflow_field({...})
828
+
829
+ // 2. Test with returnFlat
830
+ const activities = list_activities({
831
+ workflowId: "workflow-id",
832
+ limit: 1,
833
+ returnFlat: true
834
+ })
835
+
836
+ console.log("Fields:", Object.keys(activities.items[0].fields))
837
+ // Should show keys instead of field IDs
838
+ ```
839
+
840
+ ## Troubleshooting
841
+
842
+ ### Error: "Permission Denied"
843
+
844
+ **Cause:** User is not workspace administrator.
845
+
846
+ **Solution:**
847
+ - Contact workspace admin
848
+ - Request admin permissions
849
+ - Only admins can modify workflow schemas
850
+
851
+ ### Error: "Workflow Not Found"
852
+
853
+ **Cause:** Invalid workflow ID.
854
+
855
+ **Solution:**
856
+ ```javascript
857
+ // 1. List workflows
858
+ list_workflows()
859
+
860
+ // 2. Use correct workflow ID
861
+ update_workflow_field({
862
+ workflowId: "correct-workflow-id",
863
+ // ...
864
+ })
865
+ ```
866
+
867
+ ### Error: "Field Not Found"
868
+
869
+ **Cause:** Invalid field ID.
870
+
871
+ **Solution:**
872
+ ```javascript
873
+ // 1. Get workflow schema
874
+ const schema = get_workflow_schema({
875
+ workflowId: "workflow-id"
876
+ })
877
+
878
+ // 2. Find correct field ID
879
+ const field = schema.fields.find(f => f.label === "Field Label")
880
+ console.log("Field ID:", field._id)
881
+
882
+ // 3. Use correct field ID
883
+ update_workflow_field({
884
+ workflowId: "workflow-id",
885
+ fieldId: field._id,
886
+ // ...
887
+ })
888
+ ```
889
+
890
+ ### Key Not Auto-Generating
891
+
892
+ **Cause:** Auto-generation disabled or key already exists.
893
+
894
+ **Solution:**
895
+ ```javascript
896
+ // Explicitly set key
897
+ update_workflow_field({
898
+ workflowId: "workflow-id",
899
+ fieldId: "field-id",
900
+ fieldData: {
901
+ label: "Field Label",
902
+ key: "fieldKey" // Explicit key
903
+ },
904
+ autoGenerateKey: true // Ensure enabled (default)
905
+ })
906
+ ```
907
+
908
+ ### Key Not Showing in API Responses
909
+
910
+ **Cause:** Not using `returnFlat: true`.
911
+
912
+ **Solution:**
913
+ ```javascript
914
+ // Keys only appear with returnFlat
915
+ list_activities({
916
+ workflowId: "workflow-id",
917
+ returnFlat: true // Required for keys
918
+ })
919
+ ```
920
+
921
+ ### ActivityLink Update Not Working
922
+
923
+ **Cause:** Invalid target workflow IDs.
924
+
925
+ **Solution:**
926
+ ```javascript
927
+ // 1. Verify target workflows exist
928
+ list_workflows()
929
+
930
+ // 2. Use correct workflow IDs in data
931
+ update_workflow_field({
932
+ workflowId: "workflow-id",
933
+ fieldId: "field-id",
934
+ fieldData: {
935
+ data: ["valid-workflow-id-1", "valid-workflow-id-2"]
936
+ }
937
+ })
938
+ ```
939
+
940
+ ### Predefined Options Not Updating
941
+
942
+ **Cause:** Incorrect data format.
943
+
944
+ **Solution:**
945
+ ```javascript
946
+ // Correct: Array of strings
947
+ update_workflow_field({
948
+ workflowId: "workflow-id",
949
+ fieldId: "field-id",
950
+ fieldData: {
951
+ data: ["Option 1", "Option 2", "Option 3"] // Array of strings
952
+ }
953
+ })
954
+
955
+ // Incorrect: Single string
956
+ // data: "Option 1, Option 2" // Wrong format
957
+ ```
958
+
959
+ ### Changes Not Visible
960
+
961
+ **Cause:** Cache not refreshed.
962
+
963
+ **Solution:**
964
+ ```javascript
965
+ // Refresh schema
966
+ const schema = get_workflow_schema({
967
+ workflowId: "workflow-id"
968
+ })
969
+
970
+ // Check field properties
971
+ const field = schema.fields.find(f => f._id === "field-id")
972
+ console.log(field)
973
+ ```
974
+
975
+ ## Integration with Other Tools
976
+
977
+ ### With install_workflow
978
+
979
+ After installing, add keys to fields:
980
+
981
+ ```javascript
982
+ // 1. Install workflow
983
+ const result = install_workflow({...})
984
+ // Returns: { "_1000": "field-real-id" }
985
+
986
+ // 2. Add keys to fields
987
+ update_workflow_field({
988
+ workflowId: result._0001,
989
+ fieldId: result._1000,
990
+ fieldData: {
991
+ label: "Task Title",
992
+ key: "taskTitle"
993
+ }
994
+ })
995
+ ```
996
+
997
+ ### With get_workflow_schema
998
+
999
+ Inspect before updating:
1000
+
1001
+ ```javascript
1002
+ // 1. Get current schema
1003
+ const schema = get_workflow_schema({
1004
+ workflowId: "workflow-id"
1005
+ })
1006
+
1007
+ // 2. Find field to update
1008
+ const field = schema.fields.find(f => f.label === "Priority")
1009
+
1010
+ // 3. Update field
1011
+ update_workflow_field({
1012
+ workflowId: "workflow-id",
1013
+ fieldId: field._id,
1014
+ fieldData: {
1015
+ key: "priority",
1016
+ data: ["Low", "Medium", "High", "Urgent"]
1017
+ }
1018
+ })
1019
+ ```
1020
+
1021
+ ### With list_activities (returnFlat)
1022
+
1023
+ Test keys with returnFlat:
1024
+
1025
+ ```javascript
1026
+ // 1. Add key
1027
+ update_workflow_field({
1028
+ workflowId: "workflow-id",
1029
+ fieldId: "field-id",
1030
+ fieldData: { key: "priority" }
1031
+ })
1032
+
1033
+ // 2. Test with returnFlat
1034
+ const activities = list_activities({
1035
+ workflowId: "workflow-id",
1036
+ returnFlat: true
1037
+ })
1038
+
1039
+ // 3. Verify key appears
1040
+ console.log(activities.items[0].fields.priority)
1041
+ // Instead of: activities.items[0].fields["field-id"]
1042
+ ```
1043
+
1044
+ ### With create_activity
1045
+
1046
+ Use updated keys:
1047
+
1048
+ ```javascript
1049
+ // 1. Update field key
1050
+ update_workflow_field({
1051
+ workflowId: "workflow-id",
1052
+ fieldId: "field-id",
1053
+ fieldData: { key: "dueDate" }
1054
+ })
1055
+
1056
+ // 2. Create activity with key
1057
+ create_activity({
1058
+ workflowId: "workflow-id",
1059
+ name: "New Task",
1060
+ fields: {
1061
+ "dueDate": "2024-12-31" // Use key
1062
+ },
1063
+ returnFlat: true
1064
+ })
1065
+ ```
1066
+
1067
+ ## Summary
1068
+
1069
+ **Key Takeaways:**
1070
+ 1. ✏️ **Non-destructive** - Updates fields without losing data
1071
+ 2. 🔑 **Auto-generates keys** - From field labels by default
1072
+ 3. 🔒 **Admin only** - Requires workspace administrator rights
1073
+ 4. 📝 **Any property** - Update labels, keys, data, descriptions, etc.
1074
+ 5. 🔗 **ActivityLinks** - Update target workflows dynamically
1075
+ 6. 📋 **Predefined options** - Add/remove dropdown choices
1076
+ 7. ✅ **Verify changes** - Use get_workflow_schema to confirm
1077
+
1078
+ **Quick Decision Tree:**
1079
+
1080
+ ```
1081
+ Need to update workflow field?
1082
+
1083
+ ├─ Add readable keys? → Update with label (auto-generates key)
1084
+ ├─ Change dropdown options? → Update data array
1085
+ ├─ Update ActivityLink targets? → Update data with workflow IDs
1086
+ ├─ Change label/description? → Update label/description properties
1087
+ ├─ Change requirements? → Update required/editable properties
1088
+ └─ Multiple updates needed? → Loop through fields with updates
1089
+ ```
1090
+
1091
+ ## Additional Resources
1092
+
1093
+ - See `install-workflow-skill` for creating workflows with fields
1094
+ - See `remove-workflow-skill` for deleting workflows
1095
+ - Use `get_workflow_schema` to inspect current field properties
1096
+ - Use `list_activities` with `returnFlat: true` to test keys
1097
+ - See `hailer-api` skill for comprehensive API documentation
1098
+ - See `mcp-tools` skill for implementation patterns