@xyleapp/cli 0.2.0 → 0.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/bin/xyle.mjs +1 -1
- package/package.json +1 -1
- package/src/commands.mjs +20 -4
- package/src/seed.mjs +36 -3
package/bin/xyle.mjs
CHANGED
package/package.json
CHANGED
package/src/commands.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
SEO_BASE,
|
|
18
18
|
} from "./api.mjs";
|
|
19
19
|
import { getCredentials, clearCredentials, runLoginFlow } from "./auth.mjs";
|
|
20
|
-
import { seedInstructions, getToolNames, TOOLS } from "./seed.mjs";
|
|
20
|
+
import { seedInstructions, getToolNames, promptToolSelection, TOOLS } from "./seed.mjs";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Print error message in red to stderr and exit.
|
|
@@ -292,11 +292,12 @@ export function registerCommands(program) {
|
|
|
292
292
|
.description("Add xyle agent instructions to your project for AI coding tools")
|
|
293
293
|
.option(
|
|
294
294
|
"--tool <name>",
|
|
295
|
-
`Specific tool: ${getToolNames().join(", ")}
|
|
295
|
+
`Specific tool: ${getToolNames().join(", ")}`
|
|
296
296
|
)
|
|
297
|
+
.option("--all", "Seed all tools without prompting")
|
|
297
298
|
.option("--dir <path>", "Target directory", process.cwd())
|
|
298
299
|
.option("--list", "List supported tools")
|
|
299
|
-
.action((opts) => {
|
|
300
|
+
.action(async (opts) => {
|
|
300
301
|
if (opts.list) {
|
|
301
302
|
console.log("Supported tools:\n");
|
|
302
303
|
for (const [name, tool] of Object.entries(TOOLS)) {
|
|
@@ -312,7 +313,22 @@ export function registerCommands(program) {
|
|
|
312
313
|
process.exit(1);
|
|
313
314
|
}
|
|
314
315
|
|
|
315
|
-
|
|
316
|
+
let toolNames;
|
|
317
|
+
if (opts.tool) {
|
|
318
|
+
toolNames = [opts.tool];
|
|
319
|
+
} else if (opts.all) {
|
|
320
|
+
toolNames = null; // all
|
|
321
|
+
} else {
|
|
322
|
+
// Interactive selection
|
|
323
|
+
const selected = await promptToolSelection();
|
|
324
|
+
if (!selected.length) {
|
|
325
|
+
console.log("No tools selected.");
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
toolNames = selected;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const { created, skipped } = seedInstructions(opts.dir, toolNames);
|
|
316
332
|
|
|
317
333
|
if (created.length) {
|
|
318
334
|
console.log("\x1b[32mCreated:\x1b[0m");
|
package/src/seed.mjs
CHANGED
|
@@ -144,14 +144,47 @@ export const TOOLS = {
|
|
|
144
144
|
},
|
|
145
145
|
};
|
|
146
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Prompt user to select tools interactively.
|
|
149
|
+
* @returns {Promise<string[]>} Selected tool names
|
|
150
|
+
*/
|
|
151
|
+
export async function promptToolSelection() {
|
|
152
|
+
const readline = await import("node:readline");
|
|
153
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
154
|
+
const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
|
|
155
|
+
|
|
156
|
+
const entries = Object.entries(TOOLS);
|
|
157
|
+
console.log("\nSelect tools to seed (comma-separated numbers, or 'a' for all):\n");
|
|
158
|
+
entries.forEach(([name, tool], i) => {
|
|
159
|
+
console.log(` ${i + 1}) ${tool.label.padEnd(26)} ${tool.path}`);
|
|
160
|
+
});
|
|
161
|
+
console.log();
|
|
162
|
+
|
|
163
|
+
const answer = await ask("Your selection: ");
|
|
164
|
+
rl.close();
|
|
165
|
+
|
|
166
|
+
if (answer.trim().toLowerCase() === "a") {
|
|
167
|
+
return Object.keys(TOOLS);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const nums = answer.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n));
|
|
171
|
+
const selected = nums
|
|
172
|
+
.filter((n) => n >= 1 && n <= entries.length)
|
|
173
|
+
.map((n) => entries[n - 1][0]);
|
|
174
|
+
|
|
175
|
+
return [...new Set(selected)];
|
|
176
|
+
}
|
|
177
|
+
|
|
147
178
|
/**
|
|
148
179
|
* Write agent instruction files to the target directory.
|
|
149
180
|
* @param {string} targetDir - Absolute path to the project root
|
|
150
|
-
* @param {string|null}
|
|
181
|
+
* @param {string[]|null} toolNames - Specific tool names, or null for all
|
|
151
182
|
* @returns {{ created: string[], skipped: string[] }}
|
|
152
183
|
*/
|
|
153
|
-
export function seedInstructions(targetDir,
|
|
154
|
-
const tools =
|
|
184
|
+
export function seedInstructions(targetDir, toolNames) {
|
|
185
|
+
const tools = toolNames
|
|
186
|
+
? Object.fromEntries(toolNames.map((n) => [n, TOOLS[n]]))
|
|
187
|
+
: TOOLS;
|
|
155
188
|
const created = [];
|
|
156
189
|
const skipped = [];
|
|
157
190
|
|