lua-cli 2.5.7 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/agent.api.service.d.ts +45 -0
- package/dist/api/agent.api.service.js +54 -0
- package/dist/api/job.api.service.d.ts +210 -0
- package/dist/api/job.api.service.js +200 -0
- package/dist/api/lazy-instances.d.ts +24 -0
- package/dist/api/lazy-instances.js +48 -0
- package/dist/api/postprocessor.api.service.d.ts +98 -0
- package/dist/api/postprocessor.api.service.js +76 -0
- package/dist/api/preprocessor.api.service.d.ts +98 -0
- package/dist/api/preprocessor.api.service.js +76 -0
- package/dist/api/user.data.api.service.d.ts +28 -0
- package/dist/api/user.data.api.service.js +51 -0
- package/dist/api/webhook.api.service.d.ts +151 -0
- package/dist/api/webhook.api.service.js +134 -0
- package/dist/api-exports.d.ts +156 -41
- package/dist/api-exports.js +182 -21
- package/dist/cli/command-definitions.js +149 -7
- package/dist/commands/compile.js +124 -5
- package/dist/commands/completion.d.ts +11 -0
- package/dist/commands/completion.js +209 -0
- package/dist/commands/env.d.ts +3 -2
- package/dist/commands/env.js +42 -17
- package/dist/commands/features.d.ts +16 -0
- package/dist/commands/features.js +352 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/init.js +53 -7
- package/dist/commands/jobs.d.ts +20 -0
- package/dist/commands/jobs.js +533 -0
- package/dist/commands/logs.js +2 -5
- package/dist/commands/persona.d.ts +3 -2
- package/dist/commands/persona.js +43 -18
- package/dist/commands/postprocessors.d.ts +8 -0
- package/dist/commands/postprocessors.js +431 -0
- package/dist/commands/preprocessors.d.ts +8 -0
- package/dist/commands/preprocessors.js +431 -0
- package/dist/commands/push.d.ts +9 -13
- package/dist/commands/push.js +937 -69
- package/dist/commands/skills.d.ts +16 -0
- package/dist/commands/skills.js +438 -0
- package/dist/commands/test.d.ts +9 -18
- package/dist/commands/test.js +558 -82
- package/dist/commands/webhooks.d.ts +18 -0
- package/dist/commands/webhooks.js +424 -0
- package/dist/common/data.entry.instance.d.ts +7 -0
- package/dist/common/data.entry.instance.js +15 -0
- package/dist/common/job.instance.d.ts +77 -0
- package/dist/common/job.instance.js +108 -0
- package/dist/common/order.instance.d.ts +6 -0
- package/dist/common/order.instance.js +14 -0
- package/dist/common/product.instance.d.ts +6 -0
- package/dist/common/product.instance.js +14 -0
- package/dist/common/user.instance.d.ts +15 -0
- package/dist/common/user.instance.js +38 -0
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.js +4 -4
- package/dist/index.js +14 -3
- package/dist/interfaces/agent.d.ts +33 -1
- package/dist/interfaces/chat.d.ts +22 -0
- package/dist/interfaces/index.d.ts +10 -0
- package/dist/interfaces/index.js +7 -0
- package/dist/interfaces/jobs.d.ts +172 -0
- package/dist/interfaces/jobs.js +5 -0
- package/dist/interfaces/message.d.ts +18 -0
- package/dist/interfaces/message.js +1 -0
- package/dist/interfaces/postprocessors.d.ts +35 -0
- package/dist/interfaces/postprocessors.js +4 -0
- package/dist/interfaces/preprocessors.d.ts +35 -0
- package/dist/interfaces/preprocessors.js +4 -0
- package/dist/interfaces/webhooks.d.ts +104 -0
- package/dist/interfaces/webhooks.js +5 -0
- package/dist/types/api-contracts.d.ts +14 -0
- package/dist/types/api-contracts.js +0 -7
- package/dist/types/compile.types.d.ts +49 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/skill.d.ts +502 -0
- package/dist/types/skill.js +477 -0
- package/dist/utils/agent-management.d.ts +25 -0
- package/dist/utils/agent-management.js +67 -0
- package/dist/utils/bundling.d.ts +31 -1
- package/dist/utils/bundling.js +653 -10
- package/dist/utils/compile.d.ts +63 -0
- package/dist/utils/compile.js +691 -36
- package/dist/utils/deployment.d.ts +2 -1
- package/dist/utils/deployment.js +16 -2
- package/dist/utils/init-agent.d.ts +3 -1
- package/dist/utils/init-agent.js +6 -4
- package/dist/utils/init-prompts.d.ts +2 -1
- package/dist/utils/init-prompts.js +14 -9
- package/dist/utils/job-management.d.ts +24 -0
- package/dist/utils/job-management.js +264 -0
- package/dist/utils/postprocessor-management.d.ts +9 -0
- package/dist/utils/postprocessor-management.js +118 -0
- package/dist/utils/preprocessor-management.d.ts +9 -0
- package/dist/utils/preprocessor-management.js +118 -0
- package/dist/utils/sandbox.d.ts +61 -1
- package/dist/utils/sandbox.js +283 -72
- package/dist/utils/tool-detection.d.ts +3 -2
- package/dist/utils/tool-detection.js +18 -4
- package/dist/utils/webhook-management.d.ts +24 -0
- package/dist/utils/webhook-management.js +256 -0
- package/dist/web/app.css +152 -736
- package/dist/web/app.js +45 -45
- package/package.json +2 -2
- package/template/AGENT_CONFIGURATION.md +251 -0
- package/template/COMPLEX_JOB_EXAMPLES.md +795 -0
- package/template/DYNAMIC_JOB_CREATION.md +371 -0
- package/template/README.md +30 -2
- package/template/WEBHOOKS_JOBS_QUICKSTART.md +318 -0
- package/template/WEBHOOK_JOB_EXAMPLES.md +817 -0
- package/template/package.json +1 -1
- package/template/src/index-agent-example.ts +201 -0
- package/template/src/index.ts +39 -0
- package/template/src/jobs/AbandonedBasketProcessorJob.ts +139 -0
- package/template/src/jobs/DailyCleanupJob.ts +100 -0
- package/template/src/jobs/DataMigrationJob.ts +133 -0
- package/template/src/jobs/HealthCheckJob.ts +87 -0
- package/template/src/postprocessors/ResponseFormatter.ts +151 -0
- package/template/src/preprocessors/MessageFilter.ts +91 -0
- package/template/src/tools/GameScoreTrackerTool.ts +356 -0
- package/template/src/tools/SmartBasketTool.ts +188 -0
- package/template/src/webhooks/PaymentWebhook.ts +113 -0
- package/template/src/webhooks/UserEventWebhook.ts +77 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Completion Command
|
|
3
|
+
* Generates shell completion scripts for the Lua CLI
|
|
4
|
+
*/
|
|
5
|
+
import { withErrorHandling } from '../utils/cli.js';
|
|
6
|
+
/**
|
|
7
|
+
* Bash completion script
|
|
8
|
+
*/
|
|
9
|
+
const BASH_COMPLETION = `# Bash completion for lua CLI
|
|
10
|
+
_lua_completion() {
|
|
11
|
+
local cur prev commands
|
|
12
|
+
COMPREPLY=()
|
|
13
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
14
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
15
|
+
|
|
16
|
+
# Main commands
|
|
17
|
+
commands="auth init compile test push deploy chat env persona production resources admin docs channels logs skills features completion"
|
|
18
|
+
|
|
19
|
+
# Subcommands
|
|
20
|
+
case "\${prev}" in
|
|
21
|
+
lua)
|
|
22
|
+
COMPREPLY=( $(compgen -W "\${commands}" -- \${cur}) )
|
|
23
|
+
return 0
|
|
24
|
+
;;
|
|
25
|
+
auth)
|
|
26
|
+
COMPREPLY=( $(compgen -W "configure logout key" -- \${cur}) )
|
|
27
|
+
return 0
|
|
28
|
+
;;
|
|
29
|
+
push)
|
|
30
|
+
COMPREPLY=( $(compgen -W "skill persona" -- \${cur}) )
|
|
31
|
+
return 0
|
|
32
|
+
;;
|
|
33
|
+
env)
|
|
34
|
+
COMPREPLY=( $(compgen -W "sandbox staging production" -- \${cur}) )
|
|
35
|
+
return 0
|
|
36
|
+
;;
|
|
37
|
+
persona)
|
|
38
|
+
COMPREPLY=( $(compgen -W "sandbox staging production" -- \${cur}) )
|
|
39
|
+
return 0
|
|
40
|
+
;;
|
|
41
|
+
skills)
|
|
42
|
+
COMPREPLY=( $(compgen -W "sandbox staging production" -- \${cur}) )
|
|
43
|
+
return 0
|
|
44
|
+
;;
|
|
45
|
+
chat)
|
|
46
|
+
COMPREPLY=( $(compgen -W "clear" -- \${cur}) )
|
|
47
|
+
return 0
|
|
48
|
+
;;
|
|
49
|
+
completion)
|
|
50
|
+
COMPREPLY=( $(compgen -W "bash zsh fish" -- \${cur}) )
|
|
51
|
+
return 0
|
|
52
|
+
;;
|
|
53
|
+
esac
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
complete -F _lua_completion lua
|
|
57
|
+
`;
|
|
58
|
+
/**
|
|
59
|
+
* Zsh completion script
|
|
60
|
+
*/
|
|
61
|
+
const ZSH_COMPLETION = `#compdef lua
|
|
62
|
+
|
|
63
|
+
# Zsh completion for lua CLI
|
|
64
|
+
_lua() {
|
|
65
|
+
local line state
|
|
66
|
+
|
|
67
|
+
_arguments -C \\
|
|
68
|
+
"1: :(auth init compile test push deploy chat env persona production resources admin docs channels logs skills features completion)" \\
|
|
69
|
+
"*::arg:->args"
|
|
70
|
+
|
|
71
|
+
case $line[1] in
|
|
72
|
+
auth)
|
|
73
|
+
_arguments "1: :(configure logout key)"
|
|
74
|
+
;;
|
|
75
|
+
push)
|
|
76
|
+
_arguments "1: :(skill persona)"
|
|
77
|
+
;;
|
|
78
|
+
env)
|
|
79
|
+
_arguments "1: :(sandbox staging production)"
|
|
80
|
+
;;
|
|
81
|
+
persona)
|
|
82
|
+
_arguments "1: :(sandbox staging production)"
|
|
83
|
+
;;
|
|
84
|
+
skills)
|
|
85
|
+
_arguments "1: :(sandbox staging production)"
|
|
86
|
+
;;
|
|
87
|
+
chat)
|
|
88
|
+
_arguments "1: :(clear)"
|
|
89
|
+
;;
|
|
90
|
+
completion)
|
|
91
|
+
_arguments "1: :(bash zsh fish)"
|
|
92
|
+
;;
|
|
93
|
+
esac
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
_lua
|
|
97
|
+
`;
|
|
98
|
+
/**
|
|
99
|
+
* Fish completion script
|
|
100
|
+
*/
|
|
101
|
+
const FISH_COMPLETION = `# Fish completion for lua CLI
|
|
102
|
+
|
|
103
|
+
# Main commands
|
|
104
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "auth" -d "Authentication management"
|
|
105
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "init" -d "Initialize a new project"
|
|
106
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "compile" -d "Compile skill"
|
|
107
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "test" -d "Test skill tools"
|
|
108
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "push" -d "Push skill or persona"
|
|
109
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "deploy" -d "Deploy to production"
|
|
110
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "chat" -d "Interactive chat"
|
|
111
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "env" -d "Manage environment"
|
|
112
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "persona" -d "Manage persona"
|
|
113
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "production" -d "View production"
|
|
114
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "resources" -d "Manage resources"
|
|
115
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "admin" -d "Open admin dashboard"
|
|
116
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "docs" -d "Open documentation"
|
|
117
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "channels" -d "Manage channels"
|
|
118
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "logs" -d "View logs"
|
|
119
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "skills" -d "Manage skills"
|
|
120
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "features" -d "Manage agent features"
|
|
121
|
+
complete -c lua -f -n "__fish_use_subcommand" -a "completion" -d "Generate completion script"
|
|
122
|
+
|
|
123
|
+
# Auth subcommands
|
|
124
|
+
complete -c lua -f -n "__fish_seen_subcommand_from auth" -a "configure" -d "Set up API key"
|
|
125
|
+
complete -c lua -f -n "__fish_seen_subcommand_from auth" -a "logout" -d "Delete API key"
|
|
126
|
+
complete -c lua -f -n "__fish_seen_subcommand_from auth" -a "key" -d "Display API key"
|
|
127
|
+
|
|
128
|
+
# Push subcommands
|
|
129
|
+
complete -c lua -f -n "__fish_seen_subcommand_from push" -a "skill" -d "Push a skill"
|
|
130
|
+
complete -c lua -f -n "__fish_seen_subcommand_from push" -a "persona" -d "Push a persona"
|
|
131
|
+
|
|
132
|
+
# Env subcommands
|
|
133
|
+
complete -c lua -f -n "__fish_seen_subcommand_from env" -a "sandbox" -d "Manage sandbox env vars"
|
|
134
|
+
complete -c lua -f -n "__fish_seen_subcommand_from env" -a "staging" -d "Manage staging env vars"
|
|
135
|
+
complete -c lua -f -n "__fish_seen_subcommand_from env" -a "production" -d "Manage production env vars"
|
|
136
|
+
|
|
137
|
+
# Persona subcommands
|
|
138
|
+
complete -c lua -f -n "__fish_seen_subcommand_from persona" -a "sandbox" -d "Manage sandbox persona"
|
|
139
|
+
complete -c lua -f -n "__fish_seen_subcommand_from persona" -a "staging" -d "Manage staging persona"
|
|
140
|
+
complete -c lua -f -n "__fish_seen_subcommand_from persona" -a "production" -d "Manage production persona"
|
|
141
|
+
|
|
142
|
+
# Skills subcommands
|
|
143
|
+
complete -c lua -f -n "__fish_seen_subcommand_from skills" -a "sandbox" -d "View sandbox skills"
|
|
144
|
+
complete -c lua -f -n "__fish_seen_subcommand_from skills" -a "staging" -d "View staging skills"
|
|
145
|
+
complete -c lua -f -n "__fish_seen_subcommand_from skills" -a "production" -d "Manage production skills"
|
|
146
|
+
|
|
147
|
+
# Chat subcommands
|
|
148
|
+
complete -c lua -f -n "__fish_seen_subcommand_from chat" -a "clear" -d "Clear history"
|
|
149
|
+
|
|
150
|
+
# Completion subcommands
|
|
151
|
+
complete -c lua -f -n "__fish_seen_subcommand_from completion" -a "bash" -d "Generate bash completion"
|
|
152
|
+
complete -c lua -f -n "__fish_seen_subcommand_from completion" -a "zsh" -d "Generate zsh completion"
|
|
153
|
+
complete -c lua -f -n "__fish_seen_subcommand_from completion" -a "fish" -d "Generate fish completion"
|
|
154
|
+
`;
|
|
155
|
+
/**
|
|
156
|
+
* Main completion command - generates shell completion scripts
|
|
157
|
+
*
|
|
158
|
+
* @param shell - Shell type (bash, zsh, fish)
|
|
159
|
+
* @returns Promise that resolves when command completes
|
|
160
|
+
*/
|
|
161
|
+
export async function completionCommand(shell) {
|
|
162
|
+
return withErrorHandling(async () => {
|
|
163
|
+
// If no shell specified, show instructions
|
|
164
|
+
if (!shell) {
|
|
165
|
+
console.log(`
|
|
166
|
+
🎯 Lua CLI Shell Completion
|
|
167
|
+
|
|
168
|
+
To enable autocomplete, run one of the following commands based on your shell:
|
|
169
|
+
|
|
170
|
+
Bash:
|
|
171
|
+
$ lua completion bash >> ~/.bashrc
|
|
172
|
+
$ source ~/.bashrc
|
|
173
|
+
|
|
174
|
+
Zsh:
|
|
175
|
+
$ lua completion zsh >> ~/.zshrc
|
|
176
|
+
$ source ~/.zshrc
|
|
177
|
+
|
|
178
|
+
Fish:
|
|
179
|
+
$ lua completion fish > ~/.config/fish/completions/lua.fish
|
|
180
|
+
|
|
181
|
+
Or manually:
|
|
182
|
+
$ lua completion bash # Output bash completion script
|
|
183
|
+
$ lua completion zsh # Output zsh completion script
|
|
184
|
+
$ lua completion fish # Output fish completion script
|
|
185
|
+
|
|
186
|
+
Then follow the instructions above to add it to your shell configuration.
|
|
187
|
+
`);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Validate shell type
|
|
191
|
+
const validShells = ['bash', 'zsh', 'fish'];
|
|
192
|
+
if (!validShells.includes(shell.toLowerCase())) {
|
|
193
|
+
console.error(`❌ Invalid shell: "${shell}". Must be one of: ${validShells.join(', ')}`);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
// Output the appropriate completion script
|
|
197
|
+
switch (shell.toLowerCase()) {
|
|
198
|
+
case 'bash':
|
|
199
|
+
console.log(BASH_COMPLETION);
|
|
200
|
+
break;
|
|
201
|
+
case 'zsh':
|
|
202
|
+
console.log(ZSH_COMPLETION);
|
|
203
|
+
break;
|
|
204
|
+
case 'fish':
|
|
205
|
+
console.log(FISH_COMPLETION);
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}, "completion");
|
|
209
|
+
}
|
package/dist/commands/env.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Main env command - manages environment variables
|
|
7
7
|
*
|
|
8
8
|
* Features:
|
|
9
|
-
* - Environment selection (sandbox or production)
|
|
9
|
+
* - Environment selection (sandbox/staging or production)
|
|
10
10
|
* - List all environment variables
|
|
11
11
|
* - Add new variables
|
|
12
12
|
* - Update existing variables
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* - Sandbox: manages .env file
|
|
15
15
|
* - Production: uses API endpoints
|
|
16
16
|
*
|
|
17
|
+
* @param env - Optional environment argument ('sandbox', 'staging', or 'production')
|
|
17
18
|
* @returns Promise that resolves when command completes
|
|
18
19
|
*/
|
|
19
|
-
export declare function envCommand(): Promise<void>;
|
|
20
|
+
export declare function envCommand(env?: string): Promise<void>;
|
package/dist/commands/env.js
CHANGED
|
@@ -15,7 +15,7 @@ import DeveloperApi from '../api/developer.api.service.js';
|
|
|
15
15
|
* Main env command - manages environment variables
|
|
16
16
|
*
|
|
17
17
|
* Features:
|
|
18
|
-
* - Environment selection (sandbox or production)
|
|
18
|
+
* - Environment selection (sandbox/staging or production)
|
|
19
19
|
* - List all environment variables
|
|
20
20
|
* - Add new variables
|
|
21
21
|
* - Update existing variables
|
|
@@ -23,34 +23,59 @@ import DeveloperApi from '../api/developer.api.service.js';
|
|
|
23
23
|
* - Sandbox: manages .env file
|
|
24
24
|
* - Production: uses API endpoints
|
|
25
25
|
*
|
|
26
|
+
* @param env - Optional environment argument ('sandbox', 'staging', or 'production')
|
|
26
27
|
* @returns Promise that resolves when command completes
|
|
27
28
|
*/
|
|
28
|
-
export async function envCommand() {
|
|
29
|
+
export async function envCommand(env) {
|
|
29
30
|
return withErrorHandling(async () => {
|
|
30
31
|
// Step 1: Load configuration
|
|
31
32
|
const config = readSkillConfig();
|
|
32
33
|
validateConfig(config);
|
|
33
34
|
validateAgentConfig(config);
|
|
34
35
|
const agentId = config.agent.agentId;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
{ name: '🔧 Sandbox (.env file)', value: 'sandbox' },
|
|
43
|
-
{ name: '🚀 Production (API)', value: 'production' }
|
|
44
|
-
]
|
|
36
|
+
let selectedEnvironment;
|
|
37
|
+
// Step 2: Check if environment was provided as argument
|
|
38
|
+
if (env) {
|
|
39
|
+
// Normalize the environment (staging is an alias for sandbox)
|
|
40
|
+
const normalizedEnv = env.toLowerCase();
|
|
41
|
+
if (normalizedEnv === 'sandbox' || normalizedEnv === 'staging') {
|
|
42
|
+
selectedEnvironment = 'sandbox';
|
|
45
43
|
}
|
|
46
|
-
|
|
44
|
+
else if (normalizedEnv === 'production') {
|
|
45
|
+
selectedEnvironment = 'production';
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.error(`❌ Invalid environment: "${env}". Must be "sandbox", "staging", or "production".`);
|
|
49
|
+
console.log('\nUsage:');
|
|
50
|
+
console.log(' lua env - Interactive selection');
|
|
51
|
+
console.log(' lua env sandbox - Manage sandbox env vars directly');
|
|
52
|
+
console.log(' lua env staging - Manage staging env vars (alias for sandbox)');
|
|
53
|
+
console.log(' lua env production - Manage production env vars directly');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Step 3: Prompt for environment selection
|
|
59
|
+
const { environment } = await inquirer.prompt([
|
|
60
|
+
{
|
|
61
|
+
type: 'list',
|
|
62
|
+
name: 'environment',
|
|
63
|
+
message: 'Select environment:',
|
|
64
|
+
choices: [
|
|
65
|
+
{ name: '🔧 Sandbox (.env file)', value: 'sandbox' },
|
|
66
|
+
{ name: '🚀 Production (API)', value: 'production' }
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
]);
|
|
70
|
+
selectedEnvironment = environment;
|
|
71
|
+
}
|
|
47
72
|
let context = {
|
|
48
|
-
environment,
|
|
73
|
+
environment: selectedEnvironment,
|
|
49
74
|
agentId,
|
|
50
75
|
apiKey: '',
|
|
51
76
|
};
|
|
52
|
-
// Step
|
|
53
|
-
if (
|
|
77
|
+
// Step 4: Authenticate (needed for production)
|
|
78
|
+
if (selectedEnvironment === 'production') {
|
|
54
79
|
const apiKey = await loadApiKey();
|
|
55
80
|
if (!apiKey) {
|
|
56
81
|
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
@@ -61,7 +86,7 @@ export async function envCommand() {
|
|
|
61
86
|
context.developerApi = new DeveloperApi(BASE_URLS.API, apiKey, agentId);
|
|
62
87
|
writeProgress("✅ Authenticated");
|
|
63
88
|
}
|
|
64
|
-
// Step
|
|
89
|
+
// Step 5: Start management loop
|
|
65
90
|
await manageEnvironmentVariables(context);
|
|
66
91
|
}, "env");
|
|
67
92
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Features Command
|
|
3
|
+
* Manages agent features (tickets, RAG, webSearch, etc.)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Main features command - manages agent features
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - List all available features
|
|
10
|
+
* - View feature details (active status and context)
|
|
11
|
+
* - Enable/disable features
|
|
12
|
+
* - Update feature context
|
|
13
|
+
*
|
|
14
|
+
* @returns Promise that resolves when command completes
|
|
15
|
+
*/
|
|
16
|
+
export declare function featuresCommand(): Promise<void>;
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Features Command
|
|
3
|
+
* Manages agent features (tickets, RAG, webSearch, etc.)
|
|
4
|
+
*/
|
|
5
|
+
import { loadApiKey, checkApiKey } from '../services/auth.js';
|
|
6
|
+
import { readSkillConfig } from '../utils/files.js';
|
|
7
|
+
import { withErrorHandling, writeProgress, writeSuccess } from '../utils/cli.js';
|
|
8
|
+
import { BASE_URLS } from '../config/constants.js';
|
|
9
|
+
import { safePrompt } from '../utils/prompt-handler.js';
|
|
10
|
+
import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
|
|
11
|
+
import AgentApi from '../api/agent.api.service.js';
|
|
12
|
+
/**
|
|
13
|
+
* Main features command - manages agent features
|
|
14
|
+
*
|
|
15
|
+
* Features:
|
|
16
|
+
* - List all available features
|
|
17
|
+
* - View feature details (active status and context)
|
|
18
|
+
* - Enable/disable features
|
|
19
|
+
* - Update feature context
|
|
20
|
+
*
|
|
21
|
+
* @returns Promise that resolves when command completes
|
|
22
|
+
*/
|
|
23
|
+
export async function featuresCommand() {
|
|
24
|
+
return withErrorHandling(async () => {
|
|
25
|
+
// Step 1: Load configuration
|
|
26
|
+
const config = readSkillConfig();
|
|
27
|
+
validateConfig(config);
|
|
28
|
+
validateAgentConfig(config);
|
|
29
|
+
const agentId = config.agent.agentId;
|
|
30
|
+
// Step 2: Authenticate
|
|
31
|
+
const apiKey = await loadApiKey();
|
|
32
|
+
if (!apiKey) {
|
|
33
|
+
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
await checkApiKey(apiKey);
|
|
37
|
+
writeProgress("✅ Authenticated");
|
|
38
|
+
// Step 3: Create API instance
|
|
39
|
+
const agentApi = new AgentApi(BASE_URLS.API, apiKey);
|
|
40
|
+
const context = {
|
|
41
|
+
agentId,
|
|
42
|
+
apiKey,
|
|
43
|
+
agentApi,
|
|
44
|
+
};
|
|
45
|
+
// Step 4: Start feature management
|
|
46
|
+
await manageFeatures(context);
|
|
47
|
+
}, "features");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Main management loop for features
|
|
51
|
+
*/
|
|
52
|
+
async function manageFeatures(context) {
|
|
53
|
+
let continueManaging = true;
|
|
54
|
+
while (continueManaging) {
|
|
55
|
+
// Load current features
|
|
56
|
+
writeProgress("🔄 Loading features...");
|
|
57
|
+
let features;
|
|
58
|
+
try {
|
|
59
|
+
const response = await context.agentApi.getAgentFeatures(context.agentId);
|
|
60
|
+
if (!response.data) {
|
|
61
|
+
throw new Error("No data returned from API");
|
|
62
|
+
}
|
|
63
|
+
features = response.data.features;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
console.error("❌ Error loading features:", error);
|
|
67
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to try again...' }]);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
// Show current state
|
|
71
|
+
console.log("\n" + "=".repeat(60));
|
|
72
|
+
console.log("🎯 Agent Features");
|
|
73
|
+
console.log("=".repeat(60) + "\n");
|
|
74
|
+
if (features.length === 0) {
|
|
75
|
+
console.log("ℹ️ No features available for this agent.\n");
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
console.log("Available features:\n");
|
|
79
|
+
features.forEach((feature, index) => {
|
|
80
|
+
const status = feature.active ? "✅" : "❌";
|
|
81
|
+
console.log(`${index + 1}. ${status} ${feature.title}`);
|
|
82
|
+
console.log(` Name: ${feature.name}`);
|
|
83
|
+
console.log(` Status: ${feature.active ? "Active" : "Inactive"}`);
|
|
84
|
+
console.log();
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// Show menu
|
|
88
|
+
const actionAnswer = await safePrompt([
|
|
89
|
+
{
|
|
90
|
+
type: 'list',
|
|
91
|
+
name: 'action',
|
|
92
|
+
message: 'What would you like to do?',
|
|
93
|
+
choices: [
|
|
94
|
+
{ name: '👁️ View feature details', value: 'view' },
|
|
95
|
+
{ name: '✏️ Manage a feature', value: 'manage' },
|
|
96
|
+
{ name: '🔄 Refresh list', value: 'refresh' },
|
|
97
|
+
{ name: '❌ Exit', value: 'exit' }
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
]);
|
|
101
|
+
if (!actionAnswer)
|
|
102
|
+
return;
|
|
103
|
+
const { action } = actionAnswer;
|
|
104
|
+
switch (action) {
|
|
105
|
+
case 'view':
|
|
106
|
+
await viewFeatureDetails(context, features);
|
|
107
|
+
break;
|
|
108
|
+
case 'manage':
|
|
109
|
+
await manageFeature(context, features);
|
|
110
|
+
break;
|
|
111
|
+
case 'refresh':
|
|
112
|
+
// Just loop again to refresh
|
|
113
|
+
break;
|
|
114
|
+
case 'exit':
|
|
115
|
+
continueManaging = false;
|
|
116
|
+
console.log("\n👋 Goodbye!\n");
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* View detailed information about a feature
|
|
123
|
+
*/
|
|
124
|
+
async function viewFeatureDetails(context, features) {
|
|
125
|
+
if (features.length === 0) {
|
|
126
|
+
console.log("\nℹ️ No features available.\n");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// Prompt to select a feature
|
|
130
|
+
const featureAnswer = await safePrompt([
|
|
131
|
+
{
|
|
132
|
+
type: 'list',
|
|
133
|
+
name: 'selectedFeature',
|
|
134
|
+
message: 'Select a feature to view:',
|
|
135
|
+
choices: features.map(feature => ({
|
|
136
|
+
name: `${feature.active ? '✅' : '❌'} ${feature.title}`,
|
|
137
|
+
value: feature
|
|
138
|
+
}))
|
|
139
|
+
}
|
|
140
|
+
]);
|
|
141
|
+
if (!featureAnswer)
|
|
142
|
+
return;
|
|
143
|
+
const feature = featureAnswer.selectedFeature;
|
|
144
|
+
// Display feature details
|
|
145
|
+
console.log("\n" + "=".repeat(60));
|
|
146
|
+
console.log(`🎯 ${feature.title}`);
|
|
147
|
+
console.log("=".repeat(60));
|
|
148
|
+
console.log(`Name: ${feature.name}`);
|
|
149
|
+
console.log(`Status: ${feature.active ? '✅ Active' : '❌ Inactive'}`);
|
|
150
|
+
console.log("\nContext/Instructions:");
|
|
151
|
+
console.log("─".repeat(60));
|
|
152
|
+
console.log(feature.context);
|
|
153
|
+
console.log("=".repeat(60) + "\n");
|
|
154
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Manage a specific feature (activate/deactivate or update context)
|
|
158
|
+
*/
|
|
159
|
+
async function manageFeature(context, features) {
|
|
160
|
+
if (features.length === 0) {
|
|
161
|
+
console.log("\nℹ️ No features available.\n");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// Step 1: Select feature
|
|
165
|
+
const featureAnswer = await safePrompt([
|
|
166
|
+
{
|
|
167
|
+
type: 'list',
|
|
168
|
+
name: 'selectedFeature',
|
|
169
|
+
message: 'Select a feature to manage:',
|
|
170
|
+
choices: features.map(feature => ({
|
|
171
|
+
name: `${feature.active ? '✅' : '❌'} ${feature.title}`,
|
|
172
|
+
value: feature
|
|
173
|
+
}))
|
|
174
|
+
}
|
|
175
|
+
]);
|
|
176
|
+
if (!featureAnswer)
|
|
177
|
+
return;
|
|
178
|
+
const feature = featureAnswer.selectedFeature;
|
|
179
|
+
// Step 2: Show current status
|
|
180
|
+
console.log("\n" + "─".repeat(60));
|
|
181
|
+
console.log(`Feature: ${feature.title}`);
|
|
182
|
+
console.log(`Current Status: ${feature.active ? '✅ Active' : '❌ Inactive'}`);
|
|
183
|
+
console.log("─".repeat(60) + "\n");
|
|
184
|
+
// Step 3: Select action
|
|
185
|
+
const actionAnswer = await safePrompt([
|
|
186
|
+
{
|
|
187
|
+
type: 'list',
|
|
188
|
+
name: 'action',
|
|
189
|
+
message: 'What would you like to do?',
|
|
190
|
+
choices: [
|
|
191
|
+
{
|
|
192
|
+
name: feature.active ? '❌ Deactivate feature' : '✅ Activate feature',
|
|
193
|
+
value: 'toggle'
|
|
194
|
+
},
|
|
195
|
+
{ name: '✏️ Update context/instructions', value: 'context' },
|
|
196
|
+
{ name: '🔄 Update both status and context', value: 'both' },
|
|
197
|
+
{ name: '⬅️ Back', value: 'back' }
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
]);
|
|
201
|
+
if (!actionAnswer || actionAnswer.action === 'back')
|
|
202
|
+
return;
|
|
203
|
+
try {
|
|
204
|
+
switch (actionAnswer.action) {
|
|
205
|
+
case 'toggle':
|
|
206
|
+
await toggleFeature(context, feature);
|
|
207
|
+
break;
|
|
208
|
+
case 'context':
|
|
209
|
+
await updateFeatureContext(context, feature);
|
|
210
|
+
break;
|
|
211
|
+
case 'both':
|
|
212
|
+
await updateBoth(context, feature);
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
console.error("\n❌ Error updating feature:", error);
|
|
218
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Toggle feature active status
|
|
223
|
+
*/
|
|
224
|
+
async function toggleFeature(context, feature) {
|
|
225
|
+
const newStatus = !feature.active;
|
|
226
|
+
const action = newStatus ? 'activate' : 'deactivate';
|
|
227
|
+
const confirmAnswer = await safePrompt([
|
|
228
|
+
{
|
|
229
|
+
type: 'confirm',
|
|
230
|
+
name: 'confirm',
|
|
231
|
+
message: `Are you sure you want to ${action} "${feature.title}"?`,
|
|
232
|
+
default: true
|
|
233
|
+
}
|
|
234
|
+
]);
|
|
235
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
236
|
+
console.log("\n❌ Operation cancelled.\n");
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
writeProgress(`🔄 ${newStatus ? 'Activating' : 'Deactivating'} feature...`);
|
|
240
|
+
const response = await context.agentApi.updateAgentFeature(context.agentId, {
|
|
241
|
+
featureName: feature.name,
|
|
242
|
+
active: newStatus
|
|
243
|
+
});
|
|
244
|
+
writeSuccess(`✅ Feature "${feature.title}" ${newStatus ? 'activated' : 'deactivated'} successfully`);
|
|
245
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Update feature context
|
|
249
|
+
*/
|
|
250
|
+
async function updateFeatureContext(context, feature) {
|
|
251
|
+
console.log("\n📝 Current context:");
|
|
252
|
+
console.log("─".repeat(60));
|
|
253
|
+
console.log(feature.context);
|
|
254
|
+
console.log("─".repeat(60) + "\n");
|
|
255
|
+
const contextAnswer = await safePrompt([
|
|
256
|
+
{
|
|
257
|
+
type: 'editor',
|
|
258
|
+
name: 'newContext',
|
|
259
|
+
message: 'Edit feature context (will open in your default editor):',
|
|
260
|
+
default: feature.context,
|
|
261
|
+
validate: (input) => {
|
|
262
|
+
if (!input || !input.trim()) {
|
|
263
|
+
return 'Context cannot be empty';
|
|
264
|
+
}
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
]);
|
|
269
|
+
if (!contextAnswer)
|
|
270
|
+
return;
|
|
271
|
+
const confirmAnswer = await safePrompt([
|
|
272
|
+
{
|
|
273
|
+
type: 'confirm',
|
|
274
|
+
name: 'confirm',
|
|
275
|
+
message: 'Save updated context?',
|
|
276
|
+
default: true
|
|
277
|
+
}
|
|
278
|
+
]);
|
|
279
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
280
|
+
console.log("\n❌ Update cancelled.\n");
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
writeProgress("🔄 Updating feature context...");
|
|
284
|
+
const response = await context.agentApi.updateAgentFeature(context.agentId, {
|
|
285
|
+
featureName: feature.name,
|
|
286
|
+
featureContext: contextAnswer.newContext.trim()
|
|
287
|
+
});
|
|
288
|
+
writeSuccess(`✅ Context for "${feature.title}" updated successfully`);
|
|
289
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Update both status and context
|
|
293
|
+
*/
|
|
294
|
+
async function updateBoth(context, feature) {
|
|
295
|
+
// Step 1: Select new status
|
|
296
|
+
const statusAnswer = await safePrompt([
|
|
297
|
+
{
|
|
298
|
+
type: 'confirm',
|
|
299
|
+
name: 'active',
|
|
300
|
+
message: 'Should this feature be active?',
|
|
301
|
+
default: feature.active
|
|
302
|
+
}
|
|
303
|
+
]);
|
|
304
|
+
if (!statusAnswer)
|
|
305
|
+
return;
|
|
306
|
+
// Step 2: Edit context
|
|
307
|
+
console.log("\n📝 Current context:");
|
|
308
|
+
console.log("─".repeat(60));
|
|
309
|
+
console.log(feature.context);
|
|
310
|
+
console.log("─".repeat(60) + "\n");
|
|
311
|
+
const contextAnswer = await safePrompt([
|
|
312
|
+
{
|
|
313
|
+
type: 'editor',
|
|
314
|
+
name: 'newContext',
|
|
315
|
+
message: 'Edit feature context (will open in your default editor):',
|
|
316
|
+
default: feature.context,
|
|
317
|
+
validate: (input) => {
|
|
318
|
+
if (!input || !input.trim()) {
|
|
319
|
+
return 'Context cannot be empty';
|
|
320
|
+
}
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
]);
|
|
325
|
+
if (!contextAnswer)
|
|
326
|
+
return;
|
|
327
|
+
// Step 3: Confirm
|
|
328
|
+
console.log("\n📋 Summary of changes:");
|
|
329
|
+
console.log(`Status: ${feature.active ? '✅ Active' : '❌ Inactive'} → ${statusAnswer.active ? '✅ Active' : '❌ Inactive'}`);
|
|
330
|
+
console.log(`Context: ${contextAnswer.newContext === feature.context ? 'No change' : 'Updated'}`);
|
|
331
|
+
console.log();
|
|
332
|
+
const confirmAnswer = await safePrompt([
|
|
333
|
+
{
|
|
334
|
+
type: 'confirm',
|
|
335
|
+
name: 'confirm',
|
|
336
|
+
message: 'Save all changes?',
|
|
337
|
+
default: true
|
|
338
|
+
}
|
|
339
|
+
]);
|
|
340
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
341
|
+
console.log("\n❌ Update cancelled.\n");
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
writeProgress("🔄 Updating feature...");
|
|
345
|
+
const response = await context.agentApi.updateAgentFeature(context.agentId, {
|
|
346
|
+
featureName: feature.name,
|
|
347
|
+
active: statusAnswer.active,
|
|
348
|
+
featureContext: contextAnswer.newContext.trim()
|
|
349
|
+
});
|
|
350
|
+
writeSuccess(`✅ Feature "${feature.title}" updated successfully`);
|
|
351
|
+
await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
|
|
352
|
+
}
|