@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,977 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Sharing Hailer Apps
|
|
3
|
+
description: Complete guide for sharing Hailer apps with users and teams - use when granting app access
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sharing Hailer Apps - Complete Guide
|
|
7
|
+
|
|
8
|
+
Complete reference for sharing Hailer apps with workspace members using the `add_app_member` MCP tool.
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
1. [Quick Reference](#quick-reference)
|
|
12
|
+
2. [Overview](#overview)
|
|
13
|
+
3. [Core Concepts](#core-concepts)
|
|
14
|
+
4. [Member Types](#member-types)
|
|
15
|
+
5. [Basic Usage](#basic-usage)
|
|
16
|
+
6. [Sharing Strategies](#sharing-strategies)
|
|
17
|
+
7. [Common Scenarios](#common-scenarios)
|
|
18
|
+
8. [Best Practices](#best-practices)
|
|
19
|
+
9. [Troubleshooting](#troubleshooting)
|
|
20
|
+
|
|
21
|
+
## Quick Reference
|
|
22
|
+
|
|
23
|
+
**Share with Entire Workspace:**
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
add_app_member({
|
|
27
|
+
appId: 'app-id',
|
|
28
|
+
member: 'network_workspace-id'
|
|
29
|
+
})
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Share with Specific Team:**
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
add_app_member({
|
|
36
|
+
appId: 'app-id',
|
|
37
|
+
member: 'team_team-id'
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Share with Individual User:**
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
add_app_member({
|
|
45
|
+
appId: 'app-id',
|
|
46
|
+
member: 'user_user-id'
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Response:**
|
|
51
|
+
```
|
|
52
|
+
✅ App Member Added Successfully
|
|
53
|
+
|
|
54
|
+
App ID: app-id
|
|
55
|
+
Member: network_workspace-id (Entire Workspace)
|
|
56
|
+
|
|
57
|
+
The app is now accessible to the specified member(s)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Key Requirements:**
|
|
61
|
+
- Must be app owner OR workspace administrator
|
|
62
|
+
- App must exist
|
|
63
|
+
- Member ID must be valid
|
|
64
|
+
- Member format: `network_`, `team_`, or `user_` prefix
|
|
65
|
+
|
|
66
|
+
## Overview
|
|
67
|
+
|
|
68
|
+
**What does add_app_member do?**
|
|
69
|
+
|
|
70
|
+
Grants access to a Hailer app for workspace members, teams, or the entire workspace. This makes the app visible and usable for the specified members.
|
|
71
|
+
|
|
72
|
+
**Think of it as:**
|
|
73
|
+
- Publishing an app to users
|
|
74
|
+
- Granting app permissions
|
|
75
|
+
- Sharing app access
|
|
76
|
+
- Making app visible
|
|
77
|
+
|
|
78
|
+
**When to Use:**
|
|
79
|
+
- After creating published app
|
|
80
|
+
- Deploy app to workspace
|
|
81
|
+
- Share with specific teams
|
|
82
|
+
- Grant individual access
|
|
83
|
+
- Expand app availability
|
|
84
|
+
|
|
85
|
+
**When NOT to Use:**
|
|
86
|
+
- For development apps (typically private)
|
|
87
|
+
- Removing access (use remove_app_member)
|
|
88
|
+
- Changing app ownership (not supported)
|
|
89
|
+
- Managing workspace members (different functionality)
|
|
90
|
+
|
|
91
|
+
## Core Concepts
|
|
92
|
+
|
|
93
|
+
### Member vs Access
|
|
94
|
+
|
|
95
|
+
**Member:**
|
|
96
|
+
- Entity that has access to app
|
|
97
|
+
- Can be workspace, team, or user
|
|
98
|
+
- Added via add_app_member
|
|
99
|
+
- Removed via remove_app_member
|
|
100
|
+
|
|
101
|
+
**Access levels:**
|
|
102
|
+
- All members have same access level
|
|
103
|
+
- Can view and use the app
|
|
104
|
+
- No distinction between viewer/editor
|
|
105
|
+
- Owner has additional permissions (edit, delete, share)
|
|
106
|
+
|
|
107
|
+
### Visibility Model
|
|
108
|
+
|
|
109
|
+
**Before sharing:**
|
|
110
|
+
```
|
|
111
|
+
App created → Only owner can see it
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**After sharing with workspace:**
|
|
115
|
+
```
|
|
116
|
+
App created → Shared with workspace → Everyone can see it
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**After sharing with team:**
|
|
120
|
+
```
|
|
121
|
+
App created → Shared with team → Team members can see it
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Member Prefixes
|
|
125
|
+
|
|
126
|
+
**Critical:** Member IDs must have correct prefix:
|
|
127
|
+
|
|
128
|
+
| Type | Prefix | Example | Who Gets Access |
|
|
129
|
+
|------|--------|---------|-----------------|
|
|
130
|
+
| Workspace | `network_` | `network_68446...` | Everyone in workspace |
|
|
131
|
+
| Team | `team_` | `team_68446...` | All team members |
|
|
132
|
+
| User | `user_` | `user_68446...` | Single user |
|
|
133
|
+
|
|
134
|
+
**Wrong prefix = Error**
|
|
135
|
+
|
|
136
|
+
## Member Types
|
|
137
|
+
|
|
138
|
+
### Workspace Members (network_)
|
|
139
|
+
|
|
140
|
+
**Share with entire workspace:**
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
add_app_member({
|
|
144
|
+
appId: 'app-id',
|
|
145
|
+
member: 'network_workspace-id'
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Who gets access:**
|
|
150
|
+
- All current workspace members
|
|
151
|
+
- New members joining workspace
|
|
152
|
+
- Workspace-wide availability
|
|
153
|
+
|
|
154
|
+
**Use when:**
|
|
155
|
+
- App is for everyone
|
|
156
|
+
- General-purpose workspace tool
|
|
157
|
+
- No access restrictions needed
|
|
158
|
+
- Maximum visibility desired
|
|
159
|
+
|
|
160
|
+
**Getting workspace ID:**
|
|
161
|
+
```javascript
|
|
162
|
+
const workspace = get_current_workspace()
|
|
163
|
+
const memberId = `network_${workspace._id}`
|
|
164
|
+
|
|
165
|
+
add_app_member({
|
|
166
|
+
appId: 'app-id',
|
|
167
|
+
member: memberId
|
|
168
|
+
})
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Team Members (team_)
|
|
172
|
+
|
|
173
|
+
**Share with specific team:**
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
add_app_member({
|
|
177
|
+
appId: 'app-id',
|
|
178
|
+
member: 'team_team-id'
|
|
179
|
+
})
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Who gets access:**
|
|
183
|
+
- All current team members
|
|
184
|
+
- New members joining team
|
|
185
|
+
- Team-specific access
|
|
186
|
+
|
|
187
|
+
**Use when:**
|
|
188
|
+
- App is for specific team/department
|
|
189
|
+
- Need access control
|
|
190
|
+
- Team-specific functionality
|
|
191
|
+
- Limited distribution
|
|
192
|
+
|
|
193
|
+
**Getting team ID:**
|
|
194
|
+
```javascript
|
|
195
|
+
// From workspace cache or API
|
|
196
|
+
const teamId = 'team-id-here'
|
|
197
|
+
const memberId = `team_${teamId}`
|
|
198
|
+
|
|
199
|
+
add_app_member({
|
|
200
|
+
appId: 'app-id',
|
|
201
|
+
member: memberId
|
|
202
|
+
})
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Individual Users (user_)
|
|
206
|
+
|
|
207
|
+
**Share with single user:**
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
add_app_member({
|
|
211
|
+
appId: 'app-id',
|
|
212
|
+
member: 'user_user-id'
|
|
213
|
+
})
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Who gets access:**
|
|
217
|
+
- Single specified user only
|
|
218
|
+
- Most restrictive access
|
|
219
|
+
|
|
220
|
+
**Use when:**
|
|
221
|
+
- Beta testing with specific users
|
|
222
|
+
- Privileged access
|
|
223
|
+
- Personal tools
|
|
224
|
+
- Gradual rollout
|
|
225
|
+
|
|
226
|
+
**Getting user ID:**
|
|
227
|
+
```javascript
|
|
228
|
+
// Search for user
|
|
229
|
+
const users = search_workspace_users({ query: 'john@example.com' })
|
|
230
|
+
const user = users[0]
|
|
231
|
+
const memberId = `user_${user._id}`
|
|
232
|
+
|
|
233
|
+
add_app_member({
|
|
234
|
+
appId: 'app-id',
|
|
235
|
+
member: memberId
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Basic Usage
|
|
240
|
+
|
|
241
|
+
### Example 1: Share with Workspace
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
// 1. Get workspace ID
|
|
245
|
+
const workspace = get_current_workspace()
|
|
246
|
+
console.log('Workspace:', workspace.name)
|
|
247
|
+
|
|
248
|
+
// 2. Share app with entire workspace
|
|
249
|
+
add_app_member({
|
|
250
|
+
appId: 'app-id',
|
|
251
|
+
member: `network_${workspace._id}`
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
console.log('✅ App shared with entire workspace')
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Example 2: Share with Team
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
// 1. Have team ID (from workspace data or API)
|
|
261
|
+
const teamId = 'team-id'
|
|
262
|
+
|
|
263
|
+
// 2. Share with team
|
|
264
|
+
add_app_member({
|
|
265
|
+
appId: 'app-id',
|
|
266
|
+
member: `team_${teamId}`
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
console.log('✅ App shared with team')
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Example 3: Share with Individual User
|
|
273
|
+
|
|
274
|
+
```javascript
|
|
275
|
+
// 1. Find user
|
|
276
|
+
const users = search_workspace_users({ query: 'john.doe' })
|
|
277
|
+
const user = users[0]
|
|
278
|
+
|
|
279
|
+
if (!user) {
|
|
280
|
+
console.error('User not found')
|
|
281
|
+
return
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// 2. Share with user
|
|
285
|
+
add_app_member({
|
|
286
|
+
appId: 'app-id',
|
|
287
|
+
member: `user_${user._id}`
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
console.log(`✅ App shared with ${user.name}`)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Example 4: Share in Specific Workspace
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
add_app_member({
|
|
297
|
+
workspaceId: 'workspace-id',
|
|
298
|
+
appId: 'app-id',
|
|
299
|
+
member: 'network_workspace-id'
|
|
300
|
+
})
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Example 5: Complete Workflow
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
// Complete workflow: Create app → Share with workspace
|
|
307
|
+
|
|
308
|
+
// 1. Create app
|
|
309
|
+
const app = create_app({
|
|
310
|
+
name: 'Team Dashboard',
|
|
311
|
+
description: 'Real-time team metrics'
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
console.log('App created:', app.appId)
|
|
315
|
+
|
|
316
|
+
// 2. Build and publish app
|
|
317
|
+
// ... build and publish steps ...
|
|
318
|
+
|
|
319
|
+
// 3. Share with workspace
|
|
320
|
+
const workspace = get_current_workspace()
|
|
321
|
+
add_app_member({
|
|
322
|
+
appId: app.appId,
|
|
323
|
+
member: `network_${workspace._id}`
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
console.log('✅ App published and shared with workspace')
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Sharing Strategies
|
|
330
|
+
|
|
331
|
+
### Strategy 1: Immediate Workspace Sharing
|
|
332
|
+
|
|
333
|
+
**Best for:** General-purpose tools
|
|
334
|
+
|
|
335
|
+
```javascript
|
|
336
|
+
// Create and immediately share
|
|
337
|
+
const app = create_app({
|
|
338
|
+
name: 'Task Manager',
|
|
339
|
+
description: 'Workspace task management'
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
// Share with everyone
|
|
343
|
+
const workspace = get_current_workspace()
|
|
344
|
+
add_app_member({
|
|
345
|
+
appId: app.appId,
|
|
346
|
+
member: `network_${workspace._id}`
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
console.log('✅ App available to entire workspace')
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Strategy 2: Gradual Rollout
|
|
353
|
+
|
|
354
|
+
**Best for:** Testing and validation
|
|
355
|
+
|
|
356
|
+
```javascript
|
|
357
|
+
// Phase 1: Share with specific users (beta testers)
|
|
358
|
+
const betaUsers = ['user1-id', 'user2-id', 'user3-id']
|
|
359
|
+
|
|
360
|
+
betaUsers.forEach(userId => {
|
|
361
|
+
add_app_member({
|
|
362
|
+
appId: 'app-id',
|
|
363
|
+
member: `user_${userId}`
|
|
364
|
+
})
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
console.log('Phase 1: Beta testing with selected users')
|
|
368
|
+
|
|
369
|
+
// Phase 2: Share with team (after feedback)
|
|
370
|
+
add_app_member({
|
|
371
|
+
appId: 'app-id',
|
|
372
|
+
member: 'team_team-id'
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
console.log('Phase 2: Rolled out to team')
|
|
376
|
+
|
|
377
|
+
// Phase 3: Share with workspace (after validation)
|
|
378
|
+
const workspace = get_current_workspace()
|
|
379
|
+
add_app_member({
|
|
380
|
+
appId: 'app-id',
|
|
381
|
+
member: `network_${workspace._id}`
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
console.log('Phase 3: Available to entire workspace')
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Strategy 3: Team-Based Distribution
|
|
388
|
+
|
|
389
|
+
**Best for:** Department-specific tools
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
// Share with multiple teams
|
|
393
|
+
const teams = [
|
|
394
|
+
{ id: 'sales-team-id', name: 'Sales' },
|
|
395
|
+
{ id: 'support-team-id', name: 'Support' }
|
|
396
|
+
]
|
|
397
|
+
|
|
398
|
+
teams.forEach(team => {
|
|
399
|
+
add_app_member({
|
|
400
|
+
appId: 'app-id',
|
|
401
|
+
member: `team_${team.id}`
|
|
402
|
+
})
|
|
403
|
+
console.log(`✅ Shared with ${team.name} team`)
|
|
404
|
+
})
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Strategy 4: Role-Based Access
|
|
408
|
+
|
|
409
|
+
**Best for:** Privileged tools
|
|
410
|
+
|
|
411
|
+
```javascript
|
|
412
|
+
// Share only with admins and managers
|
|
413
|
+
const privilegedUsers = [
|
|
414
|
+
'admin-user-id-1',
|
|
415
|
+
'admin-user-id-2',
|
|
416
|
+
'manager-user-id-1'
|
|
417
|
+
]
|
|
418
|
+
|
|
419
|
+
privilegedUsers.forEach(userId => {
|
|
420
|
+
add_app_member({
|
|
421
|
+
appId: 'app-id',
|
|
422
|
+
member: `user_${userId}`
|
|
423
|
+
})
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
console.log('✅ Shared with privileged users only')
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
## Common Scenarios
|
|
430
|
+
|
|
431
|
+
### Scenario 1: Publish New App to Workspace
|
|
432
|
+
|
|
433
|
+
**Goal:** Make newly created app available to everyone.
|
|
434
|
+
|
|
435
|
+
```javascript
|
|
436
|
+
// 1. Create published app
|
|
437
|
+
const app = create_app({
|
|
438
|
+
name: 'Project Dashboard',
|
|
439
|
+
description: 'Real-time project tracking dashboard'
|
|
440
|
+
})
|
|
441
|
+
|
|
442
|
+
// 2. Update manifest.json with appId
|
|
443
|
+
// ... manual step ...
|
|
444
|
+
|
|
445
|
+
// 3. Build and publish
|
|
446
|
+
// ... build and publish steps ...
|
|
447
|
+
|
|
448
|
+
// 4. Share with entire workspace
|
|
449
|
+
const workspace = get_current_workspace()
|
|
450
|
+
add_app_member({
|
|
451
|
+
appId: app.appId,
|
|
452
|
+
member: `network_${workspace._id}`
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
console.log('✅ App published and available to workspace')
|
|
456
|
+
console.log('Users can now access app from Apps menu')
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### Scenario 2: Share Existing App with Team
|
|
460
|
+
|
|
461
|
+
**Goal:** Give team access to existing app.
|
|
462
|
+
|
|
463
|
+
```javascript
|
|
464
|
+
// 1. Find app
|
|
465
|
+
const apps = list_apps()
|
|
466
|
+
const app = apps.find(a => a.name === 'Analytics Dashboard')
|
|
467
|
+
|
|
468
|
+
if (!app) {
|
|
469
|
+
console.error('App not found')
|
|
470
|
+
return
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// 2. Share with team
|
|
474
|
+
const teamId = 'marketing-team-id'
|
|
475
|
+
add_app_member({
|
|
476
|
+
appId: app._id,
|
|
477
|
+
member: `team_${teamId}`
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
console.log('✅ Analytics Dashboard shared with Marketing team')
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Scenario 3: Beta Testing with Selected Users
|
|
484
|
+
|
|
485
|
+
**Goal:** Test app with specific users before wide release.
|
|
486
|
+
|
|
487
|
+
```javascript
|
|
488
|
+
// Find app
|
|
489
|
+
const app = list_apps().find(a => a.name === 'New Feature App')
|
|
490
|
+
|
|
491
|
+
// Beta tester emails
|
|
492
|
+
const betaTesters = [
|
|
493
|
+
'alice@example.com',
|
|
494
|
+
'bob@example.com',
|
|
495
|
+
'charlie@example.com'
|
|
496
|
+
]
|
|
497
|
+
|
|
498
|
+
// Share with each beta tester
|
|
499
|
+
betaTesters.forEach(email => {
|
|
500
|
+
const users = search_workspace_users({ query: email })
|
|
501
|
+
const user = users[0]
|
|
502
|
+
|
|
503
|
+
if (user) {
|
|
504
|
+
add_app_member({
|
|
505
|
+
appId: app._id,
|
|
506
|
+
member: `user_${user._id}`
|
|
507
|
+
})
|
|
508
|
+
console.log(`✅ Shared with ${user.name}`)
|
|
509
|
+
} else {
|
|
510
|
+
console.warn(`⚠️ User not found: ${email}`)
|
|
511
|
+
}
|
|
512
|
+
})
|
|
513
|
+
|
|
514
|
+
console.log('Beta testing phase initiated')
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### Scenario 4: Share Multiple Apps with Team
|
|
518
|
+
|
|
519
|
+
**Goal:** Give team access to suite of apps.
|
|
520
|
+
|
|
521
|
+
```javascript
|
|
522
|
+
// Team ID
|
|
523
|
+
const teamId = 'sales-team-id'
|
|
524
|
+
|
|
525
|
+
// App names to share
|
|
526
|
+
const appNames = [
|
|
527
|
+
'CRM Dashboard',
|
|
528
|
+
'Sales Pipeline',
|
|
529
|
+
'Customer Insights',
|
|
530
|
+
'Reporting Tool'
|
|
531
|
+
]
|
|
532
|
+
|
|
533
|
+
// Get all apps
|
|
534
|
+
const apps = list_apps()
|
|
535
|
+
|
|
536
|
+
// Share each app with team
|
|
537
|
+
appNames.forEach(name => {
|
|
538
|
+
const app = apps.find(a => a.name === name)
|
|
539
|
+
|
|
540
|
+
if (app) {
|
|
541
|
+
add_app_member({
|
|
542
|
+
appId: app._id,
|
|
543
|
+
member: `team_${teamId}`
|
|
544
|
+
})
|
|
545
|
+
console.log(`✅ Shared ${name}`)
|
|
546
|
+
} else {
|
|
547
|
+
console.warn(`⚠️ App not found: ${name}`)
|
|
548
|
+
}
|
|
549
|
+
})
|
|
550
|
+
|
|
551
|
+
console.log('Sales team now has access to all tools')
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### Scenario 5: Migrate from Team to Workspace
|
|
555
|
+
|
|
556
|
+
**Goal:** Expand app from team-only to workspace-wide.
|
|
557
|
+
|
|
558
|
+
```javascript
|
|
559
|
+
// App currently shared with team, expand to workspace
|
|
560
|
+
|
|
561
|
+
const app = list_apps().find(a => a.name === 'Report Generator')
|
|
562
|
+
|
|
563
|
+
// Check current members
|
|
564
|
+
console.log('Current members:', app.members)
|
|
565
|
+
|
|
566
|
+
// Add workspace access
|
|
567
|
+
const workspace = get_current_workspace()
|
|
568
|
+
add_app_member({
|
|
569
|
+
appId: app._id,
|
|
570
|
+
member: `network_${workspace._id}`
|
|
571
|
+
})
|
|
572
|
+
|
|
573
|
+
console.log('✅ App now available to entire workspace')
|
|
574
|
+
console.log('Note: Team-specific access remains')
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Scenario 6: Share All Apps with New Team
|
|
578
|
+
|
|
579
|
+
**Goal:** Give newly created team access to all existing apps.
|
|
580
|
+
|
|
581
|
+
```javascript
|
|
582
|
+
// New team created
|
|
583
|
+
const newTeamId = 'new-team-id'
|
|
584
|
+
|
|
585
|
+
// Get all apps you own
|
|
586
|
+
const apps = list_apps()
|
|
587
|
+
const myApps = apps.filter(a => a.isOwner && !a.url) // Published apps only
|
|
588
|
+
|
|
589
|
+
console.log(`Sharing ${myApps.length} apps with new team`)
|
|
590
|
+
|
|
591
|
+
// Share each app
|
|
592
|
+
myApps.forEach(app => {
|
|
593
|
+
add_app_member({
|
|
594
|
+
appId: app._id,
|
|
595
|
+
member: `team_${newTeamId}`
|
|
596
|
+
})
|
|
597
|
+
console.log(`✅ Shared ${app.name}`)
|
|
598
|
+
})
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
## Best Practices
|
|
602
|
+
|
|
603
|
+
### 1. Share After Publishing, Not Before
|
|
604
|
+
|
|
605
|
+
```javascript
|
|
606
|
+
// Good: Create → Publish → Share
|
|
607
|
+
const app = create_app({ name: 'My App' })
|
|
608
|
+
// ... build and publish ...
|
|
609
|
+
add_app_member({
|
|
610
|
+
appId: app.appId,
|
|
611
|
+
member: 'network_workspace-id'
|
|
612
|
+
})
|
|
613
|
+
|
|
614
|
+
// Bad: Create → Share → Publish
|
|
615
|
+
// Users might access incomplete app
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### 2. Use Correct Member Prefix
|
|
619
|
+
|
|
620
|
+
```javascript
|
|
621
|
+
// Good: Correct prefixes
|
|
622
|
+
add_app_member({
|
|
623
|
+
appId: 'app-id',
|
|
624
|
+
member: 'network_workspace-id' // ✅
|
|
625
|
+
})
|
|
626
|
+
|
|
627
|
+
add_app_member({
|
|
628
|
+
appId: 'app-id',
|
|
629
|
+
member: 'team_team-id' // ✅
|
|
630
|
+
})
|
|
631
|
+
|
|
632
|
+
// Bad: Missing prefix
|
|
633
|
+
add_app_member({
|
|
634
|
+
appId: 'app-id',
|
|
635
|
+
member: 'workspace-id' // ❌ Error!
|
|
636
|
+
})
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### 3. Verify App Exists Before Sharing
|
|
640
|
+
|
|
641
|
+
```javascript
|
|
642
|
+
// Always verify
|
|
643
|
+
const apps = list_apps()
|
|
644
|
+
const app = apps.find(a => a._id === 'app-id')
|
|
645
|
+
|
|
646
|
+
if (!app) {
|
|
647
|
+
console.error('App not found')
|
|
648
|
+
return
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (!app.isOwner && !app.isAdmin) {
|
|
652
|
+
console.error('No permission to share')
|
|
653
|
+
return
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Safe to share
|
|
657
|
+
add_app_member({
|
|
658
|
+
appId: app._id,
|
|
659
|
+
member: 'network_workspace-id'
|
|
660
|
+
})
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
### 4. Start Restrictive, Expand Later
|
|
664
|
+
|
|
665
|
+
```javascript
|
|
666
|
+
// Start with limited access
|
|
667
|
+
add_app_member({
|
|
668
|
+
appId: 'app-id',
|
|
669
|
+
member: 'team_team-id'
|
|
670
|
+
})
|
|
671
|
+
|
|
672
|
+
// Later, expand to workspace
|
|
673
|
+
// (Don't remove team access, add workspace access)
|
|
674
|
+
add_app_member({
|
|
675
|
+
appId: 'app-id',
|
|
676
|
+
member: 'network_workspace-id'
|
|
677
|
+
})
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
### 5. Document Sharing Decisions
|
|
681
|
+
|
|
682
|
+
```javascript
|
|
683
|
+
// Log sharing for audit trail
|
|
684
|
+
console.log({
|
|
685
|
+
action: 'add_app_member',
|
|
686
|
+
appId: 'app-id',
|
|
687
|
+
appName: 'Dashboard',
|
|
688
|
+
member: 'network_workspace-id',
|
|
689
|
+
memberType: 'workspace',
|
|
690
|
+
date: new Date().toISOString(),
|
|
691
|
+
sharedBy: 'admin-user-id'
|
|
692
|
+
})
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### 6. Don't Share Development Apps
|
|
696
|
+
|
|
697
|
+
```javascript
|
|
698
|
+
const apps = list_apps()
|
|
699
|
+
|
|
700
|
+
apps.forEach(app => {
|
|
701
|
+
// Only share published apps
|
|
702
|
+
if (app.url) {
|
|
703
|
+
console.log(`Skipping dev app: ${app.name}`)
|
|
704
|
+
return
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// Share published apps
|
|
708
|
+
add_app_member({
|
|
709
|
+
appId: app._id,
|
|
710
|
+
member: 'network_workspace-id'
|
|
711
|
+
})
|
|
712
|
+
})
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### 7. Batch Share Operations
|
|
716
|
+
|
|
717
|
+
```javascript
|
|
718
|
+
// Share multiple apps efficiently
|
|
719
|
+
const appIds = ['app-id-1', 'app-id-2', 'app-id-3']
|
|
720
|
+
const member = 'team_team-id'
|
|
721
|
+
|
|
722
|
+
appIds.forEach(appId => {
|
|
723
|
+
add_app_member({ appId, member })
|
|
724
|
+
console.log(`✅ Shared ${appId}`)
|
|
725
|
+
})
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
## Troubleshooting
|
|
729
|
+
|
|
730
|
+
### Error: "Permission Denied"
|
|
731
|
+
|
|
732
|
+
**Cause:** Not app owner or workspace administrator.
|
|
733
|
+
|
|
734
|
+
**Solution:**
|
|
735
|
+
|
|
736
|
+
```javascript
|
|
737
|
+
const app = list_apps().find(a => a._id === 'app-id')
|
|
738
|
+
|
|
739
|
+
console.log('Owner:', app.isOwner)
|
|
740
|
+
console.log('Admin:', app.isAdmin)
|
|
741
|
+
|
|
742
|
+
if (!app.isOwner && !app.isAdmin) {
|
|
743
|
+
console.error('Cannot share - not owner or admin')
|
|
744
|
+
console.log('App owner:', app.owner)
|
|
745
|
+
}
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Error: "Invalid Member ID"
|
|
749
|
+
|
|
750
|
+
**Cause:** Wrong member ID format.
|
|
751
|
+
|
|
752
|
+
**Solution:**
|
|
753
|
+
|
|
754
|
+
```javascript
|
|
755
|
+
// Must have correct prefix
|
|
756
|
+
// ❌ Wrong:
|
|
757
|
+
member: 'workspace-id'
|
|
758
|
+
member: 'team-id'
|
|
759
|
+
member: 'user-id'
|
|
760
|
+
|
|
761
|
+
// ✅ Correct:
|
|
762
|
+
member: 'network_workspace-id'
|
|
763
|
+
member: 'team_team-id'
|
|
764
|
+
member: 'user_user-id'
|
|
765
|
+
|
|
766
|
+
// Get workspace ID properly
|
|
767
|
+
const workspace = get_current_workspace()
|
|
768
|
+
const correctMember = `network_${workspace._id}`
|
|
769
|
+
|
|
770
|
+
add_app_member({
|
|
771
|
+
appId: 'app-id',
|
|
772
|
+
member: correctMember
|
|
773
|
+
})
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
### Error: "App Not Found"
|
|
777
|
+
|
|
778
|
+
**Cause:** Invalid app ID.
|
|
779
|
+
|
|
780
|
+
**Solution:**
|
|
781
|
+
|
|
782
|
+
```javascript
|
|
783
|
+
// List apps to find correct ID
|
|
784
|
+
const apps = list_apps()
|
|
785
|
+
apps.forEach(a => {
|
|
786
|
+
console.log(`${a.name}: ${a._id}`)
|
|
787
|
+
})
|
|
788
|
+
|
|
789
|
+
// Use correct ID
|
|
790
|
+
add_app_member({
|
|
791
|
+
appId: 'correct-app-id',
|
|
792
|
+
member: 'network_workspace-id'
|
|
793
|
+
})
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Member Added But App Not Visible
|
|
797
|
+
|
|
798
|
+
**Causes:**
|
|
799
|
+
1. Browser cache
|
|
800
|
+
2. User not logged in
|
|
801
|
+
3. Wrong member ID
|
|
802
|
+
4. App not published yet
|
|
803
|
+
|
|
804
|
+
**Solutions:**
|
|
805
|
+
|
|
806
|
+
```javascript
|
|
807
|
+
// 1. Verify member added
|
|
808
|
+
const app = list_apps().find(a => a._id === 'app-id')
|
|
809
|
+
console.log('Members:', app.members)
|
|
810
|
+
|
|
811
|
+
// 2. Check if member ID is in list
|
|
812
|
+
const memberExists = app.members.includes('network_workspace-id')
|
|
813
|
+
console.log('Member added:', memberExists)
|
|
814
|
+
|
|
815
|
+
// 3. User should refresh browser
|
|
816
|
+
console.log('⚠️ Users need to refresh browser to see new apps')
|
|
817
|
+
|
|
818
|
+
// 4. Verify app is published (not dev)
|
|
819
|
+
console.log('App type:', app.url ? 'Dev (not visible)' : 'Published')
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
### Shared with Workspace But User Can't Access
|
|
823
|
+
|
|
824
|
+
**Causes:**
|
|
825
|
+
1. User not in workspace
|
|
826
|
+
2. User needs to refresh
|
|
827
|
+
3. App entry exists but code not published
|
|
828
|
+
|
|
829
|
+
**Solutions:**
|
|
830
|
+
|
|
831
|
+
```javascript
|
|
832
|
+
// Verify sharing
|
|
833
|
+
const app = list_apps().find(a => a._id === 'app-id')
|
|
834
|
+
const workspace = get_current_workspace()
|
|
835
|
+
const workspaceMember = `network_${workspace._id}`
|
|
836
|
+
|
|
837
|
+
if (app.members.includes(workspaceMember)) {
|
|
838
|
+
console.log('✅ Shared with workspace')
|
|
839
|
+
console.log('ℹ️ Users should refresh browser')
|
|
840
|
+
console.log('ℹ️ Verify app code is published')
|
|
841
|
+
} else {
|
|
842
|
+
console.log('❌ Not shared with workspace')
|
|
843
|
+
}
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
## Integration with Other Tools
|
|
847
|
+
|
|
848
|
+
### With create_app
|
|
849
|
+
|
|
850
|
+
Create and share:
|
|
851
|
+
|
|
852
|
+
```javascript
|
|
853
|
+
// 1. Create app
|
|
854
|
+
const app = create_app({
|
|
855
|
+
name: 'Dashboard'
|
|
856
|
+
})
|
|
857
|
+
|
|
858
|
+
// 2. Build and publish
|
|
859
|
+
// ...
|
|
860
|
+
|
|
861
|
+
// 3. Share
|
|
862
|
+
const workspace = get_current_workspace()
|
|
863
|
+
add_app_member({
|
|
864
|
+
appId: app.appId,
|
|
865
|
+
member: `network_${workspace._id}`
|
|
866
|
+
})
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
### With list_apps
|
|
870
|
+
|
|
871
|
+
Find and share:
|
|
872
|
+
|
|
873
|
+
```javascript
|
|
874
|
+
// 1. Find app
|
|
875
|
+
const app = list_apps().find(a => a.name === 'Report Tool')
|
|
876
|
+
|
|
877
|
+
// 2. Share
|
|
878
|
+
if (app && app.isOwner) {
|
|
879
|
+
add_app_member({
|
|
880
|
+
appId: app._id,
|
|
881
|
+
member: 'team_team-id'
|
|
882
|
+
})
|
|
883
|
+
}
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
### With publish_hailer_app
|
|
887
|
+
|
|
888
|
+
Publish then share:
|
|
889
|
+
|
|
890
|
+
```javascript
|
|
891
|
+
// 1. Publish app
|
|
892
|
+
publish_hailer_app({
|
|
893
|
+
email: 'your@email.com',
|
|
894
|
+
password: 'password',
|
|
895
|
+
projectDirectory: '/path/to/app'
|
|
896
|
+
})
|
|
897
|
+
|
|
898
|
+
// 2. Share with workspace
|
|
899
|
+
const app = list_apps().find(a => a.name === 'My App')
|
|
900
|
+
const workspace = get_current_workspace()
|
|
901
|
+
|
|
902
|
+
add_app_member({
|
|
903
|
+
appId: app._id,
|
|
904
|
+
member: `network_${workspace._id}`
|
|
905
|
+
})
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
### With search_workspace_users
|
|
909
|
+
|
|
910
|
+
Find user and share:
|
|
911
|
+
|
|
912
|
+
```javascript
|
|
913
|
+
// 1. Find user
|
|
914
|
+
const users = search_workspace_users({ query: 'john' })
|
|
915
|
+
const user = users[0]
|
|
916
|
+
|
|
917
|
+
// 2. Share app with user
|
|
918
|
+
if (user) {
|
|
919
|
+
add_app_member({
|
|
920
|
+
appId: 'app-id',
|
|
921
|
+
member: `user_${user._id}`
|
|
922
|
+
})
|
|
923
|
+
console.log(`✅ Shared with ${user.name}`)
|
|
924
|
+
}
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
### With remove_app_member
|
|
928
|
+
|
|
929
|
+
Grant then revoke:
|
|
930
|
+
|
|
931
|
+
```javascript
|
|
932
|
+
// Grant access
|
|
933
|
+
add_app_member({
|
|
934
|
+
appId: 'app-id',
|
|
935
|
+
member: 'user_user-id'
|
|
936
|
+
})
|
|
937
|
+
|
|
938
|
+
// Later, revoke access
|
|
939
|
+
remove_app_member({
|
|
940
|
+
appId: 'app-id',
|
|
941
|
+
member: 'user_user-id'
|
|
942
|
+
})
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
## Summary
|
|
946
|
+
|
|
947
|
+
**Key Takeaways:**
|
|
948
|
+
1. 🔓 **Grants access** - Makes app visible to members
|
|
949
|
+
2. 🔒 **Owner/admin only** - Requires permissions
|
|
950
|
+
3. 🌐 **Three levels** - Workspace, team, or user
|
|
951
|
+
4. 🏷️ **Prefix required** - `network_`, `team_`, or `user_`
|
|
952
|
+
5. 📱 **After publishing** - Share published apps, not dev apps
|
|
953
|
+
6. 🔄 **Additive** - Can share with multiple members
|
|
954
|
+
7. ✅ **Immediate effect** - Access granted right away
|
|
955
|
+
|
|
956
|
+
**Quick Decision Tree:**
|
|
957
|
+
|
|
958
|
+
```
|
|
959
|
+
Need to share app?
|
|
960
|
+
│
|
|
961
|
+
├─ For everyone? → network_workspace-id
|
|
962
|
+
├─ For specific team? → team_team-id
|
|
963
|
+
├─ For one person? → user_user-id
|
|
964
|
+
├─ Beta testing? → Share with selected users first
|
|
965
|
+
├─ Dev app? → Don't share (keep private)
|
|
966
|
+
└─ After sharing? → Users refresh browser to see
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
## Additional Resources
|
|
970
|
+
|
|
971
|
+
- See `create-app-skill` for creating apps
|
|
972
|
+
- See `list-apps-skill` for viewing apps
|
|
973
|
+
- See `remove-app-member-skill` for revoking access
|
|
974
|
+
- See `publish-hailer-app-skill` for publishing apps
|
|
975
|
+
- See `app-api` skill for comprehensive App API documentation
|
|
976
|
+
- Use `search_workspace_users` to find user IDs
|
|
977
|
+
- Use `get_current_workspace` to get workspace ID
|