@hailer/mcp 0.0.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/.claude/agents/ada.md +127 -0
  2. package/.claude/agents/agent-builder.md +151 -0
  3. package/.claude/agents/alejandro.md +66 -0
  4. package/.claude/agents/bjorn.md +305 -0
  5. package/.claude/agents/dmitri.md +61 -0
  6. package/.claude/agents/giuseppe.md +66 -0
  7. package/.claude/agents/gunther.md +355 -0
  8. package/.claude/agents/helga.md +68 -0
  9. package/.claude/agents/kenji.md +58 -0
  10. package/.claude/agents/svetlana.md +394 -0
  11. package/.claude/agents/viktor.md +63 -0
  12. package/.claude/agents/yevgeni.md +60 -0
  13. package/.claude/hooks/agent-failure-detector.cjs +286 -0
  14. package/.claude/hooks/app-edit-guard.cjs +462 -0
  15. package/.claude/hooks/interactive-mode.cjs +59 -0
  16. package/.claude/hooks/mcp-server-guard.cjs +92 -0
  17. package/.claude/hooks/post-scaffold-hook.cjs +31 -0
  18. package/.claude/hooks/src-edit-guard.cjs +208 -0
  19. package/.claude/settings.json +47 -2
  20. package/.claude/skills/insight-join-patterns/SKILL.md +209 -0
  21. package/.env.example +13 -1
  22. package/CLAUDE.md +134 -0
  23. package/dist/app.js +4 -3
  24. package/dist/cli.js +0 -0
  25. package/dist/client/adaptive-documentation-bot.d.ts +0 -2
  26. package/dist/client/adaptive-documentation-bot.js +5 -16
  27. package/dist/client/message-processor.js +5 -0
  28. package/dist/client/providers/anthropic-provider.js +21 -7
  29. package/dist/mcp/UserContextCache.d.ts +14 -0
  30. package/dist/mcp/UserContextCache.js +49 -24
  31. package/dist/mcp/auth.d.ts +7 -0
  32. package/dist/mcp/auth.js +13 -5
  33. package/dist/mcp/hailer-clients.d.ts +5 -2
  34. package/dist/mcp/signal-handler.d.ts +28 -2
  35. package/dist/mcp/signal-handler.js +4 -2
  36. package/dist/mcp/tool-registry.d.ts +55 -2
  37. package/dist/mcp/tool-registry.js +197 -2
  38. package/dist/mcp/tools/app-core.d.ts +15 -0
  39. package/dist/mcp/tools/app-core.js +609 -0
  40. package/dist/mcp/tools/app-marketplace.d.ts +21 -0
  41. package/dist/mcp/tools/app-marketplace.js +1284 -0
  42. package/dist/mcp/tools/app-member.d.ts +11 -0
  43. package/dist/mcp/tools/app-member.js +258 -0
  44. package/dist/mcp/tools/app-scaffold.d.ts +11 -0
  45. package/dist/mcp/tools/app-scaffold.js +743 -0
  46. package/dist/mcp/tools/app.d.ts +13 -22
  47. package/dist/mcp/tools/app.js +17 -2466
  48. package/dist/mcp/tools/file.js +6 -6
  49. package/dist/mcp/tools/insight.d.ts +1 -0
  50. package/dist/mcp/tools/insight.js +203 -64
  51. package/dist/mcp/tools/user.js +3 -9
  52. package/dist/mcp/tools/workflow.js +49 -38
  53. package/dist/mcp/utils/hailer-api-client.js +4 -13
  54. package/dist/mcp/utils/tool-helpers.d.ts +102 -0
  55. package/dist/mcp/utils/tool-helpers.js +179 -0
  56. package/dist/mcp/utils/types.d.ts +6 -0
  57. package/dist/mcp/workspace-cache.d.ts +5 -5
  58. package/dist/mcp/workspace-cache.js +4 -3
  59. package/package.json +1 -1
  60. package/.claude/hooks/PreToolUse.sh +0 -52
  61. package/.claude/hooks/prompt-skill-loader.cjs +0 -553
  62. package/.claude/hooks/skill-loader.cjs +0 -142
  63. package/.claude/settings.local.json +0 -49
  64. package/.claude/skills/MCP-add-app-member-skill/SKILL.md +0 -977
  65. package/.claude/skills/MCP-build-data-app-skill/SKILL.md +0 -372
  66. package/.claude/skills/MCP-create-app-skill/SKILL.md +0 -1101
  67. package/.claude/skills/MCP-create-insight-skill/SKILL.md +0 -1317
  68. package/.claude/skills/MCP-get-insight-data-skill/SKILL.md +0 -1053
  69. package/.claude/skills/MCP-insight-api/SKILL.md +0 -185
  70. package/.claude/skills/MCP-insight-api/references/insight-endpoints.md +0 -514
  71. package/.claude/skills/MCP-install-workflow-skill/SKILL.md +0 -1056
  72. package/.claude/skills/MCP-list-apps-skill/SKILL.md +0 -1010
  73. package/.claude/skills/MCP-list-workflows-minimal-skill/SKILL.md +0 -992
  74. package/.claude/skills/MCP-local-first-skill/SKILL.md +0 -570
  75. package/.claude/skills/MCP-populate-workflow-data-skill/SKILL.md +0 -395
  76. package/.claude/skills/MCP-preview-insight-skill/SKILL.md +0 -1290
  77. package/.claude/skills/MCP-publish-hailer-app-skill/SKILL.md +0 -453
  78. package/.claude/skills/MCP-publish-template-skill/SKILL.md +0 -278
  79. package/.claude/skills/MCP-remove-app-member-skill/SKILL.md +0 -671
  80. package/.claude/skills/MCP-remove-app-skill/SKILL.md +0 -985
  81. package/.claude/skills/MCP-remove-insight-skill/SKILL.md +0 -1011
  82. package/.claude/skills/MCP-remove-workflow-skill/SKILL.md +0 -920
  83. package/.claude/skills/MCP-scaffold-hailer-app-skill/SKILL.md +0 -1314
  84. package/.claude/skills/MCP-update-app-skill/SKILL.md +0 -970
  85. package/.claude/skills/MCP-update-workflow-field-skill/SKILL.md +0 -1098
  86. package/.claude/skills/SDK-create-function-field-skill/SKILL.md +0 -313
  87. package/.claude/skills/SDK-generate-skill/SKILL.md +0 -223
  88. package/.claude/skills/SDK-init-skill/SKILL.md +0 -177
  89. package/.claude/skills/SDK-workspace-setup-skill/SKILL.md +0 -605
  90. package/.claude/skills/SDK-ws-config-skill/SKILL.md +0 -435
  91. package/.claude/skills/activity-api/SKILL.md +0 -96
  92. package/.claude/skills/activity-api/references/activity-endpoints.md +0 -845
  93. package/.claude/skills/agent-building/SKILL.md +0 -243
  94. package/.claude/skills/agent-building/references/architecture-patterns.md +0 -446
  95. package/.claude/skills/agent-building/references/code-examples.md +0 -587
  96. package/.claude/skills/agent-building/references/implementation-guide.md +0 -619
  97. package/.claude/skills/app-api/SKILL.md +0 -219
  98. package/.claude/skills/app-api/references/app-endpoints.md +0 -759
  99. package/.claude/skills/building-hailer-apps-skill/SKILL.md +0 -813
  100. package/.claude/skills/hailer-api/SKILL.md +0 -283
  101. package/.claude/skills/hailer-api/references/activities.md +0 -620
  102. package/.claude/skills/hailer-api/references/authentication.md +0 -216
  103. package/.claude/skills/hailer-api/references/datasets.md +0 -437
  104. package/.claude/skills/hailer-api/references/files.md +0 -301
  105. package/.claude/skills/hailer-api/references/insights.md +0 -469
  106. package/.claude/skills/hailer-api/references/workflows.md +0 -720
  107. package/.claude/skills/hailer-api/references/workspaces-users.md +0 -445
  108. package/.claude/skills/hailer-app-builder/SKILL.md +0 -340
  109. package/.claude/skills/mcp-tools/SKILL.md +0 -419
  110. package/.claude/skills/mcp-tools/references/api-endpoints.md +0 -499
  111. package/.claude/skills/mcp-tools/references/data-structures.md +0 -554
  112. package/.claude/skills/mcp-tools/references/implementation-patterns.md +0 -717
  113. package/.claude/skills/skill-testing/README.md +0 -137
  114. package/.claude/skills/skill-testing/SKILL.md +0 -348
  115. package/.claude/skills/skill-testing/references/test-patterns.md +0 -705
  116. package/.claude/skills/skill-testing/references/testing-guide.md +0 -603
  117. package/.claude/skills/skill-testing/references/validation-checklist.md +0 -537
  118. package/.claude/skills/spawn-app-builder/SKILL.md +0 -366
  119. package/.claude/skills/tool-builder/SKILL.md +0 -328
  120. package/tsconfig.json +0 -23
@@ -0,0 +1,609 @@
1
+ "use strict";
2
+ /**
3
+ * App Tools - Core CRUD Operations
4
+ *
5
+ * Core app management tools:
6
+ * - Create apps (development and published)
7
+ * - List all apps in workspace
8
+ * - Update app properties
9
+ * - Remove apps
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.removeAppTool = exports.updateAppTool = exports.listAppsTool = exports.createAppTool = void 0;
13
+ const zod_1 = require("zod");
14
+ const tool_registry_1 = require("../tool-registry");
15
+ const logger_1 = require("../../lib/logger");
16
+ const tool_helpers_1 = require("../utils/tool-helpers");
17
+ const logger = (0, logger_1.createLogger)({ component: 'app-core' });
18
+ // ============================================================================
19
+ // CREATE APP TOOL
20
+ // ============================================================================
21
+ const createAppDescription = `🧪 [PLAYGROUND] Create App - Create Hailer app entry in workspace
22
+
23
+ **What are Apps?**
24
+ Apps are custom web applications that extend Hailer workspace functionality. Think React/vanilla JS apps running within Hailer.
25
+
26
+ **App Types**:
27
+ - **Development Apps**: URL points to localhost (e.g., http://localhost:3000)
28
+ - **Published Apps**: URL empty or points to production
29
+
30
+ **Example 1 - Development App**:
31
+ \`\`\`javascript
32
+ create_app({
33
+ name: 'Local Development',
34
+ description: 'App pointing to local server',
35
+ url: 'http://localhost:3000'
36
+ })
37
+ \`\`\`
38
+
39
+ **Example 2 - Published App**:
40
+ \`\`\`javascript
41
+ create_app({
42
+ name: 'Task Manager',
43
+ description: 'Production task management app',
44
+ url: '' // Empty for auto URL
45
+ })
46
+ \`\`\`
47
+
48
+ **Properties**:
49
+ - \`name\` (required) - App display name
50
+ - \`description\` (optional) - App description
51
+ - \`url\` (optional) - App URL or empty for auto-generated
52
+ - \`image\` (optional) - Image/icon ID
53
+
54
+ **Requirements**:
55
+ - User must be workspace administrator
56
+ - For published apps, leave URL empty
57
+
58
+ **Tips**:
59
+ - Use development apps for local testing
60
+ - Published apps get automatic URLs from Hailer
61
+ - Use \`add_app_member\` to share with others`;
62
+ exports.createAppTool = {
63
+ name: 'create_app',
64
+ group: tool_registry_1.ToolGroup.PLAYGROUND,
65
+ description: createAppDescription,
66
+ schema: zod_1.z.object({
67
+ workspaceId: zod_1.z
68
+ .string()
69
+ .optional()
70
+ .describe("Optional workspace ID - defaults to current workspace"),
71
+ name: zod_1.z
72
+ .string()
73
+ .min(1)
74
+ .describe("App name (required)"),
75
+ description: zod_1.z
76
+ .string()
77
+ .optional()
78
+ .describe("App description"),
79
+ url: zod_1.z
80
+ .string()
81
+ .optional()
82
+ .describe("App URL (empty for published apps, localhost for dev)"),
83
+ image: zod_1.z
84
+ .string()
85
+ .optional()
86
+ .describe("Image/icon ID (24 characters)"),
87
+ config: zod_1.z
88
+ .record(zod_1.z.unknown())
89
+ .optional()
90
+ .describe("Optional app configuration"),
91
+ }),
92
+ async execute(args, context) {
93
+ logger.debug('Creating app', {
94
+ name: args.name,
95
+ workspaceId: args.workspaceId,
96
+ hasUrl: !!args.url,
97
+ apiKey: context.apiKey.substring(0, 8) + '...'
98
+ });
99
+ try {
100
+ const workspaceId = (0, tool_helpers_1.getResolvedWorkspaceId)(args, context);
101
+ if (!workspaceId) {
102
+ return (0, tool_helpers_1.missingWorkspaceCacheResponse)();
103
+ }
104
+ logger.debug('Calling v3.app.create', {
105
+ workspaceId,
106
+ name: args.name
107
+ });
108
+ const appData = {
109
+ cid: workspaceId,
110
+ name: args.name
111
+ };
112
+ if (args.description)
113
+ appData.description = args.description;
114
+ if (args.url !== undefined)
115
+ appData.url = args.url;
116
+ if (args.image)
117
+ appData.image = args.image;
118
+ if (args.config)
119
+ appData.config = args.config;
120
+ const result = await context.hailer.request('v3.app.create', [appData]);
121
+ logger.debug('App creation successful', {
122
+ appId: result.appId || result._id
123
+ });
124
+ const appId = result.appId || result._id;
125
+ let responseText = `✅ **App Created Successfully**\n\n`;
126
+ responseText += `**App Name:** ${args.name}\n`;
127
+ responseText += `**App ID:** \`${appId}\`\n`;
128
+ responseText += `**Workspace:** ${workspaceId}\n`;
129
+ if (args.description) {
130
+ responseText += `**Description:** ${args.description}\n`;
131
+ }
132
+ if (args.url) {
133
+ responseText += `**URL:** ${args.url}\n`;
134
+ responseText += `**Type:** Development App (points to ${args.url})\n`;
135
+ }
136
+ else {
137
+ responseText += `**URL:** Auto-generated by Hailer\n`;
138
+ responseText += `**Type:** Published App\n`;
139
+ }
140
+ responseText += `\n💡 **Next Steps:**\n`;
141
+ responseText += `- Use \`list_apps\` to see all apps\n`;
142
+ responseText += `- Use \`add_app_member\` to share with users/teams\n`;
143
+ responseText += `- Use \`update_app\` to modify properties\n`;
144
+ if (!args.url) {
145
+ responseText += `\n📦 **Publishing:**\n`;
146
+ responseText += `1. Configure manifest.json with this appId: \`${appId}\`\n`;
147
+ responseText += `2. Run: \`EMAIL=your@email.com npm run publish-production\`\n`;
148
+ }
149
+ return {
150
+ content: [{
151
+ type: "text",
152
+ text: responseText,
153
+ }],
154
+ };
155
+ }
156
+ catch (error) {
157
+ logger.error("Error creating app", error);
158
+ const errorMessage = (0, tool_helpers_1.extractErrorMessage)(error);
159
+ if (errorMessage.toLowerCase().includes('permission')) {
160
+ return {
161
+ content: [{
162
+ type: "text",
163
+ text: `❌ **Permission Denied**\n\nYou don't have permission to create apps. Only workspace administrators can create apps.\n\n**Error:** ${errorMessage}`,
164
+ }],
165
+ };
166
+ }
167
+ return {
168
+ content: [{
169
+ type: "text",
170
+ text: `❌ **Error creating app**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Invalid workspace ID\n- Image ID must be 24 characters if provided`,
171
+ }],
172
+ };
173
+ }
174
+ }
175
+ };
176
+ // ============================================================================
177
+ // LIST APPS TOOL
178
+ // ============================================================================
179
+ const listAppsDescription = `🧪 [PLAYGROUND] List Apps - View all apps in workspace
180
+
181
+ **What it does**:
182
+ Lists all Hailer apps in the current workspace that you have access to.
183
+
184
+ **Example**:
185
+ \`\`\`javascript
186
+ list_apps()
187
+ \`\`\`
188
+
189
+ **Shows**:
190
+ - App name and description
191
+ - App ID
192
+ - URL (localhost for dev, auto for published)
193
+ - Creator and timestamps
194
+ - Configuration
195
+
196
+ **Use Cases**:
197
+ - See all workspace apps
198
+ - Find app IDs for updates
199
+ - Check which apps are development vs published
200
+ - Audit app configuration`;
201
+ exports.listAppsTool = {
202
+ name: 'list_apps',
203
+ group: tool_registry_1.ToolGroup.PLAYGROUND,
204
+ description: listAppsDescription,
205
+ schema: zod_1.z.object({
206
+ workspaceId: zod_1.z
207
+ .string()
208
+ .optional()
209
+ .describe("Optional workspace ID - defaults to current workspace"),
210
+ }),
211
+ async execute(args, context) {
212
+ logger.debug('Listing apps', {
213
+ workspaceId: args.workspaceId,
214
+ apiKey: context.apiKey.substring(0, 8) + '...'
215
+ });
216
+ try {
217
+ const workspaceId = (0, tool_helpers_1.getResolvedWorkspaceId)(args, context);
218
+ if (!workspaceId) {
219
+ return (0, tool_helpers_1.missingWorkspaceCacheResponse)();
220
+ }
221
+ logger.debug('Calling v3.app.list');
222
+ const result = await context.hailer.request('v3.app.list', [{}]);
223
+ // Handle multiple possible response structures:
224
+ // - { apps: [...] } - direct response
225
+ // - { details: { apps: [...] } } - wrapped in details
226
+ // - [...] - raw array
227
+ const apps = result?.apps || result?.details?.apps || (Array.isArray(result) ? result : []);
228
+ logger.debug('List apps successful', {
229
+ appCount: apps.length,
230
+ resultKeys: result ? Object.keys(result) : 'null'
231
+ });
232
+ let responseText = `✅ **Apps Retrieved**\n\n`;
233
+ responseText += `**Workspace:** ${workspaceId}\n\n`;
234
+ if (!apps || apps.length === 0) {
235
+ responseText += `**No apps found** in this workspace.\n\n`;
236
+ responseText += `💡 Use \`create_app\` to create your first app.`;
237
+ return {
238
+ content: [{
239
+ type: "text",
240
+ text: responseText,
241
+ }],
242
+ };
243
+ }
244
+ responseText += `**Total Apps:** ${apps.length}\n\n`;
245
+ apps.forEach((app) => {
246
+ responseText += `### ${app.name || 'Unnamed App'}\n`;
247
+ responseText += `- **App ID:** \`${app._id}\`\n`;
248
+ if (app.description) {
249
+ responseText += `- **Description:** ${app.description}\n`;
250
+ }
251
+ if (app.url) {
252
+ responseText += `- **URL:** ${app.url}\n`;
253
+ responseText += `- **Type:** ${app.url.includes('localhost') ? 'Development' : 'Custom URL'}\n`;
254
+ }
255
+ else {
256
+ responseText += `- **URL:** Auto-generated (Published App)\n`;
257
+ responseText += `- **Type:** Published\n`;
258
+ }
259
+ if (app.created) {
260
+ responseText += `- **Created:** ${new Date(app.created * 1000).toLocaleString()}\n`;
261
+ }
262
+ if (app.config && Object.keys(app.config).length > 0) {
263
+ responseText += `- **Config:** Present\n`;
264
+ }
265
+ responseText += `\n`;
266
+ });
267
+ responseText += `💡 **Next Steps:**\n`;
268
+ responseText += `- Use \`update_app\` to modify an app\n`;
269
+ responseText += `- Use \`add_app_member\` to share apps\n`;
270
+ responseText += `- Use \`remove_app\` to delete apps`;
271
+ return {
272
+ content: [{
273
+ type: "text",
274
+ text: responseText,
275
+ }],
276
+ };
277
+ }
278
+ catch (error) {
279
+ logger.error("Error listing apps", error);
280
+ const errorMessage = (0, tool_helpers_1.extractErrorMessage)(error);
281
+ return {
282
+ content: [{
283
+ type: "text",
284
+ text: `❌ **Error listing apps**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- Workspace not accessible\n- Permission issues`,
285
+ }],
286
+ };
287
+ }
288
+ }
289
+ };
290
+ // ============================================================================
291
+ // UPDATE APP TOOL
292
+ // ============================================================================
293
+ const updateAppDescription = `🧪 [PLAYGROUND] Update App - Modify app properties
294
+
295
+ **What it does**:
296
+ Updates an existing app's properties (name, description, URL, etc.).
297
+
298
+ **Example - Update name and description**:
299
+ \`\`\`javascript
300
+ update_app({
301
+ appId: '<app-id>',
302
+ name: 'Updated App Name',
303
+ description: 'New description'
304
+ })
305
+ \`\`\`
306
+
307
+ **Example - Change URL (dev to prod)**:
308
+ \`\`\`javascript
309
+ update_app({
310
+ appId: '<app-id>',
311
+ url: '' // Empty for published
312
+ })
313
+ \`\`\`
314
+
315
+ **Updatable Properties**:
316
+ - \`name\` - App display name
317
+ - \`description\` - App description
318
+ - \`url\` - App URL
319
+ - \`image\` - App icon ID
320
+ - \`config\` - App configuration
321
+
322
+ **Requirements**:
323
+ - User must be app creator or workspace admin
324
+
325
+ **Tips**:
326
+ - Only specified properties are updated
327
+ - Use \`list_apps\` to get app IDs`;
328
+ exports.updateAppTool = {
329
+ name: 'update_app',
330
+ group: tool_registry_1.ToolGroup.PLAYGROUND,
331
+ description: updateAppDescription,
332
+ schema: zod_1.z.object({
333
+ appId: zod_1.z
334
+ .string()
335
+ .min(1)
336
+ .describe("App ID to update"),
337
+ name: zod_1.z
338
+ .string()
339
+ .optional()
340
+ .describe("New app name"),
341
+ description: zod_1.z
342
+ .string()
343
+ .optional()
344
+ .describe("New description"),
345
+ url: zod_1.z
346
+ .string()
347
+ .optional()
348
+ .describe("New URL"),
349
+ image: zod_1.z
350
+ .string()
351
+ .optional()
352
+ .describe("New image ID"),
353
+ config: zod_1.z
354
+ .record(zod_1.z.unknown())
355
+ .optional()
356
+ .describe("New configuration"),
357
+ }),
358
+ async execute(args, context) {
359
+ logger.debug('Updating app', {
360
+ appId: args.appId,
361
+ apiKey: context.apiKey.substring(0, 8) + '...'
362
+ });
363
+ try {
364
+ const updateData = {};
365
+ if (args.name !== undefined)
366
+ updateData.name = args.name;
367
+ if (args.description !== undefined)
368
+ updateData.description = args.description;
369
+ if (args.url !== undefined)
370
+ updateData.url = args.url;
371
+ if (args.image !== undefined)
372
+ updateData.image = args.image;
373
+ if (args.config !== undefined)
374
+ updateData.config = args.config;
375
+ logger.debug('Calling v3.app.update', {
376
+ appId: args.appId,
377
+ updates: Object.keys(updateData)
378
+ });
379
+ await context.hailer.request('v3.app.update', [
380
+ args.appId,
381
+ updateData
382
+ ]);
383
+ logger.debug('App update successful');
384
+ let responseText = `✅ **App Updated Successfully**\n\n`;
385
+ responseText += `**App ID:** \`${args.appId}\`\n\n`;
386
+ responseText += `**Updated Properties:**\n`;
387
+ const updatedFields = [];
388
+ if (args.name)
389
+ updatedFields.push(`name → "${args.name}"`);
390
+ if (args.description)
391
+ updatedFields.push(`description → "${args.description}"`);
392
+ if (args.url !== undefined)
393
+ updatedFields.push(`url → "${args.url || 'auto-generated'}"`);
394
+ if (args.image)
395
+ updatedFields.push(`image → "${args.image}"`);
396
+ if (args.config)
397
+ updatedFields.push(`config (updated)`);
398
+ updatedFields.forEach(field => {
399
+ responseText += `- ${field}\n`;
400
+ });
401
+ responseText += `\n💡 Use \`list_apps\` to verify changes.`;
402
+ return {
403
+ content: [{
404
+ type: "text",
405
+ text: responseText,
406
+ }],
407
+ };
408
+ }
409
+ catch (error) {
410
+ logger.error("Error updating app", error);
411
+ const errorMessage = (0, tool_helpers_1.extractErrorMessage)(error);
412
+ if (errorMessage.toLowerCase().includes('not found')) {
413
+ return {
414
+ content: [{
415
+ type: "text",
416
+ text: `❌ **App Not Found**\n\nThe specified app doesn't exist.\n\n**App ID:** \`${args.appId}\`\n\n💡 Use \`list_apps\` to see available apps.`,
417
+ }],
418
+ };
419
+ }
420
+ if (errorMessage.toLowerCase().includes('permission')) {
421
+ return {
422
+ content: [{
423
+ type: "text",
424
+ text: `❌ **Permission Denied**\n\nYou don't have permission to update this app. Only app creator or workspace admin can update apps.\n\n**Error:** ${errorMessage}`,
425
+ }],
426
+ };
427
+ }
428
+ return {
429
+ content: [{
430
+ type: "text",
431
+ text: `❌ **Error updating app**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- App ID invalid\n- Not app creator or admin\n- Invalid property values`,
432
+ }],
433
+ };
434
+ }
435
+ }
436
+ };
437
+ // ============================================================================
438
+ // REMOVE APP TOOL
439
+ // ============================================================================
440
+ const removeAppDescription = `🧪 [PLAYGROUND] Remove App - ⚠️ DANGER: Permanently deletes app entry from Hailer
441
+
442
+ ⚠️ **MANDATORY: GATHER COMPLETE CONTEXT BEFORE CALLING THIS TOOL**
443
+ **BEFORE calling this tool, you are REQUIRED to:**
444
+ 1. Load the skill: \`get_skill({ skillName: "remove-app-skill" })\`
445
+ 2. Fetch app details with \`list_apps\` to get:
446
+ - App name and ID
447
+ - Workspace ID and name
448
+ - App type (development/published)
449
+ - App configuration
450
+ 3. Show comprehensive confirmation message including:
451
+ - Workspace ID and name
452
+ - App ID and name
453
+ - What will be deleted (entry, permissions, configuration)
454
+ - What won't be deleted (published code remains)
455
+ - Clear irreversibility warning
456
+ 4. Wait for explicit user confirmation
457
+ **FAILURE TO GATHER AND SHOW THIS CONTEXT IS AN ERROR**
458
+
459
+ **Required**: appId
460
+ **Permission**: App creator or workspace administrator
461
+
462
+ **What gets deleted**:
463
+ - App entry (name, description, URL, metadata)
464
+ - App permissions
465
+ - App configuration
466
+
467
+ **What doesn't get deleted**:
468
+ - Published app code (remains on server)
469
+ - App data (if any)
470
+
471
+ **Example**:
472
+ \`\`\`javascript
473
+ remove_app({
474
+ appId: '<app-id>'
475
+ })
476
+ \`\`\`
477
+
478
+ **Tips**:
479
+ - Use \`list_apps\` to get app IDs
480
+ - Published app code must be removed separately
481
+ - Operation cannot be undone`;
482
+ exports.removeAppTool = {
483
+ name: 'remove_app',
484
+ group: tool_registry_1.ToolGroup.NUCLEAR,
485
+ description: removeAppDescription,
486
+ schema: zod_1.z.object({
487
+ appId: zod_1.z
488
+ .string()
489
+ .min(1)
490
+ .describe("App ID to remove"),
491
+ confirmed: zod_1.z
492
+ .boolean()
493
+ .optional()
494
+ .describe("First confirmation - must be true to proceed"),
495
+ secondConfirmed: zod_1.z
496
+ .boolean()
497
+ .optional()
498
+ .describe("Second confirmation - must be true to proceed (required for double-check safety)"),
499
+ }),
500
+ async execute(args, context) {
501
+ logger.debug('Removing app', {
502
+ appId: args.appId,
503
+ confirmed: args.confirmed,
504
+ secondConfirmed: args.secondConfirmed,
505
+ apiKey: context.apiKey.substring(0, 8) + '...'
506
+ });
507
+ try {
508
+ // Fetch app info and workspace info
509
+ const [appListResult, initData] = await Promise.all([
510
+ context.hailer.request('v3.app.list', [{}]),
511
+ context.hailer.request('v2.core.init', [["network"]])
512
+ ]);
513
+ // Handle multiple possible response structures
514
+ const appsList = appListResult?.apps || appListResult?.details?.apps || (Array.isArray(appListResult) ? appListResult : []);
515
+ const app = appsList.find((a) => a._id === args.appId);
516
+ const appName = app?.name || 'Unknown';
517
+ const workspaceId = initData.network?._id || 'Unknown';
518
+ const workspaceName = initData.network?.name || 'Unknown';
519
+ // SAFETY CHECK: Require double confirmation
520
+ if (!args.confirmed || !args.secondConfirmed) {
521
+ let warningText = `⚠️ **DESTRUCTIVE OPERATION - CONFIRMATION REQUIRED**\n\n`;
522
+ warningText += `You are about to **permanently delete** the following:\n\n`;
523
+ warningText += `**App:** ${appName}\n`;
524
+ warningText += `**App ID:** \`${args.appId}\`\n`;
525
+ warningText += `**Workspace:** ${workspaceName} (\`${workspaceId}\`)\n\n`;
526
+ warningText += `**⚠️ This will permanently delete:**\n`;
527
+ warningText += `- App entry (name, description, URL)\n`;
528
+ warningText += `- App permissions\n`;
529
+ warningText += `- App configuration\n\n`;
530
+ warningText += `**🚨 THIS CANNOT BE UNDONE! 🚨**\n\n`;
531
+ warningText += `**To proceed, you must:**\n`;
532
+ warningText += `1. Review the \`remove-app-skill\` (REQUIRED)\n`;
533
+ warningText += `2. Call this tool again with BOTH confirmations:\n\n`;
534
+ warningText += `\`\`\`javascript\n`;
535
+ warningText += `remove_app({\n`;
536
+ warningText += ` appId: "${args.appId}",\n`;
537
+ warningText += ` confirmed: true,\n`;
538
+ warningText += ` secondConfirmed: true\n`;
539
+ warningText += `})\n`;
540
+ warningText += `\`\`\`\n\n`;
541
+ warningText += `💡 **Before proceeding:**\n`;
542
+ warningText += `- Load \`remove-app-skill\` to review safety checklist\n`;
543
+ warningText += `- Verify with user that this is intentional\n`;
544
+ warningText += `- Note: Published app code remains on server`;
545
+ return {
546
+ content: [{
547
+ type: "text",
548
+ text: warningText,
549
+ }],
550
+ };
551
+ }
552
+ logger.debug('Calling v3.app.remove', {
553
+ appId: args.appId,
554
+ appName,
555
+ workspaceId,
556
+ workspaceName
557
+ });
558
+ await context.hailer.request('v3.app.remove', [args.appId]);
559
+ logger.debug('App removal successful', {
560
+ appId: args.appId,
561
+ appName
562
+ });
563
+ let responseText = `✅ **App Removed Successfully**\n\n`;
564
+ responseText += `**App:** ${appName}\n`;
565
+ responseText += `**App ID:** \`${args.appId}\`\n`;
566
+ responseText += `**Workspace:** ${workspaceName} (\`${workspaceId}\`)\n\n`;
567
+ responseText += `⚠️ **The app entry has been permanently deleted.**\n\n`;
568
+ responseText += `**What was deleted:**\n`;
569
+ responseText += `- App entry (name, description, URL)\n`;
570
+ responseText += `- App permissions\n`;
571
+ responseText += `- App configuration\n\n`;
572
+ responseText += `**Note:** Published app code remains on server (if applicable).\n\n`;
573
+ responseText += `💡 Use \`list_apps\` to see remaining apps.`;
574
+ return {
575
+ content: [{
576
+ type: "text",
577
+ text: responseText,
578
+ }],
579
+ };
580
+ }
581
+ catch (error) {
582
+ logger.error("Error removing app", error);
583
+ const errorMessage = (0, tool_helpers_1.extractErrorMessage)(error);
584
+ if (errorMessage.toLowerCase().includes('not found')) {
585
+ return {
586
+ content: [{
587
+ type: "text",
588
+ text: `❌ **App Not Found**\n\nThe specified app doesn't exist or has already been deleted.\n\n**App ID:** \`${args.appId}\`\n\n💡 Use \`list_apps\` to see available apps.`,
589
+ }],
590
+ };
591
+ }
592
+ if (errorMessage.toLowerCase().includes('permission')) {
593
+ return {
594
+ content: [{
595
+ type: "text",
596
+ text: `❌ **Permission Denied**\n\nYou don't have permission to remove this app. Only app creator or workspace admin can delete apps.\n\n**Error:** ${errorMessage}`,
597
+ }],
598
+ };
599
+ }
600
+ return {
601
+ content: [{
602
+ type: "text",
603
+ text: `❌ **Error removing app**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- App ID invalid\n- App already deleted\n- Not app creator or admin`,
604
+ }],
605
+ };
606
+ }
607
+ }
608
+ };
609
+ //# sourceMappingURL=app-core.js.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * App Tools - Marketplace & Templates
3
+ *
4
+ * App marketplace and template management tools:
5
+ * - List, create, get, and install templates
6
+ * - Publish templates to marketplace
7
+ * - Publish apps to marketplace
8
+ * - Install marketplace apps
9
+ * - Get product info and manifests
10
+ */
11
+ import { Tool } from '../tool-registry';
12
+ export declare const listTemplatesTool: Tool;
13
+ export declare const createTemplateTool: Tool;
14
+ export declare const installTemplateTool: Tool;
15
+ export declare const getTemplateTool: Tool;
16
+ export declare const publishTemplateTool: Tool;
17
+ export declare const getProductTool: Tool;
18
+ export declare const getProductManifestTool: Tool;
19
+ export declare const publishAppTool: Tool;
20
+ export declare const installMarketplaceAppTool: Tool;
21
+ //# sourceMappingURL=app-marketplace.d.ts.map