adonisjs-maestro 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/build/bin/run.js +1 -1
- package/build/chunk-73R5GXO2.js +341 -0
- package/build/index.js +1 -1
- package/package.json +3 -2
- package/build/chunk-ZWBJVZPB.js +0 -217
package/README.md
CHANGED
|
@@ -57,6 +57,13 @@ Restart your agent after installing so the new skills are loaded.
|
|
|
57
57
|
| `inertia-react` | React frontend patterns in AdonisJS + Inertia projects |
|
|
58
58
|
| `japa` | Japa testing in AdonisJS apps: API tests, browser tests, console tests, fakes, swaps, and database setup |
|
|
59
59
|
|
|
60
|
+
### In Progress
|
|
61
|
+
|
|
62
|
+
| Skill | Stack | Use it for |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `edge` | `hypermedia` | Edge.js server-side templates: layouts, components, partials, tags, and view helpers |
|
|
65
|
+
| `tuyau` | `api-monorepo` | Tuyau end-to-end type-safe API client: codegen, typed routes, and RPC-style calls |
|
|
66
|
+
|
|
60
67
|
## Recommended Entry Point
|
|
61
68
|
|
|
62
69
|
Use `maestro` when the task is broader than a single framework question.
|
package/build/bin/run.js
CHANGED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// index.ts
|
|
13
|
+
import { HelpCommand, Kernel } from "@adonisjs/ace";
|
|
14
|
+
|
|
15
|
+
// commands/main.ts
|
|
16
|
+
import { fileURLToPath } from "url";
|
|
17
|
+
import { execa } from "execa";
|
|
18
|
+
import { BaseCommand, flags } from "@adonisjs/ace";
|
|
19
|
+
|
|
20
|
+
// src/stacks.ts
|
|
21
|
+
var SKILLS_REPOSITORY = "lncitador/adonisjs-maestro";
|
|
22
|
+
var AVAILABLE_AGENTS = [
|
|
23
|
+
{ name: "claude-code", label: "Claude Code" },
|
|
24
|
+
{ name: "codex", label: "Codex" },
|
|
25
|
+
{ name: "cursor", label: "Cursor" },
|
|
26
|
+
{ name: "gemini-cli", label: "Gemini CLI" },
|
|
27
|
+
{ name: "github-copilot", label: "GitHub Copilot" },
|
|
28
|
+
{ name: "opencode", label: "OpenCode" },
|
|
29
|
+
{ name: "windsurf", label: "Windsurf" },
|
|
30
|
+
{ name: "cline", label: "Cline" },
|
|
31
|
+
{ name: "roo", label: "Roo Code" },
|
|
32
|
+
{ name: "continue", label: "Continue" },
|
|
33
|
+
{ name: "amp", label: "Amp" },
|
|
34
|
+
{ name: "aider-desk", label: "AiderDesk" },
|
|
35
|
+
{ name: "antigravity", label: "Antigravity" },
|
|
36
|
+
{ name: "augment", label: "Augment" },
|
|
37
|
+
{ name: "bob", label: "IBM Bob" },
|
|
38
|
+
{ name: "codearts-agent", label: "CodeArts Agent" },
|
|
39
|
+
{ name: "codebuddy", label: "CodeBuddy" },
|
|
40
|
+
{ name: "codemaker", label: "Codemaker" },
|
|
41
|
+
{ name: "codestudio", label: "Code Studio" },
|
|
42
|
+
{ name: "command-code", label: "Command Code" },
|
|
43
|
+
{ name: "cortex", label: "Cortex Code" },
|
|
44
|
+
{ name: "crush", label: "Crush" },
|
|
45
|
+
{ name: "deepagents", label: "Deep Agents" },
|
|
46
|
+
{ name: "devin", label: "Devin for Terminal" },
|
|
47
|
+
{ name: "dexto", label: "Dexto" },
|
|
48
|
+
{ name: "droid", label: "Droid (Factory AI)" },
|
|
49
|
+
{ name: "firebender", label: "Firebender" },
|
|
50
|
+
{ name: "forgecode", label: "ForgeCode" },
|
|
51
|
+
{ name: "goose", label: "Goose" },
|
|
52
|
+
{ name: "hermes-agent", label: "Hermes Agent" },
|
|
53
|
+
{ name: "iflow-cli", label: "iFlow CLI" },
|
|
54
|
+
{ name: "junie", label: "Junie" },
|
|
55
|
+
{ name: "kilo", label: "Kilo Code" },
|
|
56
|
+
{ name: "kimi-cli", label: "Kimi Code CLI" },
|
|
57
|
+
{ name: "kiro-cli", label: "Kiro CLI" },
|
|
58
|
+
{ name: "kode", label: "Kode" },
|
|
59
|
+
{ name: "mcpjam", label: "MCPJam" },
|
|
60
|
+
{ name: "mistral-vibe", label: "Mistral Vibe" },
|
|
61
|
+
{ name: "mux", label: "Mux" },
|
|
62
|
+
{ name: "neovate", label: "Neovate" },
|
|
63
|
+
{ name: "openclaw", label: "OpenClaw" },
|
|
64
|
+
{ name: "openhands", label: "OpenHands" },
|
|
65
|
+
{ name: "pi", label: "Pi" },
|
|
66
|
+
{ name: "pochi", label: "Pochi" },
|
|
67
|
+
{ name: "qoder", label: "Qoder" },
|
|
68
|
+
{ name: "qwen-code", label: "Qwen Code" },
|
|
69
|
+
{ name: "replit", label: "Replit" },
|
|
70
|
+
{ name: "rovodev", label: "Rovo Dev" },
|
|
71
|
+
{ name: "tabnine-cli", label: "Tabnine CLI" },
|
|
72
|
+
{ name: "trae", label: "Trae" },
|
|
73
|
+
{ name: "trae-cn", label: "Trae CN" },
|
|
74
|
+
{ name: "universal", label: "Universal" },
|
|
75
|
+
{ name: "warp", label: "Warp" },
|
|
76
|
+
{ name: "zencoder", label: "Zencoder" },
|
|
77
|
+
{ name: "adal", label: "AdaL" }
|
|
78
|
+
];
|
|
79
|
+
var AVAILABLE_SKILLS = [
|
|
80
|
+
"maestro",
|
|
81
|
+
"adonisjs",
|
|
82
|
+
"lucid",
|
|
83
|
+
"japa",
|
|
84
|
+
"inertia-react",
|
|
85
|
+
"inertia-vue"
|
|
86
|
+
];
|
|
87
|
+
var SKILL_METADATA = {
|
|
88
|
+
maestro: {
|
|
89
|
+
label: "Maestro",
|
|
90
|
+
hint: "Orchestration: intake \u2192 plan \u2192 build \u2192 verify \u2192 publish"
|
|
91
|
+
},
|
|
92
|
+
adonisjs: {
|
|
93
|
+
label: "AdonisJS",
|
|
94
|
+
hint: "Controllers, routes, auth, middleware, services, events"
|
|
95
|
+
},
|
|
96
|
+
lucid: {
|
|
97
|
+
label: "Lucid",
|
|
98
|
+
hint: "Migrations, models, relationships, query builders, factories"
|
|
99
|
+
},
|
|
100
|
+
japa: {
|
|
101
|
+
label: "Japa",
|
|
102
|
+
hint: "API, browser, and console tests with fakes and database setup"
|
|
103
|
+
},
|
|
104
|
+
"inertia-react": {
|
|
105
|
+
label: "Inertia React",
|
|
106
|
+
hint: "React frontend patterns for AdonisJS + Inertia projects"
|
|
107
|
+
},
|
|
108
|
+
"inertia-vue": {
|
|
109
|
+
label: "Inertia Vue",
|
|
110
|
+
hint: "Vue 3 frontend patterns for AdonisJS + Inertia projects"
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
var STACKS = [
|
|
114
|
+
{
|
|
115
|
+
name: "hypermedia",
|
|
116
|
+
label: "Hypermedia app",
|
|
117
|
+
hint: "A full-stack app using server-side templates",
|
|
118
|
+
starterKit: "github:adonisjs/starter-kits/hypermedia",
|
|
119
|
+
skills: ["maestro", "adonisjs", "lucid", "japa"]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "react",
|
|
123
|
+
label: "React app (using Inertia)",
|
|
124
|
+
hint: "A full-stack React app with end-to-end type safety",
|
|
125
|
+
starterKit: "github:adonisjs/starter-kits/inertia-react",
|
|
126
|
+
skills: ["maestro", "adonisjs", "lucid", "japa", "inertia-react"]
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "vue",
|
|
130
|
+
label: "Vue app (using Inertia)",
|
|
131
|
+
hint: "A full-stack Vue app with end-to-end type safety",
|
|
132
|
+
starterKit: "github:adonisjs/starter-kits/inertia-vue",
|
|
133
|
+
skills: ["maestro", "adonisjs", "lucid", "japa", "inertia-vue"]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "api",
|
|
137
|
+
label: "API",
|
|
138
|
+
hint: "A type-safe REST API with session and access token auth",
|
|
139
|
+
starterKit: "github:adonisjs/starter-kits/api",
|
|
140
|
+
skills: ["maestro", "adonisjs", "lucid", "japa"]
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: "api-monorepo",
|
|
144
|
+
label: "API (monorepo)",
|
|
145
|
+
hint: "A monorepo setup with a type-safe REST API",
|
|
146
|
+
starterKit: "github:adonisjs/starter-kits/api-monorepo",
|
|
147
|
+
skills: ["maestro", "adonisjs", "lucid", "japa"]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "custom",
|
|
151
|
+
label: "Custom",
|
|
152
|
+
hint: "Choose individual skills",
|
|
153
|
+
starterKit: null,
|
|
154
|
+
skills: []
|
|
155
|
+
}
|
|
156
|
+
];
|
|
157
|
+
function getStack(name) {
|
|
158
|
+
return STACKS.find((stack) => stack.name === name);
|
|
159
|
+
}
|
|
160
|
+
function parseSkills(value) {
|
|
161
|
+
const requested = value.split(",").map((skill) => skill.trim()).filter(Boolean);
|
|
162
|
+
const invalid = requested.filter((skill) => !AVAILABLE_SKILLS.includes(skill));
|
|
163
|
+
if (invalid.length > 0) {
|
|
164
|
+
throw new Error(`Unknown skill(s): ${invalid.join(", ")}`);
|
|
165
|
+
}
|
|
166
|
+
return [...new Set(requested)];
|
|
167
|
+
}
|
|
168
|
+
function buildSkillsAddArgs(options) {
|
|
169
|
+
const args = ["skills", "add", SKILLS_REPOSITORY];
|
|
170
|
+
for (const skill of options.skills) {
|
|
171
|
+
args.push("--skill", skill);
|
|
172
|
+
}
|
|
173
|
+
if (options.global) {
|
|
174
|
+
args.push("--global");
|
|
175
|
+
}
|
|
176
|
+
for (const agent of options.agents ?? []) {
|
|
177
|
+
args.push("--agent", agent);
|
|
178
|
+
}
|
|
179
|
+
if (options.yes) {
|
|
180
|
+
args.push("--yes");
|
|
181
|
+
}
|
|
182
|
+
return args;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// commands/main.ts
|
|
186
|
+
var skillsBin = fileURLToPath(import.meta.resolve("skills/bin/cli.mjs"));
|
|
187
|
+
var InstallSkills = class extends BaseCommand {
|
|
188
|
+
static commandName = "adonisjs-maestro";
|
|
189
|
+
static description = "Install AdonisJS Maestro agent skills for your stack";
|
|
190
|
+
async #promptForStack() {
|
|
191
|
+
if (this.stack) {
|
|
192
|
+
return this.stack;
|
|
193
|
+
}
|
|
194
|
+
const selected = await this.prompt.choice(
|
|
195
|
+
"Which AdonisJS stack are you using?",
|
|
196
|
+
STACKS.map((stack) => ({
|
|
197
|
+
name: stack.name,
|
|
198
|
+
message: stack.label,
|
|
199
|
+
hint: stack.hint
|
|
200
|
+
}))
|
|
201
|
+
);
|
|
202
|
+
return selected;
|
|
203
|
+
}
|
|
204
|
+
async #promptForCustomSkills() {
|
|
205
|
+
const selected = await this.prompt.multiple(
|
|
206
|
+
"Which skills should be installed?",
|
|
207
|
+
AVAILABLE_SKILLS.map((skill) => ({
|
|
208
|
+
name: skill,
|
|
209
|
+
message: SKILL_METADATA[skill].label,
|
|
210
|
+
hint: SKILL_METADATA[skill].hint
|
|
211
|
+
})),
|
|
212
|
+
{
|
|
213
|
+
validate: (values) => values.length > 0 || "Select at least one skill"
|
|
214
|
+
}
|
|
215
|
+
);
|
|
216
|
+
return selected;
|
|
217
|
+
}
|
|
218
|
+
async #promptForScope() {
|
|
219
|
+
if (this.global !== void 0 || this.yes) {
|
|
220
|
+
return this.global ?? false;
|
|
221
|
+
}
|
|
222
|
+
return this.prompt.toggle("Install scope", ["Global (~/.claude/skills)", "Project (.claude/skills)"], {
|
|
223
|
+
default: false
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async #resolveAgents() {
|
|
227
|
+
if (this.agent) {
|
|
228
|
+
return this.agent.split(",").map((agent) => agent.trim()).filter(Boolean);
|
|
229
|
+
}
|
|
230
|
+
if (this.yes) {
|
|
231
|
+
return ["universal"];
|
|
232
|
+
}
|
|
233
|
+
const chooseSpecific = await this.prompt.confirm("Choose specific agents?", { default: false });
|
|
234
|
+
if (!chooseSpecific) {
|
|
235
|
+
return ["universal"];
|
|
236
|
+
}
|
|
237
|
+
const selected = await this.prompt.multiple(
|
|
238
|
+
"Which agents should receive the skills?",
|
|
239
|
+
AVAILABLE_AGENTS.map((agent) => ({ name: agent.name, message: agent.label })),
|
|
240
|
+
{ hint: "Space to toggle, Enter to confirm" }
|
|
241
|
+
);
|
|
242
|
+
return selected.length > 0 ? selected : ["universal"];
|
|
243
|
+
}
|
|
244
|
+
async #resolveSkills() {
|
|
245
|
+
if (this.skills) {
|
|
246
|
+
return parseSkills(this.skills);
|
|
247
|
+
}
|
|
248
|
+
const stackName = await this.#promptForStack();
|
|
249
|
+
const stack = getStack(stackName);
|
|
250
|
+
if (!stack) {
|
|
251
|
+
throw new Error(`Unknown stack "${stackName}". Expected one of: ${STACKS.map((item) => item.name).join(", ")}`);
|
|
252
|
+
}
|
|
253
|
+
if (stack.name === "custom") {
|
|
254
|
+
return this.#promptForCustomSkills();
|
|
255
|
+
}
|
|
256
|
+
return stack.skills;
|
|
257
|
+
}
|
|
258
|
+
#renderCommand(args) {
|
|
259
|
+
return ["npx", ...args].join(" ");
|
|
260
|
+
}
|
|
261
|
+
async run() {
|
|
262
|
+
this.logger.log("\n>_ AdonisJS Maestro\n");
|
|
263
|
+
const skills = await this.#resolveSkills();
|
|
264
|
+
if (skills.length === 0) {
|
|
265
|
+
throw new Error("No skills selected");
|
|
266
|
+
}
|
|
267
|
+
const isGlobal = await this.#promptForScope();
|
|
268
|
+
const agents = await this.#resolveAgents();
|
|
269
|
+
const args = buildSkillsAddArgs({
|
|
270
|
+
skills,
|
|
271
|
+
global: isGlobal,
|
|
272
|
+
agents,
|
|
273
|
+
yes: true
|
|
274
|
+
});
|
|
275
|
+
this.logger.info(`Installing skills: ${skills.join(", ")}`);
|
|
276
|
+
this.logger.info(this.#renderCommand(args));
|
|
277
|
+
if (this.dryRun) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
await execa("node", [skillsBin, ...args.slice(1)], {
|
|
281
|
+
stdio: "inherit"
|
|
282
|
+
});
|
|
283
|
+
this.logger.success("AdonisJS Maestro skills installed");
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
__decorateClass([
|
|
287
|
+
flags.string({
|
|
288
|
+
description: "Stack preset to install: monorepo, hypermedia, react, vue, or custom"
|
|
289
|
+
})
|
|
290
|
+
], InstallSkills.prototype, "stack", 2);
|
|
291
|
+
__decorateClass([
|
|
292
|
+
flags.string({
|
|
293
|
+
description: "Comma-separated list of skills to install"
|
|
294
|
+
})
|
|
295
|
+
], InstallSkills.prototype, "skills", 2);
|
|
296
|
+
__decorateClass([
|
|
297
|
+
flags.string({
|
|
298
|
+
description: 'Target agent. Repeat by comma-separating values, or use "*" for all agents',
|
|
299
|
+
alias: "a"
|
|
300
|
+
})
|
|
301
|
+
], InstallSkills.prototype, "agent", 2);
|
|
302
|
+
__decorateClass([
|
|
303
|
+
flags.boolean({
|
|
304
|
+
description: "Install globally instead of the current project",
|
|
305
|
+
alias: "g"
|
|
306
|
+
})
|
|
307
|
+
], InstallSkills.prototype, "global", 2);
|
|
308
|
+
__decorateClass([
|
|
309
|
+
flags.boolean({
|
|
310
|
+
description: "Skip skills CLI confirmation prompts",
|
|
311
|
+
alias: "y"
|
|
312
|
+
})
|
|
313
|
+
], InstallSkills.prototype, "yes", 2);
|
|
314
|
+
__decorateClass([
|
|
315
|
+
flags.boolean({
|
|
316
|
+
description: "Print the generated npx skills command without running it"
|
|
317
|
+
})
|
|
318
|
+
], InstallSkills.prototype, "dryRun", 2);
|
|
319
|
+
__decorateClass([
|
|
320
|
+
flags.boolean({
|
|
321
|
+
description: "Show command output from the skills CLI",
|
|
322
|
+
alias: "v"
|
|
323
|
+
})
|
|
324
|
+
], InstallSkills.prototype, "verbose", 2);
|
|
325
|
+
|
|
326
|
+
// index.ts
|
|
327
|
+
Kernel.defaultCommand = InstallSkills;
|
|
328
|
+
var kernel = Kernel.create();
|
|
329
|
+
kernel.defineFlag("help", {
|
|
330
|
+
type: "boolean",
|
|
331
|
+
description: HelpCommand.description
|
|
332
|
+
});
|
|
333
|
+
kernel.on("help", async (command, $kernel, parsed) => {
|
|
334
|
+
parsed.args.unshift(command.commandName);
|
|
335
|
+
await new HelpCommand($kernel, parsed, kernel.ui, kernel.prompt).exec();
|
|
336
|
+
return $kernel.shortcircuit();
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
export {
|
|
340
|
+
kernel
|
|
341
|
+
};
|
package/build/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adonisjs-maestro",
|
|
3
3
|
"description": "Install AdonisJS Maestro agent skills by stack",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@adonisjs/ace": "^14.1.0",
|
|
28
|
-
"execa": "^9.6.1"
|
|
28
|
+
"execa": "^9.6.1",
|
|
29
|
+
"skills": "^1.5.5"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"@japa/assert": "^4.2.0",
|
package/build/chunk-ZWBJVZPB.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
-
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
-
if (decorator = decorators[i])
|
|
7
|
-
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
-
if (kind && result) __defProp(target, key, result);
|
|
9
|
-
return result;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
// index.ts
|
|
13
|
-
import { HelpCommand, Kernel } from "@adonisjs/ace";
|
|
14
|
-
|
|
15
|
-
// commands/main.ts
|
|
16
|
-
import { execa } from "execa";
|
|
17
|
-
import { BaseCommand, flags } from "@adonisjs/ace";
|
|
18
|
-
|
|
19
|
-
// src/stacks.ts
|
|
20
|
-
var SKILLS_REPOSITORY = "lncitador/adonisjs-maestro";
|
|
21
|
-
var AVAILABLE_SKILLS = [
|
|
22
|
-
"maestro",
|
|
23
|
-
"adonisjs",
|
|
24
|
-
"lucid",
|
|
25
|
-
"japa",
|
|
26
|
-
"inertia-react",
|
|
27
|
-
"inertia-vue"
|
|
28
|
-
];
|
|
29
|
-
var STACKS = [
|
|
30
|
-
{
|
|
31
|
-
name: "monorepo",
|
|
32
|
-
label: "Monorepo: API + TanStack",
|
|
33
|
-
hint: "API/backend workflow without Inertia frontend skills",
|
|
34
|
-
skills: ["maestro", "adonisjs", "lucid", "japa"]
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: "hypermedia",
|
|
38
|
-
label: "Hypermedia",
|
|
39
|
-
hint: "Server-rendered or hypermedia-oriented AdonisJS app",
|
|
40
|
-
skills: ["maestro", "adonisjs", "lucid", "japa"]
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: "react",
|
|
44
|
-
label: "Fullstack: Inertia React",
|
|
45
|
-
hint: "AdonisJS + Lucid + Inertia React",
|
|
46
|
-
skills: ["maestro", "adonisjs", "lucid", "japa", "inertia-react"]
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: "vue",
|
|
50
|
-
label: "Fullstack: Inertia Vue",
|
|
51
|
-
hint: "AdonisJS + Lucid + Inertia Vue",
|
|
52
|
-
skills: ["maestro", "adonisjs", "lucid", "japa", "inertia-vue"]
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: "custom",
|
|
56
|
-
label: "Custom",
|
|
57
|
-
hint: "Choose individual skills",
|
|
58
|
-
skills: []
|
|
59
|
-
}
|
|
60
|
-
];
|
|
61
|
-
function getStack(name) {
|
|
62
|
-
return STACKS.find((stack) => stack.name === name);
|
|
63
|
-
}
|
|
64
|
-
function parseSkills(value) {
|
|
65
|
-
const requested = value.split(",").map((skill) => skill.trim()).filter(Boolean);
|
|
66
|
-
const invalid = requested.filter((skill) => !AVAILABLE_SKILLS.includes(skill));
|
|
67
|
-
if (invalid.length > 0) {
|
|
68
|
-
throw new Error(`Unknown skill(s): ${invalid.join(", ")}`);
|
|
69
|
-
}
|
|
70
|
-
return [...new Set(requested)];
|
|
71
|
-
}
|
|
72
|
-
function buildSkillsAddArgs(options) {
|
|
73
|
-
const args = ["skills", "add", SKILLS_REPOSITORY];
|
|
74
|
-
for (const skill of options.skills) {
|
|
75
|
-
args.push("--skill", skill);
|
|
76
|
-
}
|
|
77
|
-
if (options.global) {
|
|
78
|
-
args.push("--global");
|
|
79
|
-
}
|
|
80
|
-
for (const agent of options.agents ?? []) {
|
|
81
|
-
args.push("--agent", agent);
|
|
82
|
-
}
|
|
83
|
-
if (options.yes) {
|
|
84
|
-
args.push("--yes");
|
|
85
|
-
}
|
|
86
|
-
return args;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// commands/main.ts
|
|
90
|
-
var InstallSkills = class extends BaseCommand {
|
|
91
|
-
static commandName = "adonisjs-maestro";
|
|
92
|
-
static description = "Install AdonisJS Maestro agent skills for your stack";
|
|
93
|
-
async #promptForStack() {
|
|
94
|
-
if (this.stack) {
|
|
95
|
-
return this.stack;
|
|
96
|
-
}
|
|
97
|
-
const selected = await this.prompt.choice(
|
|
98
|
-
"Which AdonisJS stack are you using?",
|
|
99
|
-
STACKS.map((stack) => ({
|
|
100
|
-
name: stack.name,
|
|
101
|
-
message: stack.label,
|
|
102
|
-
hint: stack.hint
|
|
103
|
-
}))
|
|
104
|
-
);
|
|
105
|
-
return selected;
|
|
106
|
-
}
|
|
107
|
-
async #promptForCustomSkills() {
|
|
108
|
-
const answer = await this.prompt.ask(
|
|
109
|
-
[
|
|
110
|
-
"Which skills should be installed?",
|
|
111
|
-
`Available: ${AVAILABLE_SKILLS.join(", ")}`,
|
|
112
|
-
"Enter a comma-separated list"
|
|
113
|
-
].join("\n")
|
|
114
|
-
);
|
|
115
|
-
return parseSkills(answer);
|
|
116
|
-
}
|
|
117
|
-
#parseAgents() {
|
|
118
|
-
if (!this.agent) {
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
return this.agent.split(",").map((agent) => agent.trim()).filter(Boolean);
|
|
122
|
-
}
|
|
123
|
-
async #resolveSkills() {
|
|
124
|
-
if (this.skills) {
|
|
125
|
-
return parseSkills(this.skills);
|
|
126
|
-
}
|
|
127
|
-
const stackName = await this.#promptForStack();
|
|
128
|
-
const stack = getStack(stackName);
|
|
129
|
-
if (!stack) {
|
|
130
|
-
throw new Error(`Unknown stack "${stackName}". Expected one of: ${STACKS.map((item) => item.name).join(", ")}`);
|
|
131
|
-
}
|
|
132
|
-
if (stack.name === "custom") {
|
|
133
|
-
return this.#promptForCustomSkills();
|
|
134
|
-
}
|
|
135
|
-
return stack.skills;
|
|
136
|
-
}
|
|
137
|
-
#renderCommand(args) {
|
|
138
|
-
return ["npx", ...args].join(" ");
|
|
139
|
-
}
|
|
140
|
-
async run() {
|
|
141
|
-
const skills = await this.#resolveSkills();
|
|
142
|
-
if (skills.length === 0) {
|
|
143
|
-
throw new Error("No skills selected");
|
|
144
|
-
}
|
|
145
|
-
const args = buildSkillsAddArgs({
|
|
146
|
-
skills,
|
|
147
|
-
global: this.global,
|
|
148
|
-
agents: this.#parseAgents(),
|
|
149
|
-
yes: this.yes
|
|
150
|
-
});
|
|
151
|
-
this.logger.info(`Installing skills: ${skills.join(", ")}`);
|
|
152
|
-
this.logger.info(this.#renderCommand(args));
|
|
153
|
-
if (this.dryRun) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
await execa("npx", args, {
|
|
157
|
-
stdio: this.verbose ? "inherit" : "pipe"
|
|
158
|
-
});
|
|
159
|
-
this.logger.success("AdonisJS Maestro skills installed");
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
__decorateClass([
|
|
163
|
-
flags.string({
|
|
164
|
-
description: "Stack preset to install: monorepo, hypermedia, react, vue, or custom"
|
|
165
|
-
})
|
|
166
|
-
], InstallSkills.prototype, "stack", 2);
|
|
167
|
-
__decorateClass([
|
|
168
|
-
flags.string({
|
|
169
|
-
description: "Comma-separated list of skills to install"
|
|
170
|
-
})
|
|
171
|
-
], InstallSkills.prototype, "skills", 2);
|
|
172
|
-
__decorateClass([
|
|
173
|
-
flags.string({
|
|
174
|
-
description: 'Target agent. Repeat by comma-separating values, or use "*" for all agents',
|
|
175
|
-
alias: "a"
|
|
176
|
-
})
|
|
177
|
-
], InstallSkills.prototype, "agent", 2);
|
|
178
|
-
__decorateClass([
|
|
179
|
-
flags.boolean({
|
|
180
|
-
description: "Install globally instead of the current project",
|
|
181
|
-
alias: "g"
|
|
182
|
-
})
|
|
183
|
-
], InstallSkills.prototype, "global", 2);
|
|
184
|
-
__decorateClass([
|
|
185
|
-
flags.boolean({
|
|
186
|
-
description: "Skip skills CLI confirmation prompts",
|
|
187
|
-
alias: "y"
|
|
188
|
-
})
|
|
189
|
-
], InstallSkills.prototype, "yes", 2);
|
|
190
|
-
__decorateClass([
|
|
191
|
-
flags.boolean({
|
|
192
|
-
description: "Print the generated npx skills command without running it"
|
|
193
|
-
})
|
|
194
|
-
], InstallSkills.prototype, "dryRun", 2);
|
|
195
|
-
__decorateClass([
|
|
196
|
-
flags.boolean({
|
|
197
|
-
description: "Show command output from the skills CLI",
|
|
198
|
-
alias: "v"
|
|
199
|
-
})
|
|
200
|
-
], InstallSkills.prototype, "verbose", 2);
|
|
201
|
-
|
|
202
|
-
// index.ts
|
|
203
|
-
Kernel.defaultCommand = InstallSkills;
|
|
204
|
-
var kernel = Kernel.create();
|
|
205
|
-
kernel.defineFlag("help", {
|
|
206
|
-
type: "boolean",
|
|
207
|
-
description: HelpCommand.description
|
|
208
|
-
});
|
|
209
|
-
kernel.on("help", async (command, $kernel, parsed) => {
|
|
210
|
-
parsed.args.unshift(command.commandName);
|
|
211
|
-
await new HelpCommand($kernel, parsed, kernel.ui, kernel.prompt).exec();
|
|
212
|
-
return $kernel.shortcircuit();
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
export {
|
|
216
|
-
kernel
|
|
217
|
-
};
|