lua-cli 3.2.0-alpha.2 ā 3.3.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/dist/api/agent.api.service.js +1 -0
- package/dist/api/agent.api.service.js.map +1 -0
- package/dist/api/auth.api.service.js +1 -0
- package/dist/api/auth.api.service.js.map +1 -0
- package/dist/api/basket.api.service.js +1 -0
- package/dist/api/basket.api.service.js.map +1 -0
- package/dist/api/cdn.api.service.js +1 -0
- package/dist/api/cdn.api.service.js.map +1 -0
- package/dist/api/chat.api.service.js +1 -0
- package/dist/api/chat.api.service.js.map +1 -0
- package/dist/api/credentials.js +1 -0
- package/dist/api/credentials.js.map +1 -0
- package/dist/api/custom.data.api.service.js +1 -0
- package/dist/api/custom.data.api.service.js.map +1 -0
- package/dist/api/developer.api.service.js +1 -0
- package/dist/api/developer.api.service.js.map +1 -0
- package/dist/api/job.api.service.js +1 -0
- package/dist/api/job.api.service.js.map +1 -0
- package/dist/api/lazy-instances.js +1 -0
- package/dist/api/lazy-instances.js.map +1 -0
- package/dist/api/logs.api.service.d.ts +1 -1
- package/dist/api/logs.api.service.js +1 -0
- package/dist/api/logs.api.service.js.map +1 -0
- package/dist/api/marketplace.api.service.js +1 -0
- package/dist/api/marketplace.api.service.js.map +1 -0
- package/dist/api/order.api.service.js +1 -0
- package/dist/api/order.api.service.js.map +1 -0
- package/dist/api/persona.api.service.js +1 -0
- package/dist/api/persona.api.service.js.map +1 -0
- package/dist/api/postprocessor.api.service.js +1 -0
- package/dist/api/postprocessor.api.service.js.map +1 -0
- package/dist/api/preprocessor.api.service.js +1 -0
- package/dist/api/preprocessor.api.service.js.map +1 -0
- package/dist/api/products.api.service.d.ts +17 -5
- package/dist/api/products.api.service.js +22 -9
- package/dist/api/products.api.service.js.map +1 -0
- package/dist/api/skills.api.service.js +1 -0
- package/dist/api/skills.api.service.js.map +1 -0
- package/dist/api/tool.api.service.js +1 -0
- package/dist/api/tool.api.service.js.map +1 -0
- package/dist/api/user.data.api.service.js +1 -0
- package/dist/api/user.data.api.service.js.map +1 -0
- package/dist/api/webhook.api.service.js +1 -0
- package/dist/api/webhook.api.service.js.map +1 -0
- package/dist/api/whatsapp-templates.api.service.js +1 -0
- package/dist/api/whatsapp-templates.api.service.js.map +1 -0
- package/dist/api-exports.d.ts +23 -6
- package/dist/api-exports.js +27 -5
- package/dist/api-exports.js.map +1 -0
- package/dist/cli/command-definitions.js +321 -88
- package/dist/cli/command-definitions.js.map +1 -0
- package/dist/commands/admin.js +1 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/agents.js +1 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/apiKey.d.ts +5 -2
- package/dist/commands/apiKey.js +9 -2
- package/dist/commands/apiKey.js.map +1 -0
- package/dist/commands/channels.d.ts +4 -9
- package/dist/commands/channels.js +141 -84
- package/dist/commands/channels.js.map +1 -0
- package/dist/commands/chat.d.ts +4 -2
- package/dist/commands/chat.js +127 -32
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/chatClear.d.ts +3 -2
- package/dist/commands/chatClear.js +17 -15
- package/dist/commands/chatClear.js.map +1 -0
- package/dist/commands/compile.js +68 -4
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/completion.js +1 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/configure.js +1 -0
- package/dist/commands/configure.js.map +1 -0
- package/dist/commands/deploy.d.ts +5 -24
- package/dist/commands/deploy.js +76 -48
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/destroy.d.ts +5 -2
- package/dist/commands/destroy.js +15 -2
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/dev.js +1 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/docs.js +1 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/env.d.ts +3 -1
- package/dist/commands/env.js +323 -122
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/evals.js +1 -0
- package/dist/commands/evals.js.map +1 -0
- package/dist/commands/features.d.ts +5 -9
- package/dist/commands/features.js +250 -129
- package/dist/commands/features.js.map +1 -0
- package/dist/commands/index.js +1 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +7 -1
- package/dist/commands/init.js +252 -65
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/jobs.d.ts +5 -13
- package/dist/commands/jobs.js +450 -364
- package/dist/commands/jobs.js.map +1 -0
- package/dist/commands/logs.d.ts +5 -10
- package/dist/commands/logs.js +260 -103
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/marketplace.d.ts +23 -2
- package/dist/commands/marketplace.js +531 -7
- package/dist/commands/marketplace.js.map +1 -0
- package/dist/commands/mcp.d.ts +5 -11
- package/dist/commands/mcp.js +304 -288
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/persona.d.ts +5 -9
- package/dist/commands/persona.js +350 -232
- package/dist/commands/persona.js.map +1 -0
- package/dist/commands/postprocessors.d.ts +6 -2
- package/dist/commands/postprocessors.js +388 -280
- package/dist/commands/postprocessors.js.map +1 -0
- package/dist/commands/preprocessors.d.ts +6 -2
- package/dist/commands/preprocessors.js +388 -280
- package/dist/commands/preprocessors.js.map +1 -0
- package/dist/commands/production.d.ts +5 -8
- package/dist/commands/production.js +318 -228
- package/dist/commands/production.js.map +1 -0
- package/dist/commands/push.js +386 -427
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/resources.d.ts +5 -10
- package/dist/commands/resources.js +220 -154
- package/dist/commands/resources.js.map +1 -0
- package/dist/commands/skills.d.ts +5 -9
- package/dist/commands/skills.js +355 -278
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/sync.d.ts +10 -8
- package/dist/commands/sync.js +111 -19
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/test.d.ts +1 -11
- package/dist/commands/test.js +396 -438
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/webhooks.d.ts +5 -11
- package/dist/commands/webhooks.js +357 -290
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/common/basket.instance.js +1 -0
- package/dist/common/basket.instance.js.map +1 -0
- package/dist/common/data.entry.instance.js +1 -0
- package/dist/common/data.entry.instance.js.map +1 -0
- package/dist/common/http.client.js +1 -0
- package/dist/common/http.client.js.map +1 -0
- package/dist/common/job.instance.js +1 -0
- package/dist/common/job.instance.js.map +1 -0
- package/dist/common/order.instance.js +1 -0
- package/dist/common/order.instance.js.map +1 -0
- package/dist/common/product.instance.js +1 -0
- package/dist/common/product.instance.js.map +1 -0
- package/dist/common/product.pagination.instance.js +1 -0
- package/dist/common/product.pagination.instance.js.map +1 -0
- package/dist/common/product.search.instance.js +1 -0
- package/dist/common/product.search.instance.js.map +1 -0
- package/dist/common/user.instance.js +1 -0
- package/dist/common/user.instance.js.map +1 -0
- package/dist/config/auth.constants.js +1 -0
- package/dist/config/auth.constants.js.map +1 -0
- package/dist/config/compile.constants.js +1 -0
- package/dist/config/compile.constants.js.map +1 -0
- package/dist/config/constants.js +1 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/dev.constants.js +1 -0
- package/dist/config/dev.constants.js.map +1 -0
- package/dist/config/init.constants.d.ts +0 -8
- package/dist/config/init.constants.js +1 -24
- package/dist/config/init.constants.js.map +1 -0
- package/dist/errors/auth.error.js +1 -0
- package/dist/errors/auth.error.js.map +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/admin.js +1 -0
- package/dist/interfaces/admin.js.map +1 -0
- package/dist/interfaces/agent.d.ts +2 -27
- package/dist/interfaces/agent.js +1 -0
- package/dist/interfaces/agent.js.map +1 -0
- package/dist/interfaces/baskets.js +1 -0
- package/dist/interfaces/baskets.js.map +1 -0
- package/dist/interfaces/cdn.js +1 -0
- package/dist/interfaces/cdn.js.map +1 -0
- package/dist/interfaces/chat.js +1 -0
- package/dist/interfaces/chat.js.map +1 -0
- package/dist/interfaces/common.js +1 -0
- package/dist/interfaces/common.js.map +1 -0
- package/dist/interfaces/compile.js +1 -0
- package/dist/interfaces/compile.js.map +1 -0
- package/dist/interfaces/custom.data.js +1 -0
- package/dist/interfaces/custom.data.js.map +1 -0
- package/dist/interfaces/deploy.js +1 -0
- package/dist/interfaces/deploy.js.map +1 -0
- package/dist/interfaces/dev.js +1 -0
- package/dist/interfaces/dev.js.map +1 -0
- package/dist/interfaces/index.js +1 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/init.d.ts +0 -19
- package/dist/interfaces/init.js +1 -0
- package/dist/interfaces/init.js.map +1 -0
- package/dist/interfaces/jobs.js +1 -0
- package/dist/interfaces/jobs.js.map +1 -0
- package/dist/interfaces/logs.js +1 -0
- package/dist/interfaces/logs.js.map +1 -0
- package/dist/interfaces/lua.d.ts +11 -1
- package/dist/interfaces/lua.js +1 -0
- package/dist/interfaces/lua.js.map +1 -0
- package/dist/interfaces/marketplace.js +1 -0
- package/dist/interfaces/marketplace.js.map +1 -0
- package/dist/interfaces/mcp.d.ts +28 -1
- package/dist/interfaces/mcp.js +1 -0
- package/dist/interfaces/mcp.js.map +1 -0
- package/dist/interfaces/message.js +1 -0
- package/dist/interfaces/message.js.map +1 -0
- package/dist/interfaces/orders.js +1 -0
- package/dist/interfaces/orders.js.map +1 -0
- package/dist/interfaces/persona.js +1 -0
- package/dist/interfaces/persona.js.map +1 -0
- package/dist/interfaces/postprocessors.js +1 -0
- package/dist/interfaces/postprocessors.js.map +1 -0
- package/dist/interfaces/preprocessors.js +1 -0
- package/dist/interfaces/preprocessors.js.map +1 -0
- package/dist/interfaces/product.d.ts +26 -0
- package/dist/interfaces/product.js +1 -0
- package/dist/interfaces/product.js.map +1 -0
- package/dist/interfaces/push.js +1 -0
- package/dist/interfaces/push.js.map +1 -0
- package/dist/interfaces/skills.js +1 -0
- package/dist/interfaces/skills.js.map +1 -0
- package/dist/interfaces/test.js +1 -0
- package/dist/interfaces/test.js.map +1 -0
- package/dist/interfaces/user.js +1 -0
- package/dist/interfaces/user.js.map +1 -0
- package/dist/interfaces/webhooks.js +1 -0
- package/dist/interfaces/webhooks.js.map +1 -0
- package/dist/interfaces/whatsapp-templates.js +1 -0
- package/dist/interfaces/whatsapp-templates.js.map +1 -0
- package/dist/services/auth.js +1 -0
- package/dist/services/auth.js.map +1 -0
- package/dist/types/api-contracts.d.ts +8 -4
- package/dist/types/api-contracts.js +1 -0
- package/dist/types/api-contracts.js.map +1 -0
- package/dist/types/compile.types.js +1 -0
- package/dist/types/compile.types.js.map +1 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/skill.d.ts +92 -17
- package/dist/types/skill.js +16 -11
- package/dist/types/skill.js.map +1 -0
- package/dist/types/tool-validation.js +1 -0
- package/dist/types/tool-validation.js.map +1 -0
- package/dist/utils/agent-code-utils.d.ts +2 -1
- package/dist/utils/agent-code-utils.js +14 -3
- package/dist/utils/agent-code-utils.js.map +1 -0
- package/dist/utils/auth-flows.js +1 -0
- package/dist/utils/auth-flows.js.map +1 -0
- package/dist/utils/bundling.d.ts +17 -0
- package/dist/utils/bundling.js +146 -12
- package/dist/utils/bundling.js.map +1 -0
- package/dist/utils/cli.js +1 -0
- package/dist/utils/cli.js.map +1 -0
- package/dist/utils/compile.d.ts +5 -0
- package/dist/utils/compile.js +154 -15
- package/dist/utils/compile.js.map +1 -0
- package/dist/utils/deploy-api.js +1 -0
- package/dist/utils/deploy-api.js.map +1 -0
- package/dist/utils/deploy-helpers.js +1 -0
- package/dist/utils/deploy-helpers.js.map +1 -0
- package/dist/utils/deployment.js +1 -0
- package/dist/utils/deployment.js.map +1 -0
- package/dist/utils/dev-api.js +1 -0
- package/dist/utils/dev-api.js.map +1 -0
- package/dist/utils/dev-helpers.d.ts +3 -2
- package/dist/utils/dev-helpers.js +4 -5
- package/dist/utils/dev-helpers.js.map +1 -0
- package/dist/utils/dev-server.js +1 -0
- package/dist/utils/dev-server.js.map +1 -0
- package/dist/utils/dev-watcher.js +1 -0
- package/dist/utils/dev-watcher.js.map +1 -0
- package/dist/utils/env-loader.utils.js +1 -0
- package/dist/utils/env-loader.utils.js.map +1 -0
- package/dist/utils/files.js +1 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/init-agent.d.ts +4 -4
- package/dist/utils/init-agent.js +12 -14
- package/dist/utils/init-agent.js.map +1 -0
- package/dist/utils/init-helpers.js +1 -0
- package/dist/utils/init-helpers.js.map +1 -0
- package/dist/utils/init-prompts.d.ts +10 -6
- package/dist/utils/init-prompts.js +41 -75
- package/dist/utils/init-prompts.js.map +1 -0
- package/dist/utils/job-management.js +1 -0
- package/dist/utils/job-management.js.map +1 -0
- package/dist/utils/mcp-server-management.d.ts +1 -1
- package/dist/utils/mcp-server-management.js +14 -14
- package/dist/utils/mcp-server-management.js.map +1 -0
- package/dist/utils/postprocessor-management.js +1 -0
- package/dist/utils/postprocessor-management.js.map +1 -0
- package/dist/utils/pre-bundle-jobs.js +1 -0
- package/dist/utils/pre-bundle-jobs.js.map +1 -0
- package/dist/utils/preprocessor-management.js +1 -0
- package/dist/utils/preprocessor-management.js.map +1 -0
- package/dist/utils/prompt-handler.js +1 -0
- package/dist/utils/prompt-handler.js.map +1 -0
- package/dist/utils/push-api.js +1 -0
- package/dist/utils/push-api.js.map +1 -0
- package/dist/utils/push-helpers.js +1 -0
- package/dist/utils/push-helpers.js.map +1 -0
- package/dist/utils/sandbox-storage.js +1 -0
- package/dist/utils/sandbox-storage.js.map +1 -0
- package/dist/utils/sandbox.d.ts +1 -0
- package/dist/utils/sandbox.js +2 -0
- package/dist/utils/sandbox.js.map +1 -0
- package/dist/utils/semver.js +1 -0
- package/dist/utils/semver.js.map +1 -0
- package/dist/utils/skill-management.js +1 -0
- package/dist/utils/skill-management.js.map +1 -0
- package/dist/utils/sync-helpers.js +23 -4
- package/dist/utils/sync-helpers.js.map +1 -0
- package/dist/utils/test-helpers.js +1 -0
- package/dist/utils/test-helpers.js.map +1 -0
- package/dist/utils/test-prompts.js +1 -0
- package/dist/utils/test-prompts.js.map +1 -0
- package/dist/utils/tool-detection.js +1 -0
- package/dist/utils/tool-detection.js.map +1 -0
- package/dist/utils/webhook-management.js +1 -0
- package/dist/utils/webhook-management.js.map +1 -0
- package/package.json +2 -1
- package/template/package.json +1 -1
package/dist/commands/jobs.js
CHANGED
|
@@ -9,23 +9,22 @@ import { BASE_URLS } from '../config/constants.js';
|
|
|
9
9
|
import { safePrompt } from '../utils/prompt-handler.js';
|
|
10
10
|
import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
|
|
11
11
|
import JobApi from '../api/job.api.service.js';
|
|
12
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
13
|
+
// Main Command Entry
|
|
14
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
12
15
|
/**
|
|
13
|
-
* Main jobs command - manages agent jobs
|
|
16
|
+
* Main jobs command - manages agent jobs.
|
|
14
17
|
*
|
|
15
|
-
*
|
|
16
|
-
* -
|
|
17
|
-
* -
|
|
18
|
-
* - Deploy job versions to production
|
|
19
|
-
* - Activate/deactivate, pause/resume jobs
|
|
20
|
-
* - Trigger jobs manually
|
|
21
|
-
* - View execution history
|
|
22
|
-
*
|
|
23
|
-
* Note: For local testing, use `lua test job`
|
|
24
|
-
*
|
|
25
|
-
* @returns Promise that resolves when command completes
|
|
18
|
+
* Supports both interactive and non-interactive modes:
|
|
19
|
+
* - Interactive: prompts for action and job selection
|
|
20
|
+
* - Non-interactive: use action argument with -i and -v flags
|
|
26
21
|
*/
|
|
27
|
-
export async function jobsCommand() {
|
|
22
|
+
export async function jobsCommand(action, cmdObj) {
|
|
28
23
|
return withErrorHandling(async () => {
|
|
24
|
+
const options = {
|
|
25
|
+
jobName: cmdObj?.jobName || null,
|
|
26
|
+
jobVersion: cmdObj?.jobVersion || null,
|
|
27
|
+
};
|
|
29
28
|
// Step 1: Load configuration
|
|
30
29
|
const config = readSkillConfig();
|
|
31
30
|
validateConfig(config);
|
|
@@ -44,13 +43,364 @@ export async function jobsCommand() {
|
|
|
44
43
|
agentId,
|
|
45
44
|
apiKey,
|
|
46
45
|
};
|
|
47
|
-
//
|
|
48
|
-
|
|
46
|
+
// Determine if non-interactive mode
|
|
47
|
+
if (action) {
|
|
48
|
+
await executeNonInteractive(context, config, action, options);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
await manageProductionJobs(context, config);
|
|
52
|
+
}
|
|
49
53
|
}, "jobs");
|
|
50
54
|
}
|
|
55
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
56
|
+
// Shared Core Functions (used by both interactive and non-interactive modes)
|
|
57
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
58
|
+
/**
|
|
59
|
+
* Fetches and displays all jobs with their current status.
|
|
60
|
+
*/
|
|
61
|
+
async function displayJobsCore(context, jobs) {
|
|
62
|
+
console.log("\n" + "=".repeat(60));
|
|
63
|
+
console.log("āļø Production Jobs");
|
|
64
|
+
console.log("=".repeat(60) + "\n");
|
|
65
|
+
for (const job of jobs) {
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(`${BASE_URLS.API}/developer/jobs/${context.agentId}/${job.jobId}`, {
|
|
68
|
+
method: 'GET',
|
|
69
|
+
headers: {
|
|
70
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
71
|
+
'Content-Type': 'application/json'
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
if (response.ok) {
|
|
75
|
+
const data = await response.json();
|
|
76
|
+
const jobData = data.data || data;
|
|
77
|
+
console.log(`ā° ${job.name}`);
|
|
78
|
+
console.log(` Job ID: ${job.jobId}`);
|
|
79
|
+
console.log(` Status: ${jobData.status || 'active'}`);
|
|
80
|
+
if (jobData.schedule) {
|
|
81
|
+
console.log(` Schedule: ${formatSchedule(jobData.schedule)}`);
|
|
82
|
+
}
|
|
83
|
+
if (jobData.lastRunAt) {
|
|
84
|
+
console.log(` Last Run: ${new Date(jobData.lastRunAt).toLocaleString()}`);
|
|
85
|
+
}
|
|
86
|
+
if (jobData.nextRunAt) {
|
|
87
|
+
console.log(` Next Run: ${new Date(jobData.nextRunAt).toLocaleString()}`);
|
|
88
|
+
}
|
|
89
|
+
console.log();
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
displayJobError(job, "Unable to fetch info");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
displayJobError(job, "Error loading info");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
console.log("=".repeat(60));
|
|
100
|
+
}
|
|
101
|
+
function displayJobError(job, status) {
|
|
102
|
+
console.log(`ā° ${job.name}`);
|
|
103
|
+
console.log(` Job ID: ${job.jobId}`);
|
|
104
|
+
console.log(` Status: ${status}`);
|
|
105
|
+
console.log();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Fetches and returns sorted job versions.
|
|
109
|
+
*/
|
|
110
|
+
async function fetchVersionsCore(context, job) {
|
|
111
|
+
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
112
|
+
const response = await jobApi.getJobVersions(job.jobId);
|
|
113
|
+
if (!response.success || !response.data) {
|
|
114
|
+
console.error(`ā Failed to fetch versions: ${response.error?.message || 'Unknown error'}`);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
return response.data.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Displays versions for a job.
|
|
121
|
+
*/
|
|
122
|
+
function displayVersionsCore(job, versions) {
|
|
123
|
+
console.log("\n" + "=".repeat(60));
|
|
124
|
+
console.log(`š Versions for ${job.name}`);
|
|
125
|
+
console.log("=".repeat(60) + "\n");
|
|
126
|
+
versions.forEach((version) => {
|
|
127
|
+
const isActive = version.jobId === job.activeVersionId;
|
|
128
|
+
console.log(`${isActive ? 'ā' : ' '} Version ${version.version}`);
|
|
129
|
+
console.log(` Created: ${new Date(version.createdAt).toLocaleString()}`);
|
|
130
|
+
if (version.schedule) {
|
|
131
|
+
console.log(` Schedule: ${formatSchedule(version.schedule)}`);
|
|
132
|
+
}
|
|
133
|
+
console.log();
|
|
134
|
+
});
|
|
135
|
+
console.log("=".repeat(60));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Deploys a specific version of a job.
|
|
139
|
+
*/
|
|
140
|
+
async function deployVersionCore(context, job, version) {
|
|
141
|
+
writeProgress(`š Deploying version ${version} of "${job.name}"...`);
|
|
142
|
+
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
143
|
+
const deployResponse = await jobApi.publishJobVersion(job.jobId, version);
|
|
144
|
+
if (!deployResponse.success) {
|
|
145
|
+
console.error(`ā Deploy Error: ${deployResponse.error?.message || 'Unknown error'}`);
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
writeSuccess(`ā
Version ${version} of "${job.name}" deployed successfully`);
|
|
149
|
+
writeInfo("š” The new version is now active and will run on schedule.");
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Activates a job.
|
|
154
|
+
*/
|
|
155
|
+
async function activateJobCore(context, job) {
|
|
156
|
+
writeProgress(`š Activating job "${job.name}"...`);
|
|
157
|
+
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
158
|
+
const response = await jobApi.activateJob(job.jobId);
|
|
159
|
+
if (response.success) {
|
|
160
|
+
writeSuccess(`ā
Job "${job.name}" activated successfully`);
|
|
161
|
+
writeInfo("š” The job is now enabled and will run on schedule.");
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.error(`ā Failed to activate job: ${response.error?.message || 'Unknown error'}`);
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Deactivates a job.
|
|
171
|
+
*/
|
|
172
|
+
async function deactivateJobCore(context, job) {
|
|
173
|
+
writeProgress(`š Deactivating job "${job.name}"...`);
|
|
174
|
+
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
175
|
+
const response = await jobApi.deactivateJob(job.jobId);
|
|
176
|
+
if (response.success) {
|
|
177
|
+
writeSuccess(`ā
Job "${job.name}" deactivated successfully`);
|
|
178
|
+
writeInfo("š” The job is now disabled and will not run.");
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
console.error(`ā Failed to deactivate job: ${response.error?.message || 'Unknown error'}`);
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Triggers a job execution.
|
|
188
|
+
*/
|
|
189
|
+
async function triggerJobCore(context, job) {
|
|
190
|
+
writeProgress(`ā” Triggering job "${job.name}"...`);
|
|
191
|
+
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
192
|
+
const response = await jobApi.triggerJob(job.jobId);
|
|
193
|
+
if (response.success && response.data) {
|
|
194
|
+
writeSuccess(`ā
Job "${job.name}" triggered successfully`);
|
|
195
|
+
writeInfo(`š Execution ID: ${response.data.id || 'N/A'}`);
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
console.error(`ā Failed to trigger job: ${response.error?.message || 'Unknown error'}`);
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Fetches and displays execution history for a job.
|
|
205
|
+
*/
|
|
206
|
+
async function fetchAndDisplayHistoryCore(context, job) {
|
|
207
|
+
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
208
|
+
const response = await jobApi.getJobExecutions(job.jobId, 20);
|
|
209
|
+
if (!response.success || !response.data) {
|
|
210
|
+
console.error(`ā Failed to fetch history: ${response.error?.message || 'Unknown error'}`);
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
const executions = response.data.executions || [];
|
|
214
|
+
if (executions.length === 0) {
|
|
215
|
+
console.log(`ā¹ļø No execution history found for ${job.name}.`);
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
console.log("\n" + "=".repeat(60));
|
|
219
|
+
console.log(`š Execution History for ${job.name}`);
|
|
220
|
+
console.log("=".repeat(60) + "\n");
|
|
221
|
+
executions.forEach((execution, index) => {
|
|
222
|
+
const startedAt = new Date(execution.startedAt);
|
|
223
|
+
const status = execution.status;
|
|
224
|
+
const statusEmoji = status === 'completed' ? 'ā
' :
|
|
225
|
+
status === 'failed' ? 'ā' :
|
|
226
|
+
status === 'running' ? 'š' : 'ā³';
|
|
227
|
+
console.log(`${index + 1}. ${statusEmoji} ${status.toUpperCase()}`);
|
|
228
|
+
console.log(` Execution ID: ${execution.executionId}`);
|
|
229
|
+
console.log(` Started: ${startedAt.toLocaleString()}`);
|
|
230
|
+
if (execution.completedAt) {
|
|
231
|
+
const completedAt = new Date(execution.completedAt);
|
|
232
|
+
const duration = completedAt.getTime() - startedAt.getTime();
|
|
233
|
+
console.log(` Completed: ${completedAt.toLocaleString()}`);
|
|
234
|
+
console.log(` Duration: ${Math.round(duration / 1000)}s`);
|
|
235
|
+
}
|
|
236
|
+
if (execution.result) {
|
|
237
|
+
console.log(` Result: ${JSON.stringify(execution.result).substring(0, 100)}...`);
|
|
238
|
+
}
|
|
239
|
+
if (execution.error) {
|
|
240
|
+
console.log(` Error: ${execution.error}`);
|
|
241
|
+
}
|
|
242
|
+
console.log();
|
|
243
|
+
});
|
|
244
|
+
console.log("=".repeat(60));
|
|
245
|
+
console.log(`Showing last ${executions.length} executions`);
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Resolves a version string to an actual version, supporting "latest".
|
|
250
|
+
*/
|
|
251
|
+
function resolveVersion(versions, versionArg) {
|
|
252
|
+
if (versionArg.toLowerCase() === 'latest') {
|
|
253
|
+
return versions[0].version;
|
|
254
|
+
}
|
|
255
|
+
const exists = versions.some((v) => v.version === versionArg);
|
|
256
|
+
if (!exists) {
|
|
257
|
+
console.error(`ā Version "${versionArg}" not found`);
|
|
258
|
+
console.log('\nAvailable versions:');
|
|
259
|
+
versions.slice(0, 5).forEach((v) => console.log(` - ${v.version}`));
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
return versionArg;
|
|
263
|
+
}
|
|
51
264
|
/**
|
|
52
|
-
*
|
|
265
|
+
* Prompts user to select a job from a list.
|
|
53
266
|
*/
|
|
267
|
+
async function promptJobSelection(jobs, message) {
|
|
268
|
+
const jobAnswer = await safePrompt([
|
|
269
|
+
{
|
|
270
|
+
type: 'list',
|
|
271
|
+
name: 'selectedJob',
|
|
272
|
+
message,
|
|
273
|
+
choices: jobs.map((job) => ({
|
|
274
|
+
name: `${job.name} (${job.jobId})`,
|
|
275
|
+
value: job
|
|
276
|
+
}))
|
|
277
|
+
}
|
|
278
|
+
]);
|
|
279
|
+
return jobAnswer?.selectedJob || null;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Prompts user to select a version from a list.
|
|
283
|
+
*/
|
|
284
|
+
async function promptVersionSelection(versions, activeVersionId) {
|
|
285
|
+
const versionAnswer = await safePrompt([
|
|
286
|
+
{
|
|
287
|
+
type: 'list',
|
|
288
|
+
name: 'selectedVersion',
|
|
289
|
+
message: 'Select a version to deploy:',
|
|
290
|
+
choices: versions.map((version) => {
|
|
291
|
+
const isActive = version.jobId === activeVersionId;
|
|
292
|
+
return {
|
|
293
|
+
name: `Version ${version.version} (${new Date(version.createdAt).toLocaleDateString()})${isActive ? ' ā CURRENT' : ''}`,
|
|
294
|
+
value: version
|
|
295
|
+
};
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
]);
|
|
299
|
+
return versionAnswer?.selectedVersion || null;
|
|
300
|
+
}
|
|
301
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
302
|
+
// Non-Interactive Mode
|
|
303
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
304
|
+
async function executeNonInteractive(context, config, action, options) {
|
|
305
|
+
const validActions = ['view', 'versions', 'deploy', 'activate', 'deactivate', 'trigger', 'history'];
|
|
306
|
+
const normalizedAction = action.toLowerCase();
|
|
307
|
+
if (!validActions.includes(normalizedAction)) {
|
|
308
|
+
console.error(`ā Invalid action: "${action}"`);
|
|
309
|
+
console.log('\nValid actions: view, versions, deploy, activate, deactivate, trigger, history');
|
|
310
|
+
console.log('\nExamples:');
|
|
311
|
+
console.log(' lua jobs view List all jobs');
|
|
312
|
+
console.log(' lua jobs trigger -i healthCheck Trigger a job');
|
|
313
|
+
console.log(' lua jobs deploy -i myJob -v 1.0.3 Deploy specific version');
|
|
314
|
+
process.exit(1);
|
|
315
|
+
}
|
|
316
|
+
const jobs = config.jobs || [];
|
|
317
|
+
// View action doesn't require job selection
|
|
318
|
+
if (normalizedAction === 'view') {
|
|
319
|
+
if (jobs.length === 0) {
|
|
320
|
+
console.log("ā¹ļø No jobs found in configuration.");
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
await displayJobsCore(context, jobs);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
// All other actions require job selection
|
|
327
|
+
if (!options.jobName) {
|
|
328
|
+
console.error(`ā --job-name is required for action "${normalizedAction}"`);
|
|
329
|
+
console.log(`\nUsage: lua jobs ${normalizedAction} --job-name <name>`);
|
|
330
|
+
process.exit(1);
|
|
331
|
+
}
|
|
332
|
+
const selectedJob = jobs.find((j) => j.jobId === options.jobName || j.name === options.jobName);
|
|
333
|
+
if (!selectedJob) {
|
|
334
|
+
console.error(`ā Job "${options.jobName}" not found`);
|
|
335
|
+
console.log('\nAvailable jobs:');
|
|
336
|
+
jobs.forEach((j) => console.log(` - ${j.name} (${j.jobId})`));
|
|
337
|
+
process.exit(1);
|
|
338
|
+
}
|
|
339
|
+
switch (normalizedAction) {
|
|
340
|
+
case 'versions': {
|
|
341
|
+
const versions = await fetchVersionsCore(context, selectedJob);
|
|
342
|
+
if (!versions)
|
|
343
|
+
process.exit(1);
|
|
344
|
+
if (versions.length === 0) {
|
|
345
|
+
console.log(`ā¹ļø No versions found for ${selectedJob.name}.`);
|
|
346
|
+
console.log("š” Push a version first using 'lua push job'.");
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
displayVersionsCore(selectedJob, versions);
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
case 'deploy': {
|
|
353
|
+
if (!options.jobVersion) {
|
|
354
|
+
console.error('ā --job-version is required for deploy action');
|
|
355
|
+
console.log('\nUsage: lua jobs deploy --job-name myJob --job-version 1.0.3');
|
|
356
|
+
console.log(' lua jobs deploy -i myJob -v latest');
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
const versions = await fetchVersionsCore(context, selectedJob);
|
|
360
|
+
if (!versions)
|
|
361
|
+
process.exit(1);
|
|
362
|
+
if (versions.length === 0) {
|
|
363
|
+
console.error(`ā No versions found for ${selectedJob.name}.`);
|
|
364
|
+
console.log("š” Push a version first using 'lua push job'.");
|
|
365
|
+
process.exit(1);
|
|
366
|
+
}
|
|
367
|
+
const resolvedVersion = resolveVersion(versions, options.jobVersion);
|
|
368
|
+
if (!resolvedVersion)
|
|
369
|
+
process.exit(1);
|
|
370
|
+
const success = await deployVersionCore(context, selectedJob, resolvedVersion);
|
|
371
|
+
if (!success)
|
|
372
|
+
process.exit(1);
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
case 'activate': {
|
|
376
|
+
const success = await activateJobCore(context, selectedJob);
|
|
377
|
+
if (!success)
|
|
378
|
+
process.exit(1);
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
case 'deactivate': {
|
|
382
|
+
const success = await deactivateJobCore(context, selectedJob);
|
|
383
|
+
if (!success)
|
|
384
|
+
process.exit(1);
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
case 'trigger': {
|
|
388
|
+
const success = await triggerJobCore(context, selectedJob);
|
|
389
|
+
if (!success)
|
|
390
|
+
process.exit(1);
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
case 'history': {
|
|
394
|
+
const success = await fetchAndDisplayHistoryCore(context, selectedJob);
|
|
395
|
+
if (!success)
|
|
396
|
+
process.exit(1);
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
402
|
+
// Interactive Mode
|
|
403
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
54
404
|
async function manageProductionJobs(context, config) {
|
|
55
405
|
let continueManaging = true;
|
|
56
406
|
while (continueManaging) {
|
|
@@ -79,25 +429,25 @@ async function manageProductionJobs(context, config) {
|
|
|
79
429
|
const { action } = actionAnswer;
|
|
80
430
|
switch (action) {
|
|
81
431
|
case 'view':
|
|
82
|
-
await
|
|
432
|
+
await viewDeployedJobsInteractive(context, config);
|
|
83
433
|
break;
|
|
84
434
|
case 'versions':
|
|
85
|
-
await
|
|
435
|
+
await viewJobVersionsInteractive(context, config);
|
|
86
436
|
break;
|
|
87
437
|
case 'deploy':
|
|
88
|
-
await
|
|
438
|
+
await deployJobVersionInteractive(context, config);
|
|
89
439
|
break;
|
|
90
440
|
case 'activate':
|
|
91
|
-
await
|
|
441
|
+
await activateJobInteractive(context, config);
|
|
92
442
|
break;
|
|
93
443
|
case 'deactivate':
|
|
94
|
-
await
|
|
444
|
+
await deactivateJobInteractive(context, config);
|
|
95
445
|
break;
|
|
96
446
|
case 'trigger':
|
|
97
|
-
await
|
|
447
|
+
await triggerJobInteractive(context, config);
|
|
98
448
|
break;
|
|
99
449
|
case 'history':
|
|
100
|
-
await
|
|
450
|
+
await viewExecutionHistoryInteractive(context, config);
|
|
101
451
|
break;
|
|
102
452
|
case 'exit':
|
|
103
453
|
continueManaging = false;
|
|
@@ -106,292 +456,115 @@ async function manageProductionJobs(context, config) {
|
|
|
106
456
|
}
|
|
107
457
|
}
|
|
108
458
|
}
|
|
109
|
-
|
|
110
|
-
* View deployed jobs in production
|
|
111
|
-
*/
|
|
112
|
-
async function viewDeployedJobs(context, config) {
|
|
459
|
+
async function viewDeployedJobsInteractive(context, config) {
|
|
113
460
|
writeProgress("š Loading job information...");
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
console.log("\nā¹ļø No jobs found in configuration.\n");
|
|
118
|
-
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
console.log("\n" + "=".repeat(60));
|
|
122
|
-
console.log("āļø Production Jobs");
|
|
123
|
-
console.log("=".repeat(60) + "\n");
|
|
124
|
-
for (const job of jobs) {
|
|
125
|
-
try {
|
|
126
|
-
const response = await fetch(`${BASE_URLS.API}/developer/jobs/${context.agentId}/${job.jobId}`, {
|
|
127
|
-
method: 'GET',
|
|
128
|
-
headers: {
|
|
129
|
-
'Authorization': `Bearer ${context.apiKey}`,
|
|
130
|
-
'Content-Type': 'application/json'
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
if (response.ok) {
|
|
134
|
-
const data = await response.json();
|
|
135
|
-
const jobData = data.data || data;
|
|
136
|
-
console.log(`ā° ${job.name}`);
|
|
137
|
-
console.log(` Job ID: ${job.jobId}`);
|
|
138
|
-
console.log(` Status: ${jobData.status || 'active'}`);
|
|
139
|
-
if (jobData.schedule) {
|
|
140
|
-
console.log(` Schedule: ${formatSchedule(jobData.schedule)}`);
|
|
141
|
-
}
|
|
142
|
-
if (jobData.lastRunAt) {
|
|
143
|
-
const lastRun = new Date(jobData.lastRunAt);
|
|
144
|
-
console.log(` Last Run: ${lastRun.toLocaleString()}`);
|
|
145
|
-
}
|
|
146
|
-
if (jobData.nextRunAt) {
|
|
147
|
-
const nextRun = new Date(jobData.nextRunAt);
|
|
148
|
-
console.log(` Next Run: ${nextRun.toLocaleString()}`);
|
|
149
|
-
}
|
|
150
|
-
console.log();
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
console.log(`ā° ${job.name}`);
|
|
154
|
-
console.log(` Job ID: ${job.jobId}`);
|
|
155
|
-
console.log(` Status: Unable to fetch info`);
|
|
156
|
-
console.log();
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
console.log(`ā° ${job.name}`);
|
|
161
|
-
console.log(` Job ID: ${job.jobId}`);
|
|
162
|
-
console.log(` Status: Error loading info`);
|
|
163
|
-
console.log();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
console.log("=".repeat(60) + "\n");
|
|
167
|
-
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
461
|
+
const jobs = config.jobs || [];
|
|
462
|
+
if (jobs.length === 0) {
|
|
463
|
+
console.log("\nā¹ļø No jobs found in configuration.\n");
|
|
168
464
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
465
|
+
else {
|
|
466
|
+
await displayJobsCore(context, jobs);
|
|
467
|
+
console.log();
|
|
172
468
|
}
|
|
469
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
173
470
|
}
|
|
174
|
-
|
|
175
|
-
* View all versions for a specific job
|
|
176
|
-
*/
|
|
177
|
-
async function viewJobVersions(context, config) {
|
|
471
|
+
async function viewJobVersionsInteractive(context, config) {
|
|
178
472
|
const jobs = config.jobs || [];
|
|
179
473
|
if (jobs.length === 0) {
|
|
180
474
|
console.log("\nā¹ļø No jobs found in configuration.\n");
|
|
181
475
|
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
182
476
|
return;
|
|
183
477
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
{
|
|
187
|
-
type: 'list',
|
|
188
|
-
name: 'selectedJob',
|
|
189
|
-
message: 'Select a job to view versions:',
|
|
190
|
-
choices: jobs.map((job) => ({
|
|
191
|
-
name: `${job.name} (${job.jobId})`,
|
|
192
|
-
value: job
|
|
193
|
-
}))
|
|
194
|
-
}
|
|
195
|
-
]);
|
|
196
|
-
if (!jobAnswer)
|
|
478
|
+
const selectedJob = await promptJobSelection(jobs, 'Select a job to view versions:');
|
|
479
|
+
if (!selectedJob)
|
|
197
480
|
return;
|
|
198
|
-
const selectedJob = jobAnswer.selectedJob;
|
|
199
481
|
writeProgress(`š Loading versions for ${selectedJob.name}...`);
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const response = await jobApi.getJobVersions(selectedJob.jobId);
|
|
203
|
-
if (!response.success || !response.data) {
|
|
204
|
-
throw new Error(response.error?.message || 'Failed to fetch versions');
|
|
205
|
-
}
|
|
206
|
-
const versions = response.data;
|
|
207
|
-
const activeVersionId = selectedJob.activeVersionId;
|
|
208
|
-
if (versions.length === 0) {
|
|
209
|
-
console.log(`\nā¹ļø No versions found for ${selectedJob.name}.\n`);
|
|
210
|
-
console.log("š” Push a version first using 'lua push job'.\n");
|
|
211
|
-
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
// Sort versions by date (newest first)
|
|
215
|
-
const sortedVersions = versions.sort((a, b) => {
|
|
216
|
-
const dateA = new Date(a.createdAt).getTime();
|
|
217
|
-
const dateB = new Date(b.createdAt).getTime();
|
|
218
|
-
return dateB - dateA;
|
|
219
|
-
});
|
|
220
|
-
console.log("\n" + "=".repeat(60));
|
|
221
|
-
console.log(`š Versions for ${selectedJob.name}`);
|
|
222
|
-
console.log("=".repeat(60) + "\n");
|
|
223
|
-
sortedVersions.forEach((version) => {
|
|
224
|
-
const isActive = version.jobId === activeVersionId;
|
|
225
|
-
const date = new Date(version.createdAt);
|
|
226
|
-
console.log(`${isActive ? 'ā' : ' '} Version ${version.version}`);
|
|
227
|
-
console.log(` Created: ${date.toLocaleString()}`);
|
|
228
|
-
if (version.schedule) {
|
|
229
|
-
console.log(` Schedule: ${formatSchedule(version.schedule)}`);
|
|
230
|
-
}
|
|
231
|
-
console.log();
|
|
232
|
-
});
|
|
233
|
-
console.log("=".repeat(60) + "\n");
|
|
482
|
+
const versions = await fetchVersionsCore(context, selectedJob);
|
|
483
|
+
if (!versions) {
|
|
234
484
|
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
485
|
+
return;
|
|
235
486
|
}
|
|
236
|
-
|
|
237
|
-
console.
|
|
238
|
-
|
|
487
|
+
if (versions.length === 0) {
|
|
488
|
+
console.log(`\nā¹ļø No versions found for ${selectedJob.name}.\n`);
|
|
489
|
+
console.log("š” Push a version first using 'lua push job'.\n");
|
|
239
490
|
}
|
|
491
|
+
else {
|
|
492
|
+
displayVersionsCore(selectedJob, versions);
|
|
493
|
+
console.log();
|
|
494
|
+
}
|
|
495
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
240
496
|
}
|
|
241
|
-
|
|
242
|
-
* Deploy a job version to production
|
|
243
|
-
*/
|
|
244
|
-
async function deployJobVersion(context, config) {
|
|
497
|
+
async function deployJobVersionInteractive(context, config) {
|
|
245
498
|
const jobs = config.jobs || [];
|
|
246
499
|
if (jobs.length === 0) {
|
|
247
500
|
console.log("\nā¹ļø No jobs found in configuration.\n");
|
|
248
501
|
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
249
502
|
return;
|
|
250
503
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
{
|
|
254
|
-
type: 'list',
|
|
255
|
-
name: 'selectedJob',
|
|
256
|
-
message: 'Select a job to deploy:',
|
|
257
|
-
choices: jobs.map((job) => ({
|
|
258
|
-
name: `${job.name} (${job.jobId})`,
|
|
259
|
-
value: job
|
|
260
|
-
}))
|
|
261
|
-
}
|
|
262
|
-
]);
|
|
263
|
-
if (!jobAnswer)
|
|
504
|
+
const selectedJob = await promptJobSelection(jobs, 'Select a job to deploy:');
|
|
505
|
+
if (!selectedJob)
|
|
264
506
|
return;
|
|
265
|
-
const selectedJob = jobAnswer.selectedJob;
|
|
266
507
|
writeProgress(`š Loading versions for ${selectedJob.name}...`);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const response = await jobApi.getJobVersions(selectedJob.jobId);
|
|
270
|
-
if (!response.success || !response.data) {
|
|
271
|
-
throw new Error(response.error?.message || 'Failed to fetch versions');
|
|
272
|
-
}
|
|
273
|
-
const versions = response.data;
|
|
274
|
-
const activeVersionId = selectedJob.activeVersionId;
|
|
275
|
-
if (versions.length === 0) {
|
|
276
|
-
console.log(`\nā¹ļø No versions found for ${selectedJob.name}.\n`);
|
|
277
|
-
console.log("š” Push a version first using 'lua push job'.\n");
|
|
278
|
-
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
// Sort versions by date (newest first)
|
|
282
|
-
const sortedVersions = versions.sort((a, b) => {
|
|
283
|
-
const dateA = new Date(a.createdAt).getTime();
|
|
284
|
-
const dateB = new Date(b.createdAt).getTime();
|
|
285
|
-
return dateB - dateA;
|
|
286
|
-
});
|
|
287
|
-
// Prompt to select a version
|
|
288
|
-
const versionAnswer = await safePrompt([
|
|
289
|
-
{
|
|
290
|
-
type: 'list',
|
|
291
|
-
name: 'selectedVersion',
|
|
292
|
-
message: 'Select a version to deploy:',
|
|
293
|
-
choices: sortedVersions.map((version) => {
|
|
294
|
-
const isActive = version.jobId === activeVersionId;
|
|
295
|
-
const date = new Date(version.createdAt);
|
|
296
|
-
return {
|
|
297
|
-
name: `Version ${version.version} (${date.toLocaleDateString()})${isActive ? ' ā CURRENT' : ''}`,
|
|
298
|
-
value: version
|
|
299
|
-
};
|
|
300
|
-
})
|
|
301
|
-
}
|
|
302
|
-
]);
|
|
303
|
-
if (!versionAnswer)
|
|
304
|
-
return;
|
|
305
|
-
const selectedVersion = versionAnswer.selectedVersion;
|
|
306
|
-
// Show warning
|
|
307
|
-
console.log("\nā ļø WARNING: You are about to deploy to PRODUCTION!");
|
|
308
|
-
console.log("ā ļø This will affect ALL users immediately.\n");
|
|
309
|
-
console.log(`Job: ${selectedJob.name}`);
|
|
310
|
-
console.log(`Version: ${selectedVersion.version}`);
|
|
311
|
-
console.log(`Schedule: ${formatSchedule(selectedJob.schedule)}\n`);
|
|
312
|
-
const confirmAnswer = await safePrompt([
|
|
313
|
-
{
|
|
314
|
-
type: 'confirm',
|
|
315
|
-
name: 'confirm',
|
|
316
|
-
message: 'Are you absolutely sure you want to deploy this version?',
|
|
317
|
-
default: false
|
|
318
|
-
}
|
|
319
|
-
]);
|
|
320
|
-
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
321
|
-
console.log("\nā Deployment cancelled.\n");
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
writeProgress("š Deploying version...");
|
|
325
|
-
// Reuse the same jobApi instance
|
|
326
|
-
const deployResponse = await jobApi.publishJobVersion(selectedJob.jobId, selectedVersion.version);
|
|
327
|
-
if (!deployResponse.success) {
|
|
328
|
-
console.error(`\nā Deploy Error: ${deployResponse.error?.message || 'Unknown error'}\n`);
|
|
329
|
-
throw new Error(deployResponse.error?.message || 'Failed to publish job version');
|
|
330
|
-
}
|
|
331
|
-
writeSuccess(`\nā
Version ${selectedVersion.version} of "${selectedJob.name}" deployed successfully to production\n`);
|
|
332
|
-
writeInfo("š” The new version is now active and will run on schedule.");
|
|
508
|
+
const versions = await fetchVersionsCore(context, selectedJob);
|
|
509
|
+
if (!versions) {
|
|
333
510
|
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
511
|
+
return;
|
|
334
512
|
}
|
|
335
|
-
|
|
336
|
-
console.
|
|
513
|
+
if (versions.length === 0) {
|
|
514
|
+
console.log(`\nā¹ļø No versions found for ${selectedJob.name}.\n`);
|
|
515
|
+
console.log("š” Push a version first using 'lua push job'.\n");
|
|
337
516
|
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
async function activateJob(context, config) {
|
|
341
|
-
const jobs = config.jobs || [];
|
|
342
|
-
if (jobs.length === 0) {
|
|
343
|
-
console.log("\nā¹ļø No jobs found.\n");
|
|
344
517
|
return;
|
|
345
518
|
}
|
|
346
|
-
const
|
|
519
|
+
const selectedVersion = await promptVersionSelection(versions, selectedJob.activeVersionId);
|
|
520
|
+
if (!selectedVersion)
|
|
521
|
+
return;
|
|
522
|
+
// Show warning and confirm
|
|
523
|
+
console.log("\nā ļø WARNING: You are about to deploy to PRODUCTION!");
|
|
524
|
+
console.log("ā ļø This will affect ALL users immediately.\n");
|
|
525
|
+
console.log(`Job: ${selectedJob.name}`);
|
|
526
|
+
console.log(`Version: ${selectedVersion.version}`);
|
|
527
|
+
console.log(`Schedule: ${formatSchedule(selectedJob.schedule)}\n`);
|
|
528
|
+
const confirmAnswer = await safePrompt([
|
|
347
529
|
{
|
|
348
|
-
type: '
|
|
349
|
-
name: '
|
|
350
|
-
message: '
|
|
351
|
-
|
|
352
|
-
name: `${job.name} (${job.jobId})`,
|
|
353
|
-
value: job
|
|
354
|
-
}))
|
|
530
|
+
type: 'confirm',
|
|
531
|
+
name: 'confirm',
|
|
532
|
+
message: 'Are you absolutely sure you want to deploy this version?',
|
|
533
|
+
default: false
|
|
355
534
|
}
|
|
356
535
|
]);
|
|
357
|
-
if (!
|
|
536
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
537
|
+
console.log("\nā Deployment cancelled.\n");
|
|
358
538
|
return;
|
|
359
|
-
writeProgress(`š Activating job "${jobAnswer.selectedJob.name}"...`);
|
|
360
|
-
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
361
|
-
const response = await jobApi.activateJob(jobAnswer.selectedJob.jobId);
|
|
362
|
-
if (response.success) {
|
|
363
|
-
writeSuccess(`ā
Job "${jobAnswer.selectedJob.name}" activated successfully`);
|
|
364
|
-
writeInfo("š” The job is now enabled and will run on schedule.");
|
|
365
539
|
}
|
|
366
|
-
|
|
367
|
-
|
|
540
|
+
await deployVersionCore(context, selectedJob, selectedVersion.version);
|
|
541
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
542
|
+
}
|
|
543
|
+
async function activateJobInteractive(context, config) {
|
|
544
|
+
const jobs = config.jobs || [];
|
|
545
|
+
if (jobs.length === 0) {
|
|
546
|
+
console.log("\nā¹ļø No jobs found.\n");
|
|
547
|
+
return;
|
|
368
548
|
}
|
|
549
|
+
const selectedJob = await promptJobSelection(jobs, 'Select a job to activate:');
|
|
550
|
+
if (!selectedJob)
|
|
551
|
+
return;
|
|
552
|
+
await activateJobCore(context, selectedJob);
|
|
369
553
|
}
|
|
370
|
-
async function
|
|
554
|
+
async function deactivateJobInteractive(context, config) {
|
|
371
555
|
const jobs = config.jobs || [];
|
|
372
556
|
if (jobs.length === 0) {
|
|
373
557
|
console.log("\nā¹ļø No jobs found.\n");
|
|
374
558
|
return;
|
|
375
559
|
}
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
type: 'list',
|
|
379
|
-
name: 'selectedJob',
|
|
380
|
-
message: 'Select a job to deactivate:',
|
|
381
|
-
choices: jobs.map((job) => ({
|
|
382
|
-
name: `${job.name} (${job.jobId})`,
|
|
383
|
-
value: job
|
|
384
|
-
}))
|
|
385
|
-
}
|
|
386
|
-
]);
|
|
387
|
-
if (!jobAnswer)
|
|
560
|
+
const selectedJob = await promptJobSelection(jobs, 'Select a job to deactivate:');
|
|
561
|
+
if (!selectedJob)
|
|
388
562
|
return;
|
|
389
|
-
// Confirm deactivation
|
|
390
563
|
const confirmAnswer = await safePrompt([
|
|
391
564
|
{
|
|
392
565
|
type: 'confirm',
|
|
393
566
|
name: 'confirm',
|
|
394
|
-
message: `Are you sure you want to deactivate "${
|
|
567
|
+
message: `Are you sure you want to deactivate "${selectedJob.name}"? It will stop running on schedule.`,
|
|
395
568
|
default: false
|
|
396
569
|
}
|
|
397
570
|
]);
|
|
@@ -399,124 +572,36 @@ async function deactivateJob(context, config) {
|
|
|
399
572
|
console.log("\nā Deactivation cancelled.\n");
|
|
400
573
|
return;
|
|
401
574
|
}
|
|
402
|
-
|
|
403
|
-
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
404
|
-
const response = await jobApi.deactivateJob(jobAnswer.selectedJob.jobId);
|
|
405
|
-
if (response.success) {
|
|
406
|
-
writeSuccess(`ā
Job "${jobAnswer.selectedJob.name}" deactivated successfully`);
|
|
407
|
-
writeInfo("š” The job is now disabled and will not run.");
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
console.error(`ā Failed to deactivate job: ${response.error?.message || 'Unknown error'}`);
|
|
411
|
-
}
|
|
575
|
+
await deactivateJobCore(context, selectedJob);
|
|
412
576
|
}
|
|
413
|
-
async function
|
|
577
|
+
async function triggerJobInteractive(context, config) {
|
|
414
578
|
const jobs = config.jobs || [];
|
|
415
579
|
if (jobs.length === 0) {
|
|
416
580
|
console.log("\nā¹ļø No jobs found.\n");
|
|
417
581
|
return;
|
|
418
582
|
}
|
|
419
|
-
const
|
|
420
|
-
|
|
421
|
-
type: 'list',
|
|
422
|
-
name: 'selectedJob',
|
|
423
|
-
message: 'Select a job to trigger:',
|
|
424
|
-
choices: jobs.map((job) => ({
|
|
425
|
-
name: `${job.name} (${job.jobId})`,
|
|
426
|
-
value: job
|
|
427
|
-
}))
|
|
428
|
-
}
|
|
429
|
-
]);
|
|
430
|
-
if (!jobAnswer)
|
|
583
|
+
const selectedJob = await promptJobSelection(jobs, 'Select a job to trigger:');
|
|
584
|
+
if (!selectedJob)
|
|
431
585
|
return;
|
|
432
|
-
|
|
433
|
-
const jobApi = new JobApi(BASE_URLS.API, context.apiKey, context.agentId);
|
|
434
|
-
const response = await jobApi.triggerJob(jobAnswer.selectedJob.jobId);
|
|
435
|
-
if (response.success && response.data) {
|
|
436
|
-
writeSuccess(`ā
Job "${jobAnswer.selectedJob.name}" triggered successfully`);
|
|
437
|
-
writeInfo(`š Execution ID: ${response.data.id || 'N/A'}`);
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
console.error(`ā Failed to trigger job: ${response.error?.message || 'Unknown error'}`);
|
|
441
|
-
}
|
|
586
|
+
await triggerJobCore(context, selectedJob);
|
|
442
587
|
}
|
|
443
|
-
|
|
444
|
-
* View execution history for a job
|
|
445
|
-
*/
|
|
446
|
-
async function viewExecutionHistory(context, config) {
|
|
588
|
+
async function viewExecutionHistoryInteractive(context, config) {
|
|
447
589
|
const jobs = config.jobs || [];
|
|
448
590
|
if (jobs.length === 0) {
|
|
449
591
|
console.log("\nā¹ļø No jobs found in configuration.\n");
|
|
450
592
|
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
451
593
|
return;
|
|
452
594
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
{
|
|
456
|
-
type: 'list',
|
|
457
|
-
name: 'selectedJob',
|
|
458
|
-
message: 'Select a job to view execution history:',
|
|
459
|
-
choices: jobs.map((job) => ({
|
|
460
|
-
name: `${job.name} (${job.jobId})`,
|
|
461
|
-
value: job
|
|
462
|
-
}))
|
|
463
|
-
}
|
|
464
|
-
]);
|
|
465
|
-
if (!jobAnswer)
|
|
595
|
+
const selectedJob = await promptJobSelection(jobs, 'Select a job to view execution history:');
|
|
596
|
+
if (!selectedJob)
|
|
466
597
|
return;
|
|
467
|
-
const selectedJob = jobAnswer.selectedJob;
|
|
468
598
|
writeProgress(`š Loading execution history for ${selectedJob.name}...`);
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
const response = await jobApi.getJobExecutions(selectedJob.jobId, 20); // Get last 20 executions
|
|
472
|
-
if (!response.success || !response.data) {
|
|
473
|
-
throw new Error(response.error?.message || 'Failed to fetch execution history');
|
|
474
|
-
}
|
|
475
|
-
const executions = response.data.executions || [];
|
|
476
|
-
if (executions.length === 0) {
|
|
477
|
-
console.log(`\nā¹ļø No execution history found for ${selectedJob.name}.\n`);
|
|
478
|
-
console.log("š” The job hasn't run yet or has no recorded executions.\n");
|
|
479
|
-
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
console.log("\n" + "=".repeat(60));
|
|
483
|
-
console.log(`š Execution History for ${selectedJob.name}`);
|
|
484
|
-
console.log("=".repeat(60) + "\n");
|
|
485
|
-
executions.forEach((execution, index) => {
|
|
486
|
-
const startedAt = new Date(execution.startedAt);
|
|
487
|
-
const status = execution.status;
|
|
488
|
-
const statusEmoji = status === 'completed' ? 'ā
' :
|
|
489
|
-
status === 'failed' ? 'ā' :
|
|
490
|
-
status === 'running' ? 'š' : 'ā³';
|
|
491
|
-
console.log(`${index + 1}. ${statusEmoji} ${status.toUpperCase()}`);
|
|
492
|
-
console.log(` Execution ID: ${execution.executionId}`);
|
|
493
|
-
console.log(` Started: ${startedAt.toLocaleString()}`);
|
|
494
|
-
if (execution.completedAt) {
|
|
495
|
-
const completedAt = new Date(execution.completedAt);
|
|
496
|
-
const duration = completedAt.getTime() - startedAt.getTime();
|
|
497
|
-
console.log(` Completed: ${completedAt.toLocaleString()}`);
|
|
498
|
-
console.log(` Duration: ${Math.round(duration / 1000)}s`);
|
|
499
|
-
}
|
|
500
|
-
if (execution.result) {
|
|
501
|
-
console.log(` Result: ${JSON.stringify(execution.result).substring(0, 100)}...`);
|
|
502
|
-
}
|
|
503
|
-
if (execution.error) {
|
|
504
|
-
console.log(` Error: ${execution.error}`);
|
|
505
|
-
}
|
|
506
|
-
console.log();
|
|
507
|
-
});
|
|
508
|
-
console.log("=".repeat(60) + "\n");
|
|
509
|
-
console.log(`Showing last ${executions.length} executions\n`);
|
|
510
|
-
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
511
|
-
}
|
|
512
|
-
catch (error) {
|
|
513
|
-
console.error('\nā Error loading execution history:', error);
|
|
514
|
-
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
515
|
-
}
|
|
599
|
+
await fetchAndDisplayHistoryCore(context, selectedJob);
|
|
600
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
516
601
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
602
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
603
|
+
// Utility Functions
|
|
604
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
520
605
|
function formatSchedule(schedule) {
|
|
521
606
|
if (!schedule)
|
|
522
607
|
return 'Not configured';
|
|
@@ -531,3 +616,4 @@ function formatSchedule(schedule) {
|
|
|
531
616
|
return 'Unknown schedule type';
|
|
532
617
|
}
|
|
533
618
|
}
|
|
619
|
+
//# sourceMappingURL=jobs.js.map
|