@hailer/mcp 0.1.8 → 0.1.9
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/agents/agent-dmitri-activity-crud.md +3 -1
- package/.claude/agents/agent-giuseppe-app-builder.md +11 -12
- package/.claude/agents/agent-kenji-data-reader.md +5 -3
- package/.claude/skills/hailer-app-builder/SKILL.md +506 -0
- package/.claude/skills/publish-hailer-app/SKILL.md +169 -0
- package/.claude/skills/tool-parameter-usage/SKILL.md +112 -0
- package/CLAUDE.md +6 -2
- package/REFACTOR_STATUS.md +127 -0
- package/dist/cli.js +0 -0
- package/dist/client/agents/base.d.ts +202 -0
- package/dist/client/agents/base.js +737 -0
- package/dist/client/agents/definitions.d.ts +53 -0
- package/dist/client/agents/definitions.js +178 -0
- package/dist/client/agents/orchestrator.d.ts +119 -0
- package/dist/client/agents/orchestrator.js +760 -0
- package/dist/client/agents/specialist.d.ts +86 -0
- package/dist/client/agents/specialist.js +340 -0
- package/dist/client/bot-manager.d.ts +44 -0
- package/dist/client/bot-manager.js +173 -0
- package/dist/client/chat-agent-daemon.d.ts +464 -0
- package/dist/client/chat-agent-daemon.js +1774 -0
- package/dist/client/daemon-factory.d.ts +106 -0
- package/dist/client/daemon-factory.js +301 -0
- package/dist/client/factory.d.ts +107 -0
- package/dist/client/factory.js +304 -0
- package/dist/client/index.d.ts +17 -0
- package/dist/client/index.js +38 -0
- package/dist/client/multi-bot-manager.d.ts +18 -0
- package/dist/client/multi-bot-manager.js +88 -1
- package/dist/client/orchestrator-daemon.d.ts +87 -0
- package/dist/client/orchestrator-daemon.js +444 -0
- package/dist/client/services/agent-registry.d.ts +108 -0
- package/dist/client/services/agent-registry.js +630 -0
- package/dist/client/services/conversation-manager.d.ts +50 -0
- package/dist/client/services/conversation-manager.js +136 -0
- package/dist/client/services/mcp-client.d.ts +48 -0
- package/dist/client/services/mcp-client.js +105 -0
- package/dist/client/services/message-classifier.d.ts +37 -0
- package/dist/client/services/message-classifier.js +187 -0
- package/dist/client/services/message-formatter.d.ts +84 -0
- package/dist/client/services/message-formatter.js +353 -0
- package/dist/client/services/session-logger.d.ts +106 -0
- package/dist/client/services/session-logger.js +446 -0
- package/dist/client/services/tool-executor.d.ts +41 -0
- package/dist/client/services/tool-executor.js +169 -0
- package/dist/client/services/workspace-schema-cache.d.ts +149 -0
- package/dist/client/services/workspace-schema-cache.js +732 -0
- package/dist/client/specialist-daemon.d.ts +77 -0
- package/dist/client/specialist-daemon.js +197 -0
- package/dist/client/specialists.d.ts +53 -0
- package/dist/client/specialists.js +178 -0
- package/dist/client/tool-schema-loader.d.ts +4 -3
- package/dist/client/tool-schema-loader.js +54 -8
- package/dist/client/types.d.ts +283 -55
- package/dist/client/types.js +113 -2
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/core.d.ts +10 -2
- package/dist/core.js +43 -27
- package/dist/lib/logger.js +15 -3
- package/dist/mcp/UserContextCache.js +2 -2
- package/dist/mcp/hailer-clients.js +5 -5
- package/dist/mcp/signal-handler.js +27 -5
- package/dist/mcp/tools/activity.js +137 -65
- package/dist/mcp/tools/app-core.js +4 -140
- package/dist/mcp/tools/app-marketplace.js +15 -260
- package/dist/mcp/tools/app-member.js +2 -73
- package/dist/mcp/tools/app-scaffold.js +146 -87
- package/dist/mcp/tools/discussion.js +348 -73
- package/dist/mcp/tools/insight.js +74 -190
- package/dist/mcp/tools/workflow.js +20 -94
- package/dist/mcp/utils/hailer-api-client.d.ts +4 -2
- package/dist/mcp/utils/hailer-api-client.js +24 -10
- package/dist/mcp-server.d.ts +4 -0
- package/dist/mcp-server.js +24 -4
- package/dist/routes/agents.d.ts +44 -0
- package/dist/routes/agents.js +311 -0
- package/dist/services/agent-credential-store.d.ts +73 -0
- package/dist/services/agent-credential-store.js +212 -0
- package/lineup-manager/dist/assets/index-8ce6041d.css +1 -0
- package/lineup-manager/dist/assets/index-e168f265.js +600 -0
- package/lineup-manager/dist/index.html +15 -0
- package/lineup-manager/dist/manifest.json +17 -0
- package/lineup-manager/dist/vite.svg +1 -0
- package/package.json +1 -1
- package/dist/client/adaptive-documentation-bot.d.ts +0 -106
- package/dist/client/adaptive-documentation-bot.js +0 -464
- package/dist/client/adaptive-documentation-types.d.ts +0 -66
- package/dist/client/adaptive-documentation-types.js +0 -9
- package/dist/client/agent-activity-bot.d.ts +0 -51
- package/dist/client/agent-activity-bot.js +0 -166
- package/dist/client/agent-tracker.d.ts +0 -499
- package/dist/client/agent-tracker.js +0 -659
- package/dist/client/description-updater.d.ts +0 -56
- package/dist/client/description-updater.js +0 -259
- package/dist/client/log-parser.d.ts +0 -72
- package/dist/client/log-parser.js +0 -387
- package/dist/client/mcp-assistant.d.ts +0 -21
- package/dist/client/mcp-assistant.js +0 -58
- package/dist/client/mcp-client.d.ts +0 -50
- package/dist/client/mcp-client.js +0 -538
- package/dist/client/message-processor.d.ts +0 -35
- package/dist/client/message-processor.js +0 -357
- package/dist/client/providers/anthropic-provider.d.ts +0 -19
- package/dist/client/providers/anthropic-provider.js +0 -645
- package/dist/client/providers/assistant-provider.d.ts +0 -17
- package/dist/client/providers/assistant-provider.js +0 -51
- package/dist/client/providers/llm-provider.d.ts +0 -47
- package/dist/client/providers/llm-provider.js +0 -367
- package/dist/client/providers/openai-provider.d.ts +0 -23
- package/dist/client/providers/openai-provider.js +0 -630
- package/dist/client/simple-llm-caller.d.ts +0 -19
- package/dist/client/simple-llm-caller.js +0 -100
- package/dist/client/skill-generator.d.ts +0 -81
- package/dist/client/skill-generator.js +0 -386
- package/dist/client/test-adaptive-bot.d.ts +0 -9
- package/dist/client/test-adaptive-bot.js +0 -82
- package/dist/client/token-pricing.d.ts +0 -38
- package/dist/client/token-pricing.js +0 -127
- package/dist/client/token-tracker.d.ts +0 -232
- package/dist/client/token-tracker.js +0 -457
- package/dist/client/token-usage-bot.d.ts +0 -53
- package/dist/client/token-usage-bot.js +0 -153
- package/dist/client/tool-executor.d.ts +0 -69
- package/dist/client/tool-executor.js +0 -159
- package/dist/lib/materialize.d.ts +0 -3
- package/dist/lib/materialize.js +0 -101
- package/dist/lib/normalizedName.d.ts +0 -7
- package/dist/lib/normalizedName.js +0 -48
- package/dist/lib/terminal-prompt.d.ts +0 -9
- package/dist/lib/terminal-prompt.js +0 -108
- package/dist/mcp/tools/skill.d.ts +0 -10
- package/dist/mcp/tools/skill.js +0 -279
- package/dist/mcp/tools/workflow-template.d.ts +0 -19
- package/dist/mcp/tools/workflow-template.js +0 -822
|
@@ -47,39 +47,7 @@ const logger_1 = require("../../lib/logger");
|
|
|
47
47
|
const config_1 = require("../../config");
|
|
48
48
|
const tool_helpers_1 = require("../utils/tool-helpers");
|
|
49
49
|
const logger = (0, logger_1.createLogger)({ component: 'app-scaffold' });
|
|
50
|
-
const scaffoldHailerAppDescription = `Scaffold new Hailer app from template
|
|
51
|
-
|
|
52
|
-
⚠️ **MANDATORY: YOU MUST LOAD SKILL FIRST**
|
|
53
|
-
**BEFORE calling this tool, you are REQUIRED to:**
|
|
54
|
-
1. Load the skill: \`get_skill({ skillName: "scaffold-hailer-app-skill" })\`
|
|
55
|
-
2. Read the setup guide and understand the process
|
|
56
|
-
3. Review template options and troubleshooting tips
|
|
57
|
-
**FAILURE TO LOAD THE SKILL FIRST IS AN ERROR**
|
|
58
|
-
|
|
59
|
-
**Required Parameters**:
|
|
60
|
-
- projectName: Project folder name
|
|
61
|
-
- template: react-ts-style (recommended - includes Hailer theme), react-ts-example (with example code), react-ts (basic), or vanilla
|
|
62
|
-
|
|
63
|
-
**Optional Parameters**:
|
|
64
|
-
- description: App description for Hailer
|
|
65
|
-
- autoCreateDevApp: (default: true) Automatically create dev app entry in Hailer
|
|
66
|
-
- autoShareWithWorkspace: (default: true) Share app with entire workspace
|
|
67
|
-
- autoStartDevServer: (default: true) Start dev server in background
|
|
68
|
-
- autoSpawnBuilder: (default: false) Return instruction to spawn builder agent that implements the app UI
|
|
69
|
-
|
|
70
|
-
**What This Does (One Shot)**:
|
|
71
|
-
1. ✅ Scaffolds project from template
|
|
72
|
-
2. ✅ Installs dependencies
|
|
73
|
-
3. ✅ Creates dev app entry in Hailer with correct URL
|
|
74
|
-
4. ✅ Shares app with workspace
|
|
75
|
-
5. ✅ Updates manifest.json with app ID
|
|
76
|
-
6. ✅ Starts dev server on port 3000
|
|
77
|
-
7. ✅ App ready to open in Hailer!
|
|
78
|
-
|
|
79
|
-
**Target Directory**:
|
|
80
|
-
- Uses DEV_APPS_PATH from .env.local if set
|
|
81
|
-
- Falls back to targetDirectory parameter
|
|
82
|
-
- Falls back to current directory if neither set`;
|
|
50
|
+
const scaffoldHailerAppDescription = `Scaffold new Hailer app from template`;
|
|
83
51
|
exports.scaffoldHailerAppTool = {
|
|
84
52
|
name: 'scaffold_hailer_app',
|
|
85
53
|
group: tool_registry_1.ToolGroup.PLAYGROUND,
|
|
@@ -402,49 +370,7 @@ exports.scaffoldHailerAppTool = {
|
|
|
402
370
|
// ============================================================================
|
|
403
371
|
// PUBLISH HAILER APP TOOL
|
|
404
372
|
// ============================================================================
|
|
405
|
-
const publishHailerAppDescription = `Publish Hailer app to production
|
|
406
|
-
|
|
407
|
-
**What it does:**
|
|
408
|
-
1. Runs \`npm run publish-production\` (official SDK script)
|
|
409
|
-
2. Authenticates with Hailer (uses session credentials or provided ones)
|
|
410
|
-
3. Uploads to Hailer hosting
|
|
411
|
-
4. Optionally publishes to marketplace (returns targetId)
|
|
412
|
-
|
|
413
|
-
**Authentication:**
|
|
414
|
-
- Uses session credentials from CLIENT_CONFIGS by default
|
|
415
|
-
- Override with email/password parameters if needed
|
|
416
|
-
|
|
417
|
-
**Optional Parameters**:
|
|
418
|
-
- \`projectDirectory\` - Path to app (defaults to DEV_APPS_PATH)
|
|
419
|
-
- \`publishToMarket\` - Set true to get targetId for marketplace
|
|
420
|
-
- \`email\` - Override session email
|
|
421
|
-
- \`password\` - Override session password
|
|
422
|
-
|
|
423
|
-
**Prerequisites**:
|
|
424
|
-
1. Production app entry exists (create_app with empty URL)
|
|
425
|
-
2. \`public/manifest.json\` contains the production appId
|
|
426
|
-
|
|
427
|
-
**Example:**
|
|
428
|
-
\`\`\`javascript
|
|
429
|
-
// Uses session credentials
|
|
430
|
-
publish_hailer_app({
|
|
431
|
-
projectDirectory: "/path/to/app",
|
|
432
|
-
publishToMarket: true
|
|
433
|
-
})
|
|
434
|
-
|
|
435
|
-
// Or with explicit credentials
|
|
436
|
-
publish_hailer_app({
|
|
437
|
-
projectDirectory: "/path/to/app",
|
|
438
|
-
email: "user@example.com",
|
|
439
|
-
password: "password",
|
|
440
|
-
publishToMarket: true
|
|
441
|
-
})
|
|
442
|
-
\`\`\`
|
|
443
|
-
|
|
444
|
-
**Marketplace Flow:**
|
|
445
|
-
1. Call publish_hailer_app with publishToMarket: true
|
|
446
|
-
2. Get targetId from response
|
|
447
|
-
3. Use targetId with publish_app for marketplace listing`;
|
|
373
|
+
const publishHailerAppDescription = `Publish Hailer app to production`;
|
|
448
374
|
exports.publishHailerAppTool = {
|
|
449
375
|
name: 'publish_hailer_app',
|
|
450
376
|
group: tool_registry_1.ToolGroup.PLAYGROUND,
|
|
@@ -459,6 +385,11 @@ exports.publishHailerAppTool = {
|
|
|
459
385
|
async execute(args, context) {
|
|
460
386
|
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
461
387
|
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
388
|
+
logger.debug('Step 0: Starting publishHailerApp execute function', {
|
|
389
|
+
hasProjectDirectory: !!args.projectDirectory,
|
|
390
|
+
hasAppId: !!args.appId,
|
|
391
|
+
publishToMarket: args.publishToMarket
|
|
392
|
+
});
|
|
462
393
|
// Use provided credentials or fall back to session credentials
|
|
463
394
|
const email = args.email || context.email;
|
|
464
395
|
const password = args.password || context.password;
|
|
@@ -472,16 +403,37 @@ exports.publishHailerAppTool = {
|
|
|
472
403
|
};
|
|
473
404
|
}
|
|
474
405
|
// Debug: log credential availability (not the actual values)
|
|
475
|
-
logger.debug('
|
|
406
|
+
logger.debug('Step 0.5: Credentials verified', {
|
|
476
407
|
hasEmail: !!email,
|
|
477
408
|
emailLength: email?.length,
|
|
478
409
|
hasPassword: !!password,
|
|
479
410
|
passwordLength: password?.length
|
|
480
411
|
});
|
|
481
412
|
try {
|
|
413
|
+
const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
414
|
+
// Step 1: Check if expect is installed
|
|
415
|
+
logger.debug('Step 1: Checking if expect is installed...');
|
|
416
|
+
try {
|
|
417
|
+
execSync('which expect', { encoding: 'utf-8', stdio: 'pipe' });
|
|
418
|
+
logger.debug('Step 1.5: expect command found');
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
logger.error('Step 1 ERROR: expect command not found');
|
|
422
|
+
return {
|
|
423
|
+
content: [{
|
|
424
|
+
type: "text",
|
|
425
|
+
text: `❌ **\`expect\` Not Installed**\n\nThe \`expect\` command is required for automated app publishing.\n\n**How to fix:**\n\n**macOS:**\n\`\`\`bash\nbrew install expect\n\`\`\`\n\n**Ubuntu/Debian:**\n\`\`\`bash\nsudo apt-get install expect\n\`\`\`\n\n**RHEL/CentOS:**\n\`\`\`bash\nsudo yum install expect\n\`\`\`\n\n**After installation, try again.**`,
|
|
426
|
+
}],
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
// Step 2: Determine project directory
|
|
430
|
+
logger.debug('Step 2: Checking project directory...');
|
|
482
431
|
const projectDir = args.projectDirectory || config_1.environment.DEV_APPS_PATH || process.cwd();
|
|
483
|
-
|
|
432
|
+
logger.debug('Step 2.5: Project directory resolved', { projectDir });
|
|
433
|
+
// Step 3: Check if directory exists
|
|
434
|
+
logger.debug('Step 3: Verifying project directory exists...');
|
|
484
435
|
if (!fs.existsSync(projectDir)) {
|
|
436
|
+
logger.error('Step 3 ERROR: Project directory does not exist', { projectDir });
|
|
485
437
|
return {
|
|
486
438
|
content: [{
|
|
487
439
|
type: "text",
|
|
@@ -489,9 +441,12 @@ exports.publishHailerAppTool = {
|
|
|
489
441
|
}],
|
|
490
442
|
};
|
|
491
443
|
}
|
|
492
|
-
|
|
444
|
+
logger.debug('Step 3.5: Project directory exists');
|
|
445
|
+
// Step 4: Check if package.json exists
|
|
446
|
+
logger.debug('Step 4: Checking package.json...');
|
|
493
447
|
const packageJsonPath = path.join(projectDir, 'package.json');
|
|
494
448
|
if (!fs.existsSync(packageJsonPath)) {
|
|
449
|
+
logger.error('Step 4 ERROR: package.json not found', { packageJsonPath });
|
|
495
450
|
return {
|
|
496
451
|
content: [{
|
|
497
452
|
type: "text",
|
|
@@ -499,19 +454,32 @@ exports.publishHailerAppTool = {
|
|
|
499
454
|
}],
|
|
500
455
|
};
|
|
501
456
|
}
|
|
502
|
-
|
|
457
|
+
logger.debug('Step 4.5: package.json found');
|
|
458
|
+
// Step 5: Read manifest.json to get/verify appId
|
|
459
|
+
logger.debug('Step 5: Reading manifest.json...');
|
|
503
460
|
const manifestPath = path.join(projectDir, 'public', 'manifest.json');
|
|
504
461
|
let appId = args.appId;
|
|
505
462
|
let appName = 'Unknown';
|
|
506
463
|
if (fs.existsSync(manifestPath)) {
|
|
464
|
+
logger.debug('Step 5.5: manifest.json file found');
|
|
507
465
|
try {
|
|
466
|
+
logger.debug('Step 5.7: Reading manifest file content...');
|
|
508
467
|
const manifestContent = fs.readFileSync(manifestPath, 'utf-8');
|
|
468
|
+
logger.debug('Step 5.8: Parsing manifest JSON...');
|
|
509
469
|
const manifest = JSON.parse(manifestContent);
|
|
470
|
+
logger.debug('Step 5.9: Manifest parsed successfully', {
|
|
471
|
+
hasAppId: !!manifest.appId,
|
|
472
|
+
hasName: !!manifest.name,
|
|
473
|
+
hasVersion: !!manifest.version,
|
|
474
|
+
hasVersionDescription: !!manifest.versionDescription
|
|
475
|
+
});
|
|
510
476
|
if (!appId) {
|
|
511
477
|
appId = manifest.appId;
|
|
512
478
|
}
|
|
513
479
|
appName = manifest.name || appName;
|
|
480
|
+
logger.debug('Step 5.95: Manifest data extracted', { appId, appName });
|
|
514
481
|
if (!appId) {
|
|
482
|
+
logger.error('Step 5.97 ERROR: No appId found');
|
|
515
483
|
return {
|
|
516
484
|
content: [{
|
|
517
485
|
type: "text",
|
|
@@ -519,9 +487,32 @@ exports.publishHailerAppTool = {
|
|
|
519
487
|
}],
|
|
520
488
|
};
|
|
521
489
|
}
|
|
490
|
+
// Step 6: Validate version fields are present and not empty
|
|
491
|
+
logger.debug('Step 6: Validating version fields...');
|
|
492
|
+
if (!manifest.version || manifest.version.trim() === '') {
|
|
493
|
+
logger.error('Step 6 ERROR: version field missing or empty');
|
|
494
|
+
return {
|
|
495
|
+
content: [{
|
|
496
|
+
type: "text",
|
|
497
|
+
text: `❌ **Version Not Set**\n\nThe \`version\` field in \`manifest.json\` is missing or empty.\n\n**Steps to fix:**\nEdit \`public/manifest.json\` and add:\n\`\`\`json\n"version": "1.0.0",\n"versionDescription": "Initial release"\n\`\`\`\n\nThe SDK requires version fields for publishing.`,
|
|
498
|
+
}],
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
logger.debug('Step 6.5: version field OK', { version: manifest.version });
|
|
502
|
+
if (!manifest.versionDescription || manifest.versionDescription.trim() === '') {
|
|
503
|
+
logger.error('Step 6.7 ERROR: versionDescription field missing or empty');
|
|
504
|
+
return {
|
|
505
|
+
content: [{
|
|
506
|
+
type: "text",
|
|
507
|
+
text: `❌ **Version Description Not Set**\n\nThe \`versionDescription\` field in \`manifest.json\` is missing or empty.\n\n**Steps to fix:**\nEdit \`public/manifest.json\` and add:\n\`\`\`json\n"version": "${manifest.version}",\n"versionDescription": "Description of this version"\n\`\`\`\n\nThe SDK requires version fields for publishing.`,
|
|
508
|
+
}],
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
logger.debug('Step 6.9: versionDescription field OK', { versionDescription: manifest.versionDescription });
|
|
522
512
|
}
|
|
523
513
|
catch (error) {
|
|
524
514
|
const errorMessage = (0, tool_helpers_1.extractErrorMessage)(error);
|
|
515
|
+
logger.error('Step 5 ERROR: Failed to parse manifest.json', { error: errorMessage });
|
|
525
516
|
return {
|
|
526
517
|
content: [{
|
|
527
518
|
type: "text",
|
|
@@ -531,6 +522,7 @@ exports.publishHailerAppTool = {
|
|
|
531
522
|
}
|
|
532
523
|
}
|
|
533
524
|
else if (!appId) {
|
|
525
|
+
logger.error('Step 5.99 ERROR: Manifest not found and no appId provided');
|
|
534
526
|
return {
|
|
535
527
|
content: [{
|
|
536
528
|
type: "text",
|
|
@@ -538,10 +530,14 @@ exports.publishHailerAppTool = {
|
|
|
538
530
|
}],
|
|
539
531
|
};
|
|
540
532
|
}
|
|
541
|
-
// Check if publish-production script exists
|
|
533
|
+
// Step 7: Check if publish-production script exists
|
|
534
|
+
logger.debug('Step 7: Checking publish-production script...');
|
|
542
535
|
try {
|
|
536
|
+
logger.debug('Step 7.3: Reading package.json for script...');
|
|
543
537
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
538
|
+
logger.debug('Step 7.5: package.json parsed');
|
|
544
539
|
if (!packageJson.scripts?.['publish-production']) {
|
|
540
|
+
logger.error('Step 7 ERROR: publish-production script not found');
|
|
545
541
|
return {
|
|
546
542
|
content: [{
|
|
547
543
|
type: "text",
|
|
@@ -549,9 +545,11 @@ exports.publishHailerAppTool = {
|
|
|
549
545
|
}],
|
|
550
546
|
};
|
|
551
547
|
}
|
|
548
|
+
logger.debug('Step 7.8: publish-production script found');
|
|
552
549
|
}
|
|
553
550
|
catch (error) {
|
|
554
551
|
const errorMessage = (0, tool_helpers_1.extractErrorMessage)(error);
|
|
552
|
+
logger.error('Step 7 ERROR: Failed to parse package.json for scripts', { error: errorMessage });
|
|
555
553
|
return {
|
|
556
554
|
content: [{
|
|
557
555
|
type: "text",
|
|
@@ -559,25 +557,32 @@ exports.publishHailerAppTool = {
|
|
|
559
557
|
}],
|
|
560
558
|
};
|
|
561
559
|
}
|
|
560
|
+
// Step 8: Prepare response and get ready to publish
|
|
561
|
+
logger.debug('Step 8: Preparing to run publish script...');
|
|
562
562
|
let responseText = `🚀 **Publishing Hailer App**\n\n`;
|
|
563
563
|
responseText += `**App Name:** ${appName}\n`;
|
|
564
564
|
responseText += `**App ID:** \`${appId}\`\n`;
|
|
565
565
|
responseText += `**Project:** ${projectDir}\n`;
|
|
566
566
|
responseText += `**Marketplace:** ${publishToMarket ? 'Yes (will get targetId)' : 'No'}\n\n`;
|
|
567
|
-
|
|
567
|
+
logger.debug('Step 8.5: Response header prepared');
|
|
568
|
+
// Step 9: Run the SDK publish script using `expect` for interactive automation
|
|
568
569
|
// Write expect script to temp file to avoid shell escaping issues
|
|
570
|
+
logger.debug('Step 9: Starting expect script execution process...');
|
|
571
|
+
const os = await Promise.resolve().then(() => __importStar(require('os')));
|
|
569
572
|
const result = await new Promise((resolve) => {
|
|
570
|
-
const { execSync } = require('child_process');
|
|
571
|
-
const os = require('os');
|
|
572
573
|
// Create temp expect script file
|
|
574
|
+
logger.debug('Step 9.1: Creating temp directory and script path...');
|
|
573
575
|
const tmpDir = os.tmpdir();
|
|
574
576
|
const expectScriptPath = path.join(tmpDir, `hailer-publish-${Date.now()}.exp`);
|
|
577
|
+
logger.debug('Step 9.2: Expect script path resolved', { expectScriptPath });
|
|
575
578
|
// For Tcl, use braces {} for literal strings (no escaping needed except for braces)
|
|
576
579
|
// Escape only braces in the password
|
|
580
|
+
logger.debug('Step 9.3: Escaping password for expect script...');
|
|
577
581
|
const escapedPassword = password
|
|
578
582
|
.replace(/\\/g, '\\\\')
|
|
579
583
|
.replace(/\{/g, '\\{')
|
|
580
584
|
.replace(/\}/g, '\\}');
|
|
585
|
+
logger.debug('Step 9.4: Password escaped (length: ' + escapedPassword.length + ')');
|
|
581
586
|
const expectScript = `#!/usr/bin/expect -f
|
|
582
587
|
set timeout 45
|
|
583
588
|
log_user 1
|
|
@@ -620,8 +625,11 @@ exit $value
|
|
|
620
625
|
`;
|
|
621
626
|
try {
|
|
622
627
|
// Write expect script to temp file
|
|
628
|
+
logger.debug('Step 9.5: Writing expect script to file...');
|
|
623
629
|
fs.writeFileSync(expectScriptPath, expectScript, { mode: 0o755 });
|
|
630
|
+
logger.debug('Step 9.6: Expect script written successfully', { fileSize: expectScript.length });
|
|
624
631
|
// Build environment
|
|
632
|
+
logger.debug('Step 9.7: Building environment variables...');
|
|
625
633
|
const envVars = {
|
|
626
634
|
...process.env,
|
|
627
635
|
EMAIL: email
|
|
@@ -629,43 +637,85 @@ exit $value
|
|
|
629
637
|
if (publishToMarket) {
|
|
630
638
|
envVars.MARKET = 'true';
|
|
631
639
|
}
|
|
640
|
+
logger.debug('Step 9.8: Environment prepared', { hasEmail: !!email, publishToMarket });
|
|
641
|
+
logger.debug('Step 9.9: Running expect script...', { projectDir, timeout: 60000 });
|
|
632
642
|
const output = execSync(`expect "${expectScriptPath}"`, {
|
|
633
643
|
cwd: projectDir,
|
|
634
644
|
encoding: 'utf-8',
|
|
635
|
-
timeout:
|
|
645
|
+
timeout: 60000,
|
|
636
646
|
maxBuffer: 10 * 1024 * 1024,
|
|
637
647
|
env: envVars
|
|
638
648
|
});
|
|
649
|
+
logger.debug('Step 9.95: Expect script completed successfully', { outputLength: output.length });
|
|
639
650
|
// Clean up temp file
|
|
651
|
+
logger.debug('Step 9.97: Cleaning up expect script...');
|
|
640
652
|
try {
|
|
641
653
|
fs.unlinkSync(expectScriptPath);
|
|
642
654
|
}
|
|
643
655
|
catch { }
|
|
656
|
+
logger.debug('Step 9.98: Temp file cleaned');
|
|
644
657
|
// Check if manifest was updated with targetId
|
|
658
|
+
logger.debug('Step 9.99: Checking for manifest update with targetId...');
|
|
645
659
|
let targetId;
|
|
646
660
|
try {
|
|
647
661
|
const updatedManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
648
662
|
targetId = updatedManifest.targetId;
|
|
663
|
+
logger.debug('Step 9.991: Manifest checked', { hasTargetId: !!targetId });
|
|
649
664
|
}
|
|
650
665
|
catch {
|
|
666
|
+
logger.debug('Step 9.992: Could not read updated manifest');
|
|
651
667
|
// Ignore
|
|
652
668
|
}
|
|
653
669
|
if (output.includes('Published successfully')) {
|
|
670
|
+
logger.debug('Step 9.993: Success message found in output');
|
|
654
671
|
resolve({ success: true, output, targetId });
|
|
655
672
|
}
|
|
656
673
|
else {
|
|
674
|
+
logger.debug('Step 9.994: No success message in output');
|
|
657
675
|
resolve({ success: false, output });
|
|
658
676
|
}
|
|
659
677
|
}
|
|
660
678
|
catch (error) {
|
|
679
|
+
logger.error('Step 9 ERROR: Expect script execution failed', {
|
|
680
|
+
errorCode: error.code,
|
|
681
|
+
signal: error.signal,
|
|
682
|
+
hasStdout: !!error.stdout,
|
|
683
|
+
hasStderr: !!error.stderr,
|
|
684
|
+
errorMessage: error.message
|
|
685
|
+
});
|
|
661
686
|
// Clean up temp file
|
|
687
|
+
logger.debug('Step 9.err.1: Cleaning up after error...');
|
|
662
688
|
try {
|
|
663
689
|
fs.unlinkSync(expectScriptPath);
|
|
664
690
|
}
|
|
665
691
|
catch { }
|
|
666
692
|
const output = error.stdout || error.stderr || error.message || String(error);
|
|
667
|
-
|
|
668
|
-
|
|
693
|
+
logger.debug('Step 9.err.2: Error output collected', { outputLength: output.length });
|
|
694
|
+
// Check for specific error messages
|
|
695
|
+
if (output.includes('not found') || output.includes('command not found')) {
|
|
696
|
+
logger.debug('Step 9.err.3: expect command not found error detected');
|
|
697
|
+
resolve({
|
|
698
|
+
success: false,
|
|
699
|
+
output: `ERROR: expect command not found. Try: apt-get install expect (Ubuntu) or brew install expect (macOS)\n\n${output}`
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
else if (output.includes('TIMEOUT')) {
|
|
703
|
+
logger.debug('Step 9.err.4: Timeout error detected');
|
|
704
|
+
resolve({
|
|
705
|
+
success: false,
|
|
706
|
+
output: `ERROR: expect script timed out waiting for prompts. Check your internet connection and Hailer API status.\n\n${output}`
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
else if (output.includes('INVALID PASSWORD')) {
|
|
710
|
+
logger.debug('Step 9.err.5: Invalid password error detected');
|
|
711
|
+
resolve({
|
|
712
|
+
success: false,
|
|
713
|
+
output: `ERROR: Invalid credentials provided. Check your email and password.\n\n${output}`
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
else if (output.includes('Published successfully')) {
|
|
717
|
+
logger.debug('Step 9.err.6: Success detected despite error code');
|
|
718
|
+
// Even if exit code is non-zero, check if it actually succeeded
|
|
669
719
|
let targetId;
|
|
670
720
|
try {
|
|
671
721
|
const updatedManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
@@ -677,11 +727,14 @@ exit $value
|
|
|
677
727
|
resolve({ success: true, output, targetId });
|
|
678
728
|
}
|
|
679
729
|
else {
|
|
730
|
+
logger.debug('Step 9.err.7: Generic error');
|
|
680
731
|
resolve({ success: false, output });
|
|
681
732
|
}
|
|
682
733
|
}
|
|
683
734
|
});
|
|
735
|
+
logger.debug('Step 10: Result received from promise', { success: result.success });
|
|
684
736
|
if (!result.success) {
|
|
737
|
+
logger.error('Step 10 ERROR: Publish failed', { outputLength: result.output.length });
|
|
685
738
|
return {
|
|
686
739
|
content: [{
|
|
687
740
|
type: "text",
|
|
@@ -689,6 +742,7 @@ exit $value
|
|
|
689
742
|
}],
|
|
690
743
|
};
|
|
691
744
|
}
|
|
745
|
+
logger.debug('Step 10.5: Publish succeeded, building response...');
|
|
692
746
|
responseText += `✅ **App Published Successfully!**\n\n`;
|
|
693
747
|
if (result.targetId) {
|
|
694
748
|
responseText += `**Target ID:** \`${result.targetId}\`\n\n`;
|
|
@@ -722,6 +776,7 @@ exit $value
|
|
|
722
776
|
responseText += ` member: "network_<workspace-id>" // or team_*, user_*\n`;
|
|
723
777
|
responseText += ` })\n`;
|
|
724
778
|
responseText += ` \`\`\`\n`;
|
|
779
|
+
logger.debug('Step 11: Publishing complete, returning success response');
|
|
725
780
|
return {
|
|
726
781
|
content: [{
|
|
727
782
|
type: "text",
|
|
@@ -731,6 +786,10 @@ exit $value
|
|
|
731
786
|
}
|
|
732
787
|
catch (error) {
|
|
733
788
|
const errorMessage = (0, tool_helpers_1.extractErrorMessage)(error);
|
|
789
|
+
logger.error('CRITICAL ERROR: Uncaught exception in publishHailerApp', {
|
|
790
|
+
errorMessage,
|
|
791
|
+
errorType: error instanceof Error ? error.constructor.name : typeof error
|
|
792
|
+
});
|
|
734
793
|
return {
|
|
735
794
|
content: [{
|
|
736
795
|
type: "text",
|