@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,970 @@
1
+ ---
2
+ name: Updating Hailer Apps
3
+ description: Complete guide for modifying Hailer app properties - use when changing app names, descriptions, or configurations
4
+ ---
5
+
6
+ # Updating Hailer Apps - Complete Guide
7
+
8
+ Complete reference for modifying Hailer app properties using the `update_app` 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. [Basic Usage](#basic-usage)
15
+ 5. [Updatable Properties](#updatable-properties)
16
+ 6. [Common Scenarios](#common-scenarios)
17
+ 7. [Configuration Updates](#configuration-updates)
18
+ 8. [Best Practices](#best-practices)
19
+ 9. [Troubleshooting](#troubleshooting)
20
+
21
+ ## Quick Reference
22
+
23
+ **Update App Name:**
24
+
25
+ ```javascript
26
+ update_app({
27
+ appId: 'app-id',
28
+ name: 'New App Name'
29
+ })
30
+ ```
31
+
32
+ **Update Multiple Properties:**
33
+
34
+ ```javascript
35
+ update_app({
36
+ appId: 'app-id',
37
+ name: 'Updated Name',
38
+ description: 'Updated description',
39
+ config: {
40
+ workflowId: 'new-workflow-id',
41
+ theme: 'dark'
42
+ }
43
+ })
44
+ ```
45
+
46
+ **Update in Specific Workspace:**
47
+
48
+ ```javascript
49
+ update_app({
50
+ workspaceId: 'workspace-id',
51
+ appId: 'app-id',
52
+ name: 'New Name'
53
+ })
54
+ ```
55
+
56
+ **Key Requirements:**
57
+ - Must be app owner OR workspace administrator
58
+ - App ID is required
59
+ - At least one property to update
60
+ - Cannot change app type (dev to published or vice versa)
61
+ - Changes take effect immediately
62
+
63
+ ## Overview
64
+
65
+ **What does update_app do?**
66
+
67
+ Modifies properties of an existing Hailer app entry without affecting the app's code or deployment. This updates the app metadata stored in Hailer's database.
68
+
69
+ **Think of it as:**
70
+ - Editing app settings
71
+ - Updating app metadata
72
+ - Reconfiguring app parameters
73
+ - Changing app display properties
74
+
75
+ **What it Updates:**
76
+ - App name
77
+ - App description
78
+ - App configuration
79
+ - App icon/image
80
+ - App URL (dev apps only)
81
+
82
+ **What it Does NOT Update:**
83
+ - App code (use publish_hailer_app)
84
+ - App permissions (use add_app_member/remove_app_member)
85
+ - App type (dev to published conversion not supported)
86
+ - App ID (immutable)
87
+ - manifest.json (manually edit and republish)
88
+
89
+ ## Core Concepts
90
+
91
+ ### Non-Destructive Updates
92
+
93
+ **Updates are safe:**
94
+ - Doesn't affect deployed app code
95
+ - Doesn't break existing functionality
96
+ - Changes are immediate
97
+ - Can be reverted by updating again
98
+
99
+ ### App Type Restrictions
100
+
101
+ **Cannot change app type:**
102
+ ```javascript
103
+ // ❌ Cannot do this:
104
+ // Convert dev app to published
105
+ update_app({
106
+ appId: 'dev-app-id',
107
+ url: '' // Remove URL doesn't make it published
108
+ })
109
+
110
+ // ❌ Cannot do this:
111
+ // Convert published app to dev
112
+ update_app({
113
+ appId: 'published-app-id',
114
+ url: 'http://localhost:3000' // Adding URL doesn't work
115
+ })
116
+
117
+ // ✅ Solution: Create separate app entries
118
+ ```
119
+
120
+ ### Update vs Republish
121
+
122
+ **When to use update_app:**
123
+ - Change app display name
124
+ - Update app description
125
+ - Modify configuration parameters
126
+ - Change app icon
127
+ - Update dev app URL
128
+
129
+ **When to republish (publish_hailer_app):**
130
+ - Update app code
131
+ - Deploy new features
132
+ - Fix bugs in app
133
+ - Change app behavior
134
+ - Update dependencies
135
+
136
+ ## Basic Usage
137
+
138
+ ### Example 1: Update Name
139
+
140
+ ```javascript
141
+ // 1. Find app
142
+ const apps = list_apps()
143
+ const app = apps.find(a => a.name === 'Old Name')
144
+
145
+ // 2. Update name
146
+ update_app({
147
+ appId: app._id,
148
+ name: 'New Name'
149
+ })
150
+
151
+ console.log('✅ App name updated')
152
+ ```
153
+
154
+ ### Example 2: Update Description
155
+
156
+ ```javascript
157
+ update_app({
158
+ appId: 'app-id',
159
+ description: 'Updated app description with more details about functionality'
160
+ })
161
+ ```
162
+
163
+ ### Example 3: Update Multiple Properties
164
+
165
+ ```javascript
166
+ update_app({
167
+ appId: 'app-id',
168
+ name: 'Task Manager Pro',
169
+ description: 'Advanced task management with kanban boards',
170
+ config: {
171
+ workflowId: 'tasks-workflow-id',
172
+ defaultView: 'kanban',
173
+ theme: 'dark'
174
+ }
175
+ })
176
+ ```
177
+
178
+ ### Example 4: Update Dev App URL
179
+
180
+ ```javascript
181
+ // Change dev app port
182
+ update_app({
183
+ appId: 'dev-app-id',
184
+ url: 'http://localhost:3001' // Changed from 3000
185
+ })
186
+
187
+ console.log('✅ Dev app URL updated to 3001')
188
+ ```
189
+
190
+ ### Example 5: Update in Specific Workspace
191
+
192
+ ```javascript
193
+ update_app({
194
+ workspaceId: 'workspace-id',
195
+ appId: 'app-id',
196
+ name: 'Updated Name'
197
+ })
198
+ ```
199
+
200
+ ## Updatable Properties
201
+
202
+ ### name (string)
203
+
204
+ **App display name in Hailer:**
205
+
206
+ ```javascript
207
+ update_app({
208
+ appId: 'app-id',
209
+ name: 'Customer Portal'
210
+ })
211
+ ```
212
+
213
+ **Tips:**
214
+ - Shown in Apps menu
215
+ - Should be descriptive
216
+ - Can include version (e.g., "App v2.0")
217
+ - Use "(Dev)" suffix for dev apps
218
+
219
+ ### description (string)
220
+
221
+ **App description/purpose:**
222
+
223
+ ```javascript
224
+ update_app({
225
+ appId: 'app-id',
226
+ description: 'Manage customer accounts, orders, and support tickets'
227
+ })
228
+ ```
229
+
230
+ **Tips:**
231
+ - Explain app purpose
232
+ - List key features
233
+ - Include usage instructions
234
+ - Can be longer text
235
+
236
+ ### url (string, dev apps only)
237
+
238
+ **Development app URL:**
239
+
240
+ ```javascript
241
+ update_app({
242
+ appId: 'dev-app-id',
243
+ url: 'http://localhost:3001'
244
+ })
245
+ ```
246
+
247
+ **Notes:**
248
+ - Only for development apps
249
+ - Published apps ignore this property
250
+ - Must be localhost URL
251
+ - Changes where Hailer loads app from
252
+
253
+ ### image (string)
254
+
255
+ **App icon/image ID:**
256
+
257
+ ```javascript
258
+ update_app({
259
+ appId: 'app-id',
260
+ image: 'image-id-24-chars'
261
+ })
262
+ ```
263
+
264
+ **Notes:**
265
+ - Must be 24 characters
266
+ - References uploaded image
267
+ - Optional
268
+
269
+ ### config (object)
270
+
271
+ **Custom app configuration:**
272
+
273
+ ```javascript
274
+ update_app({
275
+ appId: 'app-id',
276
+ config: {
277
+ workflowId: 'workflow-id',
278
+ theme: 'dark',
279
+ features: {
280
+ exportEnabled: true,
281
+ notificationsEnabled: false
282
+ }
283
+ }
284
+ })
285
+ ```
286
+
287
+ **Notes:**
288
+ - App-specific settings
289
+ - Passed to app at runtime
290
+ - Can be any JSON structure
291
+ - Completely replaces old config (not merged)
292
+
293
+ ### workspaceId (string, optional)
294
+
295
+ **Target workspace:**
296
+
297
+ ```javascript
298
+ update_app({
299
+ workspaceId: 'workspace-id',
300
+ appId: 'app-id',
301
+ name: 'New Name'
302
+ })
303
+ ```
304
+
305
+ **Notes:**
306
+ - Defaults to current workspace
307
+ - Use when managing multiple workspaces
308
+
309
+ ## Common Scenarios
310
+
311
+ ### Scenario 1: Rename App
312
+
313
+ **Goal:** Change app display name.
314
+
315
+ ```javascript
316
+ // 1. Find app
317
+ const apps = list_apps()
318
+ const app = apps.find(a => a.name === 'Task Manager')
319
+
320
+ if (!app) {
321
+ console.error('App not found')
322
+ return
323
+ }
324
+
325
+ // 2. Update name
326
+ update_app({
327
+ appId: app._id,
328
+ name: 'Task Manager Pro'
329
+ })
330
+
331
+ // 3. Verify update
332
+ const updatedApps = list_apps()
333
+ const updated = updatedApps.find(a => a._id === app._id)
334
+ console.log('New name:', updated.name)
335
+ // Output: New name: Task Manager Pro
336
+ ```
337
+
338
+ ### Scenario 2: Update Configuration
339
+
340
+ **Goal:** Change workflow ID or settings.
341
+
342
+ ```javascript
343
+ // Update app to use different workflow
344
+ update_app({
345
+ appId: 'app-id',
346
+ config: {
347
+ workflowId: 'new-workflow-id',
348
+ defaultView: 'table',
349
+ refreshInterval: 30
350
+ }
351
+ })
352
+
353
+ console.log('✅ App configuration updated')
354
+ console.log('⚠️ Users may need to refresh to see changes')
355
+ ```
356
+
357
+ ### Scenario 3: Fix Dev App Port
358
+
359
+ **Goal:** Change dev app port after conflict.
360
+
361
+ ```javascript
362
+ // Port 3000 is in use, switch to 3001
363
+
364
+ // 1. Update dev app URL
365
+ update_app({
366
+ appId: 'dev-app-id',
367
+ url: 'http://localhost:3001'
368
+ })
369
+
370
+ // 2. Update dev server config
371
+ // Edit vite.config.ts or package.json
372
+ // Change port to 3001
373
+
374
+ // 3. Restart dev server
375
+ // npm run dev
376
+
377
+ console.log('✅ Dev app now using port 3001')
378
+ ```
379
+
380
+ ### Scenario 4: Add Description to Existing App
381
+
382
+ **Goal:** Add helpful description to app created without one.
383
+
384
+ ```javascript
385
+ const apps = list_apps()
386
+ const appsWithoutDescription = apps.filter(a => !a.description)
387
+
388
+ console.log(`Found ${appsWithoutDescription.length} apps without descriptions`)
389
+
390
+ appsWithoutDescription.forEach(app => {
391
+ // Add description based on app name
392
+ let description = ''
393
+
394
+ if (app.name.includes('Task')) {
395
+ description = 'Task management and tracking application'
396
+ } else if (app.name.includes('Dashboard')) {
397
+ description = 'Real-time dashboard for metrics and analytics'
398
+ } else {
399
+ description = 'Hailer application'
400
+ }
401
+
402
+ update_app({
403
+ appId: app._id,
404
+ description: description
405
+ })
406
+
407
+ console.log(`✅ Added description to ${app.name}`)
408
+ })
409
+ ```
410
+
411
+ ### Scenario 5: Update All Dev Apps with Consistent Naming
412
+
413
+ **Goal:** Add "(Dev)" suffix to all development apps.
414
+
415
+ ```javascript
416
+ const apps = list_apps()
417
+ const devApps = apps.filter(a => a.url && !a.name.includes('(Dev)'))
418
+
419
+ console.log(`Found ${devApps.length} dev apps without (Dev) suffix`)
420
+
421
+ devApps.forEach(app => {
422
+ update_app({
423
+ appId: app._id,
424
+ name: `${app.name} (Dev)`
425
+ })
426
+
427
+ console.log(`✅ Updated: ${app.name} → ${app.name} (Dev)`)
428
+ })
429
+ ```
430
+
431
+ ### Scenario 6: Sync Configuration Across Environments
432
+
433
+ **Goal:** Keep dev and prod config in sync.
434
+
435
+ ```javascript
436
+ // Production config
437
+ const prodConfig = {
438
+ workflowId: 'tasks-workflow-id',
439
+ theme: 'light',
440
+ refreshInterval: 60,
441
+ features: {
442
+ exportEnabled: true,
443
+ notificationsEnabled: true
444
+ }
445
+ }
446
+
447
+ // Find dev and prod apps
448
+ const apps = list_apps()
449
+ const devApp = apps.find(a => a.name === 'My App (Dev)')
450
+ const prodApp = apps.find(a => a.name === 'My App')
451
+
452
+ // Update both with same config
453
+ if (devApp) {
454
+ update_app({
455
+ appId: devApp._id,
456
+ config: prodConfig
457
+ })
458
+ console.log('✅ Dev app config updated')
459
+ }
460
+
461
+ if (prodApp) {
462
+ update_app({
463
+ appId: prodApp._id,
464
+ config: prodConfig
465
+ })
466
+ console.log('✅ Prod app config updated')
467
+ }
468
+ ```
469
+
470
+ ## Configuration Updates
471
+
472
+ ### Complete Replacement
473
+
474
+ **Config updates replace entire object:**
475
+
476
+ ```javascript
477
+ // Original config
478
+ const app = list_apps().find(a => a.name === 'My App')
479
+ console.log('Original config:', app.config)
480
+ // { workflowId: 'wf1', theme: 'dark', refreshInterval: 30 }
481
+
482
+ // Update config
483
+ update_app({
484
+ appId: app._id,
485
+ config: {
486
+ workflowId: 'wf2'
487
+ }
488
+ })
489
+
490
+ // New config (other properties lost!)
491
+ const updated = list_apps().find(a => a._id === app._id)
492
+ console.log('New config:', updated.config)
493
+ // { workflowId: 'wf2' } // theme and refreshInterval gone!
494
+ ```
495
+
496
+ ### Merge Strategy
497
+
498
+ **To preserve existing config, merge manually:**
499
+
500
+ ```javascript
501
+ // 1. Get current config
502
+ const app = list_apps().find(a => a.name === 'My App')
503
+ const currentConfig = app.config || {}
504
+
505
+ // 2. Merge with updates
506
+ const updatedConfig = {
507
+ ...currentConfig, // Keep existing
508
+ workflowId: 'new-wf-id', // Update this
509
+ newProperty: 'new-value' // Add this
510
+ }
511
+
512
+ // 3. Update app
513
+ update_app({
514
+ appId: app._id,
515
+ config: updatedConfig
516
+ })
517
+ ```
518
+
519
+ ### Nested Configuration
520
+
521
+ **Handle nested objects carefully:**
522
+
523
+ ```javascript
524
+ const app = list_apps().find(a => a.name === 'My App')
525
+
526
+ // Current config
527
+ const currentConfig = app.config || {}
528
+
529
+ // Update nested features
530
+ const updatedConfig = {
531
+ ...currentConfig,
532
+ features: {
533
+ ...(currentConfig.features || {}), // Keep existing features
534
+ exportEnabled: true // Update this feature
535
+ }
536
+ }
537
+
538
+ update_app({
539
+ appId: app._id,
540
+ config: updatedConfig
541
+ })
542
+ ```
543
+
544
+ ### Configuration Schema Example
545
+
546
+ **Typical app configuration:**
547
+
548
+ ```javascript
549
+ update_app({
550
+ appId: 'app-id',
551
+ config: {
552
+ // Workflow references
553
+ workflowId: 'primary-workflow-id',
554
+ secondaryWorkflowId: 'secondary-workflow-id',
555
+
556
+ // Display settings
557
+ defaultView: 'kanban', // 'table', 'kanban', 'calendar'
558
+ theme: 'dark', // 'light', 'dark', 'auto'
559
+ locale: 'en', // 'en', 'fi', 'sv'
560
+
561
+ // Behavior settings
562
+ refreshInterval: 60, // seconds
563
+ autoSave: true,
564
+ confirmDeletes: true,
565
+
566
+ // Feature flags
567
+ features: {
568
+ exportEnabled: true,
569
+ importEnabled: false,
570
+ notificationsEnabled: true,
571
+ advancedFilters: true
572
+ },
573
+
574
+ // Custom settings
575
+ customSettings: {
576
+ maxItems: 100,
577
+ defaultPriority: 'medium',
578
+ sortBy: 'dueDate'
579
+ }
580
+ }
581
+ })
582
+ ```
583
+
584
+ ## Best Practices
585
+
586
+ ### 1. Verify App Exists and Permissions
587
+
588
+ ```javascript
589
+ // Always verify before updating
590
+ const apps = list_apps()
591
+ const app = apps.find(a => a._id === 'target-id')
592
+
593
+ if (!app) {
594
+ console.error('App not found')
595
+ return
596
+ }
597
+
598
+ if (!app.canEdit) {
599
+ console.error('No permission to edit this app')
600
+ return
601
+ }
602
+
603
+ // Safe to update
604
+ update_app({
605
+ appId: app._id,
606
+ name: 'New Name'
607
+ })
608
+ ```
609
+
610
+ ### 2. Preserve Existing Config
611
+
612
+ ```javascript
613
+ // Don't lose existing config
614
+ const app = list_apps().find(a => a._id === 'app-id')
615
+
616
+ // Bad: Replaces entire config
617
+ update_app({
618
+ appId: app._id,
619
+ config: { workflowId: 'new-id' } // Loses other settings
620
+ })
621
+
622
+ // Good: Merge with existing
623
+ update_app({
624
+ appId: app._id,
625
+ config: {
626
+ ...app.config,
627
+ workflowId: 'new-id' // Updates this, keeps others
628
+ }
629
+ })
630
+ ```
631
+
632
+ ### 3. Use Descriptive Names
633
+
634
+ ```javascript
635
+ // Good names
636
+ update_app({
637
+ appId: 'app-id',
638
+ name: 'Task Manager (Dev)'
639
+ })
640
+
641
+ update_app({
642
+ appId: 'app-id',
643
+ name: 'Customer Portal - Production'
644
+ })
645
+
646
+ // Bad names
647
+ update_app({
648
+ appId: 'app-id',
649
+ name: 'App 1' // Not descriptive
650
+ })
651
+ ```
652
+
653
+ ### 4. Update After Workflow Changes
654
+
655
+ ```javascript
656
+ // Workflow was replaced, update apps using it
657
+ const oldWorkflowId = 'old-workflow-id'
658
+ const newWorkflowId = 'new-workflow-id'
659
+
660
+ const apps = list_apps()
661
+ const appsUsingOldWorkflow = apps.filter(a =>
662
+ a.config?.workflowId === oldWorkflowId
663
+ )
664
+
665
+ appsUsingOldWorkflow.forEach(app => {
666
+ update_app({
667
+ appId: app._id,
668
+ config: {
669
+ ...app.config,
670
+ workflowId: newWorkflowId
671
+ }
672
+ })
673
+ console.log(`✅ Updated ${app.name}`)
674
+ })
675
+ ```
676
+
677
+ ### 5. Document Configuration Changes
678
+
679
+ ```javascript
680
+ // Log configuration updates
681
+ console.log('Updating app configuration:')
682
+ console.log('App:', app.name)
683
+ console.log('Old config:', JSON.stringify(app.config, null, 2))
684
+
685
+ update_app({
686
+ appId: app._id,
687
+ config: newConfig
688
+ })
689
+
690
+ console.log('New config:', JSON.stringify(newConfig, null, 2))
691
+ console.log('Updated:', new Date().toISOString())
692
+ ```
693
+
694
+ ### 6. Test After Configuration Updates
695
+
696
+ ```javascript
697
+ // Update config
698
+ update_app({
699
+ appId: 'app-id',
700
+ config: {
701
+ workflowId: 'new-workflow-id'
702
+ }
703
+ })
704
+
705
+ console.log('✅ Configuration updated')
706
+ console.log('⚠️ Test app in Hailer to verify changes')
707
+ console.log('⚠️ Users may need to refresh browser')
708
+ ```
709
+
710
+ ### 7. Separate Dev and Prod Configs
711
+
712
+ ```javascript
713
+ // Different configs for different environments
714
+ const devConfig = {
715
+ workflowId: 'test-workflow-id',
716
+ apiUrl: 'http://localhost:1337',
717
+ debugMode: true
718
+ }
719
+
720
+ const prodConfig = {
721
+ workflowId: 'prod-workflow-id',
722
+ apiUrl: 'https://api.hailer.com',
723
+ debugMode: false
724
+ }
725
+
726
+ // Update dev app
727
+ update_app({
728
+ appId: 'dev-app-id',
729
+ config: devConfig
730
+ })
731
+
732
+ // Update prod app
733
+ update_app({
734
+ appId: 'prod-app-id',
735
+ config: prodConfig
736
+ })
737
+ ```
738
+
739
+ ## Troubleshooting
740
+
741
+ ### Error: "Permission Denied"
742
+
743
+ **Cause:** Not app owner or workspace administrator.
744
+
745
+ **Solution:**
746
+
747
+ ```javascript
748
+ // Check permissions
749
+ const app = list_apps().find(a => a._id === 'app-id')
750
+
751
+ console.log('Owner:', app.isOwner)
752
+ console.log('Admin:', app.isAdmin)
753
+ console.log('Can edit:', app.canEdit)
754
+
755
+ if (!app.canEdit) {
756
+ console.error('No permission to edit this app')
757
+ console.log('Contact app owner:', app.owner)
758
+ }
759
+ ```
760
+
761
+ ### Error: "App Not Found"
762
+
763
+ **Cause:** Invalid app ID or app doesn't exist.
764
+
765
+ **Solution:**
766
+
767
+ ```javascript
768
+ // Verify app ID
769
+ const apps = list_apps()
770
+ const app = apps.find(a => a._id === 'target-id')
771
+
772
+ if (!app) {
773
+ console.error('App not found')
774
+ console.log('Available apps:')
775
+ apps.forEach(a => console.log(`- ${a.name}: ${a._id}`))
776
+ }
777
+ ```
778
+
779
+ ### Changes Not Visible
780
+
781
+ **Causes:**
782
+ 1. Browser cache
783
+ 2. App needs refresh
784
+ 3. Wrong app updated
785
+
786
+ **Solutions:**
787
+
788
+ ```javascript
789
+ // 1. Verify update
790
+ const apps = list_apps()
791
+ const app = apps.find(a => a._id === 'app-id')
792
+ console.log('Current name:', app.name)
793
+ console.log('Current config:', app.config)
794
+
795
+ // 2. Refresh browser
796
+ console.log('⚠️ Refresh Hailer in browser to see changes')
797
+
798
+ // 3. Check correct app
799
+ console.log('App ID:', app._id)
800
+ console.log('Type:', app.url ? 'Dev' : 'Published')
801
+ ```
802
+
803
+ ### Config Lost After Update
804
+
805
+ **Cause:** Config was replaced, not merged.
806
+
807
+ **Solution:**
808
+
809
+ ```javascript
810
+ // Get app before update
811
+ const app = list_apps().find(a => a._id === 'app-id')
812
+ console.log('Original config:', app.config)
813
+
814
+ // If config was lost, restore it
815
+ const restoredConfig = {
816
+ workflowId: 'workflow-id',
817
+ theme: 'dark',
818
+ // ... restore other properties
819
+ }
820
+
821
+ update_app({
822
+ appId: app._id,
823
+ config: restoredConfig
824
+ })
825
+ ```
826
+
827
+ ### Cannot Change App Type
828
+
829
+ **Problem:** Want to convert dev to published or vice versa.
830
+
831
+ **Solution:**
832
+
833
+ ```javascript
834
+ // Cannot convert - must create new app
835
+
836
+ // 1. Get current app config
837
+ const devApp = list_apps().find(a => a.name === 'My App (Dev)')
838
+
839
+ // 2. Create new published app
840
+ const prodApp = create_app({
841
+ name: 'My App',
842
+ config: devApp.config // Use same config
843
+ })
844
+
845
+ // 3. Update manifest.json with new appId
846
+ // 4. Republish
847
+
848
+ console.log('New published app ID:', prodApp.appId)
849
+ console.log('⚠️ Update manifest.json and republish')
850
+ ```
851
+
852
+ ## Integration with Other Tools
853
+
854
+ ### With create_app
855
+
856
+ Create then update:
857
+
858
+ ```javascript
859
+ // 1. Create basic app
860
+ const app = create_app({
861
+ name: 'My App'
862
+ })
863
+
864
+ // 2. Update with full details
865
+ update_app({
866
+ appId: app.appId,
867
+ description: 'Complete app description',
868
+ config: {
869
+ workflowId: 'workflow-id',
870
+ theme: 'dark'
871
+ }
872
+ })
873
+ ```
874
+
875
+ ### With list_apps
876
+
877
+ Find and update:
878
+
879
+ ```javascript
880
+ // 1. List apps
881
+ const apps = list_apps()
882
+
883
+ // 2. Find target
884
+ const app = apps.find(a => a.name === 'Old Name')
885
+
886
+ // 3. Update
887
+ if (app) {
888
+ update_app({
889
+ appId: app._id,
890
+ name: 'New Name'
891
+ })
892
+ }
893
+ ```
894
+
895
+ ### With publish_hailer_app
896
+
897
+ Update config then republish:
898
+
899
+ ```javascript
900
+ // 1. Update app config
901
+ update_app({
902
+ appId: 'app-id',
903
+ config: {
904
+ workflowId: 'new-workflow-id'
905
+ }
906
+ })
907
+
908
+ // 2. App code may need to use new config
909
+ // Edit app code if needed
910
+
911
+ // 3. Republish
912
+ publish_hailer_app({
913
+ email: 'your@email.com',
914
+ password: 'password',
915
+ projectDirectory: '/path/to/app'
916
+ })
917
+ ```
918
+
919
+ ### With remove_app
920
+
921
+ Update vs remove decision:
922
+
923
+ ```javascript
924
+ const app = list_apps().find(a => a.name === 'Old App')
925
+
926
+ // Option 1: Update to repurpose
927
+ update_app({
928
+ appId: app._id,
929
+ name: 'New Purpose App',
930
+ description: 'Repurposed for new use case',
931
+ config: { ... }
932
+ })
933
+
934
+ // Option 2: Remove and create new
935
+ remove_app({ appId: app._id })
936
+ create_app({ name: 'Brand New App' })
937
+ ```
938
+
939
+ ## Summary
940
+
941
+ **Key Takeaways:**
942
+ 1. ✏️ **Updates metadata** - Name, description, config
943
+ 2. 🔒 **Owner/admin only** - Requires permissions
944
+ 3. ⚡ **Immediate effect** - Changes apply right away
945
+ 4. ⚠️ **Config replacement** - Entire config replaced, merge manually
946
+ 5. 🔄 **Non-destructive** - Doesn't affect app code
947
+ 6. 🚫 **Cannot change type** - Dev stays dev, published stays published
948
+ 7. 📱 **May need refresh** - Users should refresh browser
949
+
950
+ **Quick Decision Tree:**
951
+
952
+ ```
953
+ Need to modify app?
954
+
955
+ ├─ Change name/description? → update_app
956
+ ├─ Update configuration? → update_app (merge with existing)
957
+ ├─ Change dev URL? → update_app
958
+ ├─ Update app code? → publish_hailer_app (not update_app)
959
+ ├─ Change permissions? → add_app_member/remove_app_member
960
+ └─ Convert type? → Create new app (can't convert)
961
+ ```
962
+
963
+ ## Additional Resources
964
+
965
+ - See `create-app-skill` for creating apps
966
+ - See `list-apps-skill` for viewing apps
967
+ - See `remove-app-skill` for deleting apps
968
+ - See `publish-hailer-app-skill` for publishing app code
969
+ - See `add-app-member-skill` for sharing apps
970
+ - See `app-api` skill for comprehensive App API documentation