@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,985 @@
1
+ ---
2
+ name: Removing Hailer Apps
3
+ description: Complete guide for safely removing Hailer apps - use when deleting apps or cleaning up workspace
4
+ ---
5
+
6
+ # Removing Hailer Apps - Complete Guide
7
+
8
+ Complete reference for safely removing Hailer apps using the `remove_app` MCP tool.
9
+
10
+ ## Table of Contents
11
+ 1. [Quick Reference](#quick-reference)
12
+ 2. [Overview](#overview)
13
+ 3. [What Gets Deleted](#what-gets-deleted)
14
+ 4. [Prerequisites](#prerequisites)
15
+ 5. [Basic Usage](#basic-usage)
16
+ 6. [Safety Checklist](#safety-checklist)
17
+ 7. [Common Scenarios](#common-scenarios)
18
+ 8. [Before Removing](#before-removing)
19
+ 9. [After Removing](#after-removing)
20
+ 10. [Best Practices](#best-practices)
21
+ 11. [Troubleshooting](#troubleshooting)
22
+
23
+ ## Quick Reference
24
+
25
+ **⚠️ WARNING: This operation is PERMANENT and CANNOT be undone!**
26
+
27
+ **Basic Removal:**
28
+
29
+ ```javascript
30
+ remove_app({
31
+ appId: 'app-id'
32
+ })
33
+ ```
34
+
35
+ **Remove in Specific Workspace:**
36
+
37
+ ```javascript
38
+ remove_app({
39
+ workspaceId: 'workspace-id',
40
+ appId: 'app-id'
41
+ })
42
+ ```
43
+
44
+ **Response:**
45
+ ```
46
+ ✅ App Removed Successfully
47
+
48
+ App ID: app-id
49
+ Workspace: workspace-id
50
+
51
+ ⚠️ App entry permanently deleted
52
+ ```
53
+
54
+ **Key Requirements:**
55
+ - Must be app owner OR workspace administrator
56
+ - App ID must be valid
57
+ - Cannot be undone - app entry permanently deleted
58
+ - Deployed app files remain but are inaccessible
59
+ - Associated discussion also deleted
60
+
61
+ ## Overview
62
+
63
+ The `remove_app` tool permanently deletes a Hailer app entry from your workspace. This is a **destructive operation** that removes the app database record and makes the app inaccessible.
64
+
65
+ **Think of it as:**
66
+ - Uninstalling an app
67
+ - Removing app from workspace
68
+ - Deleting app entry
69
+ - Permanent deletion
70
+
71
+ **When to use:**
72
+ - Cleaning up test/development apps
73
+ - Removing obsolete apps
74
+ - Deleting unused apps
75
+ - Workspace reorganization
76
+ - Removing broken app entries
77
+
78
+ **When NOT to use:**
79
+ - If users still need the app
80
+ - If you might want to restore it later
81
+ - For temporary deactivation (no such option exists)
82
+ - If app contains important data
83
+
84
+ ## What Gets Deleted
85
+
86
+ ### 1. App Entry
87
+ - App database record
88
+ - App name and description
89
+ - App configuration
90
+ - App metadata (created date, owner)
91
+ - App URL (for dev apps)
92
+ - App icon/image reference
93
+
94
+ ### 2. App Permissions
95
+ - Access control list
96
+ - Member list (who had access)
97
+ - Sharing settings
98
+
99
+ ### 3. Associated Discussion
100
+ - Discussion thread linked to app
101
+ - Discussion messages
102
+ - Discussion participants
103
+
104
+ ### What Does NOT Get Deleted
105
+ - Deployed app files (remain on server but inaccessible)
106
+ - Source code (your local files unaffected)
107
+ - Workflows referenced by app (workflows remain intact)
108
+ - Users who had access (user accounts unaffected)
109
+ - Other apps in workspace (unaffected)
110
+
111
+ ### Important Notes
112
+
113
+ **Published apps:**
114
+ - Deployed files remain on Hailer servers
115
+ - Files become inaccessible without app entry
116
+ - Cannot access or update deployed code
117
+ - Must republish if you recreate app
118
+
119
+ **Development apps:**
120
+ - Local dev server unaffected
121
+ - Can continue running locally
122
+ - Just removes Hailer app entry
123
+ - Can recreate entry and continue development
124
+
125
+ ## Prerequisites
126
+
127
+ ### Required Permissions
128
+
129
+ **You can remove an app if:**
130
+ - You are the app owner/creator, OR
131
+ - You are a workspace administrator
132
+
133
+ **You CANNOT remove if:**
134
+ - You're not owner and not admin
135
+ - You only have access to the app
136
+ - App was shared with you
137
+
138
+ **Check permissions:**
139
+ ```javascript
140
+ const apps = list_apps()
141
+ const app = apps.find(a => a._id === 'target-id')
142
+
143
+ console.log('Can delete:', app.canDelete)
144
+ console.log('Owner:', app.isOwner)
145
+ console.log('Admin:', app.isAdmin)
146
+ ```
147
+
148
+ ### Required Information
149
+
150
+ **1. App ID**
151
+
152
+ Get from `list_apps`:
153
+ ```javascript
154
+ const apps = list_apps()
155
+ apps.forEach(a => {
156
+ console.log(`${a.name}: ${a._id}`)
157
+ })
158
+ ```
159
+
160
+ **2. Verify It's the Right App**
161
+
162
+ Check before removing:
163
+ ```javascript
164
+ const app = apps.find(a => a._id === 'target-id')
165
+ console.log('Name:', app.name)
166
+ console.log('Type:', app.url ? 'Dev' : 'Published')
167
+ console.log('Created:', app.created)
168
+ ```
169
+
170
+ ## Basic Usage
171
+
172
+ ### Example 1: Remove Simple App
173
+
174
+ ```javascript
175
+ // 1. Find app
176
+ const apps = list_apps()
177
+ const testApp = apps.find(a => a.name === 'Test App')
178
+
179
+ console.log('Found app:', testApp.name)
180
+ console.log('ID:', testApp._id)
181
+
182
+ // 2. Remove it
183
+ remove_app({
184
+ appId: testApp._id
185
+ })
186
+
187
+ console.log('✅ App removed')
188
+ ```
189
+
190
+ ### Example 2: Remove with Verification
191
+
192
+ ```javascript
193
+ // 1. List apps
194
+ const apps = list_apps()
195
+
196
+ // 2. Find target
197
+ const target = apps.find(a => a.name === 'Old App')
198
+
199
+ // 3. Verify details
200
+ console.log('About to remove:')
201
+ console.log('- Name:', target.name)
202
+ console.log('- ID:', target._id)
203
+ console.log('- Type:', target.url ? 'Dev' : 'Published')
204
+ console.log('- Created:', target.created)
205
+ console.log('- Owner:', target.isOwner ? 'You' : 'Someone else')
206
+
207
+ // 4. Confirm and remove
208
+ const confirmed = true // Your confirmation logic
209
+ if (confirmed && target.canDelete) {
210
+ remove_app({
211
+ appId: target._id
212
+ })
213
+ console.log('✅ Removed')
214
+ } else {
215
+ console.log('❌ Cannot remove or not confirmed')
216
+ }
217
+ ```
218
+
219
+ ### Example 3: Remove in Specific Workspace
220
+
221
+ ```javascript
222
+ remove_app({
223
+ workspaceId: 'workspace-id',
224
+ appId: 'app-id'
225
+ })
226
+ ```
227
+
228
+ ## ⚠️ MANDATORY: Comprehensive Confirmation Protocol
229
+
230
+ **BEFORE calling `remove_app`, you MUST gather complete context and show it to the user:**
231
+
232
+ ### Required Context to Gather
233
+
234
+ 1. **Workspace Information:**
235
+ - Workspace ID: Get from `list_apps` or API init
236
+ - Workspace name: Get from API init
237
+
238
+ 2. **App Information:**
239
+ - App ID (provided by user)
240
+ - App name: Get from `list_apps`
241
+ - App type: Development (has URL) or Published (no URL)
242
+ - Configuration details
243
+
244
+ 3. **What Will Be Deleted:**
245
+ - App entry (name, description, URL, metadata)
246
+ - App permissions
247
+ - App configuration
248
+
249
+ ### Required Confirmation Message Format
250
+
251
+ **You MUST display this information to the user BEFORE calling the tool:**
252
+
253
+ ```
254
+ ⚠️ WARNING: This action is irreversible!
255
+
256
+ You are about to permanently delete the following:
257
+
258
+ **Workspace**:
259
+ - Workspace ID: `<workspace-id>`
260
+ - Workspace name: <workspace-name>
261
+
262
+ **App to Delete**:
263
+ - Name: <app-name>
264
+ - ID: `<app-id>`
265
+ - Type: <Development/Published>
266
+
267
+ **What Will Be Deleted**:
268
+ - ❌ App entry (name, description, URL, metadata)
269
+ - ❌ App permissions
270
+ - ❌ App configuration
271
+
272
+ **What Won't Be Deleted**:
273
+ - Published app code remains on server (but becomes inaccessible)
274
+
275
+ **This operation cannot be undone. The app entry will be permanently lost.**
276
+
277
+ Do you want to proceed with permanently deleting this app?
278
+ ```
279
+
280
+ ### Example: Complete Safe Removal Flow
281
+
282
+ ```javascript
283
+ // Step 1: Gather complete context
284
+ const apps = list_apps()
285
+ const targetApp = apps.find(a => a._id === "target-id")
286
+ const workspaceName = "My Workspace" // From init or context
287
+
288
+ // Step 2: Show comprehensive confirmation message to user
289
+ console.log(`
290
+ ⚠️ WARNING: This action is irreversible!
291
+
292
+ **Workspace**:
293
+ - Workspace ID: \`${targetApp.workspaceId}\`
294
+ - Workspace name: ${workspaceName}
295
+
296
+ **App to Delete**:
297
+ - Name: ${targetApp.name}
298
+ - ID: \`${targetApp._id}\`
299
+ - Type: ${targetApp.url ? 'Development' : 'Published'}
300
+
301
+ **What Will Be Deleted**:
302
+ - ❌ App entry (name, description, URL, metadata)
303
+ - ❌ App permissions
304
+ - ❌ App configuration
305
+
306
+ **What Won't Be Deleted**:
307
+ - Published app code remains on server (but becomes inaccessible)
308
+
309
+ This operation cannot be undone.
310
+ `)
311
+
312
+ // Step 3: Wait for explicit user confirmation
313
+
314
+ // Step 4: Only after confirmation, call the tool
315
+ remove_app({ appId: targetApp._id })
316
+ ```
317
+
318
+ ### **FAILURE TO GATHER AND SHOW THIS CONTEXT IS AN ERROR**
319
+
320
+ If you call `remove_app` without first gathering and displaying all this information to the user, you are violating safety protocols.
321
+
322
+ ## Safety Checklist
323
+
324
+ **Before removing ANY app, complete this checklist:**
325
+
326
+ ### Step 1: Identify the App
327
+ - [ ] Confirmed app name with `list_apps`
328
+ - [ ] Verified app ID is correct
329
+ - [ ] Checked app type (dev vs published)
330
+ - [ ] Reviewed app description/purpose
331
+
332
+ ### Step 2: Check Usage
333
+ - [ ] Verified no active users depend on this app
334
+ - [ ] Checked if app is in production use
335
+ - [ ] Confirmed app not referenced in documentation
336
+ - [ ] Asked team if app still needed
337
+
338
+ ### Step 3: Check Permissions
339
+ - [ ] Confirmed you are owner or admin
340
+ - [ ] Verified you have delete permission
341
+ - [ ] No organizational policies prevent removal
342
+
343
+ ### Step 4: Backup (If Needed)
344
+ - [ ] Saved app configuration
345
+ - [ ] Documented app settings
346
+ - [ ] Backed up app code (if published)
347
+ - [ ] Noted app ID for records
348
+
349
+ ### Step 5: Consider Alternatives
350
+ - [ ] Considered updating instead of removing
351
+ - [ ] Evaluated removing members instead
352
+ - [ ] Checked if temporary deactivation better
353
+ - [ ] Verified removal is only option
354
+
355
+ ### Step 6: Final Confirmation
356
+ - [ ] Double-checked app ID one more time
357
+ - [ ] Confirmed this is intended app
358
+ - [ ] Accepted that this cannot be undone
359
+ - [ ] Ready to proceed
360
+
361
+ ## Common Scenarios
362
+
363
+ ### Scenario 1: Clean Up Test Apps
364
+
365
+ **Goal:** Remove test apps created during development.
366
+
367
+ ```javascript
368
+ const apps = list_apps()
369
+
370
+ // Find test apps
371
+ const testApps = apps.filter(a =>
372
+ (a.name.toLowerCase().includes('test') ||
373
+ a.name.toLowerCase().includes('demo') ||
374
+ a.name.startsWith('TMP')) &&
375
+ a.isOwner
376
+ )
377
+
378
+ console.log(`Found ${testApps.length} test apps`)
379
+
380
+ // Remove each
381
+ testApps.forEach(app => {
382
+ console.log(`Removing: ${app.name}`)
383
+ remove_app({ appId: app._id })
384
+ })
385
+
386
+ console.log('✅ Test apps cleaned up')
387
+ ```
388
+
389
+ ### Scenario 2: Remove Old Dev Apps
390
+
391
+ **Goal:** Clean up old development app entries.
392
+
393
+ ```javascript
394
+ const apps = list_apps()
395
+ const devApps = apps.filter(a => a.url && a.isOwner)
396
+
397
+ console.log(`Found ${devApps.length} dev apps`)
398
+
399
+ // Check age
400
+ devApps.forEach(app => {
401
+ const created = new Date(app.created)
402
+ const daysOld = (Date.now() - created) / 1000 / 60 / 60 / 24
403
+
404
+ console.log(`${app.name}: ${daysOld.toFixed(0)} days old`)
405
+
406
+ if (daysOld > 30) {
407
+ console.log(` Removing old dev app`)
408
+ remove_app({ appId: app._id })
409
+ }
410
+ })
411
+ ```
412
+
413
+ ### Scenario 3: Remove After Deployment
414
+
415
+ **Goal:** Remove dev app after deploying to production.
416
+
417
+ ```javascript
418
+ // After successful production deployment
419
+
420
+ // 1. Verify prod app works
421
+ const apps = list_apps()
422
+ const prodApp = apps.find(a => a.name === 'My App')
423
+
424
+ if (!prodApp) {
425
+ console.error('Production app not found!')
426
+ return
427
+ }
428
+
429
+ console.log('✅ Production app exists:', prodApp._id)
430
+
431
+ // 2. Find dev app
432
+ const devApp = apps.find(a => a.name === 'My App (Dev)')
433
+
434
+ if (devApp) {
435
+ console.log('Removing dev app:', devApp._id)
436
+ remove_app({ appId: devApp._id })
437
+ console.log('✅ Dev app removed')
438
+ }
439
+ ```
440
+
441
+ ### Scenario 4: Remove Duplicate Apps
442
+
443
+ **Goal:** Clean up duplicate app entries.
444
+
445
+ ```javascript
446
+ const apps = list_apps()
447
+
448
+ // Find duplicates by name
449
+ const nameGroups = {}
450
+ apps.forEach(app => {
451
+ const baseName = app.name.replace(/\s*\(Dev\)\s*/i, '')
452
+ if (!nameGroups[baseName]) nameGroups[baseName] = []
453
+ nameGroups[baseName].push(app)
454
+ })
455
+
456
+ // Show duplicates
457
+ Object.entries(nameGroups).forEach(([name, apps]) => {
458
+ if (apps.length > 1) {
459
+ console.log(`\nDuplicate: ${name}`)
460
+ apps.forEach((app, i) => {
461
+ console.log(`${i + 1}. ${app.name} (${app._id})`)
462
+ console.log(` Created: ${app.created}`)
463
+ console.log(` Type: ${app.url ? 'Dev' : 'Published'}`)
464
+ })
465
+
466
+ // Remove older duplicates (keep newest)
467
+ const sorted = [...apps].sort((a, b) =>
468
+ new Date(b.created) - new Date(a.created)
469
+ )
470
+
471
+ sorted.slice(1).forEach(app => {
472
+ console.log(`Removing duplicate: ${app.name}`)
473
+ // remove_app({ appId: app._id })
474
+ })
475
+ }
476
+ })
477
+ ```
478
+
479
+ ### Scenario 5: Remove Broken App Entry
480
+
481
+ **Goal:** Remove app entry that references non-existent code.
482
+
483
+ ```javascript
484
+ // App entry exists but deployed files missing/broken
485
+
486
+ const apps = list_apps()
487
+ const brokenApp = apps.find(a => a.name === 'Broken App')
488
+
489
+ if (!brokenApp) {
490
+ console.log('App not found')
491
+ return
492
+ }
493
+
494
+ console.log('Removing broken app entry')
495
+ console.log('App ID:', brokenApp._id)
496
+ console.log('Note: Deployed files cannot be recovered')
497
+
498
+ remove_app({
499
+ appId: brokenApp._id
500
+ })
501
+
502
+ console.log('✅ Broken app entry removed')
503
+ console.log('💡 Create new app entry and republish if needed')
504
+ ```
505
+
506
+ ### Scenario 6: Batch Remove by Criteria
507
+
508
+ **Goal:** Remove multiple apps matching criteria.
509
+
510
+ ```javascript
511
+ const apps = list_apps()
512
+
513
+ // Define removal criteria
514
+ const shouldRemove = (app) => {
515
+ // Remove if:
516
+ // - It's a dev app AND
517
+ // - You own it AND
518
+ // - It's older than 60 days
519
+ if (!app.url || !app.isOwner) return false
520
+
521
+ const created = new Date(app.created)
522
+ const daysOld = (Date.now() - created) / 1000 / 60 / 60 / 24
523
+
524
+ return daysOld > 60
525
+ }
526
+
527
+ // Find apps to remove
528
+ const toRemove = apps.filter(shouldRemove)
529
+
530
+ console.log(`Found ${toRemove.length} apps to remove`)
531
+
532
+ // Review before removing
533
+ toRemove.forEach(app => {
534
+ console.log(`- ${app.name} (${app.created})`)
535
+ })
536
+
537
+ // Confirm and remove
538
+ const confirmed = true // Your confirmation
539
+ if (confirmed) {
540
+ toRemove.forEach(app => {
541
+ remove_app({ appId: app._id })
542
+ console.log(`✅ Removed: ${app.name}`)
543
+ })
544
+ }
545
+ ```
546
+
547
+ ## Before Removing
548
+
549
+ ### Export App Configuration
550
+
551
+ ```javascript
552
+ const apps = list_apps()
553
+ const target = apps.find(a => a._id === 'target-id')
554
+
555
+ // Save app details
556
+ const backup = {
557
+ name: target.name,
558
+ description: target.description,
559
+ url: target.url,
560
+ config: target.config,
561
+ created: target.created,
562
+ exportDate: new Date().toISOString()
563
+ }
564
+
565
+ console.log('App backup:')
566
+ console.log(JSON.stringify(backup, null, 2))
567
+
568
+ // Save to file or document
569
+ // saveToFile('app-backup.json', JSON.stringify(backup, null, 2))
570
+ ```
571
+
572
+ ### Document App Purpose
573
+
574
+ ```javascript
575
+ const app = apps.find(a => a._id === 'target-id')
576
+
577
+ console.log('App Removal Documentation:')
578
+ console.log('-------------------------')
579
+ console.log('App Name:', app.name)
580
+ console.log('App ID:', app._id)
581
+ console.log('Type:', app.url ? 'Development' : 'Published')
582
+ console.log('Created:', app.created)
583
+ console.log('Removal Reason:', 'No longer needed')
584
+ console.log('Removed By:', 'admin-name')
585
+ console.log('Removal Date:', new Date().toISOString())
586
+ console.log('Configuration:', JSON.stringify(app.config, null, 2))
587
+ ```
588
+
589
+ ### Check Dependencies
590
+
591
+ ```javascript
592
+ // Check if app is actively used
593
+ const app = apps.find(a => a._id === 'target-id')
594
+
595
+ console.log('App Usage Check:')
596
+ console.log('- Name:', app.name)
597
+ console.log('- Members:', app.members.length)
598
+ console.log('- Type:', app.url ? 'Dev (local only)' : 'Published (workspace)')
599
+
600
+ if (!app.url && app.members.length > 0) {
601
+ console.warn('⚠️ Published app with members - may be actively used')
602
+ }
603
+ ```
604
+
605
+ ## After Removing
606
+
607
+ ### Verify Removal
608
+
609
+ ```javascript
610
+ // 1. Remove app
611
+ remove_app({ appId: 'removed-id' })
612
+
613
+ // 2. Verify it's gone
614
+ const apps = list_apps()
615
+ const stillExists = apps.find(a => a._id === 'removed-id')
616
+
617
+ if (stillExists) {
618
+ console.error('❌ App still exists!')
619
+ } else {
620
+ console.log('✅ App successfully removed')
621
+ }
622
+ ```
623
+
624
+ ### Clean Up Local Files
625
+
626
+ **For development apps:**
627
+ ```bash
628
+ # Optional: Clean up local project files
629
+ cd /path/to/app-directory
630
+ rm -rf node_modules
631
+ rm -rf dist
632
+
633
+ # Or remove entire directory
634
+ cd ..
635
+ rm -rf app-directory
636
+ ```
637
+
638
+ **For published apps:**
639
+ - Deployed files remain on Hailer servers but are inaccessible
640
+ - Cannot clean up deployed files
641
+ - Must contact Hailer support if cleanup needed
642
+
643
+ ### Update Documentation
644
+
645
+ After removing apps:
646
+ - Update workspace documentation
647
+ - Remove app references from guides
648
+ - Update team training materials
649
+ - Document removal reason and date
650
+ - Update app inventory lists
651
+
652
+ ## Best Practices
653
+
654
+ ### 1. Always Verify Before Removing
655
+
656
+ ```javascript
657
+ // Bad: Remove without checking
658
+ remove_app({ appId: 'some-id' })
659
+
660
+ // Good: Verify first
661
+ const apps = list_apps()
662
+ const app = apps.find(a => a._id === 'some-id')
663
+
664
+ if (!app) {
665
+ console.error('App not found')
666
+ return
667
+ }
668
+
669
+ console.log('Removing:', app.name)
670
+ console.log('Type:', app.url ? 'Dev' : 'Published')
671
+
672
+ if (app.canDelete) {
673
+ remove_app({ appId: app._id })
674
+ } else {
675
+ console.error('No permission to delete')
676
+ }
677
+ ```
678
+
679
+ ### 2. Backup Configuration Before Removing
680
+
681
+ ```javascript
682
+ // Always backup important app configs
683
+ const app = apps.find(a => a._id === 'target-id')
684
+
685
+ const backup = {
686
+ name: app.name,
687
+ config: app.config,
688
+ // ... other properties
689
+ }
690
+
691
+ console.log('Backup:', JSON.stringify(backup, null, 2))
692
+
693
+ // Then remove
694
+ remove_app({ appId: app._id })
695
+ ```
696
+
697
+ ### 3. Use Descriptive Names for Easy Identification
698
+
699
+ Makes cleanup safer:
700
+ - ✅ "Task Manager (Dev) - Can Delete"
701
+ - ✅ "TEST - Demo App"
702
+ - ✅ "DEPRECATED - Old Dashboard"
703
+ - ❌ "App 1"
704
+ - ❌ "Test"
705
+
706
+ ### 4. Remove Development Apps Promptly
707
+
708
+ ```javascript
709
+ // Regular cleanup of old dev apps
710
+ function cleanupOldDevApps(maxAgeDays = 30) {
711
+ const apps = list_apps()
712
+ const devApps = apps.filter(a => a.url && a.isOwner)
713
+
714
+ devApps.forEach(app => {
715
+ const created = new Date(app.created)
716
+ const daysOld = (Date.now() - created) / 1000 / 60 / 60 / 24
717
+
718
+ if (daysOld > maxAgeDays) {
719
+ console.log(`Removing old dev app: ${app.name} (${daysOld.toFixed(0)} days)`)
720
+ remove_app({ appId: app._id })
721
+ }
722
+ })
723
+ }
724
+
725
+ // Run monthly
726
+ cleanupOldDevApps(30)
727
+ ```
728
+
729
+ ### 5. Communicate Before Removing Shared Apps
730
+
731
+ ```javascript
732
+ const app = apps.find(a => a._id === 'target-id')
733
+
734
+ // Check if app is shared
735
+ const isShared = app.members.some(m => m.startsWith('network_'))
736
+
737
+ if (isShared && !app.url) {
738
+ console.warn('⚠️ Published app shared with workspace')
739
+ console.warn('⚠️ Notify users before removing')
740
+ console.warn('Members:', app.members.length)
741
+
742
+ // Send notification
743
+ // Post in workspace discussion
744
+ // Wait for confirmation before removing
745
+ }
746
+ ```
747
+
748
+ ### 6. Keep Production Apps, Remove Dev Versions
749
+
750
+ ```javascript
751
+ // After deploying to production
752
+ const apps = list_apps()
753
+
754
+ // Keep published app
755
+ const prodApp = apps.find(a => a.name === 'My App' && !a.url)
756
+
757
+ // Remove dev app
758
+ const devApp = apps.find(a => a.name === 'My App (Dev)' && a.url)
759
+
760
+ if (prodApp && devApp) {
761
+ console.log('Prod app exists, removing dev app')
762
+ remove_app({ appId: devApp._id })
763
+ }
764
+ ```
765
+
766
+ ### 7. Document Removal
767
+
768
+ ```javascript
769
+ // Log removals for audit trail
770
+ console.log({
771
+ action: 'remove_app',
772
+ appId: 'app-id',
773
+ appName: 'App Name',
774
+ reason: 'No longer needed',
775
+ date: new Date().toISOString(),
776
+ removedBy: 'user-id'
777
+ })
778
+ ```
779
+
780
+ ## Troubleshooting
781
+
782
+ ### Error: "Permission Denied"
783
+
784
+ **Cause:** Not app owner or workspace administrator.
785
+
786
+ **Solution:**
787
+
788
+ ```javascript
789
+ const app = list_apps().find(a => a._id === 'app-id')
790
+
791
+ console.log('Owner:', app.isOwner)
792
+ console.log('Admin:', app.isAdmin)
793
+ console.log('Can delete:', app.canDelete)
794
+
795
+ if (!app.canDelete) {
796
+ console.error('Cannot remove - not owner or admin')
797
+ console.log('Owner:', app.owner)
798
+ console.log('Contact owner or workspace admin')
799
+ }
800
+ ```
801
+
802
+ ### Error: "App Not Found"
803
+
804
+ **Cause:** Invalid app ID or already deleted.
805
+
806
+ **Solution:**
807
+
808
+ ```javascript
809
+ // List all apps
810
+ const apps = list_apps()
811
+ console.log('Available apps:')
812
+ apps.forEach(a => {
813
+ console.log(`- ${a.name}: ${a._id}`)
814
+ })
815
+
816
+ // Use correct ID
817
+ remove_app({ appId: 'correct-id' })
818
+ ```
819
+
820
+ ### App Removed But Still Accessible
821
+
822
+ **Problem:** App removed but files still loading.
823
+
824
+ **Explanation:**
825
+ - Deployed files remain on server
826
+ - Browser may have cached files
827
+ - App won't load after cache expires
828
+
829
+ **Solution:**
830
+ ```javascript
831
+ console.log('✅ App entry removed successfully')
832
+ console.log('ℹ️ Deployed files may remain on server')
833
+ console.log('ℹ️ Browser cache will expire')
834
+ console.log('ℹ️ App will not be accessible after cache clears')
835
+ ```
836
+
837
+ ### Accidentally Removed Wrong App
838
+
839
+ **Reality Check:** **Cannot be undone.**
840
+
841
+ **Mitigation:**
842
+
843
+ 1. **If you have backup:**
844
+ ```javascript
845
+ // Recreate app entry
846
+ const newApp = create_app({
847
+ name: backup.name,
848
+ description: backup.description,
849
+ config: backup.config,
850
+ url: backup.url // For dev apps
851
+ })
852
+
853
+ console.log('New app ID:', newApp.appId)
854
+ console.log('⚠️ This is a NEW app with different ID')
855
+ console.log('⚠️ Must update manifest.json')
856
+ console.log('⚠️ Must republish if it was published app')
857
+ ```
858
+
859
+ 2. **If no backup:**
860
+ - App entry permanently lost
861
+ - Must recreate from scratch
862
+ - Lost configuration and settings
863
+ - Implement backup procedures
864
+
865
+ 3. **Prevention:**
866
+ - Always verify app ID
867
+ - Use descriptive names
868
+ - Export config before removal
869
+ - Test in development workspace
870
+
871
+ ### Cannot Find App to Remove
872
+
873
+ **Cause:** App in different workspace or already removed.
874
+
875
+ **Solution:**
876
+
877
+ ```javascript
878
+ // Check current workspace
879
+ const workspace = get_current_workspace()
880
+ console.log('Current workspace:', workspace.name)
881
+
882
+ // List apps
883
+ const apps = list_apps()
884
+ console.log(`Found ${apps.length} apps`)
885
+
886
+ // Search by name
887
+ const found = apps.find(a =>
888
+ a.name.toLowerCase().includes('search term')
889
+ )
890
+
891
+ if (found) {
892
+ console.log('Found:', found._id)
893
+ } else {
894
+ console.log('Not found in current workspace')
895
+ }
896
+ ```
897
+
898
+ ## Integration with Other Tools
899
+
900
+ ### With create_app
901
+
902
+ Replace pattern:
903
+
904
+ ```javascript
905
+ // 1. Remove old app
906
+ remove_app({ appId: 'old-app-id' })
907
+
908
+ // 2. Create new app
909
+ const newApp = create_app({
910
+ name: 'New App',
911
+ config: { ... }
912
+ })
913
+
914
+ // 3. Update manifest.json with new appId
915
+ console.log('New app ID:', newApp.appId)
916
+ ```
917
+
918
+ ### With list_apps
919
+
920
+ Find and remove:
921
+
922
+ ```javascript
923
+ // 1. List apps
924
+ const apps = list_apps()
925
+
926
+ // 2. Find target
927
+ const target = apps.find(a => a.name === 'Old App')
928
+
929
+ // 3. Remove
930
+ if (target && target.canDelete) {
931
+ remove_app({ appId: target._id })
932
+ }
933
+ ```
934
+
935
+ ### With update_app
936
+
937
+ Update vs remove decision:
938
+
939
+ ```javascript
940
+ const app = apps.find(a => a._id === 'app-id')
941
+
942
+ // Option 1: Update to repurpose
943
+ update_app({
944
+ appId: app._id,
945
+ name: 'Repurposed App',
946
+ config: { ... }
947
+ })
948
+
949
+ // Option 2: Remove and create new
950
+ remove_app({ appId: app._id })
951
+ create_app({ name: 'Brand New App' })
952
+ ```
953
+
954
+ ## Summary
955
+
956
+ **Key Takeaways:**
957
+ 1. ⚠️ **Permanent deletion** - Cannot be undone
958
+ 2. 🔒 **Owner/admin only** - Requires permissions
959
+ 3. 🗑️ **Removes entry** - App database record deleted
960
+ 4. 💾 **Backup first** - Save configuration if important
961
+ 5. ✅ **Verify twice** - Double-check app ID
962
+ 6. 📢 **Communicate** - Notify users for shared apps
963
+ 7. 🔄 **Files remain** - Deployed files stay but inaccessible
964
+
965
+ **Quick Decision Tree:**
966
+
967
+ ```
968
+ Need to remove app?
969
+
970
+ ├─ Test/dev app? → Remove immediately
971
+ ├─ Production app? → Notify users first
972
+ ├─ Might need later? → Backup config first
973
+ ├─ Wrong app? → Verify ID carefully
974
+ ├─ Duplicate apps? → Keep newest, remove others
975
+ └─ Sure about removal? → Verify permissions and remove
976
+ ```
977
+
978
+ ## Additional Resources
979
+
980
+ - See `create-app-skill` for creating apps
981
+ - See `list-apps-skill` for viewing apps
982
+ - See `update-app-skill` for modifying apps
983
+ - See `add-app-member-skill` for sharing apps
984
+ - See `remove-app-member-skill` for revoking access
985
+ - See `app-api` skill for comprehensive App API documentation