luxlabs 1.0.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.
- package/LICENSE +37 -0
- package/README.md +161 -0
- package/commands/ab-tests.js +437 -0
- package/commands/agents.js +226 -0
- package/commands/data.js +966 -0
- package/commands/deploy.js +166 -0
- package/commands/dev.js +569 -0
- package/commands/init.js +126 -0
- package/commands/interface/boilerplate.js +52 -0
- package/commands/interface/git-utils.js +85 -0
- package/commands/interface/index.js +7 -0
- package/commands/interface/init.js +375 -0
- package/commands/interface/path.js +74 -0
- package/commands/interface.js +125 -0
- package/commands/knowledge.js +339 -0
- package/commands/link.js +127 -0
- package/commands/list.js +97 -0
- package/commands/login.js +247 -0
- package/commands/logout.js +19 -0
- package/commands/logs.js +182 -0
- package/commands/pricing.js +328 -0
- package/commands/project.js +704 -0
- package/commands/secrets.js +129 -0
- package/commands/servers.js +411 -0
- package/commands/storage.js +177 -0
- package/commands/up.js +211 -0
- package/commands/validate-data-lux.js +502 -0
- package/commands/voice-agents.js +1055 -0
- package/commands/webview.js +393 -0
- package/commands/workflows.js +836 -0
- package/lib/config.js +403 -0
- package/lib/helpers.js +189 -0
- package/lib/node-helper.js +120 -0
- package/lux.js +268 -0
- package/package.json +56 -0
- package/templates/next-env.d.ts +6 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const ora = require('ora');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
const {
|
|
6
|
+
loadInterfaceConfig,
|
|
7
|
+
saveInterfaceConfig,
|
|
8
|
+
getApiUrl,
|
|
9
|
+
getAuthHeaders,
|
|
10
|
+
isAuthenticated,
|
|
11
|
+
} = require('../lib/config');
|
|
12
|
+
|
|
13
|
+
async function deploy() {
|
|
14
|
+
// Check authentication
|
|
15
|
+
if (!isAuthenticated()) {
|
|
16
|
+
console.log(
|
|
17
|
+
chalk.red('❌ Not authenticated. Run'),
|
|
18
|
+
chalk.white('lux login'),
|
|
19
|
+
chalk.red('first.')
|
|
20
|
+
);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Check if initialized
|
|
25
|
+
const interfaceConfig = loadInterfaceConfig();
|
|
26
|
+
if (!interfaceConfig || !interfaceConfig.id) {
|
|
27
|
+
console.log(
|
|
28
|
+
chalk.red('❌ No interface found. Run'),
|
|
29
|
+
chalk.white('lux up'),
|
|
30
|
+
chalk.red('first.')
|
|
31
|
+
);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const apiUrl = getApiUrl();
|
|
36
|
+
const interfaceId = interfaceConfig.id;
|
|
37
|
+
|
|
38
|
+
// Pre-deploy accessibility check
|
|
39
|
+
const spinner = ora('Checking accessibility...').start();
|
|
40
|
+
try {
|
|
41
|
+
execSync('npx eslint . --ext .tsx,.jsx --format stylish', {
|
|
42
|
+
cwd: process.cwd(),
|
|
43
|
+
stdio: 'pipe',
|
|
44
|
+
});
|
|
45
|
+
spinner.succeed(chalk.green('✓ Accessibility check passed'));
|
|
46
|
+
} catch (error) {
|
|
47
|
+
const output = error.stdout?.toString() || error.stderr?.toString() || '';
|
|
48
|
+
// Only fail on jsx-a11y errors, warn on others
|
|
49
|
+
if (output.includes('jsx-a11y')) {
|
|
50
|
+
spinner.fail('Accessibility issues found');
|
|
51
|
+
console.error(chalk.red('\n❌ Fix accessibility issues before deploying:\n'));
|
|
52
|
+
console.error(output);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
} else if (output.trim()) {
|
|
55
|
+
spinner.warn(chalk.yellow('Linting warnings (non-blocking)'));
|
|
56
|
+
console.log(chalk.dim(output));
|
|
57
|
+
} else {
|
|
58
|
+
spinner.succeed(chalk.green('✓ Accessibility check passed'));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Proceed with deploy
|
|
63
|
+
spinner.start('Deploying to production...');
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
// Trigger deployment
|
|
67
|
+
const { data } = await axios.post(
|
|
68
|
+
`${apiUrl}/api/interfaces/${interfaceId}/deploy`,
|
|
69
|
+
{},
|
|
70
|
+
{
|
|
71
|
+
headers: getAuthHeaders(),
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
spinner.succeed(chalk.green('✓ Deployment started!'));
|
|
76
|
+
|
|
77
|
+
console.log(chalk.dim(`\nDeployment ID: ${data.deploymentId}`));
|
|
78
|
+
console.log(chalk.dim(`Status: ${data.status}\n`));
|
|
79
|
+
|
|
80
|
+
// Poll for deployment status
|
|
81
|
+
await pollDeploymentStatus(interfaceId, apiUrl);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
spinner.fail('Deployment failed');
|
|
84
|
+
console.error(
|
|
85
|
+
chalk.red('\n❌ Error:'),
|
|
86
|
+
error.response?.data?.error || error.message
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
if (error.response?.status === 401) {
|
|
90
|
+
console.log(
|
|
91
|
+
chalk.yellow('\nYour session may have expired. Try running:'),
|
|
92
|
+
chalk.white('lux login')
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function pollDeploymentStatus(interfaceId, apiUrl) {
|
|
101
|
+
const spinner = ora('Building...').start();
|
|
102
|
+
const maxAttempts = 60; // 5 minutes max
|
|
103
|
+
let attempts = 0;
|
|
104
|
+
|
|
105
|
+
while (attempts < maxAttempts) {
|
|
106
|
+
try {
|
|
107
|
+
const { data } = await axios.get(
|
|
108
|
+
`${apiUrl}/api/interfaces/${interfaceId}`,
|
|
109
|
+
{ headers: getAuthHeaders() }
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const status = data.interface.status;
|
|
113
|
+
|
|
114
|
+
if (status === 'published') {
|
|
115
|
+
spinner.succeed(chalk.green('✓ Deployment successful!'));
|
|
116
|
+
|
|
117
|
+
const interfaceConfig = loadInterfaceConfig();
|
|
118
|
+
interfaceConfig.deploymentUrl = data.interface.vercel_deployment_url;
|
|
119
|
+
interfaceConfig.deploymentId = data.interface.vercel_deployment_id;
|
|
120
|
+
saveInterfaceConfig(interfaceConfig);
|
|
121
|
+
|
|
122
|
+
console.log(chalk.cyan('\n🎉 Your interface is live!\n'));
|
|
123
|
+
console.log(chalk.white(` ${data.interface.vercel_deployment_url}\n`));
|
|
124
|
+
|
|
125
|
+
if (data.interface.github_repo_url) {
|
|
126
|
+
console.log(chalk.dim(`GitHub: ${data.interface.github_repo_url}`));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return;
|
|
130
|
+
} else if (status === 'failed') {
|
|
131
|
+
spinner.fail('Deployment failed');
|
|
132
|
+
|
|
133
|
+
console.log(
|
|
134
|
+
chalk.red('\n❌ Build failed. View logs with:'),
|
|
135
|
+
chalk.white('lux logs --type build')
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (data.interface.error_message) {
|
|
139
|
+
console.log(chalk.dim(`\nError: ${data.interface.error_message}`));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
process.exit(1);
|
|
143
|
+
} else if (status === 'building') {
|
|
144
|
+
spinner.text = 'Building... (this may take a few minutes)';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Wait 5 seconds before next poll
|
|
148
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
149
|
+
attempts++;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
spinner.fail('Failed to check deployment status');
|
|
152
|
+
console.error(chalk.red('\n❌ Error:'), error.message);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
spinner.fail('Deployment timed out');
|
|
158
|
+
console.log(
|
|
159
|
+
chalk.yellow('\n⚠️ Deployment is still in progress. Check status with:'),
|
|
160
|
+
chalk.white('lux logs')
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = {
|
|
165
|
+
deploy,
|
|
166
|
+
};
|