@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,1010 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Listing Hailer Apps
|
|
3
|
+
description: Complete guide for viewing and managing Hailer apps in workspace - use when discovering or auditing apps
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Listing Hailer Apps - Complete Guide
|
|
7
|
+
|
|
8
|
+
Complete reference for viewing Hailer apps in your workspace using the `list_apps` MCP tool.
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
1. [Quick Reference](#quick-reference)
|
|
12
|
+
2. [Overview](#overview)
|
|
13
|
+
3. [Response Structure](#response-structure)
|
|
14
|
+
4. [Basic Usage](#basic-usage)
|
|
15
|
+
5. [Filtering and Finding](#filtering-and-finding)
|
|
16
|
+
6. [App Properties](#app-properties)
|
|
17
|
+
7. [Common Scenarios](#common-scenarios)
|
|
18
|
+
8. [Working with Results](#working-with-results)
|
|
19
|
+
9. [Best Practices](#best-practices)
|
|
20
|
+
10. [Troubleshooting](#troubleshooting)
|
|
21
|
+
|
|
22
|
+
## Quick Reference
|
|
23
|
+
|
|
24
|
+
**List All Apps:**
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
list_apps()
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**List in Specific Workspace:**
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
list_apps({
|
|
34
|
+
workspaceId: 'workspace-id'
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Response Format:**
|
|
39
|
+
```javascript
|
|
40
|
+
[
|
|
41
|
+
{
|
|
42
|
+
_id: 'app-id',
|
|
43
|
+
name: 'My App',
|
|
44
|
+
description: 'App description',
|
|
45
|
+
url: 'http://localhost:3000', // Dev apps only
|
|
46
|
+
image: 'image-id',
|
|
47
|
+
config: { ... },
|
|
48
|
+
created: '2024-01-15T10:30:00Z',
|
|
49
|
+
owner: 'user-id',
|
|
50
|
+
members: ['network_workspace-id'],
|
|
51
|
+
isOwner: true
|
|
52
|
+
},
|
|
53
|
+
// ... more apps
|
|
54
|
+
]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Key Features:**
|
|
58
|
+
- Lists all apps in workspace
|
|
59
|
+
- Shows dev and published apps
|
|
60
|
+
- Includes app metadata
|
|
61
|
+
- Shows ownership and permissions
|
|
62
|
+
- Can filter by workspace
|
|
63
|
+
|
|
64
|
+
## Overview
|
|
65
|
+
|
|
66
|
+
**What does list_apps do?**
|
|
67
|
+
|
|
68
|
+
Returns an array of all Hailer apps in your current workspace (or specified workspace). Shows both development and published apps that you have access to.
|
|
69
|
+
|
|
70
|
+
**Think of it as:**
|
|
71
|
+
- Directory of workspace apps
|
|
72
|
+
- App inventory
|
|
73
|
+
- App discovery tool
|
|
74
|
+
- Access control viewer
|
|
75
|
+
|
|
76
|
+
**When to Use:**
|
|
77
|
+
- Find app IDs for other operations
|
|
78
|
+
- Discover available apps
|
|
79
|
+
- Audit app access
|
|
80
|
+
- Check app configurations
|
|
81
|
+
- Verify app creation
|
|
82
|
+
- Find dev vs published apps
|
|
83
|
+
- Identify app owners
|
|
84
|
+
|
|
85
|
+
**When NOT to Use:**
|
|
86
|
+
- Looking for workflows (use list_workflows)
|
|
87
|
+
- Need app usage statistics (not provided)
|
|
88
|
+
- Want to execute app (open in Hailer UI)
|
|
89
|
+
|
|
90
|
+
## Response Structure
|
|
91
|
+
|
|
92
|
+
### App Object
|
|
93
|
+
|
|
94
|
+
Each app in the response contains:
|
|
95
|
+
|
|
96
|
+
```javascript
|
|
97
|
+
{
|
|
98
|
+
// Identification
|
|
99
|
+
_id: 'app-id', // App ID (use for other operations)
|
|
100
|
+
name: 'My App', // Display name
|
|
101
|
+
description: 'App description', // Optional description
|
|
102
|
+
|
|
103
|
+
// Configuration
|
|
104
|
+
url: 'http://localhost:3000', // Dev apps only, published apps omit
|
|
105
|
+
image: 'image-id', // Optional app icon
|
|
106
|
+
config: { // Custom configuration
|
|
107
|
+
workflowId: 'workflow-id',
|
|
108
|
+
theme: 'dark'
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// Metadata
|
|
112
|
+
created: '2024-01-15T10:30:00Z', // Creation timestamp
|
|
113
|
+
updated: '2024-01-20T14:00:00Z', // Last update timestamp
|
|
114
|
+
owner: 'user-id', // App creator
|
|
115
|
+
|
|
116
|
+
// Access control
|
|
117
|
+
members: [ // Who has access
|
|
118
|
+
'network_workspace-id', // Whole workspace
|
|
119
|
+
'team_team-id', // Specific team
|
|
120
|
+
'user_user-id' // Specific user
|
|
121
|
+
],
|
|
122
|
+
|
|
123
|
+
// Permissions (your access)
|
|
124
|
+
isOwner: true, // You created this app
|
|
125
|
+
isAdmin: true, // You're workspace admin
|
|
126
|
+
canEdit: true, // You can modify app
|
|
127
|
+
canDelete: true // You can remove app
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Response Array
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
const apps = list_apps()
|
|
135
|
+
|
|
136
|
+
// Array of app objects
|
|
137
|
+
console.log(`Found ${apps.length} apps`)
|
|
138
|
+
|
|
139
|
+
// Iterate through apps
|
|
140
|
+
apps.forEach(app => {
|
|
141
|
+
console.log(`${app.name}: ${app._id}`)
|
|
142
|
+
})
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Basic Usage
|
|
146
|
+
|
|
147
|
+
### Example 1: List All Apps
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
// Get all apps in current workspace
|
|
151
|
+
const apps = list_apps()
|
|
152
|
+
|
|
153
|
+
console.log(`Total apps: ${apps.length}`)
|
|
154
|
+
|
|
155
|
+
// Display app names
|
|
156
|
+
apps.forEach(app => {
|
|
157
|
+
console.log(`- ${app.name}`)
|
|
158
|
+
})
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Example 2: List with Details
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
const apps = list_apps()
|
|
165
|
+
|
|
166
|
+
apps.forEach(app => {
|
|
167
|
+
console.log('---')
|
|
168
|
+
console.log('Name:', app.name)
|
|
169
|
+
console.log('ID:', app._id)
|
|
170
|
+
console.log('Type:', app.url ? 'Development' : 'Published')
|
|
171
|
+
console.log('Owner:', app.isOwner ? 'You' : 'Someone else')
|
|
172
|
+
console.log('Created:', app.created)
|
|
173
|
+
})
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Example 3: List in Specific Workspace
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
// List apps in different workspace
|
|
180
|
+
const apps = list_apps({
|
|
181
|
+
workspaceId: 'specific-workspace-id'
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
console.log(`Apps in workspace: ${apps.length}`)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Example 4: Find Specific App
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
const apps = list_apps()
|
|
191
|
+
|
|
192
|
+
// Find by name
|
|
193
|
+
const myApp = apps.find(app => app.name === 'Task Manager')
|
|
194
|
+
|
|
195
|
+
if (myApp) {
|
|
196
|
+
console.log('Found app:', myApp._id)
|
|
197
|
+
} else {
|
|
198
|
+
console.log('App not found')
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Filtering and Finding
|
|
203
|
+
|
|
204
|
+
### Find by Name
|
|
205
|
+
|
|
206
|
+
```javascript
|
|
207
|
+
const apps = list_apps()
|
|
208
|
+
|
|
209
|
+
// Exact match
|
|
210
|
+
const app = apps.find(a => a.name === 'My App')
|
|
211
|
+
|
|
212
|
+
// Partial match
|
|
213
|
+
const matches = apps.filter(a =>
|
|
214
|
+
a.name.toLowerCase().includes('task')
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
console.log(`Found ${matches.length} task-related apps`)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Find Development Apps
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
const apps = list_apps()
|
|
224
|
+
|
|
225
|
+
// Dev apps have URL property
|
|
226
|
+
const devApps = apps.filter(app => app.url)
|
|
227
|
+
|
|
228
|
+
console.log('Development apps:')
|
|
229
|
+
devApps.forEach(app => {
|
|
230
|
+
console.log(`- ${app.name}: ${app.url}`)
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Find Published Apps
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
const apps = list_apps()
|
|
238
|
+
|
|
239
|
+
// Published apps have no URL or empty URL
|
|
240
|
+
const publishedApps = apps.filter(app => !app.url)
|
|
241
|
+
|
|
242
|
+
console.log('Published apps:')
|
|
243
|
+
publishedApps.forEach(app => {
|
|
244
|
+
console.log(`- ${app.name}`)
|
|
245
|
+
})
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Find Apps You Own
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
const apps = list_apps()
|
|
252
|
+
|
|
253
|
+
const myApps = apps.filter(app => app.isOwner)
|
|
254
|
+
|
|
255
|
+
console.log(`You own ${myApps.length} apps:`)
|
|
256
|
+
myApps.forEach(app => {
|
|
257
|
+
console.log(`- ${app.name}`)
|
|
258
|
+
})
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Find Apps by Configuration
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
const apps = list_apps()
|
|
265
|
+
|
|
266
|
+
// Find apps using specific workflow
|
|
267
|
+
const workflowId = 'target-workflow-id'
|
|
268
|
+
const appsUsingWorkflow = apps.filter(app =>
|
|
269
|
+
app.config?.workflowId === workflowId
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
console.log(`Apps using workflow: ${appsUsingWorkflow.length}`)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Sort Apps
|
|
276
|
+
|
|
277
|
+
```javascript
|
|
278
|
+
const apps = list_apps()
|
|
279
|
+
|
|
280
|
+
// Sort by name
|
|
281
|
+
const byName = [...apps].sort((a, b) =>
|
|
282
|
+
a.name.localeCompare(b.name)
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
// Sort by creation date (newest first)
|
|
286
|
+
const byDate = [...apps].sort((a, b) =>
|
|
287
|
+
new Date(b.created) - new Date(a.created)
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
console.log('Newest apps:')
|
|
291
|
+
byDate.slice(0, 5).forEach(app => {
|
|
292
|
+
console.log(`- ${app.name} (${app.created})`)
|
|
293
|
+
})
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## App Properties
|
|
297
|
+
|
|
298
|
+
### Identification Properties
|
|
299
|
+
|
|
300
|
+
**_id** - App ID
|
|
301
|
+
```javascript
|
|
302
|
+
const app = apps[0]
|
|
303
|
+
console.log('App ID:', app._id)
|
|
304
|
+
// Use for: update_app, remove_app, add_app_member
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**name** - Display name
|
|
308
|
+
```javascript
|
|
309
|
+
console.log('Name:', app.name)
|
|
310
|
+
// Shown in Hailer UI
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**description** - Optional description
|
|
314
|
+
```javascript
|
|
315
|
+
console.log('Description:', app.description || 'None')
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Configuration Properties
|
|
319
|
+
|
|
320
|
+
**url** - App URL (dev apps only)
|
|
321
|
+
```javascript
|
|
322
|
+
if (app.url) {
|
|
323
|
+
console.log('Development app:', app.url)
|
|
324
|
+
} else {
|
|
325
|
+
console.log('Published app')
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**image** - App icon ID
|
|
330
|
+
```javascript
|
|
331
|
+
if (app.image) {
|
|
332
|
+
console.log('Has custom icon:', app.image)
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**config** - Custom configuration object
|
|
337
|
+
```javascript
|
|
338
|
+
if (app.config) {
|
|
339
|
+
console.log('Configuration:', app.config)
|
|
340
|
+
console.log('Workflow ID:', app.config.workflowId)
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Metadata Properties
|
|
345
|
+
|
|
346
|
+
**created** - Creation timestamp
|
|
347
|
+
```javascript
|
|
348
|
+
const created = new Date(app.created)
|
|
349
|
+
console.log('Created:', created.toLocaleDateString())
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**updated** - Last update timestamp
|
|
353
|
+
```javascript
|
|
354
|
+
const updated = new Date(app.updated)
|
|
355
|
+
console.log('Updated:', updated.toLocaleDateString())
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**owner** - Creator user ID
|
|
359
|
+
```javascript
|
|
360
|
+
console.log('Owner:', app.owner)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Access Control Properties
|
|
364
|
+
|
|
365
|
+
**members** - Who has access
|
|
366
|
+
```javascript
|
|
367
|
+
console.log('Shared with:', app.members.length, 'members')
|
|
368
|
+
|
|
369
|
+
app.members.forEach(member => {
|
|
370
|
+
if (member.startsWith('network_')) {
|
|
371
|
+
console.log('- Workspace access')
|
|
372
|
+
} else if (member.startsWith('team_')) {
|
|
373
|
+
console.log('- Team:', member)
|
|
374
|
+
} else if (member.startsWith('user_')) {
|
|
375
|
+
console.log('- User:', member)
|
|
376
|
+
}
|
|
377
|
+
})
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**isOwner** - You created the app
|
|
381
|
+
```javascript
|
|
382
|
+
if (app.isOwner) {
|
|
383
|
+
console.log('You own this app')
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**isAdmin** - You're workspace admin
|
|
388
|
+
```javascript
|
|
389
|
+
if (app.isAdmin) {
|
|
390
|
+
console.log('You have admin access')
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**canEdit** - You can modify
|
|
395
|
+
```javascript
|
|
396
|
+
if (app.canEdit) {
|
|
397
|
+
console.log('You can update this app')
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**canDelete** - You can remove
|
|
402
|
+
```javascript
|
|
403
|
+
if (app.canDelete) {
|
|
404
|
+
console.log('You can delete this app')
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Common Scenarios
|
|
409
|
+
|
|
410
|
+
### Scenario 1: Audit All Apps
|
|
411
|
+
|
|
412
|
+
**Goal:** Review all apps in workspace.
|
|
413
|
+
|
|
414
|
+
```javascript
|
|
415
|
+
const apps = list_apps()
|
|
416
|
+
|
|
417
|
+
console.log('=== Workspace Apps Audit ===\n')
|
|
418
|
+
console.log(`Total apps: ${apps.length}\n`)
|
|
419
|
+
|
|
420
|
+
// Group by type
|
|
421
|
+
const devApps = apps.filter(a => a.url)
|
|
422
|
+
const publishedApps = apps.filter(a => !a.url)
|
|
423
|
+
|
|
424
|
+
console.log(`Development apps: ${devApps.length}`)
|
|
425
|
+
console.log(`Published apps: ${publishedApps.length}\n`)
|
|
426
|
+
|
|
427
|
+
// Show details
|
|
428
|
+
apps.forEach((app, i) => {
|
|
429
|
+
console.log(`${i + 1}. ${app.name}`)
|
|
430
|
+
console.log(` ID: ${app._id}`)
|
|
431
|
+
console.log(` Type: ${app.url ? 'Dev' : 'Published'}`)
|
|
432
|
+
console.log(` Owner: ${app.isOwner ? 'You' : app.owner}`)
|
|
433
|
+
console.log(` Created: ${app.created}`)
|
|
434
|
+
console.log(` Shared: ${app.members.length} members`)
|
|
435
|
+
console.log()
|
|
436
|
+
})
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Scenario 2: Find App ID for Operations
|
|
440
|
+
|
|
441
|
+
**Goal:** Get app ID to use in other operations.
|
|
442
|
+
|
|
443
|
+
```javascript
|
|
444
|
+
// Find app by name
|
|
445
|
+
const apps = list_apps()
|
|
446
|
+
const targetApp = apps.find(a => a.name === 'Task Manager')
|
|
447
|
+
|
|
448
|
+
if (!targetApp) {
|
|
449
|
+
console.error('App not found')
|
|
450
|
+
return
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
console.log('Found app ID:', targetApp._id)
|
|
454
|
+
|
|
455
|
+
// Use in other operations
|
|
456
|
+
update_app({
|
|
457
|
+
appId: targetApp._id,
|
|
458
|
+
name: 'Task Manager v2'
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
add_app_member({
|
|
462
|
+
appId: targetApp._id,
|
|
463
|
+
member: 'team_team-id'
|
|
464
|
+
})
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Scenario 3: Clean Up Dev Apps
|
|
468
|
+
|
|
469
|
+
**Goal:** Remove old development apps.
|
|
470
|
+
|
|
471
|
+
```javascript
|
|
472
|
+
const apps = list_apps()
|
|
473
|
+
|
|
474
|
+
// Find dev apps
|
|
475
|
+
const devApps = apps.filter(a => a.url && a.isOwner)
|
|
476
|
+
|
|
477
|
+
console.log(`Found ${devApps.length} dev apps you own`)
|
|
478
|
+
|
|
479
|
+
// Identify old apps
|
|
480
|
+
devApps.forEach(app => {
|
|
481
|
+
const created = new Date(app.created)
|
|
482
|
+
const daysOld = (Date.now() - created) / 1000 / 60 / 60 / 24
|
|
483
|
+
|
|
484
|
+
console.log(`${app.name}: ${daysOld.toFixed(0)} days old`)
|
|
485
|
+
|
|
486
|
+
if (daysOld > 30) {
|
|
487
|
+
console.log(` â ī¸ Consider removing`)
|
|
488
|
+
// remove_app({ appId: app._id })
|
|
489
|
+
}
|
|
490
|
+
})
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Scenario 4: Find Apps Using Workflow
|
|
494
|
+
|
|
495
|
+
**Goal:** Find all apps that use specific workflow.
|
|
496
|
+
|
|
497
|
+
```javascript
|
|
498
|
+
const workflowId = 'target-workflow-id'
|
|
499
|
+
const apps = list_apps()
|
|
500
|
+
|
|
501
|
+
const usingWorkflow = apps.filter(app =>
|
|
502
|
+
app.config?.workflowId === workflowId ||
|
|
503
|
+
JSON.stringify(app.config).includes(workflowId)
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
console.log(`Apps using workflow ${workflowId}:`)
|
|
507
|
+
usingWorkflow.forEach(app => {
|
|
508
|
+
console.log(`- ${app.name} (${app._id})`)
|
|
509
|
+
})
|
|
510
|
+
|
|
511
|
+
if (usingWorkflow.length === 0) {
|
|
512
|
+
console.log('No apps use this workflow')
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Scenario 5: Compare Dev and Prod Apps
|
|
517
|
+
|
|
518
|
+
**Goal:** Match development and published versions.
|
|
519
|
+
|
|
520
|
+
```javascript
|
|
521
|
+
const apps = list_apps()
|
|
522
|
+
|
|
523
|
+
// Group by base name
|
|
524
|
+
const pairs = {}
|
|
525
|
+
|
|
526
|
+
apps.forEach(app => {
|
|
527
|
+
// Remove (Dev) suffix to find base name
|
|
528
|
+
const baseName = app.name.replace(/\s*\(Dev\)\s*$/i, '')
|
|
529
|
+
|
|
530
|
+
if (!pairs[baseName]) {
|
|
531
|
+
pairs[baseName] = { dev: null, prod: null }
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (app.url) {
|
|
535
|
+
pairs[baseName].dev = app
|
|
536
|
+
} else {
|
|
537
|
+
pairs[baseName].prod = app
|
|
538
|
+
}
|
|
539
|
+
})
|
|
540
|
+
|
|
541
|
+
// Show pairs
|
|
542
|
+
console.log('App Pairs:')
|
|
543
|
+
Object.entries(pairs).forEach(([name, { dev, prod }]) => {
|
|
544
|
+
console.log(`\n${name}:`)
|
|
545
|
+
console.log(' Dev:', dev ? dev._id : 'Missing')
|
|
546
|
+
console.log(' Prod:', prod ? prod._id : 'Missing')
|
|
547
|
+
})
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### Scenario 6: Export App List
|
|
551
|
+
|
|
552
|
+
**Goal:** Export app inventory to file.
|
|
553
|
+
|
|
554
|
+
```javascript
|
|
555
|
+
const apps = list_apps()
|
|
556
|
+
|
|
557
|
+
// Create export data
|
|
558
|
+
const exportData = apps.map(app => ({
|
|
559
|
+
name: app.name,
|
|
560
|
+
id: app._id,
|
|
561
|
+
type: app.url ? 'development' : 'published',
|
|
562
|
+
url: app.url || 'N/A',
|
|
563
|
+
created: app.created,
|
|
564
|
+
owner: app.isOwner ? 'You' : app.owner,
|
|
565
|
+
members: app.members.length,
|
|
566
|
+
config: app.config
|
|
567
|
+
}))
|
|
568
|
+
|
|
569
|
+
// Export as JSON
|
|
570
|
+
const json = JSON.stringify(exportData, null, 2)
|
|
571
|
+
console.log(json)
|
|
572
|
+
|
|
573
|
+
// Or as CSV
|
|
574
|
+
console.log('name,id,type,created,members')
|
|
575
|
+
exportData.forEach(app => {
|
|
576
|
+
console.log(`"${app.name}",${app.id},${app.type},${app.created},${app.members}`)
|
|
577
|
+
})
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
## Working with Results
|
|
581
|
+
|
|
582
|
+
### Count Apps
|
|
583
|
+
|
|
584
|
+
```javascript
|
|
585
|
+
const apps = list_apps()
|
|
586
|
+
|
|
587
|
+
console.log('Statistics:')
|
|
588
|
+
console.log('- Total apps:', apps.length)
|
|
589
|
+
console.log('- Dev apps:', apps.filter(a => a.url).length)
|
|
590
|
+
console.log('- Published apps:', apps.filter(a => !a.url).length)
|
|
591
|
+
console.log('- Apps you own:', apps.filter(a => a.isOwner).length)
|
|
592
|
+
console.log('- Shared workspace:', apps.filter(a =>
|
|
593
|
+
a.members.some(m => m.startsWith('network_'))
|
|
594
|
+
).length)
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### Group Apps
|
|
598
|
+
|
|
599
|
+
```javascript
|
|
600
|
+
const apps = list_apps()
|
|
601
|
+
|
|
602
|
+
// Group by owner
|
|
603
|
+
const byOwner = {}
|
|
604
|
+
apps.forEach(app => {
|
|
605
|
+
const owner = app.isOwner ? 'You' : app.owner
|
|
606
|
+
if (!byOwner[owner]) byOwner[owner] = []
|
|
607
|
+
byOwner[owner].push(app)
|
|
608
|
+
})
|
|
609
|
+
|
|
610
|
+
console.log('Apps by owner:')
|
|
611
|
+
Object.entries(byOwner).forEach(([owner, apps]) => {
|
|
612
|
+
console.log(`${owner}: ${apps.length} apps`)
|
|
613
|
+
})
|
|
614
|
+
|
|
615
|
+
// Group by type
|
|
616
|
+
const grouped = {
|
|
617
|
+
development: apps.filter(a => a.url),
|
|
618
|
+
published: apps.filter(a => !a.url)
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
console.log('\nApps by type:')
|
|
622
|
+
Object.entries(grouped).forEach(([type, apps]) => {
|
|
623
|
+
console.log(`${type}: ${apps.length} apps`)
|
|
624
|
+
})
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### Create Index
|
|
628
|
+
|
|
629
|
+
```javascript
|
|
630
|
+
const apps = list_apps()
|
|
631
|
+
|
|
632
|
+
// Create lookup by ID
|
|
633
|
+
const byId = {}
|
|
634
|
+
apps.forEach(app => {
|
|
635
|
+
byId[app._id] = app
|
|
636
|
+
})
|
|
637
|
+
|
|
638
|
+
// Create lookup by name
|
|
639
|
+
const byName = {}
|
|
640
|
+
apps.forEach(app => {
|
|
641
|
+
byName[app.name.toLowerCase()] = app
|
|
642
|
+
})
|
|
643
|
+
|
|
644
|
+
// Use lookups
|
|
645
|
+
console.log('Lookup by ID:', byId['app-id-here']?.name)
|
|
646
|
+
console.log('Lookup by name:', byName['task manager']?._id)
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
### Filter by Date
|
|
650
|
+
|
|
651
|
+
```javascript
|
|
652
|
+
const apps = list_apps()
|
|
653
|
+
|
|
654
|
+
// Apps created in last 7 days
|
|
655
|
+
const recent = apps.filter(app => {
|
|
656
|
+
const created = new Date(app.created)
|
|
657
|
+
const daysAgo = (Date.now() - created) / 1000 / 60 / 60 / 24
|
|
658
|
+
return daysAgo <= 7
|
|
659
|
+
})
|
|
660
|
+
|
|
661
|
+
console.log(`${recent.length} apps created in last 7 days`)
|
|
662
|
+
|
|
663
|
+
// Apps updated recently
|
|
664
|
+
const recentlyUpdated = apps.filter(app => {
|
|
665
|
+
const updated = new Date(app.updated)
|
|
666
|
+
const daysAgo = (Date.now() - updated) / 1000 / 60 / 60 / 24
|
|
667
|
+
return daysAgo <= 7
|
|
668
|
+
})
|
|
669
|
+
|
|
670
|
+
console.log(`${recentlyUpdated.length} apps updated in last 7 days`)
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
## Best Practices
|
|
674
|
+
|
|
675
|
+
### 1. Cache Results When Appropriate
|
|
676
|
+
|
|
677
|
+
```javascript
|
|
678
|
+
// Don't call list_apps repeatedly
|
|
679
|
+
// Bad:
|
|
680
|
+
for (let i = 0; i < 10; i++) {
|
|
681
|
+
const apps = list_apps() // Called 10 times!
|
|
682
|
+
const app = apps.find(a => a.name === names[i])
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Good:
|
|
686
|
+
const apps = list_apps() // Called once
|
|
687
|
+
for (let i = 0; i < 10; i++) {
|
|
688
|
+
const app = apps.find(a => a.name === names[i])
|
|
689
|
+
}
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
### 2. Check App Exists Before Operations
|
|
693
|
+
|
|
694
|
+
```javascript
|
|
695
|
+
// Always verify app exists
|
|
696
|
+
const apps = list_apps()
|
|
697
|
+
const app = apps.find(a => a.name === 'My App')
|
|
698
|
+
|
|
699
|
+
if (!app) {
|
|
700
|
+
console.error('App not found')
|
|
701
|
+
return
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// Safe to proceed
|
|
705
|
+
update_app({
|
|
706
|
+
appId: app._id,
|
|
707
|
+
name: 'New Name'
|
|
708
|
+
})
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
### 3. Handle Empty Results
|
|
712
|
+
|
|
713
|
+
```javascript
|
|
714
|
+
const apps = list_apps()
|
|
715
|
+
|
|
716
|
+
if (apps.length === 0) {
|
|
717
|
+
console.log('No apps found in workspace')
|
|
718
|
+
return
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// Process apps
|
|
722
|
+
apps.forEach(app => {
|
|
723
|
+
// ...
|
|
724
|
+
})
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### 4. Use Descriptive Filters
|
|
728
|
+
|
|
729
|
+
```javascript
|
|
730
|
+
// Good: Clear intent
|
|
731
|
+
const devApps = apps.filter(app => app.url)
|
|
732
|
+
const myApps = apps.filter(app => app.isOwner)
|
|
733
|
+
const sharedApps = apps.filter(app =>
|
|
734
|
+
app.members.some(m => m.startsWith('network_'))
|
|
735
|
+
)
|
|
736
|
+
|
|
737
|
+
// Not as clear:
|
|
738
|
+
const filtered = apps.filter(a => a.url && a.isOwner)
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
### 5. Validate Permissions Before Actions
|
|
742
|
+
|
|
743
|
+
```javascript
|
|
744
|
+
const apps = list_apps()
|
|
745
|
+
const app = apps.find(a => a.name === 'Target App')
|
|
746
|
+
|
|
747
|
+
// Check before updating
|
|
748
|
+
if (app.canEdit) {
|
|
749
|
+
update_app({ appId: app._id, name: 'New Name' })
|
|
750
|
+
} else {
|
|
751
|
+
console.error('No permission to edit this app')
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// Check before deleting
|
|
755
|
+
if (app.canDelete) {
|
|
756
|
+
remove_app({ appId: app._id })
|
|
757
|
+
} else {
|
|
758
|
+
console.error('No permission to delete this app')
|
|
759
|
+
}
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
### 6. Use Type Checks
|
|
763
|
+
|
|
764
|
+
```javascript
|
|
765
|
+
const apps = list_apps()
|
|
766
|
+
|
|
767
|
+
apps.forEach(app => {
|
|
768
|
+
// Check properties exist
|
|
769
|
+
const name = app.name || 'Unnamed'
|
|
770
|
+
const description = app.description || 'No description'
|
|
771
|
+
const config = app.config || {}
|
|
772
|
+
|
|
773
|
+
console.log(`${name}: ${description}`)
|
|
774
|
+
})
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### 7. Document App Discovery Logic
|
|
778
|
+
|
|
779
|
+
```javascript
|
|
780
|
+
// Clear documentation of search logic
|
|
781
|
+
function findProductionApp(baseName) {
|
|
782
|
+
const apps = list_apps()
|
|
783
|
+
|
|
784
|
+
// Look for app without (Dev) suffix
|
|
785
|
+
return apps.find(app =>
|
|
786
|
+
app.name === baseName &&
|
|
787
|
+
!app.url // Published apps have no URL
|
|
788
|
+
)
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
const prodApp = findProductionApp('Task Manager')
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
## Troubleshooting
|
|
795
|
+
|
|
796
|
+
### No Apps Returned
|
|
797
|
+
|
|
798
|
+
**Causes:**
|
|
799
|
+
1. Wrong workspace
|
|
800
|
+
2. No apps created yet
|
|
801
|
+
3. No permission to view apps
|
|
802
|
+
|
|
803
|
+
**Solutions:**
|
|
804
|
+
|
|
805
|
+
```javascript
|
|
806
|
+
// 1. Check current workspace
|
|
807
|
+
const workspace = get_current_workspace()
|
|
808
|
+
console.log('Current workspace:', workspace.name)
|
|
809
|
+
|
|
810
|
+
// 2. Try listing
|
|
811
|
+
const apps = list_apps()
|
|
812
|
+
console.log('Apps found:', apps.length)
|
|
813
|
+
|
|
814
|
+
// 3. Create test app if needed
|
|
815
|
+
if (apps.length === 0) {
|
|
816
|
+
console.log('No apps found - create one')
|
|
817
|
+
create_app({
|
|
818
|
+
name: 'Test App',
|
|
819
|
+
url: 'http://localhost:3000'
|
|
820
|
+
})
|
|
821
|
+
}
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
### App Not in List
|
|
825
|
+
|
|
826
|
+
**Causes:**
|
|
827
|
+
1. App in different workspace
|
|
828
|
+
2. No permission to view app
|
|
829
|
+
3. App recently deleted
|
|
830
|
+
4. Cache not refreshed
|
|
831
|
+
|
|
832
|
+
**Solutions:**
|
|
833
|
+
|
|
834
|
+
```javascript
|
|
835
|
+
// 1. List apps
|
|
836
|
+
const apps = list_apps()
|
|
837
|
+
|
|
838
|
+
// 2. Search thoroughly
|
|
839
|
+
const found = apps.find(a =>
|
|
840
|
+
a.name.toLowerCase().includes('search term') ||
|
|
841
|
+
a._id === 'app-id'
|
|
842
|
+
)
|
|
843
|
+
|
|
844
|
+
// 3. Check workspace
|
|
845
|
+
if (!found) {
|
|
846
|
+
console.log('App not found in current workspace')
|
|
847
|
+
console.log('Current workspace:', get_current_workspace().name)
|
|
848
|
+
}
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
### Duplicate App Names
|
|
852
|
+
|
|
853
|
+
**Problem:** Multiple apps with same name.
|
|
854
|
+
|
|
855
|
+
**Solution:**
|
|
856
|
+
|
|
857
|
+
```javascript
|
|
858
|
+
const apps = list_apps()
|
|
859
|
+
|
|
860
|
+
// Find duplicates
|
|
861
|
+
const names = {}
|
|
862
|
+
apps.forEach(app => {
|
|
863
|
+
if (!names[app.name]) names[app.name] = []
|
|
864
|
+
names[app.name].push(app)
|
|
865
|
+
})
|
|
866
|
+
|
|
867
|
+
// Show duplicates
|
|
868
|
+
Object.entries(names).forEach(([name, apps]) => {
|
|
869
|
+
if (apps.length > 1) {
|
|
870
|
+
console.log(`\nDuplicate name: ${name}`)
|
|
871
|
+
apps.forEach(app => {
|
|
872
|
+
console.log(`- ID: ${app._id}`)
|
|
873
|
+
console.log(` Type: ${app.url ? 'Dev' : 'Published'}`)
|
|
874
|
+
console.log(` Created: ${app.created}`)
|
|
875
|
+
})
|
|
876
|
+
}
|
|
877
|
+
})
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
### Cannot Identify Dev vs Prod
|
|
881
|
+
|
|
882
|
+
**Problem:** Both apps have similar names.
|
|
883
|
+
|
|
884
|
+
**Solution:**
|
|
885
|
+
|
|
886
|
+
```javascript
|
|
887
|
+
const apps = list_apps()
|
|
888
|
+
|
|
889
|
+
// Clear identification
|
|
890
|
+
apps.forEach(app => {
|
|
891
|
+
const type = app.url ? 'DEVELOPMENT' : 'PUBLISHED'
|
|
892
|
+
const url = app.url || 'Hailer-hosted'
|
|
893
|
+
|
|
894
|
+
console.log(`${app.name}:`)
|
|
895
|
+
console.log(` Type: ${type}`)
|
|
896
|
+
console.log(` URL: ${url}`)
|
|
897
|
+
console.log(` ID: ${app._id}`)
|
|
898
|
+
console.log()
|
|
899
|
+
})
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
## Integration with Other Tools
|
|
903
|
+
|
|
904
|
+
### With create_app
|
|
905
|
+
|
|
906
|
+
Create and verify:
|
|
907
|
+
|
|
908
|
+
```javascript
|
|
909
|
+
// 1. Create app
|
|
910
|
+
const newApp = create_app({
|
|
911
|
+
name: 'My New App',
|
|
912
|
+
url: 'http://localhost:3000'
|
|
913
|
+
})
|
|
914
|
+
|
|
915
|
+
// 2. Verify it appears in list
|
|
916
|
+
const apps = list_apps()
|
|
917
|
+
const found = apps.find(a => a._id === newApp.appId)
|
|
918
|
+
|
|
919
|
+
console.log('Verified:', !!found)
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
### With update_app
|
|
923
|
+
|
|
924
|
+
Find and update:
|
|
925
|
+
|
|
926
|
+
```javascript
|
|
927
|
+
// 1. Find app
|
|
928
|
+
const apps = list_apps()
|
|
929
|
+
const app = apps.find(a => a.name === 'Old Name')
|
|
930
|
+
|
|
931
|
+
// 2. Update app
|
|
932
|
+
if (app) {
|
|
933
|
+
update_app({
|
|
934
|
+
appId: app._id,
|
|
935
|
+
name: 'New Name',
|
|
936
|
+
description: 'Updated description'
|
|
937
|
+
})
|
|
938
|
+
}
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
### With remove_app
|
|
942
|
+
|
|
943
|
+
Find and remove:
|
|
944
|
+
|
|
945
|
+
```javascript
|
|
946
|
+
// 1. List apps
|
|
947
|
+
const apps = list_apps()
|
|
948
|
+
|
|
949
|
+
// 2. Find test apps
|
|
950
|
+
const testApps = apps.filter(a =>
|
|
951
|
+
a.name.includes('Test') && a.isOwner
|
|
952
|
+
)
|
|
953
|
+
|
|
954
|
+
// 3. Remove each
|
|
955
|
+
testApps.forEach(app => {
|
|
956
|
+
console.log('Removing:', app.name)
|
|
957
|
+
remove_app({ appId: app._id })
|
|
958
|
+
})
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
### With add_app_member
|
|
962
|
+
|
|
963
|
+
Find and share:
|
|
964
|
+
|
|
965
|
+
```javascript
|
|
966
|
+
// 1. Find app
|
|
967
|
+
const apps = list_apps()
|
|
968
|
+
const app = apps.find(a => a.name === 'Dashboard')
|
|
969
|
+
|
|
970
|
+
// 2. Share with workspace
|
|
971
|
+
if (app && app.isOwner) {
|
|
972
|
+
add_app_member({
|
|
973
|
+
appId: app._id,
|
|
974
|
+
member: 'network_workspace-id'
|
|
975
|
+
})
|
|
976
|
+
}
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
## Summary
|
|
980
|
+
|
|
981
|
+
**Key Takeaways:**
|
|
982
|
+
1. đ **Lists all apps** - In current or specified workspace
|
|
983
|
+
2. đ **Filterable** - Find by name, type, owner, config
|
|
984
|
+
3. âšī¸ **Rich metadata** - Name, type, config, permissions
|
|
985
|
+
4. đ **Returns IDs** - Use for other operations
|
|
986
|
+
5. đˇī¸ **Shows types** - Dev (has URL) vs Published (no URL)
|
|
987
|
+
6. đ **Access info** - Shows what you can do with each app
|
|
988
|
+
7. đ **No limits** - Returns all apps you have access to
|
|
989
|
+
|
|
990
|
+
**Quick Decision Tree:**
|
|
991
|
+
|
|
992
|
+
```
|
|
993
|
+
Need app information?
|
|
994
|
+
â
|
|
995
|
+
ââ Find app ID? â list_apps, filter by name
|
|
996
|
+
ââ Count apps? â list_apps, check length
|
|
997
|
+
ââ Find dev apps? â filter by app.url
|
|
998
|
+
ââ Find your apps? â filter by app.isOwner
|
|
999
|
+
ââ Audit workspace? â list_apps, iterate all
|
|
1000
|
+
ââ Before operations? â list_apps, verify exists
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
## Additional Resources
|
|
1004
|
+
|
|
1005
|
+
- See `create-app-skill` for creating apps
|
|
1006
|
+
- See `update-app-skill` for modifying apps
|
|
1007
|
+
- See `remove-app-skill` for deleting apps
|
|
1008
|
+
- See `add-app-member-skill` for sharing apps
|
|
1009
|
+
- See `remove-app-member-skill` for revoking access
|
|
1010
|
+
- See `app-api` skill for comprehensive App API documentation
|