@ideascol/agents-generator-sdk 0.7.3 → 0.7.4
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/bin/cli.js +3266 -213
- package/dist/commands/agentsCommand.d.ts +1 -1
- package/dist/commands/chatCommand.d.ts +6 -0
- package/dist/commands/conversationsCommand.d.ts +1 -1
- package/dist/commands/rootCommand.d.ts +1 -1
- package/dist/index.js +19 -14
- package/dist/lib/clients/agents-generator/index.d.ts +2 -0
- package/dist/lib/clients/agents-generator/models/WhoamiResponse.d.ts +9 -0
- package/dist/lib/clients/agents-generator/services/AuthService.d.ts +11 -0
- package/dist/lib/config.d.ts +34 -0
- package/dist/lib/index.d.ts +2 -1
- package/package.json +2 -2
package/dist/bin/cli.js
CHANGED
|
@@ -91,7 +91,12 @@ var require_colors = __commonJS((exports2) => {
|
|
|
91
91
|
BgBlue: "\x1B[44m",
|
|
92
92
|
BgMagenta: "\x1B[45m",
|
|
93
93
|
BgCyan: "\x1B[46m",
|
|
94
|
-
BgWhite: "\x1B[47m"
|
|
94
|
+
BgWhite: "\x1B[47m",
|
|
95
|
+
Success: "\x1B[32m",
|
|
96
|
+
Error: "\x1B[31m",
|
|
97
|
+
Warning: "\x1B[33m",
|
|
98
|
+
Info: "\x1B[36m",
|
|
99
|
+
SpinnerFrames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
|
95
100
|
};
|
|
96
101
|
});
|
|
97
102
|
|
|
@@ -110,9 +115,1140 @@ var require_interfaces = __commonJS((exports2) => {
|
|
|
110
115
|
ParamType2["Phone"] = "phone";
|
|
111
116
|
ParamType2["Url"] = "url";
|
|
112
117
|
ParamType2["Package"] = "Package";
|
|
118
|
+
ParamType2["Password"] = "password";
|
|
113
119
|
})(ParamType || (exports2.ParamType = ParamType = {}));
|
|
114
120
|
});
|
|
115
121
|
|
|
122
|
+
// node_modules/@ideascol/cli-maker/dist/common.js
|
|
123
|
+
var require_common = __commonJS((exports2) => {
|
|
124
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
125
|
+
exports2.ProgressBar = exports2.ProgressIndicator = undefined;
|
|
126
|
+
exports2.stripAnsiCodes = stripAnsiCodes;
|
|
127
|
+
exports2.showSuccess = showSuccess;
|
|
128
|
+
exports2.showError = showError;
|
|
129
|
+
exports2.showWarning = showWarning;
|
|
130
|
+
exports2.showInfo = showInfo;
|
|
131
|
+
exports2.createTable = createTable;
|
|
132
|
+
exports2.formatParameterTable = formatParameterTable;
|
|
133
|
+
var colors_1 = require_colors();
|
|
134
|
+
function stripAnsiCodes(str) {
|
|
135
|
+
return str.replace(/\u001b\[[0-9;]*[mG]/g, "");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
class ProgressIndicator {
|
|
139
|
+
constructor() {
|
|
140
|
+
this.interval = null;
|
|
141
|
+
this.frameIndex = 0;
|
|
142
|
+
}
|
|
143
|
+
start(message = "Processing...") {
|
|
144
|
+
process.stdout.write(`${colors_1.Colors.Info}${colors_1.Colors.SpinnerFrames[0]} ${message}${colors_1.Colors.Reset}`);
|
|
145
|
+
this.interval = setInterval(() => {
|
|
146
|
+
this.frameIndex = (this.frameIndex + 1) % colors_1.Colors.SpinnerFrames.length;
|
|
147
|
+
process.stdout.write(`\r${colors_1.Colors.Info}${colors_1.Colors.SpinnerFrames[this.frameIndex]} ${message}${colors_1.Colors.Reset}`);
|
|
148
|
+
}, 100);
|
|
149
|
+
}
|
|
150
|
+
update(message) {
|
|
151
|
+
if (this.interval) {
|
|
152
|
+
process.stdout.write(`\r${colors_1.Colors.Info}${colors_1.Colors.SpinnerFrames[this.frameIndex]} ${message}${colors_1.Colors.Reset}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
stop(success = true, finalMessage) {
|
|
156
|
+
if (this.interval) {
|
|
157
|
+
clearInterval(this.interval);
|
|
158
|
+
this.interval = null;
|
|
159
|
+
const icon = success ? "✅" : "❌";
|
|
160
|
+
const color = success ? colors_1.Colors.Success : colors_1.Colors.Error;
|
|
161
|
+
const message = finalMessage || (success ? "Done!" : "Failed!");
|
|
162
|
+
process.stdout.write("\r\x1B[K");
|
|
163
|
+
process.stdout.write(`${color}${icon} ${message}${colors_1.Colors.Reset}
|
|
164
|
+
`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
success(message = "Completed successfully!") {
|
|
168
|
+
this.stop(true, message);
|
|
169
|
+
}
|
|
170
|
+
error(message = "Operation failed!") {
|
|
171
|
+
this.stop(false, message);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
exports2.ProgressIndicator = ProgressIndicator;
|
|
175
|
+
|
|
176
|
+
class ProgressBar {
|
|
177
|
+
constructor(total, barLength = 40) {
|
|
178
|
+
this.current = 0;
|
|
179
|
+
this.barLength = 40;
|
|
180
|
+
this.message = "";
|
|
181
|
+
this.total = total;
|
|
182
|
+
this.barLength = barLength;
|
|
183
|
+
}
|
|
184
|
+
render() {
|
|
185
|
+
const percentage = Math.floor(this.current / this.total * 100);
|
|
186
|
+
const filledLength = Math.floor(this.current / this.total * this.barLength);
|
|
187
|
+
const emptyLength = this.barLength - filledLength;
|
|
188
|
+
const filledBar = "█".repeat(filledLength);
|
|
189
|
+
const emptyBar = "░".repeat(emptyLength);
|
|
190
|
+
const bar = `${colors_1.Colors.FgCyan}${filledBar}${colors_1.Colors.FgGray}${emptyBar}${colors_1.Colors.Reset}`;
|
|
191
|
+
const percentageText = `${colors_1.Colors.Bright}${percentage}%${colors_1.Colors.Reset}`;
|
|
192
|
+
const messageText = this.message ? ` ${colors_1.Colors.FgGray}${this.message}${colors_1.Colors.Reset}` : "";
|
|
193
|
+
process.stdout.write(`\r\x1B[K[${bar}] ${percentageText}${messageText}`);
|
|
194
|
+
}
|
|
195
|
+
start(message = "") {
|
|
196
|
+
this.message = message;
|
|
197
|
+
this.current = 0;
|
|
198
|
+
this.render();
|
|
199
|
+
}
|
|
200
|
+
update(current, message) {
|
|
201
|
+
this.current = Math.min(current, this.total);
|
|
202
|
+
if (message !== undefined) {
|
|
203
|
+
this.message = message;
|
|
204
|
+
}
|
|
205
|
+
this.render();
|
|
206
|
+
}
|
|
207
|
+
increment(step = 1, message) {
|
|
208
|
+
this.update(this.current + step, message);
|
|
209
|
+
}
|
|
210
|
+
complete(message = "Completed!") {
|
|
211
|
+
this.current = this.total;
|
|
212
|
+
this.render();
|
|
213
|
+
process.stdout.write(`
|
|
214
|
+
${colors_1.Colors.Success}✅ ${message}${colors_1.Colors.Reset}
|
|
215
|
+
`);
|
|
216
|
+
}
|
|
217
|
+
error(message = "Failed!") {
|
|
218
|
+
process.stdout.write(`
|
|
219
|
+
${colors_1.Colors.Error}❌ ${message}${colors_1.Colors.Reset}
|
|
220
|
+
`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
exports2.ProgressBar = ProgressBar;
|
|
224
|
+
function showSuccess(message) {
|
|
225
|
+
console.log(`${colors_1.Colors.Success}✅ ${message}${colors_1.Colors.Reset}`);
|
|
226
|
+
}
|
|
227
|
+
function showError(message) {
|
|
228
|
+
console.log(`${colors_1.Colors.Error}❌ ${message}${colors_1.Colors.Reset}`);
|
|
229
|
+
}
|
|
230
|
+
function showWarning(message) {
|
|
231
|
+
console.log(`${colors_1.Colors.Warning}⚠️ ${message}${colors_1.Colors.Reset}`);
|
|
232
|
+
}
|
|
233
|
+
function showInfo(message) {
|
|
234
|
+
console.log(`${colors_1.Colors.Info}ℹ️ ${message}${colors_1.Colors.Reset}`);
|
|
235
|
+
}
|
|
236
|
+
function createTable(headers, rows) {
|
|
237
|
+
if (rows.length === 0)
|
|
238
|
+
return "";
|
|
239
|
+
const allRows = [headers, ...rows];
|
|
240
|
+
const colWidths = headers.map((_, i) => Math.max(...allRows.map((row) => stripAnsiCodes(row[i] || "").length)));
|
|
241
|
+
const createRow = (row) => {
|
|
242
|
+
return row.map((cell, i) => {
|
|
243
|
+
const cleanCell = stripAnsiCodes(cell);
|
|
244
|
+
return cell.padEnd(colWidths[i] + (cell.length - cleanCell.length));
|
|
245
|
+
}).join(" │ ");
|
|
246
|
+
};
|
|
247
|
+
const separator = colWidths.map((width) => "─".repeat(width)).join("─┼─");
|
|
248
|
+
let table = createRow(headers) + `
|
|
249
|
+
`;
|
|
250
|
+
table += separator + `
|
|
251
|
+
`;
|
|
252
|
+
table += rows.map(createRow).join(`
|
|
253
|
+
`);
|
|
254
|
+
return table;
|
|
255
|
+
}
|
|
256
|
+
function formatParameterTable(params) {
|
|
257
|
+
const headers = ["Parameter", "Type", "Required", "Description"];
|
|
258
|
+
const rows = params.map((param) => [
|
|
259
|
+
colors_1.Colors.FgGreen + param.name + colors_1.Colors.Reset,
|
|
260
|
+
colors_1.Colors.FgBlue + (param.type || "text") + colors_1.Colors.Reset,
|
|
261
|
+
param.required ? colors_1.Colors.FgRed + "Yes" + colors_1.Colors.Reset : colors_1.Colors.FgGray + "No" + colors_1.Colors.Reset,
|
|
262
|
+
param.description + (param.options ? `
|
|
263
|
+
${colors_1.Colors.FgGray}Options: ${param.options.join(", ")}${colors_1.Colors.Reset}` : "")
|
|
264
|
+
]);
|
|
265
|
+
return createTable(headers, rows);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// node_modules/@ideascol/cli-maker/dist/session/markdown.js
|
|
270
|
+
var require_markdown = __commonJS((exports2) => {
|
|
271
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
272
|
+
exports2.renderMarkdown = renderMarkdown;
|
|
273
|
+
var colors_1 = require_colors();
|
|
274
|
+
function renderMarkdown(md) {
|
|
275
|
+
const lines = md.split(`
|
|
276
|
+
`);
|
|
277
|
+
const output = [];
|
|
278
|
+
let inCodeBlock = false;
|
|
279
|
+
let codeBlockLang = "";
|
|
280
|
+
let codeLines = [];
|
|
281
|
+
for (let i = 0;i < lines.length; i++) {
|
|
282
|
+
const line = lines[i];
|
|
283
|
+
if (line.trimStart().startsWith("```")) {
|
|
284
|
+
if (!inCodeBlock) {
|
|
285
|
+
inCodeBlock = true;
|
|
286
|
+
codeBlockLang = line.trimStart().slice(3).trim();
|
|
287
|
+
codeLines = [];
|
|
288
|
+
continue;
|
|
289
|
+
} else {
|
|
290
|
+
const header = codeBlockLang ? `${colors_1.Colors.FgGray}┌─ ${codeBlockLang} ${"─".repeat(Math.max(0, 40 - codeBlockLang.length))}┐${colors_1.Colors.Reset}` : `${colors_1.Colors.FgGray}┌${"─".repeat(44)}┐${colors_1.Colors.Reset}`;
|
|
291
|
+
output.push(header);
|
|
292
|
+
for (const cl of codeLines) {
|
|
293
|
+
output.push(`${colors_1.Colors.FgGray}│${colors_1.Colors.Reset} ${colors_1.Colors.FgCyan}${cl}${colors_1.Colors.Reset}`);
|
|
294
|
+
}
|
|
295
|
+
const footer = `${colors_1.Colors.FgGray}└${"─".repeat(44)}┘${colors_1.Colors.Reset}`;
|
|
296
|
+
output.push(footer);
|
|
297
|
+
inCodeBlock = false;
|
|
298
|
+
codeBlockLang = "";
|
|
299
|
+
codeLines = [];
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (inCodeBlock) {
|
|
304
|
+
codeLines.push(line);
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
if (/^(\s*[-*_]\s*){3,}$/.test(line)) {
|
|
308
|
+
output.push(`${colors_1.Colors.FgGray}${"─".repeat(46)}${colors_1.Colors.Reset}`);
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const headerMatch = line.match(/^(#{1,6})\s+(.*)$/);
|
|
312
|
+
if (headerMatch) {
|
|
313
|
+
const level = headerMatch[1].length;
|
|
314
|
+
const text = formatInline(headerMatch[2]);
|
|
315
|
+
if (level === 1) {
|
|
316
|
+
output.push(`
|
|
317
|
+
${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}${text}${colors_1.Colors.Reset}`);
|
|
318
|
+
output.push(`${colors_1.Colors.FgGray}${"═".repeat(stripAnsi(text).length)}${colors_1.Colors.Reset}`);
|
|
319
|
+
} else if (level === 2) {
|
|
320
|
+
output.push(`
|
|
321
|
+
${colors_1.Colors.Bright}${colors_1.Colors.FgGreen}${text}${colors_1.Colors.Reset}`);
|
|
322
|
+
output.push(`${colors_1.Colors.FgGray}${"─".repeat(stripAnsi(text).length)}${colors_1.Colors.Reset}`);
|
|
323
|
+
} else {
|
|
324
|
+
output.push(`
|
|
325
|
+
${colors_1.Colors.Bright}${colors_1.Colors.FgYellow}${text}${colors_1.Colors.Reset}`);
|
|
326
|
+
}
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
const ulMatch = line.match(/^(\s*)([-*+])\s+(.*)$/);
|
|
330
|
+
if (ulMatch) {
|
|
331
|
+
const indent = ulMatch[1];
|
|
332
|
+
const text = formatInline(ulMatch[3]);
|
|
333
|
+
output.push(`${indent}${colors_1.Colors.FgCyan}•${colors_1.Colors.Reset} ${text}`);
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
const olMatch = line.match(/^(\s*)(\d+)\.\s+(.*)$/);
|
|
337
|
+
if (olMatch) {
|
|
338
|
+
const indent = olMatch[1];
|
|
339
|
+
const num = olMatch[2];
|
|
340
|
+
const text = formatInline(olMatch[3]);
|
|
341
|
+
output.push(`${indent}${colors_1.Colors.FgCyan}${num}.${colors_1.Colors.Reset} ${text}`);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
const bqMatch = line.match(/^>\s?(.*)$/);
|
|
345
|
+
if (bqMatch) {
|
|
346
|
+
const text = formatInline(bqMatch[1]);
|
|
347
|
+
output.push(`${colors_1.Colors.FgGray}│${colors_1.Colors.Reset} ${colors_1.Colors.Dim}${text}${colors_1.Colors.Reset}`);
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
output.push(formatInline(line));
|
|
351
|
+
}
|
|
352
|
+
if (inCodeBlock && codeLines.length > 0) {
|
|
353
|
+
const header = codeBlockLang ? `${colors_1.Colors.FgGray}┌─ ${codeBlockLang} ${"─".repeat(Math.max(0, 40 - codeBlockLang.length))}┐${colors_1.Colors.Reset}` : `${colors_1.Colors.FgGray}┌${"─".repeat(44)}┐${colors_1.Colors.Reset}`;
|
|
354
|
+
output.push(header);
|
|
355
|
+
for (const cl of codeLines) {
|
|
356
|
+
output.push(`${colors_1.Colors.FgGray}│${colors_1.Colors.Reset} ${colors_1.Colors.FgCyan}${cl}${colors_1.Colors.Reset}`);
|
|
357
|
+
}
|
|
358
|
+
const footer = `${colors_1.Colors.FgGray}└${"─".repeat(44)}┘${colors_1.Colors.Reset}`;
|
|
359
|
+
output.push(footer);
|
|
360
|
+
}
|
|
361
|
+
return output.join(`
|
|
362
|
+
`);
|
|
363
|
+
}
|
|
364
|
+
function formatInline(text) {
|
|
365
|
+
text = text.replace(/`([^`]+)`/g, `${colors_1.Colors.FgCyan}$1${colors_1.Colors.Reset}`);
|
|
366
|
+
text = text.replace(/\*\*\*(.+?)\*\*\*/g, `${colors_1.Colors.Bright}${colors_1.Colors.Dim}$1${colors_1.Colors.Reset}`);
|
|
367
|
+
text = text.replace(/\*\*(.+?)\*\*/g, `${colors_1.Colors.Bright}$1${colors_1.Colors.Reset}`);
|
|
368
|
+
text = text.replace(/__(.+?)__/g, `${colors_1.Colors.Bright}$1${colors_1.Colors.Reset}`);
|
|
369
|
+
text = text.replace(/\*(.+?)\*/g, `${colors_1.Colors.Dim}$1${colors_1.Colors.Reset}`);
|
|
370
|
+
text = text.replace(/_(.+?)_/g, `${colors_1.Colors.Dim}$1${colors_1.Colors.Reset}`);
|
|
371
|
+
text = text.replace(/~~(.+?)~~/g, `${colors_1.Colors.FgGray}$1${colors_1.Colors.Reset}`);
|
|
372
|
+
text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, `${colors_1.Colors.FgBlue}${colors_1.Colors.Underscore}$1${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}($2)${colors_1.Colors.Reset}`);
|
|
373
|
+
return text;
|
|
374
|
+
}
|
|
375
|
+
function stripAnsi(str) {
|
|
376
|
+
return str.replace(/\u001b\[[0-9;]*[mG]/g, "");
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// node_modules/@ideascol/cli-maker/dist/session/slash-commands.js
|
|
381
|
+
var require_slash_commands = __commonJS((exports2) => {
|
|
382
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
383
|
+
exports2.getBuiltInSlashCommands = getBuiltInSlashCommands;
|
|
384
|
+
var colors_1 = require_colors();
|
|
385
|
+
function getBuiltInSlashCommands() {
|
|
386
|
+
return [
|
|
387
|
+
{
|
|
388
|
+
name: "help",
|
|
389
|
+
description: "Show available slash commands",
|
|
390
|
+
action: (_args, ctx) => {
|
|
391
|
+
const allCommands = getAllSlashCommands(ctx);
|
|
392
|
+
console.log(`
|
|
393
|
+
${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}Available Commands${colors_1.Colors.Reset}`);
|
|
394
|
+
console.log(`${colors_1.Colors.FgGray}${"─".repeat(40)}${colors_1.Colors.Reset}`);
|
|
395
|
+
for (const cmd of allCommands) {
|
|
396
|
+
console.log(` ${colors_1.Colors.FgGreen}/${cmd.name}${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}${cmd.description}${colors_1.Colors.Reset}`);
|
|
397
|
+
}
|
|
398
|
+
console.log("");
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
name: "clear",
|
|
403
|
+
description: "Clear the screen",
|
|
404
|
+
action: (_args, _ctx) => {
|
|
405
|
+
process.stdout.write("\x1B[2J\x1B[0;0H");
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
name: "history",
|
|
410
|
+
description: "Show conversation history",
|
|
411
|
+
action: (_args, ctx) => {
|
|
412
|
+
if (ctx.history.length === 0) {
|
|
413
|
+
console.log(`
|
|
414
|
+
${colors_1.Colors.FgGray}No messages in history yet.${colors_1.Colors.Reset}
|
|
415
|
+
`);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
console.log(`
|
|
419
|
+
${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}Conversation History${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}(${ctx.history.length} messages)${colors_1.Colors.Reset}`);
|
|
420
|
+
console.log(`${colors_1.Colors.FgGray}${"─".repeat(40)}${colors_1.Colors.Reset}`);
|
|
421
|
+
for (const msg of ctx.history) {
|
|
422
|
+
const roleColor = msg.role === "user" ? colors_1.Colors.FgGreen : msg.role === "assistant" ? colors_1.Colors.FgCyan : colors_1.Colors.FgYellow;
|
|
423
|
+
const roleLabel = msg.role === "tool" && msg.toolName ? `tool:${msg.toolName}` : msg.role;
|
|
424
|
+
const preview = msg.content.length > 80 ? msg.content.slice(0, 80) + "..." : msg.content;
|
|
425
|
+
console.log(` ${roleColor}[${roleLabel}]${colors_1.Colors.Reset} ${preview}`);
|
|
426
|
+
}
|
|
427
|
+
console.log("");
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
name: "tools",
|
|
432
|
+
description: "List registered tools",
|
|
433
|
+
action: (_args, ctx) => {
|
|
434
|
+
if (ctx.tools.length === 0) {
|
|
435
|
+
console.log(`
|
|
436
|
+
${colors_1.Colors.FgGray}No tools registered.${colors_1.Colors.Reset}
|
|
437
|
+
`);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
console.log(`
|
|
441
|
+
${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}Registered Tools${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}(${ctx.tools.length})${colors_1.Colors.Reset}`);
|
|
442
|
+
console.log(`${colors_1.Colors.FgGray}${"─".repeat(40)}${colors_1.Colors.Reset}`);
|
|
443
|
+
for (const tool of ctx.tools) {
|
|
444
|
+
console.log(` ${colors_1.Colors.FgYellow}⚡${colors_1.Colors.Reset} ${colors_1.Colors.Bright}${tool.name}${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}${tool.description}${colors_1.Colors.Reset}`);
|
|
445
|
+
if (tool.parameters && tool.parameters.length > 0) {
|
|
446
|
+
for (const p of tool.parameters) {
|
|
447
|
+
const req = p.required ? `${colors_1.Colors.FgRed}*${colors_1.Colors.Reset}` : "";
|
|
448
|
+
console.log(` ${colors_1.Colors.FgGray}${p.name}${req} (${p.type}) — ${p.description}${colors_1.Colors.Reset}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
console.log("");
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
name: "compact",
|
|
457
|
+
description: "Trim conversation history to the last N messages (default: 10)",
|
|
458
|
+
action: (args, ctx) => {
|
|
459
|
+
const keep = parseInt(args.trim(), 10) || 10;
|
|
460
|
+
const removed = Math.max(0, ctx.history.length - keep);
|
|
461
|
+
if (removed > 0) {
|
|
462
|
+
ctx.history.splice(0, removed);
|
|
463
|
+
}
|
|
464
|
+
console.log(`
|
|
465
|
+
${colors_1.Colors.FgGreen}✓${colors_1.Colors.Reset} History compacted: kept ${ctx.history.length} messages, removed ${removed}.
|
|
466
|
+
`);
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
name: "exit",
|
|
471
|
+
description: "End the interactive session",
|
|
472
|
+
action: (_args, _ctx) => {}
|
|
473
|
+
}
|
|
474
|
+
];
|
|
475
|
+
}
|
|
476
|
+
function getAllSlashCommands(ctx) {
|
|
477
|
+
const builtIn = getBuiltInSlashCommands();
|
|
478
|
+
return builtIn;
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
// node_modules/@ideascol/cli-maker/dist/session/ui.js
|
|
483
|
+
var require_ui = __commonJS((exports2) => {
|
|
484
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
485
|
+
exports2.drawBox = drawBox;
|
|
486
|
+
exports2.drawTwoColumnBox = drawTwoColumnBox;
|
|
487
|
+
exports2.infoBar = infoBar;
|
|
488
|
+
exports2.separator = separator;
|
|
489
|
+
exports2.toolCallHeader = toolCallHeader;
|
|
490
|
+
exports2.toolCallArgs = toolCallArgs;
|
|
491
|
+
exports2.toolResultBox = toolResultBox;
|
|
492
|
+
exports2.sectionHeader = sectionHeader;
|
|
493
|
+
exports2.alignedList = alignedList;
|
|
494
|
+
var colors_1 = require_colors();
|
|
495
|
+
var common_1 = require_common();
|
|
496
|
+
var BORDERS = {
|
|
497
|
+
single: { tl: "┌", tr: "┐", bl: "└", br: "┘", h: "─", v: "│" },
|
|
498
|
+
double: { tl: "╔", tr: "╗", bl: "╚", br: "╝", h: "═", v: "║" },
|
|
499
|
+
dashed: { tl: "┌", tr: "┐", bl: "└", br: "┘", h: "╌", v: "╎" },
|
|
500
|
+
rounded: { tl: "╭", tr: "╮", bl: "╰", br: "╯", h: "─", v: "│" }
|
|
501
|
+
};
|
|
502
|
+
function drawBox(contentLines, opts = {}) {
|
|
503
|
+
const border = BORDERS[opts.borderStyle ?? "rounded"];
|
|
504
|
+
const bColor = opts.borderColor ?? colors_1.Colors.FgGray;
|
|
505
|
+
const pad = opts.padding ?? 1;
|
|
506
|
+
const termWidth = process.stdout.columns || 80;
|
|
507
|
+
const maxW = opts.maxWidth ?? termWidth - 4;
|
|
508
|
+
const contentWidths = contentLines.map((l) => (0, common_1.stripAnsiCodes)(l).length);
|
|
509
|
+
let innerWidth = Math.max(...contentWidths, 10);
|
|
510
|
+
if (opts.title) {
|
|
511
|
+
innerWidth = Math.max(innerWidth, (0, common_1.stripAnsiCodes)(opts.title).length + 4);
|
|
512
|
+
}
|
|
513
|
+
innerWidth = Math.min(innerWidth, maxW - pad * 2 - 2);
|
|
514
|
+
const totalInner = innerWidth + pad * 2;
|
|
515
|
+
const padStr = " ".repeat(pad);
|
|
516
|
+
const output = [];
|
|
517
|
+
if (opts.title) {
|
|
518
|
+
const tColor = opts.titleColor ?? colors_1.Colors.Bright;
|
|
519
|
+
const titleClean = (0, common_1.stripAnsiCodes)(opts.title);
|
|
520
|
+
const remaining = Math.max(0, totalInner - titleClean.length - 3);
|
|
521
|
+
output.push(`${bColor}${border.tl}${border.h} ${colors_1.Colors.Reset}${tColor}${opts.title}${colors_1.Colors.Reset}${bColor} ${border.h.repeat(remaining)}${border.tr}${colors_1.Colors.Reset}`);
|
|
522
|
+
} else {
|
|
523
|
+
output.push(`${bColor}${border.tl}${border.h.repeat(totalInner)}${border.tr}${colors_1.Colors.Reset}`);
|
|
524
|
+
}
|
|
525
|
+
for (const line of contentLines) {
|
|
526
|
+
const cleanLen = (0, common_1.stripAnsiCodes)(line).length;
|
|
527
|
+
const rightPad = Math.max(0, innerWidth - cleanLen);
|
|
528
|
+
output.push(`${bColor}${border.v}${colors_1.Colors.Reset}${padStr}${line}${" ".repeat(rightPad)}${padStr}${bColor}${border.v}${colors_1.Colors.Reset}`);
|
|
529
|
+
}
|
|
530
|
+
output.push(`${bColor}${border.bl}${border.h.repeat(totalInner)}${border.br}${colors_1.Colors.Reset}`);
|
|
531
|
+
return output.join(`
|
|
532
|
+
`);
|
|
533
|
+
}
|
|
534
|
+
function drawTwoColumnBox(leftLines, rightLines, opts = {}) {
|
|
535
|
+
const border = BORDERS[opts.borderStyle ?? "rounded"];
|
|
536
|
+
const bColor = opts.borderColor ?? colors_1.Colors.FgGray;
|
|
537
|
+
const pad = opts.padding ?? 1;
|
|
538
|
+
const termWidth = process.stdout.columns || 80;
|
|
539
|
+
const maxW = opts.maxWidth ?? termWidth;
|
|
540
|
+
const totalInner = maxW - 2;
|
|
541
|
+
const ratio = opts.leftRatio ?? 0.45;
|
|
542
|
+
const divider = opts.dividerChar ?? border.v;
|
|
543
|
+
const overhead = pad * 4 + 1;
|
|
544
|
+
const usable = totalInner - overhead;
|
|
545
|
+
const leftW = Math.max(10, Math.floor(usable * ratio));
|
|
546
|
+
const rightW = Math.max(10, usable - leftW);
|
|
547
|
+
const maxRows = Math.max(leftLines.length, rightLines.length);
|
|
548
|
+
const padStr = " ".repeat(pad);
|
|
549
|
+
const truncate = (s, maxLen) => {
|
|
550
|
+
const clean = (0, common_1.stripAnsiCodes)(s);
|
|
551
|
+
if (clean.length <= maxLen)
|
|
552
|
+
return s;
|
|
553
|
+
let visible = 0;
|
|
554
|
+
let i = 0;
|
|
555
|
+
let inEsc = false;
|
|
556
|
+
let result = "";
|
|
557
|
+
while (i < s.length && visible < maxLen - 1) {
|
|
558
|
+
if (s[i] === "\x1B") {
|
|
559
|
+
inEsc = true;
|
|
560
|
+
result += s[i];
|
|
561
|
+
} else if (inEsc) {
|
|
562
|
+
result += s[i];
|
|
563
|
+
if (/[a-zA-Z]/.test(s[i]))
|
|
564
|
+
inEsc = false;
|
|
565
|
+
} else {
|
|
566
|
+
result += s[i];
|
|
567
|
+
visible++;
|
|
568
|
+
}
|
|
569
|
+
i++;
|
|
570
|
+
}
|
|
571
|
+
return result + "…" + colors_1.Colors.Reset;
|
|
572
|
+
};
|
|
573
|
+
const output = [];
|
|
574
|
+
if (opts.title) {
|
|
575
|
+
const tColor = opts.titleColor ?? colors_1.Colors.Bright;
|
|
576
|
+
const titleClean = (0, common_1.stripAnsiCodes)(opts.title);
|
|
577
|
+
const remaining = Math.max(0, totalInner - titleClean.length - 4);
|
|
578
|
+
output.push(`${bColor}${border.tl}${border.h}${border.h}${border.h} ${colors_1.Colors.Reset}${tColor}${opts.title}${colors_1.Colors.Reset}${bColor} ${border.h.repeat(remaining)}${border.tr}${colors_1.Colors.Reset}`);
|
|
579
|
+
} else {
|
|
580
|
+
output.push(`${bColor}${border.tl}${border.h.repeat(totalInner)}${border.tr}${colors_1.Colors.Reset}`);
|
|
581
|
+
}
|
|
582
|
+
for (let i = 0;i < maxRows; i++) {
|
|
583
|
+
const rawLeft = leftLines[i] ?? "";
|
|
584
|
+
const rawRight = rightLines[i] ?? "";
|
|
585
|
+
const left = truncate(rawLeft, leftW);
|
|
586
|
+
const right = truncate(rawRight, rightW);
|
|
587
|
+
const leftClean = (0, common_1.stripAnsiCodes)(left).length;
|
|
588
|
+
const rightClean = (0, common_1.stripAnsiCodes)(right).length;
|
|
589
|
+
const leftPadR = Math.max(0, leftW - leftClean);
|
|
590
|
+
const rightPadR = Math.max(0, rightW - rightClean);
|
|
591
|
+
output.push(`${bColor}${border.v}${colors_1.Colors.Reset}${padStr}${left}${" ".repeat(leftPadR)}${padStr}${bColor}${divider}${colors_1.Colors.Reset}${padStr}${right}${" ".repeat(rightPadR)}${padStr}${bColor}${border.v}${colors_1.Colors.Reset}`);
|
|
592
|
+
}
|
|
593
|
+
output.push(`${bColor}${border.bl}${border.h.repeat(totalInner)}${border.br}${colors_1.Colors.Reset}`);
|
|
594
|
+
return output.join(`
|
|
595
|
+
`);
|
|
596
|
+
}
|
|
597
|
+
function infoBar(text) {
|
|
598
|
+
return `${colors_1.Colors.FgGray}${text}${colors_1.Colors.Reset}`;
|
|
599
|
+
}
|
|
600
|
+
function separator(char = "─", width) {
|
|
601
|
+
const w = width ?? (process.stdout.columns || 80) - 2;
|
|
602
|
+
return `${colors_1.Colors.FgGray}${char.repeat(w)}${colors_1.Colors.Reset}`;
|
|
603
|
+
}
|
|
604
|
+
function toolCallHeader(toolName, description) {
|
|
605
|
+
return ` ${colors_1.Colors.FgYellow}⏺${colors_1.Colors.Reset} ${colors_1.Colors.Bright}${toolName}${colors_1.Colors.Reset}`;
|
|
606
|
+
}
|
|
607
|
+
function toolCallArgs(args) {
|
|
608
|
+
const lines = [];
|
|
609
|
+
for (const [key, val] of Object.entries(args)) {
|
|
610
|
+
const display = typeof val === "string" ? val : JSON.stringify(val);
|
|
611
|
+
lines.push(` ${colors_1.Colors.FgGray}${key}:${colors_1.Colors.Reset} ${display}`);
|
|
612
|
+
}
|
|
613
|
+
return lines.join(`
|
|
614
|
+
`);
|
|
615
|
+
}
|
|
616
|
+
function toolResultBox(result) {
|
|
617
|
+
const lines = result.split(`
|
|
618
|
+
`);
|
|
619
|
+
const output = [];
|
|
620
|
+
for (const line of lines) {
|
|
621
|
+
output.push(` ${colors_1.Colors.FgGray}│${colors_1.Colors.Reset} ${line}`);
|
|
622
|
+
}
|
|
623
|
+
return output.join(`
|
|
624
|
+
`);
|
|
625
|
+
}
|
|
626
|
+
function sectionHeader(title) {
|
|
627
|
+
return `
|
|
628
|
+
${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}${title}${colors_1.Colors.Reset}`;
|
|
629
|
+
}
|
|
630
|
+
function alignedList(items, indent = 4) {
|
|
631
|
+
const indentStr = " ".repeat(indent);
|
|
632
|
+
const maxKeyLen = Math.max(...items.map((i) => (0, common_1.stripAnsiCodes)(i.prefix ?? "").length + (0, common_1.stripAnsiCodes)(i.key).length));
|
|
633
|
+
const gap = 3;
|
|
634
|
+
const lines = [];
|
|
635
|
+
for (const item of items) {
|
|
636
|
+
const prefix = item.prefix ?? "";
|
|
637
|
+
const prefixClean = (0, common_1.stripAnsiCodes)(prefix).length;
|
|
638
|
+
const keyClean = (0, common_1.stripAnsiCodes)(item.key).length;
|
|
639
|
+
const keyColor = item.keyColor ?? colors_1.Colors.FgGreen;
|
|
640
|
+
const padding = " ".repeat(Math.max(1, maxKeyLen - prefixClean - keyClean + gap));
|
|
641
|
+
lines.push(`${indentStr}${prefix}${keyColor}${item.key}${colors_1.Colors.Reset}${padding}${colors_1.Colors.FgGray}${item.value}${colors_1.Colors.Reset}`);
|
|
642
|
+
}
|
|
643
|
+
return lines.join(`
|
|
644
|
+
`);
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
// node_modules/@ideascol/cli-maker/dist/session/session.js
|
|
649
|
+
var require_session = __commonJS((exports2) => {
|
|
650
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
651
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
|
652
|
+
};
|
|
653
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
654
|
+
exports2.InteractiveSession = undefined;
|
|
655
|
+
var readline_1 = __importDefault(require("readline"));
|
|
656
|
+
var child_process_1 = require("child_process");
|
|
657
|
+
var colors_1 = require_colors();
|
|
658
|
+
var common_1 = require_common();
|
|
659
|
+
var markdown_1 = require_markdown();
|
|
660
|
+
var slash_commands_1 = require_slash_commands();
|
|
661
|
+
var ui_1 = require_ui();
|
|
662
|
+
|
|
663
|
+
class InteractiveSession {
|
|
664
|
+
constructor(options) {
|
|
665
|
+
this.history = [];
|
|
666
|
+
this.rl = null;
|
|
667
|
+
this.inputHistory = [];
|
|
668
|
+
this.running = false;
|
|
669
|
+
this.options = {
|
|
670
|
+
prompt: options.prompt ?? "> ",
|
|
671
|
+
historySize: options.historySize ?? 100,
|
|
672
|
+
multiLineEnabled: options.multiLineEnabled ?? true,
|
|
673
|
+
...options
|
|
674
|
+
};
|
|
675
|
+
this.tools = options.tools ?? [];
|
|
676
|
+
this.slashCommands = this.mergeSlashCommands(options.slashCommands ?? []);
|
|
677
|
+
this.theme = {
|
|
678
|
+
borderColor: options.theme?.borderColor ?? colors_1.Colors.FgGreen,
|
|
679
|
+
borderStyle: options.theme?.borderStyle ?? "dashed",
|
|
680
|
+
promptColor: options.theme?.promptColor ?? colors_1.Colors.FgGreen,
|
|
681
|
+
accentColor: options.theme?.accentColor ?? colors_1.Colors.FgCyan
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
async start() {
|
|
685
|
+
this.running = true;
|
|
686
|
+
const ctx = this.buildContext();
|
|
687
|
+
this.renderWelcomeScreen();
|
|
688
|
+
if (this.options.onStart) {
|
|
689
|
+
await this.options.onStart(ctx);
|
|
690
|
+
}
|
|
691
|
+
const termW = process.stdout.columns || 80;
|
|
692
|
+
console.log(` ${colors_1.Colors.FgGray}${"─".repeat(Math.max(10, termW - 4))}${colors_1.Colors.Reset}
|
|
693
|
+
`);
|
|
694
|
+
while (this.running) {
|
|
695
|
+
let input;
|
|
696
|
+
try {
|
|
697
|
+
input = await this.readInput();
|
|
698
|
+
} catch {
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
const trimmed = input.trim();
|
|
702
|
+
if (trimmed.length === 0)
|
|
703
|
+
continue;
|
|
704
|
+
if (trimmed.startsWith("!")) {
|
|
705
|
+
const shellCmd = trimmed.slice(1).trim();
|
|
706
|
+
if (shellCmd.length === 0) {
|
|
707
|
+
console.log(` ${colors_1.Colors.FgGray}Usage: ! <command> (e.g. ! ls, ! pwd, ! git status)${colors_1.Colors.Reset}
|
|
708
|
+
`);
|
|
709
|
+
} else {
|
|
710
|
+
console.log(` ${colors_1.Colors.FgGray}$ ${shellCmd}${colors_1.Colors.Reset}`);
|
|
711
|
+
try {
|
|
712
|
+
const output = (0, child_process_1.execSync)(shellCmd, {
|
|
713
|
+
encoding: "utf-8",
|
|
714
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
715
|
+
timeout: 30000,
|
|
716
|
+
cwd: process.cwd()
|
|
717
|
+
});
|
|
718
|
+
if (output.trim().length > 0) {
|
|
719
|
+
const indented = output.trimEnd().split(`
|
|
720
|
+
`).map((l) => ` ${l}`).join(`
|
|
721
|
+
`);
|
|
722
|
+
console.log(indented);
|
|
723
|
+
}
|
|
724
|
+
} catch (err) {
|
|
725
|
+
if (err.stderr) {
|
|
726
|
+
const indented = err.stderr.toString().trimEnd().split(`
|
|
727
|
+
`).map((l) => ` ${l}`).join(`
|
|
728
|
+
`);
|
|
729
|
+
console.log(`${colors_1.Colors.FgRed}${indented}${colors_1.Colors.Reset}`);
|
|
730
|
+
}
|
|
731
|
+
if (err.status != null) {
|
|
732
|
+
console.log(` ${colors_1.Colors.FgGray}exit code: ${err.status}${colors_1.Colors.Reset}`);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
console.log("");
|
|
736
|
+
}
|
|
737
|
+
continue;
|
|
738
|
+
}
|
|
739
|
+
if (trimmed.startsWith("/")) {
|
|
740
|
+
const spaceIdx = trimmed.indexOf(" ");
|
|
741
|
+
const cmdName = spaceIdx === -1 ? trimmed.slice(1) : trimmed.slice(1, spaceIdx);
|
|
742
|
+
const cmdArgs = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1);
|
|
743
|
+
if (cmdName === "exit" || cmdName === "quit") {
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
if (cmdName === "clear") {
|
|
747
|
+
process.stdout.write("\x1B[2J\x1B[0;0H");
|
|
748
|
+
this.renderWelcomeScreen();
|
|
749
|
+
const termW2 = process.stdout.columns || 80;
|
|
750
|
+
console.log(` ${colors_1.Colors.FgGray}${"─".repeat(Math.max(10, termW2 - 4))}${colors_1.Colors.Reset}
|
|
751
|
+
`);
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
const cmd = this.slashCommands.find((c) => c.name === cmdName);
|
|
755
|
+
if (cmd) {
|
|
756
|
+
await cmd.action(cmdArgs, this.buildContext());
|
|
757
|
+
} else {
|
|
758
|
+
console.log(` ${colors_1.Colors.FgRed}✗${colors_1.Colors.Reset} Unknown command: ${colors_1.Colors.Bright}/${cmdName}${colors_1.Colors.Reset}`);
|
|
759
|
+
console.log(` ${colors_1.Colors.FgGray}Type ${colors_1.Colors.FgGreen}/help${colors_1.Colors.FgGray} for a list of commands.${colors_1.Colors.Reset}
|
|
760
|
+
`);
|
|
761
|
+
}
|
|
762
|
+
continue;
|
|
763
|
+
}
|
|
764
|
+
this.addToHistory({ role: "user", content: trimmed });
|
|
765
|
+
try {
|
|
766
|
+
await this.options.onMessage(trimmed, this.buildContext());
|
|
767
|
+
} catch (err) {
|
|
768
|
+
console.log(`
|
|
769
|
+
${colors_1.Colors.FgRed}✗ Error:${colors_1.Colors.Reset} ${err?.message ?? err}
|
|
770
|
+
`);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
if (this.options.onEnd) {
|
|
774
|
+
await this.options.onEnd(this.buildContext());
|
|
775
|
+
}
|
|
776
|
+
console.log(`
|
|
777
|
+
${colors_1.Colors.FgGray}Session ended. Goodbye!${colors_1.Colors.Reset}
|
|
778
|
+
`);
|
|
779
|
+
this.cleanup();
|
|
780
|
+
}
|
|
781
|
+
stop() {
|
|
782
|
+
this.running = false;
|
|
783
|
+
}
|
|
784
|
+
getHistory() {
|
|
785
|
+
return [...this.history];
|
|
786
|
+
}
|
|
787
|
+
renderWelcomeScreen() {
|
|
788
|
+
console.log("");
|
|
789
|
+
const hasTips = this.options.tips && this.options.tips.length > 0;
|
|
790
|
+
const hasWelcome = !!this.options.welcomeMessage;
|
|
791
|
+
if (hasWelcome && hasTips) {
|
|
792
|
+
const leftLines = this.options.welcomeMessage.split(`
|
|
793
|
+
`).map((l) => {
|
|
794
|
+
return l.replace(/\*\*(.+?)\*\*/g, `${colors_1.Colors.Bright}$1${colors_1.Colors.Reset}`).replace(/`([^`]+)`/g, `${colors_1.Colors.FgCyan}$1${colors_1.Colors.Reset}`);
|
|
795
|
+
});
|
|
796
|
+
const rightLines = [];
|
|
797
|
+
for (const tip of this.options.tips) {
|
|
798
|
+
rightLines.push(`${colors_1.Colors.FgYellow}${colors_1.Colors.Bright}${tip.title}${colors_1.Colors.Reset}`);
|
|
799
|
+
for (const line of tip.lines) {
|
|
800
|
+
rightLines.push(`${line}`);
|
|
801
|
+
}
|
|
802
|
+
rightLines.push("");
|
|
803
|
+
}
|
|
804
|
+
if (rightLines.length > 0 && rightLines[rightLines.length - 1] === "") {
|
|
805
|
+
rightLines.pop();
|
|
806
|
+
}
|
|
807
|
+
console.log((0, ui_1.drawTwoColumnBox)(leftLines, rightLines, {
|
|
808
|
+
borderColor: this.theme.borderColor,
|
|
809
|
+
borderStyle: this.theme.borderStyle
|
|
810
|
+
}));
|
|
811
|
+
} else if (hasWelcome) {
|
|
812
|
+
const lines = this.options.welcomeMessage.split(`
|
|
813
|
+
`).map((l) => {
|
|
814
|
+
return l.replace(/\*\*(.+?)\*\*/g, `${colors_1.Colors.Bright}$1${colors_1.Colors.Reset}`).replace(/`([^`]+)`/g, `${colors_1.Colors.FgCyan}$1${colors_1.Colors.Reset}`);
|
|
815
|
+
});
|
|
816
|
+
console.log((0, ui_1.drawBox)(lines, {
|
|
817
|
+
borderColor: this.theme.borderColor,
|
|
818
|
+
borderStyle: this.theme.borderStyle
|
|
819
|
+
}));
|
|
820
|
+
}
|
|
821
|
+
if (this.options.infoLines && this.options.infoLines.length > 0) {
|
|
822
|
+
for (const line of this.options.infoLines) {
|
|
823
|
+
console.log(` ${colors_1.Colors.FgGray}${line}${colors_1.Colors.Reset}`);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
readInput() {
|
|
828
|
+
const isTTY = process.stdin.isTTY ?? false;
|
|
829
|
+
if (!isTTY) {
|
|
830
|
+
return new Promise((resolve, reject) => {
|
|
831
|
+
this.rl = readline_1.default.createInterface({
|
|
832
|
+
input: process.stdin,
|
|
833
|
+
output: process.stdout,
|
|
834
|
+
terminal: false
|
|
835
|
+
});
|
|
836
|
+
this.rl.question("> ", (answer) => {
|
|
837
|
+
this.rl.close();
|
|
838
|
+
this.rl = null;
|
|
839
|
+
resolve(answer);
|
|
840
|
+
});
|
|
841
|
+
this.rl.on("close", () => reject(new Error("EOF")));
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
return new Promise((resolve, reject) => {
|
|
845
|
+
let line = "";
|
|
846
|
+
let cursor = 0;
|
|
847
|
+
let historyIdx = -1;
|
|
848
|
+
let savedLine = "";
|
|
849
|
+
let menuItems = [];
|
|
850
|
+
let menuSelected = 0;
|
|
851
|
+
let menuLineCount = 0;
|
|
852
|
+
const promptStr = `${this.theme.promptColor}>${colors_1.Colors.Reset} `;
|
|
853
|
+
const promptVisualLen = 2;
|
|
854
|
+
const eraseBelow = () => {
|
|
855
|
+
if (menuLineCount > 0) {
|
|
856
|
+
process.stdout.write("\x1B[J");
|
|
857
|
+
menuLineCount = 0;
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
const renderPromptLine = () => {
|
|
861
|
+
process.stdout.write("\r\x1B[2K");
|
|
862
|
+
process.stdout.write(promptStr + line);
|
|
863
|
+
const cursorPos = promptVisualLen + cursor;
|
|
864
|
+
process.stdout.write(`\r\x1B[${cursorPos + 1}G`);
|
|
865
|
+
};
|
|
866
|
+
const renderMenu = () => {
|
|
867
|
+
if (menuItems.length === 0)
|
|
868
|
+
return;
|
|
869
|
+
const maxNameLen = Math.max(...menuItems.map((c) => c.name.length));
|
|
870
|
+
const gap = 4;
|
|
871
|
+
const rows = [];
|
|
872
|
+
for (let i = 0;i < menuItems.length; i++) {
|
|
873
|
+
const cmd = menuItems[i];
|
|
874
|
+
const nameStr = `/${cmd.name}`.padEnd(maxNameLen + 1 + gap);
|
|
875
|
+
if (i === menuSelected) {
|
|
876
|
+
rows.push(` ${colors_1.Colors.Dim}${colors_1.Colors.Reverse} ${nameStr}${cmd.description} ${colors_1.Colors.Reset}`);
|
|
877
|
+
} else {
|
|
878
|
+
rows.push(` ${colors_1.Colors.FgWhite}/${cmd.name}${colors_1.Colors.Reset}${" ".repeat(maxNameLen - cmd.name.length + gap)}${colors_1.Colors.FgGray}${cmd.description}${colors_1.Colors.Reset}`);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
for (const row of rows) {
|
|
882
|
+
process.stdout.write(`
|
|
883
|
+
\x1B[2K` + row);
|
|
884
|
+
}
|
|
885
|
+
menuLineCount = rows.length;
|
|
886
|
+
if (menuLineCount > 0) {
|
|
887
|
+
process.stdout.write(`\x1B[${menuLineCount}A`);
|
|
888
|
+
}
|
|
889
|
+
const cursorPos = promptVisualLen + cursor;
|
|
890
|
+
process.stdout.write(`\r\x1B[${cursorPos + 1}G`);
|
|
891
|
+
};
|
|
892
|
+
const redraw = () => {
|
|
893
|
+
eraseBelow();
|
|
894
|
+
renderPromptLine();
|
|
895
|
+
const isSlashPrefix = line.startsWith("/") && !line.includes(" ");
|
|
896
|
+
if (isSlashPrefix) {
|
|
897
|
+
const partial = line.slice(1).toLowerCase();
|
|
898
|
+
menuItems = this.slashCommands.filter((c) => c.name.toLowerCase().startsWith(partial));
|
|
899
|
+
menuSelected = Math.min(menuSelected, Math.max(0, menuItems.length - 1));
|
|
900
|
+
if (menuItems.length > 0) {
|
|
901
|
+
renderMenu();
|
|
902
|
+
}
|
|
903
|
+
} else {
|
|
904
|
+
menuItems = [];
|
|
905
|
+
menuSelected = 0;
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
const finish = (result) => {
|
|
909
|
+
eraseBelow();
|
|
910
|
+
process.stdin.removeListener("data", onData);
|
|
911
|
+
if (process.stdin.setRawMode) {
|
|
912
|
+
process.stdin.setRawMode(false);
|
|
913
|
+
}
|
|
914
|
+
process.stdout.write(`
|
|
915
|
+
`);
|
|
916
|
+
const trimmed = result.trim();
|
|
917
|
+
if (trimmed.length > 0) {
|
|
918
|
+
this.inputHistory.unshift(trimmed);
|
|
919
|
+
if (this.inputHistory.length > 50)
|
|
920
|
+
this.inputHistory.pop();
|
|
921
|
+
}
|
|
922
|
+
resolve(result);
|
|
923
|
+
};
|
|
924
|
+
const onData = (data) => {
|
|
925
|
+
const s = data.toString();
|
|
926
|
+
if (s === "\x03") {
|
|
927
|
+
eraseBelow();
|
|
928
|
+
process.stdin.removeListener("data", onData);
|
|
929
|
+
if (process.stdin.setRawMode) {
|
|
930
|
+
process.stdin.setRawMode(false);
|
|
931
|
+
}
|
|
932
|
+
process.stdout.write(`
|
|
933
|
+
`);
|
|
934
|
+
reject(new Error("EOF"));
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
937
|
+
if (s === "\x04") {
|
|
938
|
+
if (line.length === 0) {
|
|
939
|
+
eraseBelow();
|
|
940
|
+
process.stdin.removeListener("data", onData);
|
|
941
|
+
if (process.stdin.setRawMode) {
|
|
942
|
+
process.stdin.setRawMode(false);
|
|
943
|
+
}
|
|
944
|
+
process.stdout.write(`
|
|
945
|
+
`);
|
|
946
|
+
reject(new Error("EOF"));
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
if (s === "\r" || s === `
|
|
952
|
+
`) {
|
|
953
|
+
if (menuItems.length > 0 && menuSelected < menuItems.length) {
|
|
954
|
+
const selected = menuItems[menuSelected];
|
|
955
|
+
line = `/${selected.name}`;
|
|
956
|
+
cursor = line.length;
|
|
957
|
+
}
|
|
958
|
+
finish(line);
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
if (s === "\t") {
|
|
962
|
+
if (menuItems.length > 0 && menuSelected < menuItems.length) {
|
|
963
|
+
const selected = menuItems[menuSelected];
|
|
964
|
+
line = `/${selected.name}`;
|
|
965
|
+
cursor = line.length;
|
|
966
|
+
menuItems = [];
|
|
967
|
+
menuSelected = 0;
|
|
968
|
+
redraw();
|
|
969
|
+
}
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
if (s === "" || s === "\b") {
|
|
973
|
+
if (cursor > 0) {
|
|
974
|
+
line = line.slice(0, cursor - 1) + line.slice(cursor);
|
|
975
|
+
cursor--;
|
|
976
|
+
menuSelected = 0;
|
|
977
|
+
redraw();
|
|
978
|
+
}
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
if (s === "\x1B") {
|
|
982
|
+
if (menuItems.length > 0) {
|
|
983
|
+
menuItems = [];
|
|
984
|
+
menuSelected = 0;
|
|
985
|
+
redraw();
|
|
986
|
+
}
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
if (s === "\x1B[A" || s === "\x1BOA") {
|
|
990
|
+
if (menuItems.length > 0) {
|
|
991
|
+
menuSelected = (menuSelected - 1 + menuItems.length) % menuItems.length;
|
|
992
|
+
eraseBelow();
|
|
993
|
+
renderPromptLine();
|
|
994
|
+
renderMenu();
|
|
995
|
+
} else {
|
|
996
|
+
if (historyIdx === -1)
|
|
997
|
+
savedLine = line;
|
|
998
|
+
if (historyIdx < this.inputHistory.length - 1) {
|
|
999
|
+
historyIdx++;
|
|
1000
|
+
line = this.inputHistory[historyIdx];
|
|
1001
|
+
cursor = line.length;
|
|
1002
|
+
redraw();
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
if (s === "\x1B[B" || s === "\x1BOB") {
|
|
1008
|
+
if (menuItems.length > 0) {
|
|
1009
|
+
menuSelected = (menuSelected + 1) % menuItems.length;
|
|
1010
|
+
eraseBelow();
|
|
1011
|
+
renderPromptLine();
|
|
1012
|
+
renderMenu();
|
|
1013
|
+
} else {
|
|
1014
|
+
if (historyIdx > 0) {
|
|
1015
|
+
historyIdx--;
|
|
1016
|
+
line = this.inputHistory[historyIdx];
|
|
1017
|
+
cursor = line.length;
|
|
1018
|
+
redraw();
|
|
1019
|
+
} else if (historyIdx === 0) {
|
|
1020
|
+
historyIdx = -1;
|
|
1021
|
+
line = savedLine;
|
|
1022
|
+
cursor = line.length;
|
|
1023
|
+
redraw();
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
if (s === "\x1B[D" || s === "\x1BOD") {
|
|
1029
|
+
if (cursor > 0) {
|
|
1030
|
+
cursor--;
|
|
1031
|
+
process.stdout.write("\x1B[1D");
|
|
1032
|
+
}
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
if (s === "\x1B[C" || s === "\x1BOC") {
|
|
1036
|
+
if (cursor < line.length) {
|
|
1037
|
+
cursor++;
|
|
1038
|
+
process.stdout.write("\x1B[1C");
|
|
1039
|
+
}
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
if (s === "\x1B[H" || s === "\x01") {
|
|
1043
|
+
cursor = 0;
|
|
1044
|
+
process.stdout.write(`\r\x1B[${promptVisualLen + 1}G`);
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
if (s === "\x1B[F" || s === "\x05") {
|
|
1048
|
+
cursor = line.length;
|
|
1049
|
+
process.stdout.write(`\r\x1B[${promptVisualLen + cursor + 1}G`);
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
if (s === "\x1B[3~") {
|
|
1053
|
+
if (cursor < line.length) {
|
|
1054
|
+
line = line.slice(0, cursor) + line.slice(cursor + 1);
|
|
1055
|
+
menuSelected = 0;
|
|
1056
|
+
redraw();
|
|
1057
|
+
}
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
if (s.startsWith("\x1B")) {
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
if (s.length === 1 && s.charCodeAt(0) >= 32) {
|
|
1064
|
+
line = line.slice(0, cursor) + s + line.slice(cursor);
|
|
1065
|
+
cursor++;
|
|
1066
|
+
historyIdx = -1;
|
|
1067
|
+
menuSelected = 0;
|
|
1068
|
+
redraw();
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
if (process.stdin.setRawMode) {
|
|
1073
|
+
process.stdin.setRawMode(true);
|
|
1074
|
+
}
|
|
1075
|
+
process.stdin.resume();
|
|
1076
|
+
renderPromptLine();
|
|
1077
|
+
process.stdin.on("data", onData);
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
buildContext() {
|
|
1081
|
+
const self = this;
|
|
1082
|
+
return {
|
|
1083
|
+
history: this.history,
|
|
1084
|
+
tools: this.tools,
|
|
1085
|
+
callTool: (name, args) => self.executeTool(name, args),
|
|
1086
|
+
print: (text) => self.print(text),
|
|
1087
|
+
printStream: (stream) => self.printStream(stream),
|
|
1088
|
+
printMarkdown: (md) => self.printMarkdown(md),
|
|
1089
|
+
spinner: new common_1.ProgressIndicator,
|
|
1090
|
+
session: self
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
async executeTool(name, args) {
|
|
1094
|
+
const tool = this.tools.find((t) => t.name === name);
|
|
1095
|
+
if (!tool) {
|
|
1096
|
+
throw new Error(`Tool not found: ${name}`);
|
|
1097
|
+
}
|
|
1098
|
+
if (tool.parameters) {
|
|
1099
|
+
for (const param of tool.parameters) {
|
|
1100
|
+
if (param.required && (args[param.name] === undefined || args[param.name] === null)) {
|
|
1101
|
+
throw new Error(`Missing required parameter '${param.name}' for tool '${name}'`);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
console.log("");
|
|
1106
|
+
console.log((0, ui_1.toolCallHeader)(tool.name, tool.description));
|
|
1107
|
+
if (Object.keys(args).length > 0) {
|
|
1108
|
+
console.log((0, ui_1.toolCallArgs)(args));
|
|
1109
|
+
}
|
|
1110
|
+
const spinner = new common_1.ProgressIndicator;
|
|
1111
|
+
spinner.start(" Running...");
|
|
1112
|
+
let result;
|
|
1113
|
+
try {
|
|
1114
|
+
result = await tool.execute(args, this.buildContext());
|
|
1115
|
+
spinner.success("Done");
|
|
1116
|
+
} catch (err) {
|
|
1117
|
+
spinner.error(err?.message ?? "Tool execution failed");
|
|
1118
|
+
throw err;
|
|
1119
|
+
}
|
|
1120
|
+
const resultStr = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
1121
|
+
console.log((0, ui_1.toolResultBox)(resultStr));
|
|
1122
|
+
console.log("");
|
|
1123
|
+
this.addToHistory({ role: "tool", content: resultStr, toolName: name });
|
|
1124
|
+
return result;
|
|
1125
|
+
}
|
|
1126
|
+
print(text) {
|
|
1127
|
+
console.log(` ${text}`);
|
|
1128
|
+
this.addToHistory({ role: "assistant", content: text });
|
|
1129
|
+
}
|
|
1130
|
+
async printStream(stream) {
|
|
1131
|
+
let full = "";
|
|
1132
|
+
process.stdout.write(" ");
|
|
1133
|
+
for await (const chunk of stream) {
|
|
1134
|
+
process.stdout.write(chunk);
|
|
1135
|
+
full += chunk;
|
|
1136
|
+
}
|
|
1137
|
+
process.stdout.write(`
|
|
1138
|
+
|
|
1139
|
+
`);
|
|
1140
|
+
this.addToHistory({ role: "assistant", content: full });
|
|
1141
|
+
}
|
|
1142
|
+
printMarkdown(md) {
|
|
1143
|
+
const rendered = (0, markdown_1.renderMarkdown)(md);
|
|
1144
|
+
const indented = rendered.split(`
|
|
1145
|
+
`).map((l) => ` ${l}`).join(`
|
|
1146
|
+
`);
|
|
1147
|
+
console.log(indented);
|
|
1148
|
+
this.addToHistory({ role: "assistant", content: md });
|
|
1149
|
+
}
|
|
1150
|
+
addToHistory(message) {
|
|
1151
|
+
this.history.push(message);
|
|
1152
|
+
while (this.history.length > this.options.historySize) {
|
|
1153
|
+
this.history.shift();
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
mergeSlashCommands(custom) {
|
|
1157
|
+
const builtIn = (0, slash_commands_1.getBuiltInSlashCommands)();
|
|
1158
|
+
const customNames = new Set(custom.map((c) => c.name));
|
|
1159
|
+
const merged = builtIn.filter((b) => !customNames.has(b.name));
|
|
1160
|
+
merged.push(...custom);
|
|
1161
|
+
const helpIdx = merged.findIndex((c) => c.name === "help");
|
|
1162
|
+
if (helpIdx !== -1) {
|
|
1163
|
+
merged[helpIdx] = {
|
|
1164
|
+
name: "help",
|
|
1165
|
+
description: "Show available slash commands",
|
|
1166
|
+
action: (_args, _ctx) => {
|
|
1167
|
+
console.log((0, ui_1.sectionHeader)("Commands"));
|
|
1168
|
+
console.log("");
|
|
1169
|
+
const items = merged.map((cmd) => ({
|
|
1170
|
+
key: `/${cmd.name}`,
|
|
1171
|
+
value: cmd.description,
|
|
1172
|
+
keyColor: colors_1.Colors.FgGreen
|
|
1173
|
+
}));
|
|
1174
|
+
console.log((0, ui_1.alignedList)(items));
|
|
1175
|
+
console.log("");
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
const toolsIdx = merged.findIndex((c) => c.name === "tools");
|
|
1180
|
+
if (toolsIdx !== -1) {
|
|
1181
|
+
const self = this;
|
|
1182
|
+
merged[toolsIdx] = {
|
|
1183
|
+
name: "tools",
|
|
1184
|
+
description: "List registered tools",
|
|
1185
|
+
action: (_args, _ctx) => {
|
|
1186
|
+
if (self.tools.length === 0) {
|
|
1187
|
+
console.log(`
|
|
1188
|
+
${colors_1.Colors.FgGray}No tools registered.${colors_1.Colors.Reset}
|
|
1189
|
+
`);
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
console.log((0, ui_1.sectionHeader)(`Tools ${colors_1.Colors.FgGray}(${self.tools.length})${colors_1.Colors.Reset}`));
|
|
1193
|
+
console.log("");
|
|
1194
|
+
for (const tool of self.tools) {
|
|
1195
|
+
console.log(` ${colors_1.Colors.FgYellow}⚡${colors_1.Colors.Reset} ${colors_1.Colors.Bright}${tool.name}${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}${tool.description}${colors_1.Colors.Reset}`);
|
|
1196
|
+
if (tool.parameters && tool.parameters.length > 0) {
|
|
1197
|
+
for (const p of tool.parameters) {
|
|
1198
|
+
const req = p.required ? `${colors_1.Colors.FgRed}*${colors_1.Colors.Reset}` : "";
|
|
1199
|
+
console.log(` ${colors_1.Colors.FgGray}${p.name}${req} ${colors_1.Colors.Dim}(${p.type})${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}${p.description}${colors_1.Colors.Reset}`);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
console.log("");
|
|
1204
|
+
}
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
const historyIdx = merged.findIndex((c) => c.name === "history");
|
|
1208
|
+
if (historyIdx !== -1) {
|
|
1209
|
+
const self = this;
|
|
1210
|
+
merged[historyIdx] = {
|
|
1211
|
+
name: "history",
|
|
1212
|
+
description: "Show conversation history",
|
|
1213
|
+
action: (_args, _ctx) => {
|
|
1214
|
+
if (self.history.length === 0) {
|
|
1215
|
+
console.log(`
|
|
1216
|
+
${colors_1.Colors.FgGray}No messages yet.${colors_1.Colors.Reset}
|
|
1217
|
+
`);
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
console.log((0, ui_1.sectionHeader)(`History ${colors_1.Colors.FgGray}(${self.history.length} messages)${colors_1.Colors.Reset}`));
|
|
1221
|
+
console.log("");
|
|
1222
|
+
for (const msg of self.history) {
|
|
1223
|
+
const roleColor = msg.role === "user" ? colors_1.Colors.FgGreen : msg.role === "assistant" ? colors_1.Colors.FgCyan : colors_1.Colors.FgYellow;
|
|
1224
|
+
const roleLabel = msg.role === "tool" && msg.toolName ? `tool:${msg.toolName}` : msg.role;
|
|
1225
|
+
const icon = msg.role === "user" ? "▸" : msg.role === "assistant" ? "◂" : "⚡";
|
|
1226
|
+
const preview = msg.content.length > 80 ? msg.content.slice(0, 80) + "…" : msg.content;
|
|
1227
|
+
console.log(` ${roleColor}${icon} ${roleLabel}${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}${preview}${colors_1.Colors.Reset}`);
|
|
1228
|
+
}
|
|
1229
|
+
console.log("");
|
|
1230
|
+
}
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
return merged;
|
|
1234
|
+
}
|
|
1235
|
+
cleanup() {
|
|
1236
|
+
if (this.rl) {
|
|
1237
|
+
this.rl.close();
|
|
1238
|
+
this.rl = null;
|
|
1239
|
+
}
|
|
1240
|
+
if (process.stdin.setRawMode) {
|
|
1241
|
+
try {
|
|
1242
|
+
process.stdin.setRawMode(false);
|
|
1243
|
+
} catch {}
|
|
1244
|
+
}
|
|
1245
|
+
process.stdin.pause();
|
|
1246
|
+
process.stdin.unref();
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
exports2.InteractiveSession = InteractiveSession;
|
|
1250
|
+
});
|
|
1251
|
+
|
|
116
1252
|
// node_modules/@ideascol/cli-maker/dist/command/validator.js
|
|
117
1253
|
var require_validator = __commonJS((exports2) => {
|
|
118
1254
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -123,68 +1259,785 @@ var require_validator = __commonJS((exports2) => {
|
|
|
123
1259
|
class Validator {
|
|
124
1260
|
validateParam(value, type, isRequired, options, paramName) {
|
|
125
1261
|
if (this.checkEmpty(value) && isRequired) {
|
|
126
|
-
return {
|
|
1262
|
+
return {
|
|
1263
|
+
error: `
|
|
1264
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Missing required parameter${paramName ? `: ${colors_1.Colors.Bright}${paramName}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}` : ""}${colors_1.Colors.Reset}
|
|
1265
|
+
`
|
|
1266
|
+
};
|
|
127
1267
|
} else if (this.checkEmpty(value) && !isRequired) {
|
|
128
1268
|
return { value: undefined, error: "" };
|
|
129
1269
|
}
|
|
130
|
-
if (value === undefined) {
|
|
131
|
-
return { value };
|
|
1270
|
+
if (value === undefined) {
|
|
1271
|
+
return { value };
|
|
1272
|
+
}
|
|
1273
|
+
switch (type) {
|
|
1274
|
+
case interfaces_1.ParamType.Number:
|
|
1275
|
+
if (!/^[0-9]+$/.test(value)) {
|
|
1276
|
+
return {
|
|
1277
|
+
error: `
|
|
1278
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Invalid number format: '${colors_1.Colors.Bright}${value}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
1279
|
+
${colors_1.Colors.FgGray} Expected: whole numbers only (e.g., 42)${colors_1.Colors.Reset}
|
|
1280
|
+
`
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
return { value: Number(value) };
|
|
1284
|
+
case interfaces_1.ParamType.Custom:
|
|
1285
|
+
try {
|
|
1286
|
+
const customValue = JSON.parse(value);
|
|
1287
|
+
if (Array.isArray(customValue) || typeof customValue === "object") {
|
|
1288
|
+
return { value: customValue };
|
|
1289
|
+
} else {
|
|
1290
|
+
return {
|
|
1291
|
+
error: `
|
|
1292
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Invalid custom value: '${colors_1.Colors.Bright}${value}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
1293
|
+
${colors_1.Colors.FgGray} Expected: JSON array or object (e.g., ["item1", "item2"] or {"key": "value"})${colors_1.Colors.Reset}
|
|
1294
|
+
`
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
} catch {
|
|
1298
|
+
return {
|
|
1299
|
+
error: `
|
|
1300
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Invalid JSON format: '${colors_1.Colors.Bright}${value}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
1301
|
+
${colors_1.Colors.FgGray} Expected: Valid JSON array or object${colors_1.Colors.Reset}
|
|
1302
|
+
`
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
case interfaces_1.ParamType.List: {
|
|
1306
|
+
if (options === undefined || options?.length === 0) {
|
|
1307
|
+
return {
|
|
1308
|
+
error: `
|
|
1309
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}List parameter has no options configured${colors_1.Colors.Reset}
|
|
1310
|
+
`,
|
|
1311
|
+
value: undefined
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
const foundValue = options?.filter((x) => x === value);
|
|
1315
|
+
if (foundValue?.length === 0) {
|
|
1316
|
+
return {
|
|
1317
|
+
error: `
|
|
1318
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Invalid option: '${colors_1.Colors.Bright}${value}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
1319
|
+
${colors_1.Colors.FgGray} Available options: ${options?.join(", ")}${colors_1.Colors.Reset}
|
|
1320
|
+
`,
|
|
1321
|
+
value: undefined
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
return { value };
|
|
1325
|
+
}
|
|
1326
|
+
case interfaces_1.ParamType.Boolean:
|
|
1327
|
+
if (value.toLowerCase() !== "true" && value.toLowerCase() !== "false") {
|
|
1328
|
+
return {
|
|
1329
|
+
error: `
|
|
1330
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Invalid boolean: '${colors_1.Colors.Bright}${value}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
1331
|
+
${colors_1.Colors.FgGray} Expected: 'true' or 'false'${colors_1.Colors.Reset}
|
|
1332
|
+
`
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
return { value: value.toLowerCase() === "true" };
|
|
1336
|
+
case interfaces_1.ParamType.Email:
|
|
1337
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
|
|
1338
|
+
return {
|
|
1339
|
+
error: `
|
|
1340
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Invalid email format: '${colors_1.Colors.Bright}${value}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
1341
|
+
${colors_1.Colors.FgGray} Expected: user@domain.com${colors_1.Colors.Reset}
|
|
1342
|
+
`
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
return { value };
|
|
1346
|
+
case interfaces_1.ParamType.Url:
|
|
1347
|
+
if (!/^https?:\/\/.+$/.test(value)) {
|
|
1348
|
+
return {
|
|
1349
|
+
error: `
|
|
1350
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Invalid URL format: '${colors_1.Colors.Bright}${value}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
1351
|
+
${colors_1.Colors.FgGray} Expected: https://example.com or http://example.com${colors_1.Colors.Reset}
|
|
1352
|
+
`
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
return { value };
|
|
1356
|
+
case interfaces_1.ParamType.Package:
|
|
1357
|
+
if (!/^@[a-zA-Z0-9-]+\/[a-zA-Z0-9-]+$/.test(value)) {
|
|
1358
|
+
return {
|
|
1359
|
+
error: `
|
|
1360
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Invalid package format: '${colors_1.Colors.Bright}${value}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
1361
|
+
${colors_1.Colors.FgGray} Expected: @company/package-name${colors_1.Colors.Reset}
|
|
1362
|
+
`
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
return { value };
|
|
1366
|
+
case interfaces_1.ParamType.Password:
|
|
1367
|
+
if (this.checkEmpty(value) && isRequired) {
|
|
1368
|
+
return {
|
|
1369
|
+
error: `
|
|
1370
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Password cannot be empty${colors_1.Colors.Reset}
|
|
1371
|
+
`
|
|
1372
|
+
};
|
|
1373
|
+
}
|
|
1374
|
+
return { value };
|
|
1375
|
+
default:
|
|
1376
|
+
return { value };
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
checkEmpty(value) {
|
|
1380
|
+
return value === undefined || value === "" || value === null;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
exports2.Validator = Validator;
|
|
1384
|
+
});
|
|
1385
|
+
|
|
1386
|
+
// node_modules/@ideascol/cli-maker/dist/setup.js
|
|
1387
|
+
var require_setup = __commonJS((exports2) => {
|
|
1388
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
1389
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
|
1390
|
+
};
|
|
1391
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1392
|
+
exports2.createSetupCommand = createSetupCommand;
|
|
1393
|
+
exports2.loadSetupConfig = loadSetupConfig;
|
|
1394
|
+
exports2.getRawConfig = getRawConfig;
|
|
1395
|
+
exports2.getConfigValue = getConfigValue;
|
|
1396
|
+
exports2.hiddenPrompt = hiddenPrompt;
|
|
1397
|
+
exports2.prompt = prompt;
|
|
1398
|
+
var fs_1 = __importDefault(require("fs"));
|
|
1399
|
+
var path_1 = __importDefault(require("path"));
|
|
1400
|
+
var readline_1 = __importDefault(require("readline"));
|
|
1401
|
+
var crypto_1 = __importDefault(require("crypto"));
|
|
1402
|
+
var os_1 = __importDefault(require("os"));
|
|
1403
|
+
var colors_1 = require_colors();
|
|
1404
|
+
var interfaces_1 = require_interfaces();
|
|
1405
|
+
var validator_1 = require_validator();
|
|
1406
|
+
function createSetupCommand(cliName, options) {
|
|
1407
|
+
const commandName = options.name || "setup";
|
|
1408
|
+
const description = options.description || "Configure CLI defaults";
|
|
1409
|
+
const validator = new validator_1.Validator;
|
|
1410
|
+
const configFile = buildConfigPath(cliName, options.configFileName);
|
|
1411
|
+
return {
|
|
1412
|
+
name: commandName,
|
|
1413
|
+
description,
|
|
1414
|
+
params: [
|
|
1415
|
+
{
|
|
1416
|
+
name: "interactive",
|
|
1417
|
+
description: "Select a single config option to setup interactively",
|
|
1418
|
+
required: false,
|
|
1419
|
+
type: interfaces_1.ParamType.Boolean
|
|
1420
|
+
}
|
|
1421
|
+
],
|
|
1422
|
+
action: async (args) => {
|
|
1423
|
+
let passphrase;
|
|
1424
|
+
let existingConfig = {};
|
|
1425
|
+
const hasExistingConfig = fs_1.default.existsSync(configFile);
|
|
1426
|
+
let hasEncryptedFields = false;
|
|
1427
|
+
if (hasExistingConfig) {
|
|
1428
|
+
try {
|
|
1429
|
+
const rawConfig = JSON.parse(fs_1.default.readFileSync(configFile, "utf-8"));
|
|
1430
|
+
hasEncryptedFields = Object.values(rawConfig).some((value) => value && typeof value === "object" && (value.__enc || value.__b64));
|
|
1431
|
+
} catch {}
|
|
1432
|
+
}
|
|
1433
|
+
if (hasEncryptedFields || options.encryption?.enabled) {
|
|
1434
|
+
if (hasEncryptedFields) {
|
|
1435
|
+
let validPassphrase = false;
|
|
1436
|
+
while (!validPassphrase) {
|
|
1437
|
+
passphrase = await askPassphrase(options.encryption?.prompt || "Passphrase to decrypt existing config");
|
|
1438
|
+
if (!passphrase) {
|
|
1439
|
+
console.log(`${colors_1.Colors.Error}❌ Passphrase is required to modify encrypted configuration.${colors_1.Colors.Reset}
|
|
1440
|
+
`);
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
const testConfig = loadConfig(configFile, options.steps, passphrase);
|
|
1444
|
+
const rawConfig = JSON.parse(fs_1.default.readFileSync(configFile, "utf-8"));
|
|
1445
|
+
const encryptedKeys = Object.keys(rawConfig).filter((key) => {
|
|
1446
|
+
const value = rawConfig[key];
|
|
1447
|
+
return value && typeof value === "object" && (value.__enc || value.__b64);
|
|
1448
|
+
});
|
|
1449
|
+
if (encryptedKeys.length > 0) {
|
|
1450
|
+
const successfullyDecrypted = encryptedKeys.some((key) => testConfig[key] !== undefined && typeof testConfig[key] === "string");
|
|
1451
|
+
if (successfullyDecrypted) {
|
|
1452
|
+
validPassphrase = true;
|
|
1453
|
+
existingConfig = testConfig;
|
|
1454
|
+
} else {
|
|
1455
|
+
console.log(`${colors_1.Colors.Error}❌ Invalid passphrase. Please try again.${colors_1.Colors.Reset}
|
|
1456
|
+
`);
|
|
1457
|
+
}
|
|
1458
|
+
} else {
|
|
1459
|
+
validPassphrase = true;
|
|
1460
|
+
existingConfig = testConfig;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
} else {
|
|
1464
|
+
passphrase = await askPassphrase(options.encryption?.prompt || "Passphrase for encryption (not stored)");
|
|
1465
|
+
if (!passphrase) {
|
|
1466
|
+
console.log(`${colors_1.Colors.Error}❌ Passphrase is required for encrypted configuration.${colors_1.Colors.Reset}
|
|
1467
|
+
`);
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
} else {
|
|
1472
|
+
existingConfig = loadConfig(configFile, options.steps, passphrase);
|
|
1473
|
+
}
|
|
1474
|
+
const answers = { ...existingConfig };
|
|
1475
|
+
if (args?.interactive === true) {
|
|
1476
|
+
console.log(`
|
|
1477
|
+
${colors_1.Colors.BgBlue}${colors_1.Colors.FgWhite} SETUP ${colors_1.Colors.Reset} ${colors_1.Colors.FgBlue}Select a configuration to setup${colors_1.Colors.Reset}
|
|
1478
|
+
`);
|
|
1479
|
+
const selectedStep = await selectSingleConfigStep(options.steps, existingConfig);
|
|
1480
|
+
if (selectedStep) {
|
|
1481
|
+
const value = await askForStep(selectedStep, answers[selectedStep.name], validator);
|
|
1482
|
+
if (value !== undefined) {
|
|
1483
|
+
answers[selectedStep.name] = value;
|
|
1484
|
+
}
|
|
1485
|
+
ensureDir(path_1.default.dirname(configFile));
|
|
1486
|
+
const encoded = encodePasswords(options.steps, answers, passphrase);
|
|
1487
|
+
fs_1.default.writeFileSync(configFile, JSON.stringify(encoded, null, 2), "utf-8");
|
|
1488
|
+
console.log(`
|
|
1489
|
+
${colors_1.Colors.Success}✅ Config '${selectedStep.name}' updated in ${configFile}${colors_1.Colors.Reset}
|
|
1490
|
+
`);
|
|
1491
|
+
} else {
|
|
1492
|
+
console.log(`
|
|
1493
|
+
${colors_1.Colors.Warning}Setup cancelled.${colors_1.Colors.Reset}
|
|
1494
|
+
`);
|
|
1495
|
+
}
|
|
1496
|
+
} else {
|
|
1497
|
+
console.log(`
|
|
1498
|
+
${colors_1.Colors.BgBlue}${colors_1.Colors.FgWhite} SETUP ${colors_1.Colors.Reset} ${colors_1.Colors.FgBlue}Configure your CLI step by step${colors_1.Colors.Reset}
|
|
1499
|
+
`);
|
|
1500
|
+
for (const step of options.steps) {
|
|
1501
|
+
const value = await askForStep(step, answers[step.name], validator);
|
|
1502
|
+
if (value !== undefined) {
|
|
1503
|
+
answers[step.name] = value;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
ensureDir(path_1.default.dirname(configFile));
|
|
1507
|
+
const encoded = encodePasswords(options.steps, answers, passphrase);
|
|
1508
|
+
fs_1.default.writeFileSync(configFile, JSON.stringify(encoded, null, 2), "utf-8");
|
|
1509
|
+
console.log(`
|
|
1510
|
+
${colors_1.Colors.Success}✅ Config stored in ${configFile}${colors_1.Colors.Reset}
|
|
1511
|
+
`);
|
|
1512
|
+
}
|
|
1513
|
+
if (options.onComplete) {
|
|
1514
|
+
options.onComplete(answers);
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
function loadSetupConfig(cliName, steps, options) {
|
|
1520
|
+
const configFile = buildConfigPath(cliName, options?.configFileName);
|
|
1521
|
+
return loadConfig(configFile, steps, options?.passphrase);
|
|
1522
|
+
}
|
|
1523
|
+
function getRawConfig(cliName, options) {
|
|
1524
|
+
const configFile = buildConfigPath(cliName, options?.configFileName);
|
|
1525
|
+
try {
|
|
1526
|
+
if (fs_1.default.existsSync(configFile)) {
|
|
1527
|
+
return JSON.parse(fs_1.default.readFileSync(configFile, "utf-8"));
|
|
132
1528
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
1529
|
+
} catch {}
|
|
1530
|
+
return {};
|
|
1531
|
+
}
|
|
1532
|
+
function getConfigValue(cliName, key, options) {
|
|
1533
|
+
const config = getRawConfig(cliName, options);
|
|
1534
|
+
return config[key];
|
|
1535
|
+
}
|
|
1536
|
+
function buildConfigPath(cliName, customName) {
|
|
1537
|
+
const safeName = (customName || `${cliName}-config.json`).replace(/[^a-z0-9._-]/gi, "-");
|
|
1538
|
+
const home = os_1.default.homedir();
|
|
1539
|
+
return path_1.default.join(home, ".cli-maker", safeName);
|
|
1540
|
+
}
|
|
1541
|
+
function loadConfig(file, steps, passphrase) {
|
|
1542
|
+
try {
|
|
1543
|
+
if (fs_1.default.existsSync(file)) {
|
|
1544
|
+
const raw = JSON.parse(fs_1.default.readFileSync(file, "utf-8"));
|
|
1545
|
+
return decodePasswords(steps, raw, passphrase);
|
|
1546
|
+
}
|
|
1547
|
+
} catch {}
|
|
1548
|
+
return {};
|
|
1549
|
+
}
|
|
1550
|
+
function ensureDir(dir) {
|
|
1551
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
1552
|
+
}
|
|
1553
|
+
async function askForStep(step, existing, validator) {
|
|
1554
|
+
let rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
1555
|
+
const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
|
|
1556
|
+
const label = `${colors_1.Colors.Bright}${step.name}${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}(${step.description})${colors_1.Colors.Reset}`;
|
|
1557
|
+
console.log(label);
|
|
1558
|
+
if (step.options && step.options.length > 0) {
|
|
1559
|
+
console.log(`${colors_1.Colors.FgGray}Opciones: ${step.options.join(", ")}${colors_1.Colors.Reset}`);
|
|
1560
|
+
}
|
|
1561
|
+
if (existing !== undefined) {
|
|
1562
|
+
const display = step.type === interfaces_1.ParamType.Password ? "********" : existing;
|
|
1563
|
+
console.log(`${colors_1.Colors.FgYellow}Actual value:${colors_1.Colors.Reset} ${display}`);
|
|
1564
|
+
} else if (step.defaultValue !== undefined) {
|
|
1565
|
+
const displayDefault = step.type === interfaces_1.ParamType.Password ? "********" : step.defaultValue;
|
|
1566
|
+
console.log(`${colors_1.Colors.FgYellow}Default value:${colors_1.Colors.Reset} ${displayDefault}`);
|
|
1567
|
+
}
|
|
1568
|
+
let finalValue;
|
|
1569
|
+
let done = false;
|
|
1570
|
+
while (!done) {
|
|
1571
|
+
if (step.type === interfaces_1.ParamType.List && step.options && step.options.length > 0) {
|
|
1572
|
+
const chosen = await askListOption(step, rl);
|
|
1573
|
+
finalValue = step.options[chosen];
|
|
1574
|
+
done = true;
|
|
1575
|
+
} else {
|
|
1576
|
+
const prompt2 = `${colors_1.Colors.FgGreen}>${colors_1.Colors.Reset} `;
|
|
1577
|
+
let input;
|
|
1578
|
+
if (step.type === interfaces_1.ParamType.Password) {
|
|
1579
|
+
rl.close();
|
|
1580
|
+
input = await readHiddenInput(prompt2);
|
|
1581
|
+
rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
1582
|
+
} else {
|
|
1583
|
+
input = await ask(prompt2);
|
|
1584
|
+
}
|
|
1585
|
+
const candidateRaw = input === "" ? existing ?? step.defaultValue ?? "" : input;
|
|
1586
|
+
const candidate = typeof candidateRaw === "boolean" ? String(candidateRaw) : candidateRaw;
|
|
1587
|
+
const validation = validator.validateParam(candidate, step.type, step.required, step.options, step.name);
|
|
1588
|
+
if (validation.error) {
|
|
1589
|
+
console.log(validation.error);
|
|
1590
|
+
} else {
|
|
1591
|
+
finalValue = validation.value;
|
|
1592
|
+
done = true;
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
rl.close();
|
|
1597
|
+
return finalValue;
|
|
1598
|
+
}
|
|
1599
|
+
async function selectSingleConfigStep(steps, existingConfig) {
|
|
1600
|
+
console.log(`${colors_1.Colors.FgYellow}Available configuration options:${colors_1.Colors.Reset}
|
|
1601
|
+
`);
|
|
1602
|
+
console.log(`${colors_1.Colors.FgGray}Use ↑/↓ arrows to navigate, Enter to select, or 'q' to cancel${colors_1.Colors.Reset}
|
|
1603
|
+
`);
|
|
1604
|
+
const options = [...steps, { name: "Cancel", description: "Exit setup", type: interfaces_1.ParamType.Text }];
|
|
1605
|
+
let selectedIndex = 0;
|
|
1606
|
+
const renderMenu = () => {
|
|
1607
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
1608
|
+
console.log(`${colors_1.Colors.FgYellow}Available configuration options:${colors_1.Colors.Reset}
|
|
1609
|
+
`);
|
|
1610
|
+
console.log(`${colors_1.Colors.FgGray}Use ↑/↓ arrows to navigate, Enter to select, or 'q' to cancel${colors_1.Colors.Reset}
|
|
1611
|
+
`);
|
|
1612
|
+
options.forEach((option, idx) => {
|
|
1613
|
+
const isSelected = idx === selectedIndex;
|
|
1614
|
+
const prefix = isSelected ? `${colors_1.Colors.BgBlue}${colors_1.Colors.FgWhite} ▶ ${colors_1.Colors.Reset}` : " ";
|
|
1615
|
+
if (idx < steps.length) {
|
|
1616
|
+
const step = steps[idx];
|
|
1617
|
+
const hasValue = existingConfig[step.name] !== undefined;
|
|
1618
|
+
const statusIcon = hasValue ? `${colors_1.Colors.FgGreen}✓${colors_1.Colors.Reset}` : `${colors_1.Colors.FgGray}○${colors_1.Colors.Reset}`;
|
|
1619
|
+
const valueDisplay = hasValue ? step.type === interfaces_1.ParamType.Password ? " (configured)" : ` (${existingConfig[step.name]})` : " (not set)";
|
|
1620
|
+
const highlight = isSelected ? `${colors_1.Colors.BgBlue}${colors_1.Colors.FgWhite}` : "";
|
|
1621
|
+
const resetColor = isSelected ? `${colors_1.Colors.Reset}` : "";
|
|
1622
|
+
console.log(`${prefix}${highlight}${statusIcon} ${colors_1.Colors.Bright}${step.name}${colors_1.Colors.Reset}${highlight} - ${step.description}${colors_1.Colors.FgGray}${valueDisplay}${resetColor}${colors_1.Colors.Reset}`);
|
|
1623
|
+
} else {
|
|
1624
|
+
const highlight = isSelected ? `${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite}` : `${colors_1.Colors.FgRed}`;
|
|
1625
|
+
const resetColor = isSelected ? `${colors_1.Colors.Reset}` : `${colors_1.Colors.Reset}`;
|
|
1626
|
+
console.log(`${prefix}${highlight}Cancel${resetColor}`);
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1629
|
+
console.log(`
|
|
1630
|
+
${colors_1.Colors.FgGray}Selected: ${options[selectedIndex].name}${colors_1.Colors.Reset}`);
|
|
1631
|
+
};
|
|
1632
|
+
return new Promise((resolve) => {
|
|
1633
|
+
process.stdin.setRawMode(true);
|
|
1634
|
+
process.stdin.resume();
|
|
1635
|
+
process.stdin.setEncoding("utf8");
|
|
1636
|
+
renderMenu();
|
|
1637
|
+
const onKeyPress = (key) => {
|
|
1638
|
+
switch (key) {
|
|
1639
|
+
case "\x1B[A":
|
|
1640
|
+
selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : options.length - 1;
|
|
1641
|
+
renderMenu();
|
|
1642
|
+
break;
|
|
1643
|
+
case "\x1B[B":
|
|
1644
|
+
selectedIndex = selectedIndex < options.length - 1 ? selectedIndex + 1 : 0;
|
|
1645
|
+
renderMenu();
|
|
1646
|
+
break;
|
|
1647
|
+
case "\r":
|
|
1648
|
+
process.stdin.setRawMode(false);
|
|
1649
|
+
process.stdin.removeListener("data", onKeyPress);
|
|
1650
|
+
process.stdin.pause();
|
|
1651
|
+
if (selectedIndex === steps.length) {
|
|
1652
|
+
resolve(null);
|
|
144
1653
|
} else {
|
|
145
|
-
|
|
1654
|
+
resolve(steps[selectedIndex]);
|
|
146
1655
|
}
|
|
1656
|
+
break;
|
|
1657
|
+
case "q":
|
|
1658
|
+
case "Q":
|
|
1659
|
+
case "\x03":
|
|
1660
|
+
process.stdin.setRawMode(false);
|
|
1661
|
+
process.stdin.removeListener("data", onKeyPress);
|
|
1662
|
+
process.stdin.pause();
|
|
1663
|
+
resolve(null);
|
|
1664
|
+
break;
|
|
1665
|
+
default:
|
|
1666
|
+
break;
|
|
1667
|
+
}
|
|
1668
|
+
};
|
|
1669
|
+
process.stdin.on("data", onKeyPress);
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1672
|
+
async function askListOption(step, rl) {
|
|
1673
|
+
const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
|
|
1674
|
+
step.options = step.options || [];
|
|
1675
|
+
step.options.forEach((opt, idx) => {
|
|
1676
|
+
console.log(` ${colors_1.Colors.FgCyan}${idx + 1}.${colors_1.Colors.Reset} ${opt}`);
|
|
1677
|
+
});
|
|
1678
|
+
let selected = -1;
|
|
1679
|
+
while (selected < 0 || selected >= step.options.length) {
|
|
1680
|
+
const answer = await ask(`${colors_1.Colors.FgGreen}Select option (1-${step.options.length}):${colors_1.Colors.Reset} `);
|
|
1681
|
+
const num = parseInt(answer, 10);
|
|
1682
|
+
if (!isNaN(num) && num >= 1 && num <= step.options.length) {
|
|
1683
|
+
selected = num - 1;
|
|
1684
|
+
} else {
|
|
1685
|
+
console.log(`${colors_1.Colors.Warning}Invalid option.${colors_1.Colors.Reset}`);
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
return selected;
|
|
1689
|
+
}
|
|
1690
|
+
function encodePasswords(steps, data, passphrase) {
|
|
1691
|
+
const result = { ...data };
|
|
1692
|
+
steps.forEach((step) => {
|
|
1693
|
+
if (step.type === interfaces_1.ParamType.Password && result[step.name] !== undefined) {
|
|
1694
|
+
const str = String(result[step.name]);
|
|
1695
|
+
if (passphrase) {
|
|
1696
|
+
result[step.name] = encryptWithPassphrase(str, passphrase);
|
|
1697
|
+
} else {
|
|
1698
|
+
result[step.name] = { __b64: true, value: Buffer.from(str, "utf-8").toString("base64") };
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
});
|
|
1702
|
+
return result;
|
|
1703
|
+
}
|
|
1704
|
+
function decodePasswords(steps, data, passphrase) {
|
|
1705
|
+
const result = { ...data };
|
|
1706
|
+
steps.forEach((step) => {
|
|
1707
|
+
const value = result[step.name];
|
|
1708
|
+
if (step.type === interfaces_1.ParamType.Password && value && typeof value === "object") {
|
|
1709
|
+
if (value.__enc && value.data && passphrase) {
|
|
1710
|
+
const decrypted = decryptWithPassphrase(value, passphrase);
|
|
1711
|
+
result[step.name] = decrypted;
|
|
1712
|
+
} else if (value.__b64 && value.value) {
|
|
1713
|
+
try {
|
|
1714
|
+
result[step.name] = Buffer.from(value.value, "base64").toString("utf-8");
|
|
147
1715
|
} catch {
|
|
148
|
-
|
|
1716
|
+
result[step.name] = undefined;
|
|
149
1717
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
});
|
|
1721
|
+
return result;
|
|
1722
|
+
}
|
|
1723
|
+
async function hiddenPrompt(prompt2) {
|
|
1724
|
+
return readHiddenInput(prompt2);
|
|
1725
|
+
}
|
|
1726
|
+
async function prompt(question) {
|
|
1727
|
+
return new Promise((resolve) => {
|
|
1728
|
+
const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
1729
|
+
rl.question(question, (answer) => {
|
|
1730
|
+
rl.close();
|
|
1731
|
+
resolve(answer);
|
|
1732
|
+
});
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
async function readHiddenInput(prompt2) {
|
|
1736
|
+
return new Promise((resolve) => {
|
|
1737
|
+
const stdin = process.stdin;
|
|
1738
|
+
const stdout = process.stdout;
|
|
1739
|
+
stdout.write(prompt2);
|
|
1740
|
+
const onData = (char) => {
|
|
1741
|
+
const key = char.toString();
|
|
1742
|
+
if (key === `
|
|
1743
|
+
` || key === "\r" || key === "\x04") {
|
|
1744
|
+
stdout.write(`
|
|
1745
|
+
`);
|
|
1746
|
+
stdin.removeListener("data", onData);
|
|
1747
|
+
if (stdin.isTTY)
|
|
1748
|
+
stdin.setRawMode(false);
|
|
1749
|
+
stdin.pause();
|
|
1750
|
+
resolve(buffer);
|
|
1751
|
+
} else if (key === "\x03") {
|
|
1752
|
+
stdin.removeListener("data", onData);
|
|
1753
|
+
if (stdin.isTTY)
|
|
1754
|
+
stdin.setRawMode(false);
|
|
1755
|
+
stdin.pause();
|
|
1756
|
+
process.exit(0);
|
|
1757
|
+
} else if (key === "" || key === "\b") {
|
|
1758
|
+
if (buffer.length > 0) {
|
|
1759
|
+
buffer = buffer.slice(0, -1);
|
|
1760
|
+
stdout.write("\b \b");
|
|
153
1761
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
1762
|
+
} else {
|
|
1763
|
+
const printableChars = key.split("").filter((c) => c >= " " && c <= "~").join("");
|
|
1764
|
+
if (printableChars.length > 0) {
|
|
1765
|
+
buffer += printableChars;
|
|
1766
|
+
stdout.write("*".repeat(printableChars.length));
|
|
157
1767
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
let buffer = "";
|
|
1771
|
+
stdin.resume();
|
|
1772
|
+
if (stdin.isTTY) {
|
|
1773
|
+
stdin.setRawMode(true);
|
|
1774
|
+
}
|
|
1775
|
+
stdin.on("data", onData);
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
function encryptWithPassphrase(plain, passphrase) {
|
|
1779
|
+
const salt = crypto_1.default.randomBytes(16);
|
|
1780
|
+
const iv = crypto_1.default.randomBytes(12);
|
|
1781
|
+
const key = crypto_1.default.pbkdf2Sync(passphrase, salt, 120000, 32, "sha256");
|
|
1782
|
+
const cipher = crypto_1.default.createCipheriv("aes-256-gcm", key, iv);
|
|
1783
|
+
const encrypted = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
|
|
1784
|
+
const tag = cipher.getAuthTag();
|
|
1785
|
+
return {
|
|
1786
|
+
__enc: true,
|
|
1787
|
+
alg: "aes-256-gcm",
|
|
1788
|
+
iv: iv.toString("base64"),
|
|
1789
|
+
salt: salt.toString("base64"),
|
|
1790
|
+
tag: tag.toString("base64"),
|
|
1791
|
+
data: encrypted.toString("base64")
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
function decryptWithPassphrase(payload, passphrase) {
|
|
1795
|
+
try {
|
|
1796
|
+
const salt = Buffer.from(payload.salt, "base64");
|
|
1797
|
+
const iv = Buffer.from(payload.iv, "base64");
|
|
1798
|
+
const tag = Buffer.from(payload.tag, "base64");
|
|
1799
|
+
const data = Buffer.from(payload.data, "base64");
|
|
1800
|
+
const key = crypto_1.default.pbkdf2Sync(passphrase, salt, 120000, 32, "sha256");
|
|
1801
|
+
const decipher = crypto_1.default.createDecipheriv("aes-256-gcm", key, iv);
|
|
1802
|
+
decipher.setAuthTag(tag);
|
|
1803
|
+
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
|
|
1804
|
+
return decrypted.toString("utf8");
|
|
1805
|
+
} catch {
|
|
1806
|
+
return;
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
async function askPassphrase(promptText) {
|
|
1810
|
+
const pass = await readHiddenInput(`${colors_1.Colors.FgCyan}${promptText}:${colors_1.Colors.Reset} `);
|
|
1811
|
+
return pass || undefined;
|
|
1812
|
+
}
|
|
1813
|
+
});
|
|
1814
|
+
|
|
1815
|
+
// node_modules/@ideascol/cli-maker/dist/rotate-passphrase.js
|
|
1816
|
+
var require_rotate_passphrase = __commonJS((exports2) => {
|
|
1817
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
1818
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
|
1819
|
+
};
|
|
1820
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1821
|
+
exports2.createRotatePassphraseCommand = createRotatePassphraseCommand;
|
|
1822
|
+
var interfaces_1 = require_interfaces();
|
|
1823
|
+
var colors_1 = require_colors();
|
|
1824
|
+
var setup_1 = require_setup();
|
|
1825
|
+
var fs_1 = __importDefault(require("fs"));
|
|
1826
|
+
var path_1 = __importDefault(require("path"));
|
|
1827
|
+
var os_1 = __importDefault(require("os"));
|
|
1828
|
+
var crypto_1 = __importDefault(require("crypto"));
|
|
1829
|
+
function createRotatePassphraseCommand(cliName) {
|
|
1830
|
+
return {
|
|
1831
|
+
name: "rotate-passphrase",
|
|
1832
|
+
description: "Rotate the passphrase used to encrypt configuration values",
|
|
1833
|
+
params: [
|
|
1834
|
+
{
|
|
1835
|
+
name: "config-file",
|
|
1836
|
+
description: "Specific config file to rotate passphrase for (optional)",
|
|
1837
|
+
required: false,
|
|
1838
|
+
type: interfaces_1.ParamType.Text
|
|
1839
|
+
},
|
|
1840
|
+
{
|
|
1841
|
+
name: "create-backup",
|
|
1842
|
+
description: "Create backup file before rotation (less secure but allows recovery)",
|
|
1843
|
+
required: false,
|
|
1844
|
+
type: interfaces_1.ParamType.Boolean
|
|
1845
|
+
},
|
|
1846
|
+
{
|
|
1847
|
+
name: "secure-delete-backup",
|
|
1848
|
+
description: "Securely delete backup after successful rotation (only works with --create-backup)",
|
|
1849
|
+
required: false,
|
|
1850
|
+
type: interfaces_1.ParamType.Boolean
|
|
1851
|
+
}
|
|
1852
|
+
],
|
|
1853
|
+
action: async (args) => {
|
|
1854
|
+
const configFileName = args["config-file"];
|
|
1855
|
+
console.log(`
|
|
1856
|
+
${colors_1.Colors.BgYellow}${colors_1.Colors.FgBlack} ROTATE PASSPHRASE ${colors_1.Colors.Reset} ${colors_1.Colors.FgYellow}Updating encryption passphrase${colors_1.Colors.Reset}
|
|
1857
|
+
`);
|
|
1858
|
+
const configFile = buildConfigPath(cliName, configFileName);
|
|
1859
|
+
if (!fs_1.default.existsSync(configFile)) {
|
|
1860
|
+
console.log(`${colors_1.Colors.Error}❌ Config file not found: ${configFile}${colors_1.Colors.Reset}
|
|
1861
|
+
`);
|
|
1862
|
+
console.log(`${colors_1.Colors.FgGray}Run the setup command first to create a configuration.${colors_1.Colors.Reset}
|
|
1863
|
+
`);
|
|
1864
|
+
return;
|
|
1865
|
+
}
|
|
1866
|
+
const rawConfig = JSON.parse(fs_1.default.readFileSync(configFile, "utf-8"));
|
|
1867
|
+
const hasEncryptedFields = Object.values(rawConfig).some((value) => value && typeof value === "object" && (value.__enc || value.__b64));
|
|
1868
|
+
if (!hasEncryptedFields) {
|
|
1869
|
+
console.log(`${colors_1.Colors.Warning}⚠️ No encrypted fields found in config file.${colors_1.Colors.Reset}
|
|
1870
|
+
`);
|
|
1871
|
+
console.log(`${colors_1.Colors.FgGray}The configuration doesn't contain any password fields that require encryption.${colors_1.Colors.Reset}
|
|
1872
|
+
`);
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
try {
|
|
1876
|
+
console.log(`${colors_1.Colors.FgCyan}Enter current passphrase to decrypt existing configuration:${colors_1.Colors.Reset}`);
|
|
1877
|
+
const currentPassphrase = await (0, setup_1.hiddenPrompt)("Current passphrase: ");
|
|
1878
|
+
if (!currentPassphrase) {
|
|
1879
|
+
console.log(`${colors_1.Colors.Error}❌ Current passphrase is required.${colors_1.Colors.Reset}
|
|
1880
|
+
`);
|
|
1881
|
+
return;
|
|
162
1882
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
1883
|
+
const decryptedConfig = await tryDecryptConfig(rawConfig, currentPassphrase);
|
|
1884
|
+
if (!decryptedConfig) {
|
|
1885
|
+
console.log(`${colors_1.Colors.Error}❌ Invalid current passphrase. Unable to decrypt configuration.${colors_1.Colors.Reset}
|
|
1886
|
+
`);
|
|
1887
|
+
return;
|
|
167
1888
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
1889
|
+
console.log(`
|
|
1890
|
+
${colors_1.Colors.FgCyan}Enter new passphrase for encryption:${colors_1.Colors.Reset}`);
|
|
1891
|
+
const newPassphrase = await (0, setup_1.hiddenPrompt)("New passphrase: ");
|
|
1892
|
+
if (!newPassphrase) {
|
|
1893
|
+
console.log(`${colors_1.Colors.Error}❌ New passphrase is required.${colors_1.Colors.Reset}
|
|
1894
|
+
`);
|
|
1895
|
+
return;
|
|
172
1896
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return
|
|
1897
|
+
if (newPassphrase === currentPassphrase) {
|
|
1898
|
+
console.log(`${colors_1.Colors.Warning}⚠️ New passphrase is the same as current passphrase.${colors_1.Colors.Reset}
|
|
1899
|
+
`);
|
|
1900
|
+
return;
|
|
177
1901
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
1902
|
+
console.log(`${colors_1.Colors.FgCyan}Confirm new passphrase:${colors_1.Colors.Reset}`);
|
|
1903
|
+
const confirmPassphrase = await (0, setup_1.hiddenPrompt)("Confirm new passphrase: ");
|
|
1904
|
+
if (newPassphrase !== confirmPassphrase) {
|
|
1905
|
+
console.log(`${colors_1.Colors.Error}❌ Passphrases do not match.${colors_1.Colors.Reset}
|
|
1906
|
+
`);
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
const reencryptedConfig = reencryptConfig(rawConfig, decryptedConfig, newPassphrase);
|
|
1910
|
+
let backupFile = null;
|
|
1911
|
+
if (args["create-backup"]) {
|
|
1912
|
+
backupFile = `${configFile}.backup.${Date.now()}`;
|
|
1913
|
+
fs_1.default.copyFileSync(configFile, backupFile);
|
|
1914
|
+
console.log(`${colors_1.Colors.FgGray}\uD83D\uDCC1 Backup created: ${backupFile}${colors_1.Colors.Reset}`);
|
|
1915
|
+
if (args["secure-delete-backup"]) {
|
|
1916
|
+
console.log(`${colors_1.Colors.FgYellow}⚠️ Backup will be securely deleted after successful rotation.${colors_1.Colors.Reset}`);
|
|
1917
|
+
}
|
|
1918
|
+
} else {
|
|
1919
|
+
console.log(`${colors_1.Colors.FgGreen}\uD83D\uDD12 No backup created (secure by default).${colors_1.Colors.Reset}`);
|
|
1920
|
+
if (args["secure-delete-backup"]) {
|
|
1921
|
+
console.log(`${colors_1.Colors.FgYellow}⚠️ --secure-delete-backup ignored (no backup created).${colors_1.Colors.Reset}`);
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
fs_1.default.writeFileSync(configFile, JSON.stringify(reencryptedConfig, null, 2), "utf-8");
|
|
1925
|
+
if (backupFile && args["secure-delete-backup"]) {
|
|
1926
|
+
try {
|
|
1927
|
+
secureDeleteFile(backupFile);
|
|
1928
|
+
console.log(`${colors_1.Colors.FgGray}\uD83D\uDDD1️ Backup securely deleted.${colors_1.Colors.Reset}`);
|
|
1929
|
+
} catch (error) {
|
|
1930
|
+
console.log(`${colors_1.Colors.Warning}⚠️ Warning: Could not securely delete backup file: ${backupFile}${colors_1.Colors.Reset}`);
|
|
1931
|
+
console.log(`${colors_1.Colors.FgGray}Please manually delete it: rm "${backupFile}"${colors_1.Colors.Reset}`);
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
console.log(`
|
|
1935
|
+
${colors_1.Colors.Success}✅ Passphrase rotated successfully!${colors_1.Colors.Reset}`);
|
|
1936
|
+
console.log(`${colors_1.Colors.FgGray}Configuration file: ${configFile}${colors_1.Colors.Reset}`);
|
|
1937
|
+
console.log(`${colors_1.Colors.FgGray}All encrypted fields have been re-encrypted with the new passphrase.${colors_1.Colors.Reset}`);
|
|
1938
|
+
if (backupFile && !args["secure-delete-backup"]) {
|
|
1939
|
+
console.log(`${colors_1.Colors.FgYellow}⚠️ Security reminder: Backup file contains old passphrase encryption.${colors_1.Colors.Reset}`);
|
|
1940
|
+
console.log(`${colors_1.Colors.FgGray}Consider deleting it manually: rm "${backupFile}"${colors_1.Colors.Reset}`);
|
|
1941
|
+
}
|
|
1942
|
+
console.log("");
|
|
1943
|
+
} catch (error) {
|
|
1944
|
+
console.log(`${colors_1.Colors.Error}❌ Error rotating passphrase: ${error instanceof Error ? error.message : "Unknown error"}${colors_1.Colors.Reset}
|
|
1945
|
+
`);
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
};
|
|
1949
|
+
}
|
|
1950
|
+
function buildConfigPath(cliName, customName) {
|
|
1951
|
+
const safeName = (customName || `${cliName}-config.json`).replace(/[^a-z0-9._-]/gi, "-");
|
|
1952
|
+
const home = os_1.default.homedir();
|
|
1953
|
+
return path_1.default.join(home, ".cli-maker", safeName);
|
|
1954
|
+
}
|
|
1955
|
+
async function tryDecryptConfig(rawConfig, passphrase) {
|
|
1956
|
+
try {
|
|
1957
|
+
const decrypted = { ...rawConfig };
|
|
1958
|
+
for (const [key, value] of Object.entries(rawConfig)) {
|
|
1959
|
+
if (value && typeof value === "object") {
|
|
1960
|
+
if (value.__enc && value.data) {
|
|
1961
|
+
const decryptedValue = decryptWithPassphrase(value, passphrase);
|
|
1962
|
+
if (decryptedValue === undefined) {
|
|
1963
|
+
return null;
|
|
1964
|
+
}
|
|
1965
|
+
decrypted[key] = decryptedValue;
|
|
1966
|
+
} else if (value.__b64 && value.value) {
|
|
1967
|
+
try {
|
|
1968
|
+
decrypted[key] = Buffer.from(value.value, "base64").toString("utf-8");
|
|
1969
|
+
} catch {
|
|
1970
|
+
decrypted[key] = undefined;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
181
1974
|
}
|
|
1975
|
+
return decrypted;
|
|
1976
|
+
} catch {
|
|
1977
|
+
return null;
|
|
182
1978
|
}
|
|
183
|
-
|
|
184
|
-
|
|
1979
|
+
}
|
|
1980
|
+
function reencryptConfig(rawConfig, decryptedConfig, newPassphrase) {
|
|
1981
|
+
const reencrypted = { ...rawConfig };
|
|
1982
|
+
for (const [key, value] of Object.entries(rawConfig)) {
|
|
1983
|
+
if (value && typeof value === "object" && (value.__enc || value.__b64)) {
|
|
1984
|
+
const decryptedValue = decryptedConfig[key];
|
|
1985
|
+
if (typeof decryptedValue === "string") {
|
|
1986
|
+
reencrypted[key] = encryptWithPassphrase(decryptedValue, newPassphrase);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
return reencrypted;
|
|
1991
|
+
}
|
|
1992
|
+
function encryptWithPassphrase(plain, passphrase) {
|
|
1993
|
+
const salt = crypto_1.default.randomBytes(16);
|
|
1994
|
+
const iv = crypto_1.default.randomBytes(12);
|
|
1995
|
+
const key = crypto_1.default.pbkdf2Sync(passphrase, salt, 120000, 32, "sha256");
|
|
1996
|
+
const cipher = crypto_1.default.createCipheriv("aes-256-gcm", key, iv);
|
|
1997
|
+
const encrypted = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
|
|
1998
|
+
const tag = cipher.getAuthTag();
|
|
1999
|
+
return {
|
|
2000
|
+
__enc: true,
|
|
2001
|
+
alg: "aes-256-gcm",
|
|
2002
|
+
iv: iv.toString("base64"),
|
|
2003
|
+
salt: salt.toString("base64"),
|
|
2004
|
+
tag: tag.toString("base64"),
|
|
2005
|
+
data: encrypted.toString("base64")
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
function decryptWithPassphrase(payload, passphrase) {
|
|
2009
|
+
try {
|
|
2010
|
+
const salt = Buffer.from(payload.salt, "base64");
|
|
2011
|
+
const iv = Buffer.from(payload.iv, "base64");
|
|
2012
|
+
const tag = Buffer.from(payload.tag, "base64");
|
|
2013
|
+
const data = Buffer.from(payload.data, "base64");
|
|
2014
|
+
const key = crypto_1.default.pbkdf2Sync(passphrase, salt, 120000, 32, "sha256");
|
|
2015
|
+
const decipher = crypto_1.default.createDecipheriv("aes-256-gcm", key, iv);
|
|
2016
|
+
decipher.setAuthTag(tag);
|
|
2017
|
+
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
|
|
2018
|
+
return decrypted.toString("utf8");
|
|
2019
|
+
} catch {
|
|
2020
|
+
return;
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
function secureDeleteFile(filePath) {
|
|
2024
|
+
try {
|
|
2025
|
+
const stats = fs_1.default.statSync(filePath);
|
|
2026
|
+
const fileSize = stats.size;
|
|
2027
|
+
const passes = 3;
|
|
2028
|
+
for (let i = 0;i < passes; i++) {
|
|
2029
|
+
const randomData = crypto_1.default.randomBytes(fileSize);
|
|
2030
|
+
fs_1.default.writeFileSync(filePath, randomData);
|
|
2031
|
+
fs_1.default.fsyncSync(fs_1.default.openSync(filePath, "r+"));
|
|
2032
|
+
}
|
|
2033
|
+
const zeroData = Buffer.alloc(fileSize, 0);
|
|
2034
|
+
fs_1.default.writeFileSync(filePath, zeroData);
|
|
2035
|
+
fs_1.default.fsyncSync(fs_1.default.openSync(filePath, "r+"));
|
|
2036
|
+
fs_1.default.unlinkSync(filePath);
|
|
2037
|
+
} catch (error) {
|
|
2038
|
+
throw new Error(`Failed to securely delete file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
185
2039
|
}
|
|
186
2040
|
}
|
|
187
|
-
exports2.Validator = Validator;
|
|
188
2041
|
});
|
|
189
2042
|
|
|
190
2043
|
// node_modules/@ideascol/cli-maker/dist/command/command.js
|
|
@@ -195,9 +2048,152 @@ var require_command = __commonJS((exports2) => {
|
|
|
195
2048
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
196
2049
|
exports2.CLI = undefined;
|
|
197
2050
|
var readline_1 = __importDefault(require("readline"));
|
|
2051
|
+
var fs_1 = __importDefault(require("fs"));
|
|
2052
|
+
var path_1 = __importDefault(require("path"));
|
|
2053
|
+
var os_1 = __importDefault(require("os"));
|
|
198
2054
|
var colors_1 = require_colors();
|
|
199
2055
|
var interfaces_1 = require_interfaces();
|
|
2056
|
+
var session_1 = require_session();
|
|
200
2057
|
var validator_1 = require_validator();
|
|
2058
|
+
var common_1 = require_common();
|
|
2059
|
+
var setup_1 = require_setup();
|
|
2060
|
+
var rotate_passphrase_1 = require_rotate_passphrase();
|
|
2061
|
+
function generatePixelAsciiArt(text) {
|
|
2062
|
+
const font = {
|
|
2063
|
+
A: ["███", "█ █", "███", "█ █", "█ █"],
|
|
2064
|
+
B: ["██ ", "█ █", "██ ", "█ █", "██ "],
|
|
2065
|
+
C: ["███", "█ ", "█ ", "█ ", "███"],
|
|
2066
|
+
D: ["██ ", "█ █", "█ █", "█ █", "██ "],
|
|
2067
|
+
E: ["███", "█ ", "██ ", "█ ", "███"],
|
|
2068
|
+
F: ["███", "█ ", "██ ", "█ ", "█ "],
|
|
2069
|
+
G: ["███", "█ ", "█ █", "█ █", "███"],
|
|
2070
|
+
H: ["█ █", "█ █", "███", "█ █", "█ █"],
|
|
2071
|
+
I: ["███", " █ ", " █ ", " █ ", "███"],
|
|
2072
|
+
J: ["███", " █", " █", "█ █", "███"],
|
|
2073
|
+
K: ["█ █", "██ ", "█ ", "██ ", "█ █"],
|
|
2074
|
+
L: ["█ ", "█ ", "█ ", "█ ", "███"],
|
|
2075
|
+
M: ["█ █", "███", "███", "█ █", "█ █"],
|
|
2076
|
+
N: ["█ █", "███", "███", "███", "█ █"],
|
|
2077
|
+
O: ["███", "█ █", "█ █", "█ █", "███"],
|
|
2078
|
+
P: ["██ ", "█ █", "██ ", "█ ", "█ "],
|
|
2079
|
+
Q: ["███", "█ █", "█ █", "███", " █"],
|
|
2080
|
+
R: ["██ ", "█ █", "██ ", "█ █", "█ █"],
|
|
2081
|
+
S: ["███", "█ ", "███", " █", "███"],
|
|
2082
|
+
T: ["███", " █ ", " █ ", " █ ", " █ "],
|
|
2083
|
+
U: ["█ █", "█ █", "█ █", "█ █", "███"],
|
|
2084
|
+
V: ["█ █", "█ █", "█ █", "█ █", " █ "],
|
|
2085
|
+
W: ["█ █", "█ █", "███", "███", "█ █"],
|
|
2086
|
+
X: ["█ █", "█ █", " █ ", "█ █", "█ █"],
|
|
2087
|
+
Y: ["█ █", "█ █", " █ ", " █ ", " █ "],
|
|
2088
|
+
Z: ["███", " █", " █ ", "█ ", "███"],
|
|
2089
|
+
"-": [" ", " ", "███", " ", " "],
|
|
2090
|
+
" ": [" ", " ", " ", " ", " "],
|
|
2091
|
+
"0": ["███", "█ █", "█ █", "█ █", "███"],
|
|
2092
|
+
"1": [" █ ", "██ ", " █ ", " █ ", "███"],
|
|
2093
|
+
"2": ["██ ", " █", "███", "█ ", "███"],
|
|
2094
|
+
"3": ["██ ", " █", "██ ", " █", "██ "],
|
|
2095
|
+
"4": ["█ █", "█ █", "███", " █", " █"],
|
|
2096
|
+
"5": ["███", "█ ", "██ ", " █", "██ "],
|
|
2097
|
+
"6": ["███", "█ ", "███", "█ █", "███"],
|
|
2098
|
+
"7": ["███", " █", " █ ", " █ ", " █ "],
|
|
2099
|
+
"8": ["███", "█ █", "███", "█ █", "███"],
|
|
2100
|
+
"9": ["███", "█ █", "███", " █", "███"]
|
|
2101
|
+
};
|
|
2102
|
+
const upperText = text.toUpperCase();
|
|
2103
|
+
const lines = ["", "", "", "", ""];
|
|
2104
|
+
for (let i = 0;i < upperText.length; i++) {
|
|
2105
|
+
const char = upperText[i];
|
|
2106
|
+
const charLines = font[char] || font[" "];
|
|
2107
|
+
for (let row = 0;row < 5; row++) {
|
|
2108
|
+
lines[row] += charLines[row] + " ";
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
return lines.map((line) => line.trimEnd());
|
|
2112
|
+
}
|
|
2113
|
+
var INTRO_PRESETS = {
|
|
2114
|
+
hacker: {
|
|
2115
|
+
frames: ["▌", " ", "▌", " "],
|
|
2116
|
+
padding: 1,
|
|
2117
|
+
speedMs: 120,
|
|
2118
|
+
loops: 2,
|
|
2119
|
+
lines: ["Initializing secure channel..."]
|
|
2120
|
+
},
|
|
2121
|
+
vaporwave: {
|
|
2122
|
+
frames: ["✦", "✺", "✹", "✸"],
|
|
2123
|
+
padding: 2,
|
|
2124
|
+
speedMs: 85,
|
|
2125
|
+
loops: 2,
|
|
2126
|
+
lines: ["Ride the gradient."]
|
|
2127
|
+
},
|
|
2128
|
+
radar: {
|
|
2129
|
+
frames: ["◜", "◠", "◝", "◡"],
|
|
2130
|
+
padding: 2,
|
|
2131
|
+
speedMs: 75,
|
|
2132
|
+
loops: 3,
|
|
2133
|
+
lines: ["Scanning environment..."]
|
|
2134
|
+
},
|
|
2135
|
+
pixel: {
|
|
2136
|
+
frames: ["░", "▒", "▓", "█"],
|
|
2137
|
+
padding: 1,
|
|
2138
|
+
speedMs: 70,
|
|
2139
|
+
loops: 2,
|
|
2140
|
+
lines: ["Booting 8-bit systems..."]
|
|
2141
|
+
},
|
|
2142
|
+
steampunk: {
|
|
2143
|
+
frames: ["⚙︎", "⚙", "⚙︎", "⚙"],
|
|
2144
|
+
padding: 2,
|
|
2145
|
+
speedMs: 90,
|
|
2146
|
+
loops: 2,
|
|
2147
|
+
lines: ["Warming valves..."],
|
|
2148
|
+
asciiArt: [
|
|
2149
|
+
" ___ ",
|
|
2150
|
+
" __/ o \\__",
|
|
2151
|
+
"| ⚙ ⚙ |",
|
|
2152
|
+
"‾‾‾‾‾‾‾‾‾‾‾"
|
|
2153
|
+
]
|
|
2154
|
+
},
|
|
2155
|
+
sonar: {
|
|
2156
|
+
frames: ["◉", "◎", "◉", "◎"],
|
|
2157
|
+
padding: 2,
|
|
2158
|
+
speedMs: 95,
|
|
2159
|
+
loops: 3,
|
|
2160
|
+
lines: ["Ping..."]
|
|
2161
|
+
},
|
|
2162
|
+
"retro-space": {
|
|
2163
|
+
frames: ["=≡>", "⇝◎", "⇢✸", "⇝◎"],
|
|
2164
|
+
padding: 2,
|
|
2165
|
+
speedMs: 90,
|
|
2166
|
+
loops: 3,
|
|
2167
|
+
lines: ["Scanning for lifeforms..."],
|
|
2168
|
+
asciiArt: [
|
|
2169
|
+
" /\\",
|
|
2170
|
+
" /::\\",
|
|
2171
|
+
" /::::\\",
|
|
2172
|
+
" |/::\\|",
|
|
2173
|
+
" ‾‾‾‾‾‾"
|
|
2174
|
+
]
|
|
2175
|
+
},
|
|
2176
|
+
rainbow: {
|
|
2177
|
+
frames: [
|
|
2178
|
+
`${colors_1.Colors.FgRed}◐${colors_1.Colors.Reset}`,
|
|
2179
|
+
`${colors_1.Colors.FgYellow}◐${colors_1.Colors.Reset}`,
|
|
2180
|
+
`${colors_1.Colors.FgGreen}◐${colors_1.Colors.Reset}`,
|
|
2181
|
+
`${colors_1.Colors.FgCyan}◐${colors_1.Colors.Reset}`,
|
|
2182
|
+
`${colors_1.Colors.FgBlue}◐${colors_1.Colors.Reset}`,
|
|
2183
|
+
`${colors_1.Colors.FgMagenta}◐${colors_1.Colors.Reset}`
|
|
2184
|
+
],
|
|
2185
|
+
padding: 2,
|
|
2186
|
+
speedMs: 70,
|
|
2187
|
+
loops: 2,
|
|
2188
|
+
lines: ["Painting the sky..."],
|
|
2189
|
+
asciiArt: [
|
|
2190
|
+
`${colors_1.Colors.FgRed}╭────────────────────╮${colors_1.Colors.Reset}`,
|
|
2191
|
+
`${colors_1.Colors.FgRed}│${colors_1.Colors.Reset}${colors_1.Colors.FgYellow}████${colors_1.Colors.Reset}${colors_1.Colors.FgGreen}████${colors_1.Colors.Reset}${colors_1.Colors.FgCyan}████${colors_1.Colors.Reset}${colors_1.Colors.FgBlue}████${colors_1.Colors.Reset}${colors_1.Colors.FgMagenta}████${colors_1.Colors.Reset}${colors_1.Colors.FgRed}│${colors_1.Colors.Reset}`,
|
|
2192
|
+
`${colors_1.Colors.FgRed}│${colors_1.Colors.Reset}${colors_1.Colors.FgMagenta}████${colors_1.Colors.Reset}${colors_1.Colors.FgBlue}████${colors_1.Colors.Reset}${colors_1.Colors.FgCyan}████${colors_1.Colors.Reset}${colors_1.Colors.FgGreen}████${colors_1.Colors.Reset}${colors_1.Colors.FgYellow}████${colors_1.Colors.Reset}${colors_1.Colors.FgRed}│${colors_1.Colors.Reset}`,
|
|
2193
|
+
`${colors_1.Colors.FgRed}╰────────────────────╯${colors_1.Colors.Reset}`
|
|
2194
|
+
]
|
|
2195
|
+
}
|
|
2196
|
+
};
|
|
201
2197
|
|
|
202
2198
|
class CLI {
|
|
203
2199
|
constructor(name, description, options) {
|
|
@@ -206,9 +2202,49 @@ var require_command = __commonJS((exports2) => {
|
|
|
206
2202
|
this.options = options;
|
|
207
2203
|
this.commands = [];
|
|
208
2204
|
if (this.options == null) {
|
|
209
|
-
this.options = { interactive: true, version: "1.0.0" };
|
|
2205
|
+
this.options = { interactive: true, version: "1.0.0", branding: true, introAnimation: { enabled: false, showOnce: true } };
|
|
2206
|
+
} else {
|
|
2207
|
+
if (this.options.branding === undefined) {
|
|
2208
|
+
this.options.branding = true;
|
|
2209
|
+
}
|
|
2210
|
+
if (this.options.introAnimation == null) {
|
|
2211
|
+
this.options.introAnimation = { enabled: false, showOnce: true };
|
|
2212
|
+
} else {
|
|
2213
|
+
if (this.options.introAnimation.enabled === undefined) {
|
|
2214
|
+
this.options.introAnimation.enabled = true;
|
|
2215
|
+
}
|
|
2216
|
+
if (this.options.introAnimation.showOnce === undefined) {
|
|
2217
|
+
this.options.introAnimation.showOnce = true;
|
|
2218
|
+
}
|
|
2219
|
+
if (this.options.introAnimation.introMode === undefined) {
|
|
2220
|
+
this.options.introAnimation.introMode = undefined;
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
210
2223
|
}
|
|
211
2224
|
this.validator = new validator_1.Validator;
|
|
2225
|
+
this.resolvedIntro = this.resolveIntroOptions(this.options?.introAnimation);
|
|
2226
|
+
const binName = this.getBinName();
|
|
2227
|
+
if (binName) {
|
|
2228
|
+
this.executableName = binName;
|
|
2229
|
+
} else {
|
|
2230
|
+
this.executableName = this.name;
|
|
2231
|
+
}
|
|
2232
|
+
this.commands.push((0, rotate_passphrase_1.createRotatePassphraseCommand)(this.name));
|
|
2233
|
+
}
|
|
2234
|
+
getBinName() {
|
|
2235
|
+
try {
|
|
2236
|
+
const scriptDir = path_1.default.dirname(process.argv[1]);
|
|
2237
|
+
const packageJsonPath = path_1.default.join(scriptDir, "package.json");
|
|
2238
|
+
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, "utf-8"));
|
|
2239
|
+
const bin = packageJson.bin;
|
|
2240
|
+
if (typeof bin === "string") {
|
|
2241
|
+
return bin;
|
|
2242
|
+
} else if (typeof bin === "object" && bin !== null) {
|
|
2243
|
+
const keys = Object.keys(bin);
|
|
2244
|
+
return keys.length > 0 ? keys[0] : null;
|
|
2245
|
+
}
|
|
2246
|
+
} catch (error) {}
|
|
2247
|
+
return null;
|
|
212
2248
|
}
|
|
213
2249
|
getCommands() {
|
|
214
2250
|
return this.commands;
|
|
@@ -225,102 +2261,322 @@ var require_command = __commonJS((exports2) => {
|
|
|
225
2261
|
command(command) {
|
|
226
2262
|
this.commands.push(command);
|
|
227
2263
|
}
|
|
2264
|
+
setupCommand(options) {
|
|
2265
|
+
this.setupSteps = options.steps;
|
|
2266
|
+
this.setupConfigFileName = options.configFileName;
|
|
2267
|
+
const setupCmd = (0, setup_1.createSetupCommand)(this.name, options);
|
|
2268
|
+
this.commands.push(setupCmd);
|
|
2269
|
+
return this;
|
|
2270
|
+
}
|
|
2271
|
+
async getConfigValue(key, passphrase) {
|
|
2272
|
+
if (!this.setupSteps) {
|
|
2273
|
+
const config = (0, setup_1.getRawConfig)(this.name, { configFileName: this.setupConfigFileName });
|
|
2274
|
+
return config[key];
|
|
2275
|
+
}
|
|
2276
|
+
const step = this.setupSteps.find((s) => s.name === key);
|
|
2277
|
+
const isPasswordField = step?.type === interfaces_1.ParamType.Password;
|
|
2278
|
+
if (isPasswordField) {
|
|
2279
|
+
let actualPassphrase = passphrase;
|
|
2280
|
+
if (!actualPassphrase) {
|
|
2281
|
+
actualPassphrase = process.env.CLI_PASSPHRASE;
|
|
2282
|
+
if (!actualPassphrase) {
|
|
2283
|
+
actualPassphrase = await (0, setup_1.hiddenPrompt)("Passphrase to decrypt: ");
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
const config = (0, setup_1.loadSetupConfig)(this.name, this.setupSteps, {
|
|
2287
|
+
passphrase: actualPassphrase,
|
|
2288
|
+
configFileName: this.setupConfigFileName
|
|
2289
|
+
});
|
|
2290
|
+
return config[key];
|
|
2291
|
+
} else {
|
|
2292
|
+
const config = (0, setup_1.getRawConfig)(this.name, { configFileName: this.setupConfigFileName });
|
|
2293
|
+
return config[key];
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
async loadConfig(passphrase) {
|
|
2297
|
+
if (!this.setupSteps) {
|
|
2298
|
+
return (0, setup_1.getRawConfig)(this.name, { configFileName: this.setupConfigFileName });
|
|
2299
|
+
}
|
|
2300
|
+
const hasPasswordFields = this.setupSteps.some((s) => s.type === interfaces_1.ParamType.Password);
|
|
2301
|
+
if (hasPasswordFields) {
|
|
2302
|
+
let actualPassphrase = passphrase;
|
|
2303
|
+
if (!actualPassphrase) {
|
|
2304
|
+
actualPassphrase = process.env.CLI_PASSPHRASE;
|
|
2305
|
+
if (!actualPassphrase) {
|
|
2306
|
+
actualPassphrase = await (0, setup_1.hiddenPrompt)("Passphrase to decrypt: ");
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
return (0, setup_1.loadSetupConfig)(this.name, this.setupSteps, {
|
|
2310
|
+
passphrase: actualPassphrase,
|
|
2311
|
+
configFileName: this.setupConfigFileName
|
|
2312
|
+
});
|
|
2313
|
+
} else {
|
|
2314
|
+
return (0, setup_1.getRawConfig)(this.name, { configFileName: this.setupConfigFileName });
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
async startSession(options) {
|
|
2318
|
+
const session = new session_1.InteractiveSession(options);
|
|
2319
|
+
return session.start();
|
|
2320
|
+
}
|
|
228
2321
|
setOptions(options) {
|
|
229
|
-
this.options
|
|
2322
|
+
const merged = { ...this.options, ...options };
|
|
2323
|
+
if (merged.branding === undefined) {
|
|
2324
|
+
merged.branding = true;
|
|
2325
|
+
}
|
|
2326
|
+
if (merged.introAnimation == null) {
|
|
2327
|
+
merged.introAnimation = { enabled: false, showOnce: true };
|
|
2328
|
+
} else {
|
|
2329
|
+
if (merged.introAnimation.enabled === undefined) {
|
|
2330
|
+
merged.introAnimation.enabled = true;
|
|
2331
|
+
}
|
|
2332
|
+
if (merged.introAnimation.showOnce === undefined) {
|
|
2333
|
+
merged.introAnimation.showOnce = true;
|
|
2334
|
+
}
|
|
2335
|
+
if (merged.introAnimation.introMode === undefined) {
|
|
2336
|
+
merged.introAnimation.introMode = undefined;
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
this.options = merged;
|
|
2340
|
+
this.resolvedIntro = this.resolveIntroOptions(this.options.introAnimation);
|
|
230
2341
|
}
|
|
231
2342
|
parse(argv) {
|
|
232
|
-
const [nodePath, scriptPath, ...
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
2343
|
+
const [nodePath, scriptPath, ...rawArgs] = argv;
|
|
2344
|
+
const { introMode, filteredArgs } = this.extractIntroFlags(rawArgs);
|
|
2345
|
+
const args = filteredArgs;
|
|
2346
|
+
this.showIntroIfNeeded(introMode);
|
|
2347
|
+
if (args.length === 0 || args[0] === "--version") {
|
|
2348
|
+
if (args[0] === "--version") {
|
|
236
2349
|
console.log(`
|
|
237
|
-
${colors_1.Colors.FgGreen}${this.
|
|
2350
|
+
${colors_1.Colors.FgGreen}${this.executableName} version: ${this.options?.version}${colors_1.Colors.Reset}
|
|
238
2351
|
`);
|
|
239
2352
|
} else {
|
|
240
2353
|
this.help();
|
|
241
2354
|
}
|
|
242
2355
|
return;
|
|
243
2356
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
2357
|
+
if (args.length === 1 && args[0] === "--help") {
|
|
2358
|
+
this.help();
|
|
2359
|
+
return;
|
|
2360
|
+
}
|
|
2361
|
+
const commandPath = [];
|
|
2362
|
+
let currentArgs = [...args];
|
|
2363
|
+
let i = 0;
|
|
2364
|
+
while (i < args.length) {
|
|
2365
|
+
const potentialCommand = args[i];
|
|
2366
|
+
if (potentialCommand.startsWith("--"))
|
|
2367
|
+
break;
|
|
2368
|
+
commandPath.push(potentialCommand);
|
|
2369
|
+
currentArgs = args.slice(i + 1);
|
|
2370
|
+
i++;
|
|
2371
|
+
if (commandPath.length === 1) {
|
|
2372
|
+
const rootCommand = this.findCommand(commandPath[0]);
|
|
2373
|
+
if (!rootCommand) {
|
|
2374
|
+
this.showUnknownCommandError(commandPath[0]);
|
|
2375
|
+
return;
|
|
2376
|
+
}
|
|
2377
|
+
if (!rootCommand.subcommands || i >= args.length || args[i].startsWith("--"))
|
|
2378
|
+
break;
|
|
2379
|
+
} else {
|
|
2380
|
+
const result = this.findSubcommand(commandPath);
|
|
2381
|
+
if (!result) {
|
|
2382
|
+
commandPath.pop();
|
|
2383
|
+
currentArgs = args.slice(i);
|
|
2384
|
+
break;
|
|
2385
|
+
}
|
|
2386
|
+
const { command } = result;
|
|
2387
|
+
if (!command.subcommands || i >= args.length || args[i].startsWith("--"))
|
|
2388
|
+
break;
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
if (currentArgs.includes("--help")) {
|
|
2392
|
+
if (commandPath.length === 1) {
|
|
2393
|
+
const command = this.findCommand(commandPath[0]);
|
|
2394
|
+
if (command)
|
|
2395
|
+
this.commandHelp(command, commandPath);
|
|
2396
|
+
} else if (commandPath.length > 1) {
|
|
2397
|
+
const result = this.findSubcommand(commandPath);
|
|
2398
|
+
if (result)
|
|
2399
|
+
this.commandHelp(result.command, commandPath);
|
|
2400
|
+
}
|
|
247
2401
|
return;
|
|
248
2402
|
}
|
|
249
|
-
|
|
250
|
-
|
|
2403
|
+
let commandToExecute;
|
|
2404
|
+
if (commandPath.length === 1) {
|
|
2405
|
+
commandToExecute = this.findCommand(commandPath[0]);
|
|
2406
|
+
} else if (commandPath.length > 1) {
|
|
2407
|
+
const result = this.findSubcommand(commandPath);
|
|
2408
|
+
if (result)
|
|
2409
|
+
commandToExecute = result.command;
|
|
2410
|
+
}
|
|
2411
|
+
if (!commandToExecute) {
|
|
2412
|
+
this.showUnknownCommandError(commandPath.join(" "));
|
|
251
2413
|
return;
|
|
252
2414
|
}
|
|
253
|
-
const params = this.parseArgs(
|
|
2415
|
+
const params = this.parseArgs(currentArgs, commandToExecute);
|
|
254
2416
|
if (params.error) {
|
|
255
2417
|
console.log(`
|
|
256
2418
|
${params.error}`);
|
|
257
2419
|
process.exit(1);
|
|
258
2420
|
}
|
|
259
|
-
if (Object.keys(params.result).length > 0) {
|
|
260
|
-
|
|
261
|
-
this.options.interactive = false;
|
|
262
|
-
}
|
|
2421
|
+
if (Object.keys(params.result).length > 0 && this.options.interactive) {
|
|
2422
|
+
this.options.interactive = false;
|
|
263
2423
|
}
|
|
264
|
-
const missingParams = this.getMissingParams(
|
|
2424
|
+
const missingParams = this.getMissingParams(commandToExecute, params.result);
|
|
265
2425
|
if (missingParams.length > 0 && this.options?.interactive) {
|
|
266
|
-
this.handleMissingParams(
|
|
2426
|
+
this.handleMissingParams(commandToExecute.params, params.result, commandToExecute);
|
|
267
2427
|
} else {
|
|
268
2428
|
if (missingParams.length > 0) {
|
|
269
2429
|
console.log(`
|
|
270
|
-
${colors_1.Colors.FgRed}
|
|
2430
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Missing required parameters${colors_1.Colors.Reset}
|
|
271
2431
|
`);
|
|
272
|
-
missingParams.
|
|
273
|
-
console.log(
|
|
274
|
-
console.log(`
|
|
275
|
-
console.log(` > ${colors_1.Colors.FgGray}Description: ${param.description}${colors_1.Colors.Reset}`);
|
|
2432
|
+
missingParams.forEach((param) => {
|
|
2433
|
+
console.log(`${colors_1.Colors.FgRed}❌ ${colors_1.Colors.Bright}${param.name}${colors_1.Colors.Reset}${colors_1.Colors.FgRed} (${param.type})${colors_1.Colors.Reset}`);
|
|
2434
|
+
console.log(` ${colors_1.Colors.FgGray}${param.description}${colors_1.Colors.Reset}`);
|
|
276
2435
|
if (param.options) {
|
|
277
|
-
console.log(`
|
|
2436
|
+
console.log(` ${colors_1.Colors.FgGray}Options: ${param.options.join(", ")}${colors_1.Colors.Reset}`);
|
|
278
2437
|
}
|
|
2438
|
+
console.log("");
|
|
279
2439
|
});
|
|
280
|
-
|
|
281
|
-
|
|
2440
|
+
const optionalParams = this.getOptionalParams(commandToExecute, params.result);
|
|
2441
|
+
if (optionalParams.length > 0) {
|
|
2442
|
+
console.log(`${colors_1.Colors.FgYellow}⚠️ Optional parameters you can provide:${colors_1.Colors.Reset}
|
|
2443
|
+
`);
|
|
2444
|
+
optionalParams.forEach((param) => {
|
|
2445
|
+
console.log(`${colors_1.Colors.FgYellow}○ ${param.name}${colors_1.Colors.Reset}${colors_1.Colors.FgYellow} (${param.type})${colors_1.Colors.Reset}`);
|
|
2446
|
+
console.log(` ${colors_1.Colors.FgGray}${param.description}${colors_1.Colors.Reset}`);
|
|
2447
|
+
if (param.options) {
|
|
2448
|
+
console.log(` ${colors_1.Colors.FgGray}Options: ${param.options.join(", ")}${colors_1.Colors.Reset}`);
|
|
2449
|
+
}
|
|
2450
|
+
console.log("");
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
console.log(`${colors_1.Colors.FgGray}Try '${colors_1.Colors.Bright}${this.executableName} ${commandToExecute.name} --help${colors_1.Colors.Reset}${colors_1.Colors.FgGray}' for more information.${colors_1.Colors.Reset}
|
|
282
2454
|
`);
|
|
283
|
-
this.getOptionalParams(command, params.result).map((param) => {
|
|
284
|
-
console.log(`> ${colors_1.Colors.FgYellow}${param.name}${colors_1.Colors.Reset}`);
|
|
285
|
-
console.log(` > ${colors_1.Colors.FgGray}Type: ${param.type}${colors_1.Colors.Reset}`);
|
|
286
|
-
console.log(` > ${colors_1.Colors.FgGray}Description: ${param.description}${colors_1.Colors.Reset}`);
|
|
287
|
-
if (param.options) {
|
|
288
|
-
console.log(` > ${colors_1.Colors.FgGray}Options: ${param.options}${colors_1.Colors.Reset}`);
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
2455
|
process.exit(1);
|
|
292
2456
|
}
|
|
293
|
-
|
|
2457
|
+
const actionResult = commandToExecute.action(params.result);
|
|
2458
|
+
Promise.resolve(actionResult).then(() => this.showBranding()).catch((error) => {
|
|
2459
|
+
console.error(`${colors_1.Colors.Error}❌ Command failed:${colors_1.Colors.Reset}`, error);
|
|
2460
|
+
});
|
|
294
2461
|
}
|
|
295
2462
|
}
|
|
296
2463
|
help() {
|
|
297
|
-
console.log(
|
|
298
|
-
|
|
299
|
-
console.log(
|
|
300
|
-
|
|
301
|
-
console.log(
|
|
302
|
-
console.log(
|
|
2464
|
+
console.log(`
|
|
2465
|
+
${colors_1.Colors.BgGreen}${colors_1.Colors.FgBlack} ${this.name} ${colors_1.Colors.Reset}`);
|
|
2466
|
+
console.log(`${colors_1.Colors.FgGreen}${this.description}${colors_1.Colors.Reset}
|
|
2467
|
+
`);
|
|
2468
|
+
console.log(`${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}USAGE${colors_1.Colors.Reset}`);
|
|
2469
|
+
console.log(` ${colors_1.Colors.FgGray}$ ${this.executableName} <command> [options]${colors_1.Colors.Reset}
|
|
2470
|
+
`);
|
|
2471
|
+
console.log(`${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}COMMANDS${colors_1.Colors.Reset}`);
|
|
303
2472
|
this.commands.forEach((cmd) => {
|
|
304
|
-
console.log(
|
|
2473
|
+
console.log(` ${colors_1.Colors.FgGreen}${cmd.name.padEnd(15)}${colors_1.Colors.Reset}${cmd.description}`);
|
|
2474
|
+
if (cmd.subcommands && cmd.subcommands.length > 0) {
|
|
2475
|
+
cmd.subcommands.forEach((subcmd) => {
|
|
2476
|
+
console.log(` ${colors_1.Colors.FgGreen}${cmd.name} ${subcmd.name}${colors_1.Colors.Reset}: ${subcmd.description}`);
|
|
2477
|
+
});
|
|
2478
|
+
}
|
|
305
2479
|
});
|
|
306
2480
|
console.log("");
|
|
2481
|
+
console.log(`${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}OPTIONS${colors_1.Colors.Reset}`);
|
|
2482
|
+
console.log(` ${colors_1.Colors.FgYellow}--help${colors_1.Colors.Reset}${colors_1.Colors.FgGray.padEnd(12)}Show help for a command${colors_1.Colors.Reset}`);
|
|
2483
|
+
console.log(` ${colors_1.Colors.FgYellow}--version${colors_1.Colors.Reset}${colors_1.Colors.FgGray.padEnd(10)}Show version information${colors_1.Colors.Reset}
|
|
2484
|
+
`);
|
|
2485
|
+
console.log(`${colors_1.Colors.FgGray}Run '${colors_1.Colors.Bright}${this.executableName} <command> --help${colors_1.Colors.Reset}${colors_1.Colors.FgGray}' for detailed help on a specific command.${colors_1.Colors.Reset}
|
|
2486
|
+
`);
|
|
2487
|
+
}
|
|
2488
|
+
showBranding() {
|
|
2489
|
+
if (this.options?.branding) {
|
|
2490
|
+
console.log(`
|
|
2491
|
+
${colors_1.Colors.FgGray}─────────────────────────────────────────────────────────────────${colors_1.Colors.Reset}`);
|
|
2492
|
+
console.log(`${colors_1.Colors.FgYellow}⭐ ${colors_1.Colors.Bright}Like this CLI? Star us on GitHub!${colors_1.Colors.Reset}`);
|
|
2493
|
+
console.log(`${colors_1.Colors.FgGray} https://github.com/ideascoldigital/cli-maker${colors_1.Colors.Reset}`);
|
|
2494
|
+
console.log(`${colors_1.Colors.FgGray}─────────────────────────────────────────────────────────────────${colors_1.Colors.Reset}
|
|
2495
|
+
`);
|
|
2496
|
+
}
|
|
307
2497
|
}
|
|
308
|
-
commandHelp(command) {
|
|
309
|
-
|
|
310
|
-
console.log(
|
|
2498
|
+
commandHelp(command, fullCommandPath) {
|
|
2499
|
+
const fullCommand = fullCommandPath.join(" ");
|
|
2500
|
+
console.log(`
|
|
2501
|
+
${colors_1.Colors.BgGreen}${colors_1.Colors.FgBlack} ${this.name} ${fullCommand} ${colors_1.Colors.Reset}`);
|
|
2502
|
+
console.log(`${colors_1.Colors.FgGreen}${command.description}${colors_1.Colors.Reset}
|
|
2503
|
+
`);
|
|
2504
|
+
console.log(`${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}USAGE${colors_1.Colors.Reset}`);
|
|
2505
|
+
const paramList = command.params.map((p) => `${p.required ? "<" : "["}${p.name}${p.required ? ">" : "]"} `).join("");
|
|
2506
|
+
console.log(` ${colors_1.Colors.FgGray}$ ${this.executableName} ${fullCommand} ${paramList}${colors_1.Colors.Reset}
|
|
2507
|
+
`);
|
|
311
2508
|
if (command.params.length > 0) {
|
|
312
|
-
console.log(`${colors_1.Colors.
|
|
313
|
-
|
|
314
|
-
|
|
2509
|
+
console.log(`${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}PARAMETERS${colors_1.Colors.Reset}
|
|
2510
|
+
`);
|
|
2511
|
+
console.log((0, common_1.formatParameterTable)(command.params));
|
|
2512
|
+
console.log("");
|
|
2513
|
+
}
|
|
2514
|
+
if (command.subcommands && command.subcommands.length > 0) {
|
|
2515
|
+
console.log(`${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}SUBCOMMANDS${colors_1.Colors.Reset}`);
|
|
2516
|
+
command.subcommands.forEach((subcmd) => {
|
|
2517
|
+
console.log(` ${colors_1.Colors.FgGreen}${subcmd.name}${colors_1.Colors.Reset}: ${subcmd.description}`);
|
|
315
2518
|
});
|
|
2519
|
+
console.log("");
|
|
2520
|
+
}
|
|
2521
|
+
console.log(`${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}EXAMPLES${colors_1.Colors.Reset}`);
|
|
2522
|
+
console.log(` ${colors_1.Colors.FgGray}$ ${this.executableName} ${fullCommand} --help${colors_1.Colors.Reset}`);
|
|
2523
|
+
if (command.params.some((p) => p.required)) {
|
|
2524
|
+
const exampleParams = command.params.filter((p) => p.required).slice(0, 2).map((p) => {
|
|
2525
|
+
if (p.type === interfaces_1.ParamType.List && p.options) {
|
|
2526
|
+
return `--${p.name} ${p.options[0]}`;
|
|
2527
|
+
} else if (p.type === interfaces_1.ParamType.Boolean) {
|
|
2528
|
+
return `--${p.name}`;
|
|
2529
|
+
} else {
|
|
2530
|
+
return `--${p.name} value`;
|
|
2531
|
+
}
|
|
2532
|
+
}).join(" ");
|
|
2533
|
+
console.log(` ${colors_1.Colors.FgGray}$ ${this.executableName} ${fullCommand} ${exampleParams}${colors_1.Colors.Reset}`);
|
|
2534
|
+
}
|
|
2535
|
+
console.log("");
|
|
2536
|
+
}
|
|
2537
|
+
findCommand(commandName, commands = this.commands) {
|
|
2538
|
+
return commands.find((cmd) => cmd.name === commandName);
|
|
2539
|
+
}
|
|
2540
|
+
findSubcommand(commandPath) {
|
|
2541
|
+
if (commandPath.length < 2)
|
|
2542
|
+
return;
|
|
2543
|
+
const rootCommandName = commandPath[0];
|
|
2544
|
+
const rootCommand = this.findCommand(rootCommandName);
|
|
2545
|
+
if (!rootCommand || !rootCommand.subcommands)
|
|
2546
|
+
return;
|
|
2547
|
+
let currentCommand = rootCommand;
|
|
2548
|
+
let currentCommands = rootCommand.subcommands;
|
|
2549
|
+
let i = 1;
|
|
2550
|
+
while (i < commandPath.length - 1) {
|
|
2551
|
+
const subCmd = this.findCommand(commandPath[i], currentCommands);
|
|
2552
|
+
if (!subCmd || !subCmd.subcommands)
|
|
2553
|
+
return;
|
|
2554
|
+
currentCommand = subCmd;
|
|
2555
|
+
currentCommands = subCmd.subcommands;
|
|
2556
|
+
i++;
|
|
316
2557
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
2558
|
+
const finalSubcommand = this.findCommand(commandPath[commandPath.length - 1], currentCommands);
|
|
2559
|
+
if (!finalSubcommand)
|
|
2560
|
+
return;
|
|
2561
|
+
return { parentCommand: currentCommand, command: finalSubcommand };
|
|
320
2562
|
}
|
|
321
2563
|
showUnknownCommandError(commandName) {
|
|
322
|
-
console.log(
|
|
323
|
-
|
|
2564
|
+
console.log(`
|
|
2565
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Unknown command: '${colors_1.Colors.Bright}${commandName}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
2566
|
+
`);
|
|
2567
|
+
console.log(`${colors_1.Colors.FgYellow}Available commands:${colors_1.Colors.Reset}
|
|
2568
|
+
`);
|
|
2569
|
+
this.commands.forEach((cmd) => {
|
|
2570
|
+
console.log(` ${colors_1.Colors.FgGreen}${cmd.name}${colors_1.Colors.Reset}: ${cmd.description}`);
|
|
2571
|
+
if (cmd.subcommands && cmd.subcommands.length > 0) {
|
|
2572
|
+
cmd.subcommands.forEach((subcmd) => {
|
|
2573
|
+
console.log(` ${colors_1.Colors.FgGreen}${cmd.name} ${subcmd.name}${colors_1.Colors.Reset}: ${subcmd.description}`);
|
|
2574
|
+
});
|
|
2575
|
+
}
|
|
2576
|
+
});
|
|
2577
|
+
console.log(`
|
|
2578
|
+
${colors_1.Colors.FgGray}Try '${colors_1.Colors.Bright}${this.executableName} --help${colors_1.Colors.Reset}${colors_1.Colors.FgGray}' for more information.${colors_1.Colors.Reset}
|
|
2579
|
+
`);
|
|
324
2580
|
}
|
|
325
2581
|
getMissingParams(command, result) {
|
|
326
2582
|
const requiredParams = command.params.filter((p) => p.required === true);
|
|
@@ -342,9 +2598,22 @@ ${colors_1.Colors.FgYellow}Optional missing params${colors_1.Colors.Reset}
|
|
|
342
2598
|
}
|
|
343
2599
|
parseArgs(args, command) {
|
|
344
2600
|
const result = {};
|
|
345
|
-
for (
|
|
346
|
-
const
|
|
347
|
-
if (
|
|
2601
|
+
for (let i = 0;i < args.length; i++) {
|
|
2602
|
+
const arg = args[i];
|
|
2603
|
+
if (arg.startsWith("--")) {
|
|
2604
|
+
let key;
|
|
2605
|
+
let value;
|
|
2606
|
+
if (arg.includes("=")) {
|
|
2607
|
+
[key, value] = arg.split("=");
|
|
2608
|
+
} else {
|
|
2609
|
+
key = arg;
|
|
2610
|
+
value = args[i + 1];
|
|
2611
|
+
if (value && !value.startsWith("--")) {
|
|
2612
|
+
i++;
|
|
2613
|
+
} else {
|
|
2614
|
+
value = undefined;
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
348
2617
|
const paramName = key.slice(2);
|
|
349
2618
|
const commandParam = command.params.find((p) => p.name === paramName);
|
|
350
2619
|
if (commandParam) {
|
|
@@ -354,8 +2623,12 @@ ${colors_1.Colors.FgYellow}Optional missing params${colors_1.Colors.Reset}
|
|
|
354
2623
|
}
|
|
355
2624
|
result[paramName] = validation.value;
|
|
356
2625
|
} else {
|
|
357
|
-
return {
|
|
358
|
-
|
|
2626
|
+
return {
|
|
2627
|
+
error: `
|
|
2628
|
+
${colors_1.Colors.BgRed}${colors_1.Colors.FgWhite} ERROR ${colors_1.Colors.Reset} ${colors_1.Colors.FgRed}Unknown parameter: '${colors_1.Colors.Bright}${paramName}${colors_1.Colors.Reset}${colors_1.Colors.FgRed}'${colors_1.Colors.Reset}
|
|
2629
|
+
${colors_1.Colors.FgGray} Available parameters: ${command.params.map((p) => p.name).join(", ")}${colors_1.Colors.Reset}
|
|
2630
|
+
`
|
|
2631
|
+
};
|
|
359
2632
|
}
|
|
360
2633
|
}
|
|
361
2634
|
}
|
|
@@ -367,67 +2640,319 @@ Param ${colors_1.Colors.FgRed}${paramName}${colors_1.Colors.Reset} ${colors_1.Co
|
|
|
367
2640
|
findParamType(paramName) {
|
|
368
2641
|
return this.commands.flatMap((command) => command.params).find((param) => param.name === paramName);
|
|
369
2642
|
}
|
|
2643
|
+
showIntroIfNeeded(overrideMode) {
|
|
2644
|
+
const introOptions = this.resolvedIntro || this.resolveIntroOptions(this.options?.introAnimation);
|
|
2645
|
+
const mode = overrideMode || introOptions?.introMode;
|
|
2646
|
+
if (!introOptions || introOptions.enabled === false) {
|
|
2647
|
+
if (mode === "always") {
|
|
2648
|
+
this.renderIntroAnimation(introOptions || {});
|
|
2649
|
+
}
|
|
2650
|
+
return;
|
|
2651
|
+
}
|
|
2652
|
+
if (mode === "never")
|
|
2653
|
+
return;
|
|
2654
|
+
const markerPath = this.getIntroMarkerPath(introOptions);
|
|
2655
|
+
if (mode !== "always" && introOptions.showOnce !== false && this.hasSeenIntro(markerPath)) {
|
|
2656
|
+
return;
|
|
2657
|
+
}
|
|
2658
|
+
this.renderIntroAnimation(introOptions);
|
|
2659
|
+
if (introOptions.showOnce !== false && mode !== "always") {
|
|
2660
|
+
this.markIntroSeen(markerPath);
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
resolveIntroOptions(intro) {
|
|
2664
|
+
if (!intro)
|
|
2665
|
+
return { enabled: false, showOnce: true };
|
|
2666
|
+
const preset = intro.preset ? INTRO_PRESETS[intro.preset] : undefined;
|
|
2667
|
+
const replacePlaceholders = (text) => {
|
|
2668
|
+
if (!text)
|
|
2669
|
+
return text;
|
|
2670
|
+
return text.replace(/\{\{cliName\}\}/g, this.name).replace(/\{\{cliDescription\}\}/g, this.description);
|
|
2671
|
+
};
|
|
2672
|
+
const extractCliNameWithoutCompany = (fullName) => {
|
|
2673
|
+
const parts = fullName.split("/");
|
|
2674
|
+
return parts.length > 1 ? parts[1] : fullName;
|
|
2675
|
+
};
|
|
2676
|
+
const extractCompany = (fullName) => {
|
|
2677
|
+
const parts = fullName.split("/");
|
|
2678
|
+
return parts.length > 1 ? parts[0] : null;
|
|
2679
|
+
};
|
|
2680
|
+
let resolvedTitle = replacePlaceholders(intro.title ?? preset?.title);
|
|
2681
|
+
let resolvedSubtitle = replacePlaceholders(intro.subtitle ?? preset?.subtitle);
|
|
2682
|
+
let resolvedLines = intro.lines ?? preset?.lines;
|
|
2683
|
+
let resolvedAsciiArt = intro.asciiArt ?? preset?.asciiArt;
|
|
2684
|
+
if (intro.preset === "ascii-art") {
|
|
2685
|
+
const cliNameOnly = extractCliNameWithoutCompany(this.name);
|
|
2686
|
+
const company = extractCompany(this.name);
|
|
2687
|
+
resolvedAsciiArt = generatePixelAsciiArt(cliNameOnly).map((line) => `${colors_1.Colors.FgYellow}${line}${colors_1.Colors.Reset}`);
|
|
2688
|
+
resolvedTitle = undefined;
|
|
2689
|
+
resolvedSubtitle = undefined;
|
|
2690
|
+
if (company) {
|
|
2691
|
+
resolvedLines = [`${colors_1.Colors.FgGray}by ${company}${colors_1.Colors.Reset}`];
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
return {
|
|
2695
|
+
enabled: intro.enabled ?? preset?.enabled ?? false,
|
|
2696
|
+
showOnce: intro.showOnce ?? preset?.showOnce ?? true,
|
|
2697
|
+
introMode: intro.introMode ?? preset?.introMode,
|
|
2698
|
+
animateText: intro.animateText ?? preset?.animateText ?? true,
|
|
2699
|
+
preset: intro.preset,
|
|
2700
|
+
frames: intro.frames ?? preset?.frames,
|
|
2701
|
+
padding: intro.padding ?? preset?.padding,
|
|
2702
|
+
speedMs: intro.speedMs ?? preset?.speedMs,
|
|
2703
|
+
loops: intro.loops ?? preset?.loops,
|
|
2704
|
+
lines: resolvedLines,
|
|
2705
|
+
asciiArt: resolvedAsciiArt,
|
|
2706
|
+
title: resolvedTitle,
|
|
2707
|
+
subtitle: resolvedSubtitle,
|
|
2708
|
+
storageKey: intro.storageKey ?? preset?.storageKey
|
|
2709
|
+
};
|
|
2710
|
+
}
|
|
2711
|
+
renderIntroAnimation(introOptions) {
|
|
2712
|
+
const frames = introOptions.frames && introOptions.frames.length > 0 ? introOptions.frames : ["◢", "◣", "◤", "◥"];
|
|
2713
|
+
const loops = Math.max(1, introOptions.loops ?? 2);
|
|
2714
|
+
const speed = Math.max(40, introOptions.speedMs ?? 90);
|
|
2715
|
+
const totalFrames = frames.length * loops;
|
|
2716
|
+
const fallbackFrame = frames[0] || "★";
|
|
2717
|
+
let renderedLines = 0;
|
|
2718
|
+
if (!process.stdout.isTTY) {
|
|
2719
|
+
const lines = this.buildIntroLines(fallbackFrame, introOptions, 1);
|
|
2720
|
+
console.log(lines.join(`
|
|
2721
|
+
`));
|
|
2722
|
+
console.log("");
|
|
2723
|
+
return;
|
|
2724
|
+
}
|
|
2725
|
+
for (let i = 0;i < totalFrames; i++) {
|
|
2726
|
+
const frameSymbol = frames[i % frames.length] || fallbackFrame;
|
|
2727
|
+
const revealProgress = introOptions.animateText === false ? 1 : Math.min(1, (i + 1) / totalFrames);
|
|
2728
|
+
const lines = this.buildIntroLines(frameSymbol, introOptions, revealProgress);
|
|
2729
|
+
if (renderedLines > 0) {
|
|
2730
|
+
process.stdout.write(`\x1B[${renderedLines}A\r`);
|
|
2731
|
+
process.stdout.write("\x1B[0J");
|
|
2732
|
+
}
|
|
2733
|
+
process.stdout.write(lines.join(`
|
|
2734
|
+
`) + `
|
|
2735
|
+
`);
|
|
2736
|
+
renderedLines = lines.length;
|
|
2737
|
+
this.blockingSleep(speed);
|
|
2738
|
+
}
|
|
2739
|
+
console.log("");
|
|
2740
|
+
}
|
|
2741
|
+
buildIntroLines(frameSymbol, introOptions, revealProgress) {
|
|
2742
|
+
const paddingSize = Math.max(0, introOptions.padding ?? 2);
|
|
2743
|
+
const padding = " ".repeat(paddingSize);
|
|
2744
|
+
const title = introOptions.title || this.name;
|
|
2745
|
+
const subtitle = introOptions.subtitle ?? this.description;
|
|
2746
|
+
const extraLines = introOptions.lines ?? [];
|
|
2747
|
+
const asciiArt = introOptions.asciiArt ?? [];
|
|
2748
|
+
const rawTitle = `${frameSymbol} ${title}`;
|
|
2749
|
+
const rawLines = [rawTitle];
|
|
2750
|
+
if (subtitle)
|
|
2751
|
+
rawLines.push(subtitle);
|
|
2752
|
+
rawLines.push(...extraLines);
|
|
2753
|
+
rawLines.push(...asciiArt);
|
|
2754
|
+
const contentWidth = Math.max(...rawLines.map((line) => (0, common_1.stripAnsiCodes)(line).length));
|
|
2755
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
2756
|
+
const minWidth = Math.floor(terminalWidth / 2) - paddingSize * 2 - 4;
|
|
2757
|
+
const maxContentWidth = Math.max(contentWidth, minWidth);
|
|
2758
|
+
const horizontal = "─".repeat(maxContentWidth + 2);
|
|
2759
|
+
const topBorder = `${padding}${colors_1.Colors.FgGray}┌${horizontal}┐${colors_1.Colors.Reset}`;
|
|
2760
|
+
const bottomBorder = `${padding}${colors_1.Colors.FgGray}└${horizontal}┘${colors_1.Colors.Reset}`;
|
|
2761
|
+
const formatLine = (text, rawText) => {
|
|
2762
|
+
const displayLength = (0, common_1.stripAnsiCodes)(text).length;
|
|
2763
|
+
const spaces = Math.max(0, maxContentWidth - displayLength);
|
|
2764
|
+
const lineContent = ` ${text}${" ".repeat(spaces)} `;
|
|
2765
|
+
return `${padding}${colors_1.Colors.FgGray}│${colors_1.Colors.Reset}${lineContent}${colors_1.Colors.FgGray}│${colors_1.Colors.Reset}`;
|
|
2766
|
+
};
|
|
2767
|
+
const rainbowMode = introOptions.preset === "rainbow";
|
|
2768
|
+
const visibleTitle = this.revealText(title, revealProgress, introOptions.animateText);
|
|
2769
|
+
const coloredTitle = rainbowMode ? this.colorizeRainbow(visibleTitle) : `${colors_1.Colors.Bright}${colors_1.Colors.FgCyan}${visibleTitle}${colors_1.Colors.Reset}`;
|
|
2770
|
+
const formattedTitle = `${colors_1.Colors.FgYellow}${frameSymbol}${colors_1.Colors.Reset} ${coloredTitle}`;
|
|
2771
|
+
const formattedLines = [formatLine(formattedTitle, rawTitle)];
|
|
2772
|
+
if (subtitle) {
|
|
2773
|
+
const visibleSubtitle = this.revealText(subtitle, revealProgress, introOptions.animateText);
|
|
2774
|
+
const coloredSubtitle = rainbowMode ? this.colorizeRainbow(visibleSubtitle) : `${colors_1.Colors.FgGray}${visibleSubtitle}${colors_1.Colors.Reset}`;
|
|
2775
|
+
formattedLines.push(formatLine(coloredSubtitle, subtitle));
|
|
2776
|
+
}
|
|
2777
|
+
extraLines.forEach((line) => {
|
|
2778
|
+
const visibleLine = this.revealText(line, revealProgress, introOptions.animateText);
|
|
2779
|
+
const coloredLine = rainbowMode ? this.colorizeRainbow(visibleLine) : `${colors_1.Colors.FgGray}${visibleLine}${colors_1.Colors.Reset}`;
|
|
2780
|
+
formattedLines.push(formatLine(coloredLine, line));
|
|
2781
|
+
});
|
|
2782
|
+
asciiArt.forEach((line) => {
|
|
2783
|
+
const shouldAnimateArt = introOptions.animateText !== false && !line.includes("\x1B");
|
|
2784
|
+
const visibleArt = this.revealText(line, shouldAnimateArt ? revealProgress : 1, shouldAnimateArt);
|
|
2785
|
+
formattedLines.push(formatLine(visibleArt, line));
|
|
2786
|
+
});
|
|
2787
|
+
return [topBorder, ...formattedLines, bottomBorder];
|
|
2788
|
+
}
|
|
2789
|
+
getIntroMarkerPath(introOptions) {
|
|
2790
|
+
if (introOptions.showOnce === false)
|
|
2791
|
+
return null;
|
|
2792
|
+
const homeDir = os_1.default.homedir();
|
|
2793
|
+
const safeName = (introOptions.storageKey || `${this.executableName || this.name}-intro`).replace(/[^a-z0-9-_]/gi, "-").toLowerCase();
|
|
2794
|
+
const markerDir = path_1.default.join(homeDir, ".cli-maker");
|
|
2795
|
+
return path_1.default.join(markerDir, `${safeName}.json`);
|
|
2796
|
+
}
|
|
2797
|
+
hasSeenIntro(markerPath) {
|
|
2798
|
+
if (!markerPath)
|
|
2799
|
+
return false;
|
|
2800
|
+
try {
|
|
2801
|
+
return fs_1.default.existsSync(markerPath);
|
|
2802
|
+
} catch {
|
|
2803
|
+
return false;
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
markIntroSeen(markerPath) {
|
|
2807
|
+
if (!markerPath)
|
|
2808
|
+
return;
|
|
2809
|
+
try {
|
|
2810
|
+
fs_1.default.mkdirSync(path_1.default.dirname(markerPath), { recursive: true });
|
|
2811
|
+
fs_1.default.writeFileSync(markerPath, JSON.stringify({ seenAt: new Date().toISOString() }), "utf-8");
|
|
2812
|
+
} catch {}
|
|
2813
|
+
}
|
|
2814
|
+
blockingSleep(ms) {
|
|
2815
|
+
if (ms <= 0)
|
|
2816
|
+
return;
|
|
2817
|
+
const sharedBuffer = new SharedArrayBuffer(4);
|
|
2818
|
+
const sharedArray = new Int32Array(sharedBuffer);
|
|
2819
|
+
Atomics.wait(sharedArray, 0, 0, ms);
|
|
2820
|
+
}
|
|
2821
|
+
revealText(text, progress, animate) {
|
|
2822
|
+
if (!text)
|
|
2823
|
+
return "";
|
|
2824
|
+
if (animate === false)
|
|
2825
|
+
return text;
|
|
2826
|
+
const clean = (0, common_1.stripAnsiCodes)(text);
|
|
2827
|
+
const len = clean.length;
|
|
2828
|
+
if (len === 0)
|
|
2829
|
+
return "";
|
|
2830
|
+
const visible = Math.min(len, Math.max(0, Math.round(len * progress)));
|
|
2831
|
+
return text.slice(0, visible);
|
|
2832
|
+
}
|
|
2833
|
+
colorizeRainbow(text) {
|
|
2834
|
+
const palette = [colors_1.Colors.FgRed, colors_1.Colors.FgYellow, colors_1.Colors.FgGreen, colors_1.Colors.FgCyan, colors_1.Colors.FgBlue, colors_1.Colors.FgMagenta];
|
|
2835
|
+
let colored = "";
|
|
2836
|
+
let colorIndex = 0;
|
|
2837
|
+
for (let i = 0;i < text.length; i++) {
|
|
2838
|
+
const char = text[i];
|
|
2839
|
+
if (char.trim().length === 0) {
|
|
2840
|
+
colored += char;
|
|
2841
|
+
continue;
|
|
2842
|
+
}
|
|
2843
|
+
colored += `${palette[colorIndex % palette.length]}${char}${colors_1.Colors.Reset}`;
|
|
2844
|
+
colorIndex++;
|
|
2845
|
+
}
|
|
2846
|
+
return colored;
|
|
2847
|
+
}
|
|
2848
|
+
extractIntroFlags(rawArgs) {
|
|
2849
|
+
let introMode;
|
|
2850
|
+
const filteredArgs = rawArgs.filter((arg) => {
|
|
2851
|
+
if (arg === "--intro-always") {
|
|
2852
|
+
introMode = "always";
|
|
2853
|
+
return false;
|
|
2854
|
+
}
|
|
2855
|
+
if (arg === "--no-intro") {
|
|
2856
|
+
introMode = "never";
|
|
2857
|
+
return false;
|
|
2858
|
+
}
|
|
2859
|
+
return true;
|
|
2860
|
+
});
|
|
2861
|
+
return { introMode, filteredArgs };
|
|
2862
|
+
}
|
|
370
2863
|
async promptForMissingParams(missingParams, existingParams) {
|
|
371
|
-
|
|
2864
|
+
let rl = readline_1.default.createInterface({
|
|
372
2865
|
input: process.stdin,
|
|
373
2866
|
output: process.stdout
|
|
374
2867
|
});
|
|
375
2868
|
const askQuestion = (question) => {
|
|
376
2869
|
return new Promise((resolve) => rl.question(question, resolve));
|
|
377
2870
|
};
|
|
2871
|
+
console.log(`
|
|
2872
|
+
${colors_1.Colors.BgBlue}${colors_1.Colors.FgWhite} INTERACTIVE MODE ${colors_1.Colors.Reset} ${colors_1.Colors.FgBlue}Please provide the following information:${colors_1.Colors.Reset}
|
|
2873
|
+
`);
|
|
378
2874
|
const prompts = missingParams.reduce((promise, param) => {
|
|
379
2875
|
return promise.then(async (answers) => {
|
|
380
2876
|
let answer;
|
|
381
2877
|
let validation;
|
|
2878
|
+
const requiredIndicator = param.required ? `${colors_1.Colors.FgRed}*${colors_1.Colors.Reset}` : `${colors_1.Colors.FgGray}○${colors_1.Colors.Reset}`;
|
|
2879
|
+
console.log(`${requiredIndicator} ${colors_1.Colors.Bright}${param.name}${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}(${param.type})${colors_1.Colors.Reset}`);
|
|
2880
|
+
console.log(` ${colors_1.Colors.FgGray}${param.description}${colors_1.Colors.Reset}`);
|
|
2881
|
+
if (param.options && param.options.length > 0) {
|
|
2882
|
+
console.log(` ${colors_1.Colors.FgGray}Options: ${param.options.join(", ")}${colors_1.Colors.Reset}`);
|
|
2883
|
+
}
|
|
2884
|
+
console.log("");
|
|
382
2885
|
if (param.type === interfaces_1.ParamType.List && param.options) {
|
|
383
|
-
|
|
384
|
-
console.log(`
|
|
385
|
-
${colors_1.Colors.FgYellow}(${param.type}) ${colors_1.Colors.Reset}${colors_1.Colors.FgGreen}${param.name}${colors_1.Colors.Reset} `);
|
|
386
|
-
console.log(`${colors_1.Colors.FgYellow}> ${colors_1.Colors.Reset}${colors_1.Colors.FgGray}${isRequired}${param.description}:${colors_1.Colors.Reset}
|
|
387
|
-
`);
|
|
2886
|
+
console.log(`${colors_1.Colors.FgCyan}Use ↑/↓ arrow keys to navigate, Enter to select:${colors_1.Colors.Reset}`);
|
|
388
2887
|
answer = await this.promptWithArrows(param);
|
|
389
2888
|
validation = { value: param.options[parseInt(answer, 10)] };
|
|
2889
|
+
console.log(`${colors_1.Colors.Success}✓ Selected: ${validation.value}${colors_1.Colors.Reset}
|
|
2890
|
+
`);
|
|
390
2891
|
} else {
|
|
2892
|
+
let attemptCount = 0;
|
|
391
2893
|
do {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
2894
|
+
if (attemptCount > 0) {
|
|
2895
|
+
console.log(`${colors_1.Colors.FgYellow}Please try again:${colors_1.Colors.Reset}`);
|
|
2896
|
+
}
|
|
2897
|
+
const promptText = param.required ? `${colors_1.Colors.FgGreen}Enter value${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}(required)${colors_1.Colors.Reset}: ` : `${colors_1.Colors.FgGreen}Enter value${colors_1.Colors.Reset} ${colors_1.Colors.FgGray}(or press Enter to skip)${colors_1.Colors.Reset}: `;
|
|
2898
|
+
if (param.type === interfaces_1.ParamType.Password) {
|
|
2899
|
+
rl.close();
|
|
2900
|
+
answer = await CLI.askHiddenQuestion(promptText);
|
|
2901
|
+
rl = readline_1.default.createInterface({
|
|
2902
|
+
input: process.stdin,
|
|
2903
|
+
output: process.stdout
|
|
2904
|
+
});
|
|
2905
|
+
} else {
|
|
2906
|
+
answer = await askQuestion(promptText);
|
|
2907
|
+
}
|
|
398
2908
|
validation = this.validateParam(answer, param.type, param.required, param.options);
|
|
399
2909
|
if (validation.error) {
|
|
400
2910
|
console.log(validation.error);
|
|
2911
|
+
attemptCount++;
|
|
2912
|
+
} else if (validation.value !== undefined) {
|
|
2913
|
+
console.log(`${colors_1.Colors.Success}✓ Accepted${colors_1.Colors.Reset}
|
|
2914
|
+
`);
|
|
2915
|
+
} else {
|
|
2916
|
+
console.log(`${colors_1.Colors.FgGray}○ Skipped${colors_1.Colors.Reset}
|
|
2917
|
+
`);
|
|
401
2918
|
}
|
|
402
2919
|
} while (validation.error);
|
|
403
2920
|
}
|
|
404
2921
|
return { ...answers, [param.name]: validation.value };
|
|
405
2922
|
});
|
|
406
2923
|
}, Promise.resolve(existingParams));
|
|
407
|
-
return prompts.finally(() =>
|
|
2924
|
+
return prompts.finally(() => {
|
|
2925
|
+
rl.close();
|
|
2926
|
+
console.log(`${colors_1.Colors.Success}✅ All parameters collected successfully!${colors_1.Colors.Reset}
|
|
2927
|
+
`);
|
|
2928
|
+
});
|
|
408
2929
|
}
|
|
409
2930
|
async promptWithArrows(param) {
|
|
410
2931
|
return new Promise((resolve) => {
|
|
411
2932
|
let index = 0;
|
|
412
2933
|
const options = param.options;
|
|
413
2934
|
const renderOptions = () => {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
if (i === index) {
|
|
417
|
-
process.stdout.write(`${colors_1.Colors.FgGreen}> ${option}${colors_1.Colors.Reset}
|
|
418
|
-
`);
|
|
419
|
-
} else {
|
|
420
|
-
process.stdout.write(` ${option}
|
|
2935
|
+
console.clear();
|
|
2936
|
+
console.log(`${colors_1.Colors.BgBlue}${colors_1.Colors.FgWhite} SELECT OPTION ${colors_1.Colors.Reset} ${colors_1.Colors.FgBlue}for ${param.name}${colors_1.Colors.Reset}
|
|
421
2937
|
`);
|
|
422
|
-
|
|
2938
|
+
options.forEach((option, i) => {
|
|
2939
|
+
const prefix = i === index ? `${colors_1.Colors.FgGreen}❯ ${option}${colors_1.Colors.Reset}` : ` ${option}`;
|
|
2940
|
+
const indicator = i === index ? ` ${colors_1.Colors.FgCyan}← Current selection${colors_1.Colors.Reset}` : "";
|
|
2941
|
+
console.log(`${prefix}${indicator}`);
|
|
423
2942
|
});
|
|
424
|
-
|
|
2943
|
+
console.log(`
|
|
2944
|
+
${colors_1.Colors.FgGray}Use ↑/↓ to navigate, Enter to confirm, Ctrl+C to cancel${colors_1.Colors.Reset}`);
|
|
2945
|
+
console.log(`${colors_1.Colors.FgGray}Selected: ${options[index]}${colors_1.Colors.Reset}`);
|
|
2946
|
+
};
|
|
2947
|
+
const clearScreen = () => {
|
|
2948
|
+
process.stdout.write("\x1B[0J");
|
|
2949
|
+
process.stdout.write("\x1B[0;0H");
|
|
425
2950
|
};
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
2951
|
+
const cleanup = () => {
|
|
2952
|
+
process.stdin.removeListener("keypress", keypressHandler);
|
|
2953
|
+
if (process.stdin.isTTY) {
|
|
2954
|
+
process.stdin.setRawMode(false);
|
|
429
2955
|
}
|
|
430
|
-
process.stdout.write("\x1B[2K\x1B[0G");
|
|
431
2956
|
};
|
|
432
2957
|
const keypressHandler = (str, key) => {
|
|
433
2958
|
if (key.name === "up") {
|
|
@@ -437,22 +2962,16 @@ ${colors_1.Colors.FgYellow}> ${colors_1.Colors.Reset}${colors_1.Colors.FgGray}${
|
|
|
437
2962
|
index = (index + 1) % options.length;
|
|
438
2963
|
renderOptions();
|
|
439
2964
|
} else if (key.name === "return") {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
options.forEach((option, i) => {
|
|
443
|
-
if (i === index) {
|
|
444
|
-
process.stdout.write(`${colors_1.Colors.FgGreen}> ${option}${colors_1.Colors.Reset}
|
|
445
|
-
`);
|
|
446
|
-
} else {
|
|
447
|
-
process.stdout.write(` ${option}
|
|
448
|
-
`);
|
|
449
|
-
}
|
|
450
|
-
});
|
|
451
|
-
process.stdout.write(`
|
|
452
|
-
Selected: ${options[index]}
|
|
453
|
-
`);
|
|
2965
|
+
cleanup();
|
|
2966
|
+
clearScreen();
|
|
454
2967
|
resolve(index.toString());
|
|
455
2968
|
return;
|
|
2969
|
+
} else if (key.ctrl && key.name === "c") {
|
|
2970
|
+
cleanup();
|
|
2971
|
+
clearScreen();
|
|
2972
|
+
console.log(`${colors_1.Colors.Warning}⚠️ Selection cancelled${colors_1.Colors.Reset}
|
|
2973
|
+
`);
|
|
2974
|
+
process.exit(0);
|
|
456
2975
|
}
|
|
457
2976
|
};
|
|
458
2977
|
readline_1.default.emitKeypressEvents(process.stdin);
|
|
@@ -463,23 +2982,111 @@ Selected: ${options[index]}
|
|
|
463
2982
|
renderOptions();
|
|
464
2983
|
});
|
|
465
2984
|
}
|
|
2985
|
+
static async askQuestion(question) {
|
|
2986
|
+
return new Promise((resolve) => {
|
|
2987
|
+
const rl = readline_1.default.createInterface({
|
|
2988
|
+
input: process.stdin,
|
|
2989
|
+
output: process.stdout
|
|
2990
|
+
});
|
|
2991
|
+
rl.question(question, (answer) => {
|
|
2992
|
+
rl.close();
|
|
2993
|
+
resolve(answer);
|
|
2994
|
+
});
|
|
2995
|
+
});
|
|
2996
|
+
}
|
|
2997
|
+
static async askHiddenQuestion(question) {
|
|
2998
|
+
return new Promise((resolve) => {
|
|
2999
|
+
const stdin = process.stdin;
|
|
3000
|
+
const stdout = process.stdout;
|
|
3001
|
+
stdout.write(question);
|
|
3002
|
+
let buffer = "";
|
|
3003
|
+
const onData = (char) => {
|
|
3004
|
+
const key = char.toString();
|
|
3005
|
+
if (key === `
|
|
3006
|
+
` || key === "\r" || key === "\x04") {
|
|
3007
|
+
stdout.write(`
|
|
3008
|
+
`);
|
|
3009
|
+
stdin.removeListener("data", onData);
|
|
3010
|
+
if (stdin.isTTY)
|
|
3011
|
+
stdin.setRawMode(false);
|
|
3012
|
+
stdin.pause();
|
|
3013
|
+
resolve(buffer);
|
|
3014
|
+
} else if (key === "\x03") {
|
|
3015
|
+
stdin.removeListener("data", onData);
|
|
3016
|
+
if (stdin.isTTY)
|
|
3017
|
+
stdin.setRawMode(false);
|
|
3018
|
+
stdin.pause();
|
|
3019
|
+
process.exit(0);
|
|
3020
|
+
} else if (key === "" || key === "\b") {
|
|
3021
|
+
if (buffer.length > 0) {
|
|
3022
|
+
buffer = buffer.slice(0, -1);
|
|
3023
|
+
stdout.write("\b \b");
|
|
3024
|
+
}
|
|
3025
|
+
} else {
|
|
3026
|
+
const printableChars = key.split("").filter((c) => c >= " " && c <= "~").join("");
|
|
3027
|
+
if (printableChars.length > 0) {
|
|
3028
|
+
buffer += printableChars;
|
|
3029
|
+
stdout.write("*".repeat(printableChars.length));
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
};
|
|
3033
|
+
stdin.resume();
|
|
3034
|
+
if (stdin.isTTY)
|
|
3035
|
+
stdin.setRawMode(true);
|
|
3036
|
+
stdin.on("data", onData);
|
|
3037
|
+
});
|
|
3038
|
+
}
|
|
466
3039
|
}
|
|
467
3040
|
exports2.CLI = CLI;
|
|
468
3041
|
});
|
|
469
3042
|
|
|
470
|
-
// node_modules/@ideascol/cli-maker/dist/
|
|
471
|
-
var
|
|
3043
|
+
// node_modules/@ideascol/cli-maker/dist/session/index.js
|
|
3044
|
+
var require_session2 = __commonJS((exports2) => {
|
|
472
3045
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
473
|
-
exports2.
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
3046
|
+
exports2.separator = exports2.alignedList = exports2.sectionHeader = exports2.toolResultBox = exports2.toolCallArgs = exports2.toolCallHeader = exports2.drawTwoColumnBox = exports2.drawBox = exports2.getBuiltInSlashCommands = exports2.renderMarkdown = exports2.InteractiveSession = undefined;
|
|
3047
|
+
var session_1 = require_session();
|
|
3048
|
+
Object.defineProperty(exports2, "InteractiveSession", { enumerable: true, get: function() {
|
|
3049
|
+
return session_1.InteractiveSession;
|
|
3050
|
+
} });
|
|
3051
|
+
var markdown_1 = require_markdown();
|
|
3052
|
+
Object.defineProperty(exports2, "renderMarkdown", { enumerable: true, get: function() {
|
|
3053
|
+
return markdown_1.renderMarkdown;
|
|
3054
|
+
} });
|
|
3055
|
+
var slash_commands_1 = require_slash_commands();
|
|
3056
|
+
Object.defineProperty(exports2, "getBuiltInSlashCommands", { enumerable: true, get: function() {
|
|
3057
|
+
return slash_commands_1.getBuiltInSlashCommands;
|
|
3058
|
+
} });
|
|
3059
|
+
var ui_1 = require_ui();
|
|
3060
|
+
Object.defineProperty(exports2, "drawBox", { enumerable: true, get: function() {
|
|
3061
|
+
return ui_1.drawBox;
|
|
3062
|
+
} });
|
|
3063
|
+
Object.defineProperty(exports2, "drawTwoColumnBox", { enumerable: true, get: function() {
|
|
3064
|
+
return ui_1.drawTwoColumnBox;
|
|
3065
|
+
} });
|
|
3066
|
+
Object.defineProperty(exports2, "toolCallHeader", { enumerable: true, get: function() {
|
|
3067
|
+
return ui_1.toolCallHeader;
|
|
3068
|
+
} });
|
|
3069
|
+
Object.defineProperty(exports2, "toolCallArgs", { enumerable: true, get: function() {
|
|
3070
|
+
return ui_1.toolCallArgs;
|
|
3071
|
+
} });
|
|
3072
|
+
Object.defineProperty(exports2, "toolResultBox", { enumerable: true, get: function() {
|
|
3073
|
+
return ui_1.toolResultBox;
|
|
3074
|
+
} });
|
|
3075
|
+
Object.defineProperty(exports2, "sectionHeader", { enumerable: true, get: function() {
|
|
3076
|
+
return ui_1.sectionHeader;
|
|
3077
|
+
} });
|
|
3078
|
+
Object.defineProperty(exports2, "alignedList", { enumerable: true, get: function() {
|
|
3079
|
+
return ui_1.alignedList;
|
|
3080
|
+
} });
|
|
3081
|
+
Object.defineProperty(exports2, "separator", { enumerable: true, get: function() {
|
|
3082
|
+
return ui_1.separator;
|
|
3083
|
+
} });
|
|
477
3084
|
});
|
|
478
3085
|
|
|
479
3086
|
// node_modules/@ideascol/cli-maker/dist/index.js
|
|
480
3087
|
var require_dist = __commonJS((exports2) => {
|
|
481
3088
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
482
|
-
exports2.stripAnsiCodes = exports2.ParamType = exports2.CLI = undefined;
|
|
3089
|
+
exports2.getBuiltInSlashCommands = exports2.renderMarkdown = exports2.InteractiveSession = exports2.hiddenPrompt = exports2.getConfigValue = exports2.getRawConfig = exports2.loadSetupConfig = exports2.createSetupCommand = exports2.formatParameterTable = exports2.createTable = exports2.showInfo = exports2.showWarning = exports2.showError = exports2.showSuccess = exports2.ProgressBar = exports2.ProgressIndicator = exports2.stripAnsiCodes = exports2.ParamType = exports2.CLI = undefined;
|
|
483
3090
|
var command_1 = require_command();
|
|
484
3091
|
Object.defineProperty(exports2, "CLI", { enumerable: true, get: function() {
|
|
485
3092
|
return command_1.CLI;
|
|
@@ -492,6 +3099,59 @@ var require_dist = __commonJS((exports2) => {
|
|
|
492
3099
|
Object.defineProperty(exports2, "stripAnsiCodes", { enumerable: true, get: function() {
|
|
493
3100
|
return common_1.stripAnsiCodes;
|
|
494
3101
|
} });
|
|
3102
|
+
Object.defineProperty(exports2, "ProgressIndicator", { enumerable: true, get: function() {
|
|
3103
|
+
return common_1.ProgressIndicator;
|
|
3104
|
+
} });
|
|
3105
|
+
Object.defineProperty(exports2, "ProgressBar", { enumerable: true, get: function() {
|
|
3106
|
+
return common_1.ProgressBar;
|
|
3107
|
+
} });
|
|
3108
|
+
Object.defineProperty(exports2, "showSuccess", { enumerable: true, get: function() {
|
|
3109
|
+
return common_1.showSuccess;
|
|
3110
|
+
} });
|
|
3111
|
+
Object.defineProperty(exports2, "showError", { enumerable: true, get: function() {
|
|
3112
|
+
return common_1.showError;
|
|
3113
|
+
} });
|
|
3114
|
+
Object.defineProperty(exports2, "showWarning", { enumerable: true, get: function() {
|
|
3115
|
+
return common_1.showWarning;
|
|
3116
|
+
} });
|
|
3117
|
+
Object.defineProperty(exports2, "showInfo", { enumerable: true, get: function() {
|
|
3118
|
+
return common_1.showInfo;
|
|
3119
|
+
} });
|
|
3120
|
+
Object.defineProperty(exports2, "createTable", { enumerable: true, get: function() {
|
|
3121
|
+
return common_1.createTable;
|
|
3122
|
+
} });
|
|
3123
|
+
Object.defineProperty(exports2, "formatParameterTable", { enumerable: true, get: function() {
|
|
3124
|
+
return common_1.formatParameterTable;
|
|
3125
|
+
} });
|
|
3126
|
+
var setup_1 = require_setup();
|
|
3127
|
+
Object.defineProperty(exports2, "createSetupCommand", { enumerable: true, get: function() {
|
|
3128
|
+
return setup_1.createSetupCommand;
|
|
3129
|
+
} });
|
|
3130
|
+
Object.defineProperty(exports2, "loadSetupConfig", { enumerable: true, get: function() {
|
|
3131
|
+
return setup_1.loadSetupConfig;
|
|
3132
|
+
} });
|
|
3133
|
+
Object.defineProperty(exports2, "getRawConfig", { enumerable: true, get: function() {
|
|
3134
|
+
return setup_1.getRawConfig;
|
|
3135
|
+
} });
|
|
3136
|
+
Object.defineProperty(exports2, "getConfigValue", { enumerable: true, get: function() {
|
|
3137
|
+
return setup_1.getConfigValue;
|
|
3138
|
+
} });
|
|
3139
|
+
Object.defineProperty(exports2, "prompt", { enumerable: true, get: function() {
|
|
3140
|
+
return setup_1.prompt;
|
|
3141
|
+
} });
|
|
3142
|
+
Object.defineProperty(exports2, "hiddenPrompt", { enumerable: true, get: function() {
|
|
3143
|
+
return setup_1.hiddenPrompt;
|
|
3144
|
+
} });
|
|
3145
|
+
var index_1 = require_session2();
|
|
3146
|
+
Object.defineProperty(exports2, "InteractiveSession", { enumerable: true, get: function() {
|
|
3147
|
+
return index_1.InteractiveSession;
|
|
3148
|
+
} });
|
|
3149
|
+
Object.defineProperty(exports2, "renderMarkdown", { enumerable: true, get: function() {
|
|
3150
|
+
return index_1.renderMarkdown;
|
|
3151
|
+
} });
|
|
3152
|
+
Object.defineProperty(exports2, "getBuiltInSlashCommands", { enumerable: true, get: function() {
|
|
3153
|
+
return index_1.getBuiltInSlashCommands;
|
|
3154
|
+
} });
|
|
495
3155
|
});
|
|
496
3156
|
|
|
497
3157
|
// src/lib/clients/agents-generator/core/ApiError.ts
|
|
@@ -619,7 +3279,7 @@ var OpenAPI;
|
|
|
619
3279
|
var init_OpenAPI = __esm(() => {
|
|
620
3280
|
OpenAPI = {
|
|
621
3281
|
BASE: "",
|
|
622
|
-
VERSION: "main-
|
|
3282
|
+
VERSION: "main-18ea61a3a4dd0d19d2d7aba58dce085c8bf2e17b",
|
|
623
3283
|
WITH_CREDENTIALS: false,
|
|
624
3284
|
CREDENTIALS: "include",
|
|
625
3285
|
TOKEN: undefined,
|
|
@@ -2391,6 +5051,20 @@ var init_AgentFoldersService = __esm(() => {
|
|
|
2391
5051
|
init_request();
|
|
2392
5052
|
});
|
|
2393
5053
|
|
|
5054
|
+
// src/lib/clients/agents-generator/services/AuthService.ts
|
|
5055
|
+
class AuthService {
|
|
5056
|
+
static whoami() {
|
|
5057
|
+
return request(OpenAPI, {
|
|
5058
|
+
method: "GET",
|
|
5059
|
+
url: "/auth/whoami"
|
|
5060
|
+
});
|
|
5061
|
+
}
|
|
5062
|
+
}
|
|
5063
|
+
var init_AuthService = __esm(() => {
|
|
5064
|
+
init_OpenAPI();
|
|
5065
|
+
init_request();
|
|
5066
|
+
});
|
|
5067
|
+
|
|
2394
5068
|
// src/lib/clients/agents-generator/services/ConversationsService.ts
|
|
2395
5069
|
class ConversationsService {
|
|
2396
5070
|
static createConversation(requestBody) {
|
|
@@ -3539,6 +6213,7 @@ var init_agents_generator = __esm(() => {
|
|
|
3539
6213
|
init_AdminWorkspacesService();
|
|
3540
6214
|
init_AgentService();
|
|
3541
6215
|
init_AgentFoldersService();
|
|
6216
|
+
init_AuthService();
|
|
3542
6217
|
init_ConversationsService();
|
|
3543
6218
|
init_CredentialsService();
|
|
3544
6219
|
init_FileLibraryService();
|
|
@@ -3556,6 +6231,57 @@ var init_agents_generator = __esm(() => {
|
|
|
3556
6231
|
init_WorkspacesService();
|
|
3557
6232
|
});
|
|
3558
6233
|
|
|
6234
|
+
// src/lib/config.ts
|
|
6235
|
+
function decodeConfigValue(value) {
|
|
6236
|
+
if (!value)
|
|
6237
|
+
return;
|
|
6238
|
+
if (typeof value === "string")
|
|
6239
|
+
return value;
|
|
6240
|
+
if (typeof value === "object" && value !== null) {
|
|
6241
|
+
const obj = value;
|
|
6242
|
+
if (obj.__b64 && obj.value) {
|
|
6243
|
+
try {
|
|
6244
|
+
return Buffer.from(obj.value, "base64").toString("utf-8");
|
|
6245
|
+
} catch {
|
|
6246
|
+
return;
|
|
6247
|
+
}
|
|
6248
|
+
}
|
|
6249
|
+
}
|
|
6250
|
+
return String(value);
|
|
6251
|
+
}
|
|
6252
|
+
async function getCli() {
|
|
6253
|
+
if (!cliInstance) {
|
|
6254
|
+
const { cli } = await Promise.resolve().then(() => (init_cli(), exports_cli));
|
|
6255
|
+
cliInstance = cli;
|
|
6256
|
+
}
|
|
6257
|
+
return cliInstance;
|
|
6258
|
+
}
|
|
6259
|
+
async function loadAppConfig() {
|
|
6260
|
+
const cli = await getCli();
|
|
6261
|
+
const cfg = await cli.loadConfig();
|
|
6262
|
+
const apiKey = decodeConfigValue(cfg.api_key);
|
|
6263
|
+
const apiUrl = decodeConfigValue(cfg.api_url);
|
|
6264
|
+
if (!apiKey) {
|
|
6265
|
+
throw new Error("API key not configured. Run `agents-generator-sdk setup` first.");
|
|
6266
|
+
}
|
|
6267
|
+
return {
|
|
6268
|
+
apiKey,
|
|
6269
|
+
apiUrl: apiUrl || DEFAULT_CONFIG.apiUrl
|
|
6270
|
+
};
|
|
6271
|
+
}
|
|
6272
|
+
function getConfigFilePath() {
|
|
6273
|
+
const os = require("os");
|
|
6274
|
+
const path = require("path");
|
|
6275
|
+
const safeName = `${CLI_NAME}-config.json`.replace(/[^a-z0-9._-]/gi, "-");
|
|
6276
|
+
return path.join(os.homedir(), ".cli-maker", safeName);
|
|
6277
|
+
}
|
|
6278
|
+
var CLI_NAME = "@ideascol/agents-generator-sdk", DEFAULT_CONFIG, cliInstance = null;
|
|
6279
|
+
var init_config = __esm(() => {
|
|
6280
|
+
DEFAULT_CONFIG = {
|
|
6281
|
+
apiUrl: "https://api.agentsgenerator.dev"
|
|
6282
|
+
};
|
|
6283
|
+
});
|
|
6284
|
+
|
|
3559
6285
|
// src/lib/index.ts
|
|
3560
6286
|
class AgentClient {
|
|
3561
6287
|
admin;
|
|
@@ -3598,7 +6324,8 @@ class AgentClient {
|
|
|
3598
6324
|
apiKeys: AdminApiKeysService,
|
|
3599
6325
|
presence: PresenceService,
|
|
3600
6326
|
schema: SchemaGeneratorService,
|
|
3601
|
-
tokenUsage: TokenUsageService
|
|
6327
|
+
tokenUsage: TokenUsageService,
|
|
6328
|
+
auth: AuthService
|
|
3602
6329
|
};
|
|
3603
6330
|
this.public = {
|
|
3604
6331
|
agents: PublicAgentsService,
|
|
@@ -3667,13 +6394,10 @@ var init_lib = __esm(() => {
|
|
|
3667
6394
|
function processStream() {
|
|
3668
6395
|
reader.read().then(({ done, value }) => {
|
|
3669
6396
|
if (done) {
|
|
3670
|
-
console.log("Stream completado");
|
|
3671
6397
|
if (buffer.length > 0) {
|
|
3672
|
-
console.log("Procesando buffer final:", buffer);
|
|
3673
6398
|
if (isDirectTextMode) {
|
|
3674
6399
|
fullMessage += buffer;
|
|
3675
6400
|
if (callbacks.onMessage) {
|
|
3676
|
-
console.log("Actualizando mensaje final (texto directo):", fullMessage);
|
|
3677
6401
|
callbacks.onMessage(fullMessage);
|
|
3678
6402
|
}
|
|
3679
6403
|
} else {
|
|
@@ -3704,7 +6428,6 @@ var init_lib = __esm(() => {
|
|
|
3704
6428
|
if (buffer.length > 0) {
|
|
3705
6429
|
fullMessage += buffer;
|
|
3706
6430
|
if (callbacks.onMessage) {
|
|
3707
|
-
console.log("Actualizando mensaje final (buffer restante):", fullMessage);
|
|
3708
6431
|
callbacks.onMessage(fullMessage);
|
|
3709
6432
|
}
|
|
3710
6433
|
}
|
|
@@ -3717,18 +6440,15 @@ var init_lib = __esm(() => {
|
|
|
3717
6440
|
}
|
|
3718
6441
|
const chunk = decoder.decode(value, { stream: true });
|
|
3719
6442
|
buffer += chunk;
|
|
3720
|
-
console.log("Chunk recibido:", chunk);
|
|
3721
6443
|
let eventEnd = buffer.indexOf(`
|
|
3722
6444
|
|
|
3723
6445
|
`);
|
|
3724
6446
|
if (buffer.length > 50 && eventEnd === -1 && !isDirectTextMode) {
|
|
3725
6447
|
isDirectTextMode = true;
|
|
3726
|
-
console.log("Detectado modo texto directo");
|
|
3727
6448
|
}
|
|
3728
6449
|
if (isDirectTextMode) {
|
|
3729
6450
|
fullMessage += chunk;
|
|
3730
6451
|
if (callbacks.onMessage) {
|
|
3731
|
-
console.log("Actualizando con texto directo:", fullMessage);
|
|
3732
6452
|
callbacks.onMessage(fullMessage);
|
|
3733
6453
|
}
|
|
3734
6454
|
} else {
|
|
@@ -3739,7 +6459,6 @@ var init_lib = __esm(() => {
|
|
|
3739
6459
|
const jsonStr = eventData.substring(6);
|
|
3740
6460
|
try {
|
|
3741
6461
|
const data = JSON.parse(jsonStr);
|
|
3742
|
-
console.log("Evento SSE recibido:", data);
|
|
3743
6462
|
if (data.type === "message" && data.content && callbacks.onMessage) {
|
|
3744
6463
|
fullMessage = data.content;
|
|
3745
6464
|
callbacks.onMessage(fullMessage);
|
|
@@ -3749,12 +6468,10 @@ var init_lib = __esm(() => {
|
|
|
3749
6468
|
callbacks.onTransfer(data.transfer);
|
|
3750
6469
|
}
|
|
3751
6470
|
} catch (e) {
|
|
3752
|
-
console.error("Error al parsear JSON del evento:", e);
|
|
3753
6471
|
if (eventData.startsWith("data: ")) {
|
|
3754
6472
|
const directContent = eventData.substring(6);
|
|
3755
6473
|
fullMessage += directContent;
|
|
3756
6474
|
if (callbacks.onMessage) {
|
|
3757
|
-
console.log("Actualizando con texto SSE simple:", fullMessage);
|
|
3758
6475
|
callbacks.onMessage(fullMessage);
|
|
3759
6476
|
}
|
|
3760
6477
|
} else {
|
|
@@ -3766,7 +6483,6 @@ var init_lib = __esm(() => {
|
|
|
3766
6483
|
} else {
|
|
3767
6484
|
fullMessage += eventData;
|
|
3768
6485
|
if (callbacks.onMessage) {
|
|
3769
|
-
console.log("Actualizando con evento no reconocido:", fullMessage);
|
|
3770
6486
|
callbacks.onMessage(fullMessage);
|
|
3771
6487
|
}
|
|
3772
6488
|
}
|
|
@@ -3778,7 +6494,6 @@ var init_lib = __esm(() => {
|
|
|
3778
6494
|
fullMessage += buffer;
|
|
3779
6495
|
buffer = "";
|
|
3780
6496
|
if (callbacks.onMessage) {
|
|
3781
|
-
console.log("Actualizando con buffer residual:", fullMessage);
|
|
3782
6497
|
callbacks.onMessage(fullMessage);
|
|
3783
6498
|
}
|
|
3784
6499
|
}
|
|
@@ -3850,55 +6565,39 @@ var init_lib = __esm(() => {
|
|
|
3850
6565
|
});
|
|
3851
6566
|
|
|
3852
6567
|
// src/commands/agentsCommand.ts
|
|
3853
|
-
var
|
|
6568
|
+
var commandAgents, agentsCommand_default;
|
|
3854
6569
|
var init_agentsCommand = __esm(() => {
|
|
3855
6570
|
init_lib();
|
|
3856
|
-
|
|
6571
|
+
init_config();
|
|
3857
6572
|
commandAgents = {
|
|
3858
6573
|
name: "getAgents",
|
|
3859
6574
|
description: "Get the list of agents",
|
|
3860
|
-
params: [
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
action: async (args) => {
|
|
3867
|
-
const client = new lib_default({ apiUrl: args.URL, apiToken: "" });
|
|
3868
|
-
const agents = await client.agent.getAgents(0, 100);
|
|
3869
|
-
const agents2 = await client.admin.agents.getAgents(0, 100);
|
|
3870
|
-
const agent = await client.public.agents.getAgent("some-agent-id");
|
|
3871
|
-
const conversation = await client.public.conversations.sendMessageWithStreaming;
|
|
6575
|
+
params: [],
|
|
6576
|
+
action: async () => {
|
|
6577
|
+
const config = await loadAppConfig();
|
|
6578
|
+
const client = new lib_default({ apiUrl: config.apiUrl, apiToken: config.apiKey });
|
|
6579
|
+
const workspaceId = (await client.admin.auth.whoami()).workspace_id;
|
|
6580
|
+
const agents = await client.admin.agents.getAgents(0, 100, workspaceId);
|
|
3872
6581
|
console.log(agents);
|
|
3873
|
-
console.log(agents2);
|
|
3874
6582
|
}
|
|
3875
6583
|
};
|
|
3876
6584
|
agentsCommand_default = commandAgents;
|
|
3877
6585
|
});
|
|
3878
6586
|
|
|
3879
6587
|
// src/commands/rootCommand.ts
|
|
3880
|
-
var
|
|
6588
|
+
var rootCommand, rootCommand_default;
|
|
3881
6589
|
var init_rootCommand = __esm(() => {
|
|
3882
6590
|
init_lib();
|
|
3883
|
-
|
|
6591
|
+
init_config();
|
|
3884
6592
|
rootCommand = {
|
|
3885
6593
|
name: "version",
|
|
3886
6594
|
description: "Get the version of the API",
|
|
3887
|
-
params: [
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
required: false,
|
|
3891
|
-
type: import_cli_maker2.ParamType.Url
|
|
3892
|
-
}, {
|
|
3893
|
-
name: "apiToken",
|
|
3894
|
-
description: "The API token",
|
|
3895
|
-
required: false,
|
|
3896
|
-
type: import_cli_maker2.ParamType.Text
|
|
3897
|
-
}],
|
|
3898
|
-
action: async (args) => {
|
|
6595
|
+
params: [],
|
|
6596
|
+
action: async () => {
|
|
6597
|
+
const config = await loadAppConfig();
|
|
3899
6598
|
const client = new AgentClient({
|
|
3900
|
-
apiUrl:
|
|
3901
|
-
apiToken:
|
|
6599
|
+
apiUrl: config.apiUrl,
|
|
6600
|
+
apiToken: config.apiKey
|
|
3902
6601
|
});
|
|
3903
6602
|
const hello = await client.root.healthCheck();
|
|
3904
6603
|
console.log(hello);
|
|
@@ -3908,42 +6607,323 @@ var init_rootCommand = __esm(() => {
|
|
|
3908
6607
|
});
|
|
3909
6608
|
|
|
3910
6609
|
// src/commands/conversationsCommand.ts
|
|
3911
|
-
var
|
|
6610
|
+
var import_cli_maker, commandConversations, conversationsCommand_default;
|
|
3912
6611
|
var init_conversationsCommand = __esm(() => {
|
|
3913
6612
|
init_agents_generator();
|
|
3914
|
-
|
|
6613
|
+
init_config();
|
|
6614
|
+
import_cli_maker = __toESM(require_dist(), 1);
|
|
3915
6615
|
commandConversations = {
|
|
3916
6616
|
name: "getConversations",
|
|
3917
6617
|
description: "Get the list of conversations",
|
|
3918
6618
|
params: [{
|
|
3919
|
-
name: "URL",
|
|
3920
|
-
description: "The URL of the API",
|
|
3921
|
-
required: true,
|
|
3922
|
-
type: import_cli_maker3.ParamType.Url
|
|
3923
|
-
}, {
|
|
3924
6619
|
name: "conversationId",
|
|
3925
6620
|
description: "The ID of the conversation",
|
|
3926
6621
|
required: true,
|
|
3927
|
-
type:
|
|
6622
|
+
type: import_cli_maker.ParamType.Text
|
|
3928
6623
|
}, {
|
|
3929
6624
|
name: "agentId",
|
|
3930
6625
|
description: "The ID of the agent",
|
|
3931
6626
|
required: true,
|
|
3932
|
-
type:
|
|
6627
|
+
type: import_cli_maker.ParamType.Text
|
|
3933
6628
|
}],
|
|
3934
6629
|
action: async (args) => {
|
|
3935
|
-
|
|
6630
|
+
const config = await loadAppConfig();
|
|
6631
|
+
OpenAPI.BASE = config.apiUrl;
|
|
6632
|
+
OpenAPI.TOKEN = config.apiKey;
|
|
3936
6633
|
const conversationId = args.conversationId;
|
|
3937
6634
|
const agentId = args.agentId;
|
|
3938
6635
|
const conversationList = await ConversationsService.getAgentConversations(agentId);
|
|
3939
6636
|
const conversations = await ConversationsService.getConversation(conversationId);
|
|
6637
|
+
console.log({ conversationList, conversations });
|
|
6638
|
+
}
|
|
6639
|
+
};
|
|
6640
|
+
conversationsCommand_default = commandConversations;
|
|
6641
|
+
});
|
|
6642
|
+
|
|
6643
|
+
// src/commands/chatCommand.ts
|
|
6644
|
+
function formatAgentList(agentList) {
|
|
6645
|
+
if (agentList.length === 0) {
|
|
6646
|
+
return " No agents found.";
|
|
6647
|
+
}
|
|
6648
|
+
return agentList.map((a, i) => ` ${i + 1}. **${a.name}** (${a.id}) — ${a.status || "unknown"}`).join(`
|
|
6649
|
+
`);
|
|
6650
|
+
}
|
|
6651
|
+
function formatConversationList(conversations) {
|
|
6652
|
+
if (conversations.length === 0) {
|
|
6653
|
+
return " No conversations found.";
|
|
6654
|
+
}
|
|
6655
|
+
return conversations.map((c, i) => ` ${i + 1}. ${c.title || "Untitled"} (${c.id}) — ${c.created_at}`).join(`
|
|
6656
|
+
`);
|
|
6657
|
+
}
|
|
6658
|
+
async function initClient() {
|
|
6659
|
+
const config = await loadAppConfig();
|
|
6660
|
+
return new AgentClient({
|
|
6661
|
+
apiUrl: config.apiUrl,
|
|
6662
|
+
apiToken: config.apiKey
|
|
6663
|
+
});
|
|
6664
|
+
}
|
|
6665
|
+
function createMessageStream(agentClient, conversationId, message) {
|
|
6666
|
+
let lastContent = "";
|
|
6667
|
+
const chunks = [];
|
|
6668
|
+
let resolveNext = null;
|
|
6669
|
+
let done = false;
|
|
6670
|
+
let streamError = null;
|
|
6671
|
+
let abortFn = null;
|
|
6672
|
+
function push(chunk) {
|
|
6673
|
+
if (resolveNext) {
|
|
6674
|
+
const r = resolveNext;
|
|
6675
|
+
resolveNext = null;
|
|
6676
|
+
r({ value: chunk, done: false });
|
|
6677
|
+
} else {
|
|
6678
|
+
chunks.push(chunk);
|
|
6679
|
+
}
|
|
6680
|
+
}
|
|
6681
|
+
function finish() {
|
|
6682
|
+
done = true;
|
|
6683
|
+
if (resolveNext) {
|
|
6684
|
+
const r = resolveNext;
|
|
6685
|
+
resolveNext = null;
|
|
6686
|
+
r({ value: "", done: true });
|
|
6687
|
+
}
|
|
6688
|
+
}
|
|
6689
|
+
abortFn = agentClient.sendMessageWithStreaming(conversationId, { content: message }, {
|
|
6690
|
+
onMessage: (content) => {
|
|
6691
|
+
const newChunk = content.slice(lastContent.length);
|
|
6692
|
+
lastContent = content;
|
|
6693
|
+
if (newChunk)
|
|
6694
|
+
push(newChunk);
|
|
6695
|
+
},
|
|
6696
|
+
onTransfer: (transfer) => {
|
|
6697
|
+
push(`
|
|
6698
|
+
\uD83D\uDD04 Transfer: ${transfer.from_agent || "?"} → ${transfer.to_agent || "?"} (${transfer.reason || "no reason"})
|
|
6699
|
+
`);
|
|
6700
|
+
},
|
|
6701
|
+
onDone: () => {
|
|
6702
|
+
finish();
|
|
6703
|
+
},
|
|
6704
|
+
onError: (err) => {
|
|
6705
|
+
streamError = err;
|
|
6706
|
+
finish();
|
|
6707
|
+
}
|
|
6708
|
+
});
|
|
6709
|
+
return {
|
|
6710
|
+
[Symbol.asyncIterator]() {
|
|
3940
6711
|
return {
|
|
3941
|
-
|
|
3942
|
-
|
|
6712
|
+
async next() {
|
|
6713
|
+
if (streamError)
|
|
6714
|
+
throw streamError;
|
|
6715
|
+
if (chunks.length > 0)
|
|
6716
|
+
return { value: chunks.shift(), done: false };
|
|
6717
|
+
if (done)
|
|
6718
|
+
return { value: "", done: true };
|
|
6719
|
+
return new Promise((res) => {
|
|
6720
|
+
resolveNext = res;
|
|
6721
|
+
});
|
|
6722
|
+
},
|
|
6723
|
+
async return() {
|
|
6724
|
+
if (abortFn)
|
|
6725
|
+
abortFn();
|
|
6726
|
+
return { value: "", done: true };
|
|
6727
|
+
}
|
|
3943
6728
|
};
|
|
3944
6729
|
}
|
|
3945
6730
|
};
|
|
3946
|
-
|
|
6731
|
+
}
|
|
6732
|
+
function createChatCommand(cliInstance2) {
|
|
6733
|
+
return {
|
|
6734
|
+
name: "chat",
|
|
6735
|
+
description: "Start an interactive chat session with your agents",
|
|
6736
|
+
params: [],
|
|
6737
|
+
action: async () => {
|
|
6738
|
+
try {
|
|
6739
|
+
client = await initClient();
|
|
6740
|
+
} catch (err) {
|
|
6741
|
+
console.error(`
|
|
6742
|
+
❌ ${err.message}
|
|
6743
|
+
`);
|
|
6744
|
+
return;
|
|
6745
|
+
}
|
|
6746
|
+
try {
|
|
6747
|
+
const workspaceId = (await client.admin.auth.whoami()).workspace_id;
|
|
6748
|
+
agents = await client.admin.agents.getAgents(0, 100, workspaceId);
|
|
6749
|
+
} catch (err) {
|
|
6750
|
+
console.error(`
|
|
6751
|
+
❌ Failed to fetch agents: ${err.message}
|
|
6752
|
+
`);
|
|
6753
|
+
return;
|
|
6754
|
+
}
|
|
6755
|
+
await cliInstance2.startSession({
|
|
6756
|
+
welcomeMessage: [
|
|
6757
|
+
" Welcome to **Agents Generator** Chat",
|
|
6758
|
+
"",
|
|
6759
|
+
" Select an agent and start chatting.",
|
|
6760
|
+
"",
|
|
6761
|
+
` Found **${agents.length}** agent(s):`,
|
|
6762
|
+
"",
|
|
6763
|
+
formatAgentList(agents)
|
|
6764
|
+
].join(`
|
|
6765
|
+
`),
|
|
6766
|
+
tips: [
|
|
6767
|
+
{
|
|
6768
|
+
title: "Getting started",
|
|
6769
|
+
lines: [
|
|
6770
|
+
"Use `/select <number>` to pick an agent",
|
|
6771
|
+
"Then type a message to chat",
|
|
6772
|
+
"Responses stream in real-time"
|
|
6773
|
+
]
|
|
6774
|
+
},
|
|
6775
|
+
{
|
|
6776
|
+
title: "Commands",
|
|
6777
|
+
lines: [
|
|
6778
|
+
"/agents Refresh agent list",
|
|
6779
|
+
"/select <n|id> Select an agent",
|
|
6780
|
+
"/conversations List conversations",
|
|
6781
|
+
"/new New conversation",
|
|
6782
|
+
"/help Show all commands"
|
|
6783
|
+
]
|
|
6784
|
+
}
|
|
6785
|
+
],
|
|
6786
|
+
infoLines: [
|
|
6787
|
+
`v${client.OpenAPI.VERSION} · ${client.OpenAPI.BASE}`
|
|
6788
|
+
],
|
|
6789
|
+
theme: {
|
|
6790
|
+
borderColor: "\x1B[36m",
|
|
6791
|
+
borderStyle: "rounded",
|
|
6792
|
+
promptColor: "\x1B[36m",
|
|
6793
|
+
accentColor: "\x1B[33m"
|
|
6794
|
+
},
|
|
6795
|
+
historySize: 50,
|
|
6796
|
+
tools: [],
|
|
6797
|
+
slashCommands: [
|
|
6798
|
+
{
|
|
6799
|
+
name: "agents",
|
|
6800
|
+
description: "List available agents",
|
|
6801
|
+
action: async (_args, ctx) => {
|
|
6802
|
+
ctx.spinner.start("Fetching agents...");
|
|
6803
|
+
try {
|
|
6804
|
+
const workspaceId = (await client.admin.auth.whoami()).workspace_id;
|
|
6805
|
+
agents = await client.admin.agents.getAgents(0, 100, workspaceId);
|
|
6806
|
+
ctx.spinner.stop();
|
|
6807
|
+
ctx.printMarkdown(`**Agents (${agents.length}):**
|
|
6808
|
+
|
|
6809
|
+
${formatAgentList(agents)}`);
|
|
6810
|
+
} catch (err) {
|
|
6811
|
+
ctx.spinner.stop();
|
|
6812
|
+
ctx.print(`❌ Error: ${err.message}`);
|
|
6813
|
+
}
|
|
6814
|
+
}
|
|
6815
|
+
},
|
|
6816
|
+
{
|
|
6817
|
+
name: "select",
|
|
6818
|
+
description: "Select an agent by number or ID",
|
|
6819
|
+
action: async (args, ctx) => {
|
|
6820
|
+
const input = args.trim();
|
|
6821
|
+
if (!input) {
|
|
6822
|
+
ctx.print("Usage: /select <number or agent-id>");
|
|
6823
|
+
return;
|
|
6824
|
+
}
|
|
6825
|
+
const index = parseInt(input, 10);
|
|
6826
|
+
if (!isNaN(index) && index >= 1 && index <= agents.length) {
|
|
6827
|
+
selectedAgent = agents[index - 1];
|
|
6828
|
+
} else {
|
|
6829
|
+
const found = agents.find((a) => a.id === input || a.name.toLowerCase() === input.toLowerCase());
|
|
6830
|
+
if (found) {
|
|
6831
|
+
selectedAgent = found;
|
|
6832
|
+
} else {
|
|
6833
|
+
ctx.print(`❌ Agent not found: "${input}". Use /agents to see the list.`);
|
|
6834
|
+
return;
|
|
6835
|
+
}
|
|
6836
|
+
}
|
|
6837
|
+
ctx.printMarkdown(`✅ Selected agent: **${selectedAgent.name}** (\`${selectedAgent.id}\`)`);
|
|
6838
|
+
ctx.spinner.start("Creating conversation...");
|
|
6839
|
+
try {
|
|
6840
|
+
activeConversation = await client.public.conversations.createConversation({
|
|
6841
|
+
agent_id: selectedAgent.id,
|
|
6842
|
+
title: `CLI Chat — ${new Date().toLocaleString()}`
|
|
6843
|
+
});
|
|
6844
|
+
ctx.spinner.stop();
|
|
6845
|
+
ctx.printMarkdown(`\uD83D\uDCAC New conversation: \`${activeConversation.id}\`
|
|
6846
|
+
|
|
6847
|
+
Type a message to start chatting.`);
|
|
6848
|
+
} catch (err) {
|
|
6849
|
+
ctx.spinner.stop();
|
|
6850
|
+
ctx.print(`❌ Failed to create conversation: ${err.message}`);
|
|
6851
|
+
activeConversation = null;
|
|
6852
|
+
}
|
|
6853
|
+
}
|
|
6854
|
+
},
|
|
6855
|
+
{
|
|
6856
|
+
name: "conversations",
|
|
6857
|
+
description: "List conversations for the selected agent",
|
|
6858
|
+
action: async (_args, ctx) => {
|
|
6859
|
+
if (!selectedAgent) {
|
|
6860
|
+
ctx.print("No agent selected. Use /select first.");
|
|
6861
|
+
return;
|
|
6862
|
+
}
|
|
6863
|
+
ctx.spinner.start("Fetching conversations...");
|
|
6864
|
+
try {
|
|
6865
|
+
const convos = await client.conversations.getAgentConversations(selectedAgent.id, 0, 20);
|
|
6866
|
+
ctx.spinner.stop();
|
|
6867
|
+
ctx.printMarkdown(`**Conversations for ${selectedAgent.name}:**
|
|
6868
|
+
|
|
6869
|
+
${formatConversationList(convos)}`);
|
|
6870
|
+
} catch (err) {
|
|
6871
|
+
ctx.spinner.stop();
|
|
6872
|
+
ctx.print(`❌ Error: ${err.message}`);
|
|
6873
|
+
}
|
|
6874
|
+
}
|
|
6875
|
+
},
|
|
6876
|
+
{
|
|
6877
|
+
name: "new",
|
|
6878
|
+
description: "Create a new conversation for the selected agent",
|
|
6879
|
+
action: async (_args, ctx) => {
|
|
6880
|
+
if (!selectedAgent) {
|
|
6881
|
+
ctx.print("No agent selected. Use /select first.");
|
|
6882
|
+
return;
|
|
6883
|
+
}
|
|
6884
|
+
ctx.spinner.start("Creating conversation...");
|
|
6885
|
+
try {
|
|
6886
|
+
activeConversation = await client.public.conversations.createConversation({
|
|
6887
|
+
agent_id: selectedAgent.id,
|
|
6888
|
+
title: `CLI Chat — ${new Date().toLocaleString()}`
|
|
6889
|
+
});
|
|
6890
|
+
ctx.spinner.stop();
|
|
6891
|
+
ctx.printMarkdown(`\uD83D\uDCAC New conversation: \`${activeConversation.id}\`
|
|
6892
|
+
|
|
6893
|
+
Type a message to start chatting.`);
|
|
6894
|
+
} catch (err) {
|
|
6895
|
+
ctx.spinner.stop();
|
|
6896
|
+
ctx.print(`❌ Failed to create conversation: ${err.message}`);
|
|
6897
|
+
}
|
|
6898
|
+
}
|
|
6899
|
+
}
|
|
6900
|
+
],
|
|
6901
|
+
onMessage: async (message, ctx) => {
|
|
6902
|
+
if (!selectedAgent) {
|
|
6903
|
+
ctx.printMarkdown("⚠️ No agent selected. Use `/select <number>` to pick an agent first.\n\n" + formatAgentList(agents));
|
|
6904
|
+
return;
|
|
6905
|
+
}
|
|
6906
|
+
if (!activeConversation) {
|
|
6907
|
+
ctx.print("⚠️ No active conversation. Use /new to create one.");
|
|
6908
|
+
return;
|
|
6909
|
+
}
|
|
6910
|
+
const stream = createMessageStream(client, activeConversation.id, message);
|
|
6911
|
+
await ctx.printStream(stream);
|
|
6912
|
+
},
|
|
6913
|
+
onEnd: async (ctx) => {
|
|
6914
|
+
console.log(` Total messages: ${ctx.history.length}`);
|
|
6915
|
+
selectedAgent = null;
|
|
6916
|
+
activeConversation = null;
|
|
6917
|
+
}
|
|
6918
|
+
});
|
|
6919
|
+
}
|
|
6920
|
+
};
|
|
6921
|
+
}
|
|
6922
|
+
var client = null, agents, selectedAgent = null, activeConversation = null;
|
|
6923
|
+
var init_chatCommand = __esm(() => {
|
|
6924
|
+
init_lib();
|
|
6925
|
+
init_config();
|
|
6926
|
+
agents = [];
|
|
3947
6927
|
});
|
|
3948
6928
|
|
|
3949
6929
|
// src/cli.ts
|
|
@@ -3951,21 +6931,94 @@ var exports_cli = {};
|
|
|
3951
6931
|
__export(exports_cli, {
|
|
3952
6932
|
cli: () => cli
|
|
3953
6933
|
});
|
|
3954
|
-
|
|
6934
|
+
function truncateValue(value, showFull = false) {
|
|
6935
|
+
if (!value)
|
|
6936
|
+
return "<not set>";
|
|
6937
|
+
const str = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
6938
|
+
if (showFull)
|
|
6939
|
+
return str;
|
|
6940
|
+
if (str.length <= 8)
|
|
6941
|
+
return "****";
|
|
6942
|
+
return str.substring(0, 4) + "..." + str.substring(str.length - 4);
|
|
6943
|
+
}
|
|
6944
|
+
var import_cli_maker2, import_fs, cli, args, isSetupCommand, isHelpCommand, isVersionCommand, isShowConfigCommand, cleanArgv;
|
|
3955
6945
|
var init_cli = __esm(() => {
|
|
3956
6946
|
init_agents_generator();
|
|
6947
|
+
init_config();
|
|
3957
6948
|
init_agentsCommand();
|
|
3958
6949
|
init_rootCommand();
|
|
3959
6950
|
init_conversationsCommand();
|
|
3960
|
-
|
|
3961
|
-
|
|
6951
|
+
init_chatCommand();
|
|
6952
|
+
import_cli_maker2 = __toESM(require_dist(), 1);
|
|
6953
|
+
import_fs = __toESM(require("fs"));
|
|
6954
|
+
cli = new import_cli_maker2.CLI("@ideascol/agents-generator-sdk", "agents-generator-sdk", {
|
|
3962
6955
|
interactive: true,
|
|
3963
6956
|
version: OpenAPI.VERSION
|
|
3964
6957
|
});
|
|
6958
|
+
cli.setupCommand({
|
|
6959
|
+
name: "setup",
|
|
6960
|
+
description: "Configure API credentials for agents-generator",
|
|
6961
|
+
steps: [
|
|
6962
|
+
{ name: "api_key", description: "API token (JWT)", required: true, type: import_cli_maker2.ParamType.Password },
|
|
6963
|
+
{ name: "api_url", description: "API base URL", required: true, type: import_cli_maker2.ParamType.Url, defaultValue: "https://api.agentsgenerator.dev" }
|
|
6964
|
+
],
|
|
6965
|
+
encryption: {
|
|
6966
|
+
enabled: true,
|
|
6967
|
+
prompt: "Passphrase to encrypt your credentials"
|
|
6968
|
+
}
|
|
6969
|
+
});
|
|
6970
|
+
cli.command({
|
|
6971
|
+
name: "show-config",
|
|
6972
|
+
description: "Show your current configuration",
|
|
6973
|
+
params: [],
|
|
6974
|
+
action: async () => {
|
|
6975
|
+
const cfgPath = getConfigFilePath();
|
|
6976
|
+
const showRaw = process.argv.includes("--raw");
|
|
6977
|
+
if (!import_fs.default.existsSync(cfgPath)) {
|
|
6978
|
+
console.log("\n⚠️ No configuration found. Run `agents-generator-sdk setup` first.\n");
|
|
6979
|
+
return;
|
|
6980
|
+
}
|
|
6981
|
+
console.log(`
|
|
6982
|
+
\uD83D\uDCC1 Config file: ` + cfgPath);
|
|
6983
|
+
try {
|
|
6984
|
+
const cfg = await cli.loadConfig();
|
|
6985
|
+
const sensitiveKeys = ["api_key"];
|
|
6986
|
+
console.log(`
|
|
6987
|
+
✅ Configuration:`);
|
|
6988
|
+
console.log("─".repeat(50));
|
|
6989
|
+
for (const [key, value] of Object.entries(cfg)) {
|
|
6990
|
+
const decoded = decodeConfigValue(value);
|
|
6991
|
+
const display = sensitiveKeys.includes(key) ? truncateValue(decoded, showRaw) : String(decoded || "<not set>");
|
|
6992
|
+
console.log(` ${key.padEnd(20)} ${display}`);
|
|
6993
|
+
}
|
|
6994
|
+
console.log("─".repeat(50));
|
|
6995
|
+
if (!showRaw) {
|
|
6996
|
+
console.log(`
|
|
6997
|
+
\uD83D\uDCA1 Use --raw to show full values`);
|
|
6998
|
+
}
|
|
6999
|
+
} catch (err) {
|
|
7000
|
+
console.error(`
|
|
7001
|
+
❌ Error loading config: ${err.message}`);
|
|
7002
|
+
}
|
|
7003
|
+
}
|
|
7004
|
+
});
|
|
3965
7005
|
cli.command(rootCommand_default);
|
|
3966
7006
|
cli.command(agentsCommand_default);
|
|
3967
7007
|
cli.command(conversationsCommand_default);
|
|
3968
|
-
cli.
|
|
7008
|
+
cli.command(createChatCommand(cli));
|
|
7009
|
+
args = process.argv.slice(2);
|
|
7010
|
+
isSetupCommand = args[0] === "setup";
|
|
7011
|
+
isHelpCommand = args.includes("--help") || args.includes("-h");
|
|
7012
|
+
isVersionCommand = args[0] === "version" || args.includes("--version") || args.includes("-v");
|
|
7013
|
+
isShowConfigCommand = args[0] === "show-config";
|
|
7014
|
+
if (!import_fs.default.existsSync(getConfigFilePath()) && !isSetupCommand && !isHelpCommand && !isVersionCommand && !isShowConfigCommand) {
|
|
7015
|
+
console.log(`
|
|
7016
|
+
⚠️ No configuration found. Running setup wizard...
|
|
7017
|
+
`);
|
|
7018
|
+
process.argv = [process.argv[0], process.argv[1], "setup"];
|
|
7019
|
+
}
|
|
7020
|
+
cleanArgv = process.argv.filter((a) => a !== "--raw");
|
|
7021
|
+
cli.parse(cleanArgv);
|
|
3969
7022
|
});
|
|
3970
7023
|
|
|
3971
7024
|
// src/bin/cli.ts
|