@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.
- package/.claude/commands/tool-builder.md +37 -0
- package/.claude/commands/ws-pull.md +44 -0
- package/.claude/settings.json +8 -0
- package/.claude/settings.local.json +49 -0
- package/.claude/skills/activity-api/SKILL.md +96 -0
- package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
- package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
- package/.claude/skills/agent-building/SKILL.md +243 -0
- package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
- package/.claude/skills/agent-building/references/code-examples.md +587 -0
- package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
- package/.claude/skills/app-api/SKILL.md +219 -0
- package/.claude/skills/app-api/references/app-endpoints.md +759 -0
- package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
- package/.claude/skills/create-app-skill/SKILL.md +1101 -0
- package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
- package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
- package/.claude/skills/hailer-api/SKILL.md +283 -0
- package/.claude/skills/hailer-api/references/activities.md +620 -0
- package/.claude/skills/hailer-api/references/authentication.md +216 -0
- package/.claude/skills/hailer-api/references/datasets.md +437 -0
- package/.claude/skills/hailer-api/references/files.md +301 -0
- package/.claude/skills/hailer-api/references/insights.md +469 -0
- package/.claude/skills/hailer-api/references/workflows.md +720 -0
- package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
- package/.claude/skills/insight-api/SKILL.md +185 -0
- package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
- package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
- package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
- package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
- package/.claude/skills/local-first-skill/SKILL.md +570 -0
- package/.claude/skills/mcp-tools/SKILL.md +419 -0
- package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
- package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
- package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
- package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
- package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
- package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
- package/.claude/skills/remove-app-skill/SKILL.md +985 -0
- package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
- package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
- package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
- package/.claude/skills/skill-testing/README.md +137 -0
- package/.claude/skills/skill-testing/SKILL.md +348 -0
- package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
- package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
- package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
- package/.claude/skills/tool-builder/SKILL.md +328 -0
- package/.claude/skills/update-app-skill/SKILL.md +970 -0
- package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
- package/.env.example +81 -0
- package/.mcp.json +13 -0
- package/README.md +297 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +74 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +5 -0
- package/dist/client/adaptive-documentation-bot.d.ts +108 -0
- package/dist/client/adaptive-documentation-bot.js +475 -0
- package/dist/client/adaptive-documentation-types.d.ts +66 -0
- package/dist/client/adaptive-documentation-types.js +9 -0
- package/dist/client/agent-activity-bot.d.ts +51 -0
- package/dist/client/agent-activity-bot.js +166 -0
- package/dist/client/agent-tracker.d.ts +499 -0
- package/dist/client/agent-tracker.js +659 -0
- package/dist/client/description-updater.d.ts +56 -0
- package/dist/client/description-updater.js +259 -0
- package/dist/client/log-parser.d.ts +72 -0
- package/dist/client/log-parser.js +387 -0
- package/dist/client/mcp-client.d.ts +50 -0
- package/dist/client/mcp-client.js +532 -0
- package/dist/client/message-processor.d.ts +35 -0
- package/dist/client/message-processor.js +352 -0
- package/dist/client/multi-bot-manager.d.ts +24 -0
- package/dist/client/multi-bot-manager.js +74 -0
- package/dist/client/providers/anthropic-provider.d.ts +19 -0
- package/dist/client/providers/anthropic-provider.js +631 -0
- package/dist/client/providers/llm-provider.d.ts +47 -0
- package/dist/client/providers/llm-provider.js +367 -0
- package/dist/client/providers/openai-provider.d.ts +23 -0
- package/dist/client/providers/openai-provider.js +621 -0
- package/dist/client/simple-llm-caller.d.ts +19 -0
- package/dist/client/simple-llm-caller.js +100 -0
- package/dist/client/skill-generator.d.ts +81 -0
- package/dist/client/skill-generator.js +386 -0
- package/dist/client/test-adaptive-bot.d.ts +9 -0
- package/dist/client/test-adaptive-bot.js +82 -0
- package/dist/client/token-pricing.d.ts +38 -0
- package/dist/client/token-pricing.js +127 -0
- package/dist/client/token-tracker.d.ts +232 -0
- package/dist/client/token-tracker.js +457 -0
- package/dist/client/token-usage-bot.d.ts +53 -0
- package/dist/client/token-usage-bot.js +153 -0
- package/dist/client/tool-executor.d.ts +69 -0
- package/dist/client/tool-executor.js +159 -0
- package/dist/client/tool-schema-loader.d.ts +60 -0
- package/dist/client/tool-schema-loader.js +178 -0
- package/dist/client/types.d.ts +69 -0
- package/dist/client/types.js +7 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.js +296 -0
- package/dist/core.d.ts +26 -0
- package/dist/core.js +147 -0
- package/dist/lib/context-manager.d.ts +111 -0
- package/dist/lib/context-manager.js +431 -0
- package/dist/lib/logger.d.ts +74 -0
- package/dist/lib/logger.js +277 -0
- package/dist/lib/materialize.d.ts +3 -0
- package/dist/lib/materialize.js +101 -0
- package/dist/lib/normalizedName.d.ts +7 -0
- package/dist/lib/normalizedName.js +48 -0
- package/dist/lib/prompt-length-manager.d.ts +81 -0
- package/dist/lib/prompt-length-manager.js +457 -0
- package/dist/lib/terminal-prompt.d.ts +9 -0
- package/dist/lib/terminal-prompt.js +108 -0
- package/dist/mcp/UserContextCache.d.ts +56 -0
- package/dist/mcp/UserContextCache.js +163 -0
- package/dist/mcp/auth.d.ts +2 -0
- package/dist/mcp/auth.js +29 -0
- package/dist/mcp/hailer-clients.d.ts +42 -0
- package/dist/mcp/hailer-clients.js +246 -0
- package/dist/mcp/signal-handler.d.ts +45 -0
- package/dist/mcp/signal-handler.js +317 -0
- package/dist/mcp/tool-registry.d.ts +100 -0
- package/dist/mcp/tool-registry.js +306 -0
- package/dist/mcp/tools/activity.d.ts +15 -0
- package/dist/mcp/tools/activity.js +955 -0
- package/dist/mcp/tools/app.d.ts +20 -0
- package/dist/mcp/tools/app.js +1488 -0
- package/dist/mcp/tools/discussion.d.ts +19 -0
- package/dist/mcp/tools/discussion.js +950 -0
- package/dist/mcp/tools/file.d.ts +15 -0
- package/dist/mcp/tools/file.js +119 -0
- package/dist/mcp/tools/insight.d.ts +17 -0
- package/dist/mcp/tools/insight.js +806 -0
- package/dist/mcp/tools/skill.d.ts +10 -0
- package/dist/mcp/tools/skill.js +279 -0
- package/dist/mcp/tools/user.d.ts +10 -0
- package/dist/mcp/tools/user.js +108 -0
- package/dist/mcp/tools/workflow-template.d.ts +19 -0
- package/dist/mcp/tools/workflow-template.js +822 -0
- package/dist/mcp/tools/workflow.d.ts +18 -0
- package/dist/mcp/tools/workflow.js +1362 -0
- package/dist/mcp/utils/api-errors.d.ts +45 -0
- package/dist/mcp/utils/api-errors.js +160 -0
- package/dist/mcp/utils/data-transformers.d.ts +102 -0
- package/dist/mcp/utils/data-transformers.js +194 -0
- package/dist/mcp/utils/file-upload.d.ts +33 -0
- package/dist/mcp/utils/file-upload.js +148 -0
- package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
- package/dist/mcp/utils/hailer-api-client.js +323 -0
- package/dist/mcp/utils/index.d.ts +13 -0
- package/dist/mcp/utils/index.js +39 -0
- package/dist/mcp/utils/logger.d.ts +42 -0
- package/dist/mcp/utils/logger.js +103 -0
- package/dist/mcp/utils/types.d.ts +286 -0
- package/dist/mcp/utils/types.js +7 -0
- package/dist/mcp/workspace-cache.d.ts +42 -0
- package/dist/mcp/workspace-cache.js +97 -0
- package/dist/mcp-server.d.ts +42 -0
- package/dist/mcp-server.js +280 -0
- package/package.json +56 -0
- 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
|