@poolzin/pool-bot 2026.4.42 → 2026.4.43
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/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infer-cli.d.ts","sourceRoot":"","sources":["../../src/cli/infer-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkDzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"infer-cli.d.ts","sourceRoot":"","sources":["../../src/cli/infer-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkDzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,QAobhD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Config TUI - Interactive plugin configuration prompts
|
|
3
|
+
*
|
|
4
|
+
* Provides interactive prompts for configuring plugins during install/setup.
|
|
5
|
+
* Integrates with existing plugins CLI for guided configuration flows.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { promptPluginConfig } from "./plugins-config-tui.js";
|
|
9
|
+
* const config = await promptPluginConfig(pluginId, pluginManifest);
|
|
10
|
+
*/
|
|
11
|
+
type ConfigField = {
|
|
12
|
+
key: string;
|
|
13
|
+
label: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
type: "string" | "number" | "boolean" | "select" | "secret";
|
|
16
|
+
default?: unknown;
|
|
17
|
+
options?: string[];
|
|
18
|
+
required?: boolean;
|
|
19
|
+
validate?: (value: unknown) => string | null;
|
|
20
|
+
};
|
|
21
|
+
type PluginManifest = {
|
|
22
|
+
name?: string;
|
|
23
|
+
version?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
poolbot?: {
|
|
26
|
+
config?: {
|
|
27
|
+
fields?: ConfigField[];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
type PluginConfigResult = Record<string, unknown>;
|
|
32
|
+
/**
|
|
33
|
+
* Prompt user for plugin configuration interactively.
|
|
34
|
+
*
|
|
35
|
+
* @param pluginId - Plugin identifier
|
|
36
|
+
* @param manifest - Plugin manifest with config schema
|
|
37
|
+
* @param options - Optional config values (pre-filled)
|
|
38
|
+
* @returns Configured values
|
|
39
|
+
*/
|
|
40
|
+
export declare function promptPluginConfig(pluginId: string, manifest: PluginManifest, options?: PluginConfigResult): Promise<PluginConfigResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Display plugin configuration summary.
|
|
43
|
+
*/
|
|
44
|
+
export declare function displayPluginConfigSummary(pluginId: string, config: PluginConfigResult): void;
|
|
45
|
+
/**
|
|
46
|
+
* Confirm plugin installation with config summary.
|
|
47
|
+
*/
|
|
48
|
+
export declare function confirmPluginInstall(pluginId: string, config: PluginConfigResult): Promise<boolean>;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=plugins-config-tui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins-config-tui.d.ts","sourceRoot":"","sources":["../../src/cli/plugins-config-tui.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,KAAK,WAAW,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC;CAC9C,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE;YACP,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;SACxB,CAAC;KACH,CAAC;CACH,CAAC;AAEF,KAAK,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA8HlD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAuD7B;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,GACzB,IAAI,CAqBN;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,OAAO,CAAC,CAUlB"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Config TUI - Interactive plugin configuration prompts
|
|
3
|
+
*
|
|
4
|
+
* Provides interactive prompts for configuring plugins during install/setup.
|
|
5
|
+
* Integrates with existing plugins CLI for guided configuration flows.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { promptPluginConfig } from "./plugins-config-tui.js";
|
|
9
|
+
* const config = await promptPluginConfig(pluginId, pluginManifest);
|
|
10
|
+
*/
|
|
11
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
12
|
+
import readline from "node:readline/promises";
|
|
13
|
+
import { isYes } from "../globals.js";
|
|
14
|
+
async function createReadlineInterface() {
|
|
15
|
+
return readline.createInterface({ input, output });
|
|
16
|
+
}
|
|
17
|
+
async function promptText(rl, question, defaultValue) {
|
|
18
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : "";
|
|
19
|
+
const answer = (await rl.question(`${question}${suffix}: `)).trim();
|
|
20
|
+
return answer || defaultValue || "";
|
|
21
|
+
}
|
|
22
|
+
async function promptSecret(rl, question) {
|
|
23
|
+
// Note: readline doesn't support hidden input in Node.js without external deps
|
|
24
|
+
// For now, just warn user
|
|
25
|
+
console.log("(Input will be visible - consider using environment variables for secrets)");
|
|
26
|
+
return await promptText(rl, question);
|
|
27
|
+
}
|
|
28
|
+
async function promptNumber(rl, question, defaultValue) {
|
|
29
|
+
const suffix = defaultValue !== undefined ? ` [${defaultValue}]` : "";
|
|
30
|
+
const answer = (await rl.question(`${question}${suffix}: `)).trim();
|
|
31
|
+
if (!answer && defaultValue !== undefined)
|
|
32
|
+
return defaultValue;
|
|
33
|
+
const num = Number.parseInt(answer, 10);
|
|
34
|
+
if (Number.isNaN(num)) {
|
|
35
|
+
console.log("Please enter a valid number");
|
|
36
|
+
return await promptNumber(rl, question, defaultValue);
|
|
37
|
+
}
|
|
38
|
+
return num;
|
|
39
|
+
}
|
|
40
|
+
async function promptBoolean(rl, question, defaultValue) {
|
|
41
|
+
const defaultStr = defaultValue === true ? "Y/n" : defaultValue === false ? "y/N" : "y/n";
|
|
42
|
+
const answer = (await rl.question(`${question} [${defaultStr}]: `)).trim().toLowerCase();
|
|
43
|
+
if (!answer)
|
|
44
|
+
return defaultValue ?? false;
|
|
45
|
+
return answer.startsWith("y");
|
|
46
|
+
}
|
|
47
|
+
async function promptSelect(rl, question, options, defaultValue) {
|
|
48
|
+
console.log(question);
|
|
49
|
+
options.forEach((opt, i) => {
|
|
50
|
+
const defaultMarker = opt === defaultValue ? " (default)" : "";
|
|
51
|
+
console.log(` ${i + 1}. ${opt}${defaultMarker}`);
|
|
52
|
+
});
|
|
53
|
+
const answer = (await rl.question("Select option (number): ")).trim();
|
|
54
|
+
const index = Number.parseInt(answer, 10) - 1;
|
|
55
|
+
if (Number.isNaN(index) || index < 0 || index >= options.length) {
|
|
56
|
+
console.log("Invalid selection");
|
|
57
|
+
return await promptSelect(rl, question, options, defaultValue);
|
|
58
|
+
}
|
|
59
|
+
return options[index];
|
|
60
|
+
}
|
|
61
|
+
async function promptField(rl, field) {
|
|
62
|
+
const { key, label, description, type, default: defaultValue, options, required, validate } = field;
|
|
63
|
+
if (description) {
|
|
64
|
+
console.log(` ${label}: ${description}`);
|
|
65
|
+
}
|
|
66
|
+
let value;
|
|
67
|
+
switch (type) {
|
|
68
|
+
case "string":
|
|
69
|
+
value = await promptText(rl, label, defaultValue);
|
|
70
|
+
break;
|
|
71
|
+
case "secret":
|
|
72
|
+
value = await promptSecret(rl, label);
|
|
73
|
+
break;
|
|
74
|
+
case "number":
|
|
75
|
+
value = await promptNumber(rl, label, defaultValue);
|
|
76
|
+
break;
|
|
77
|
+
case "boolean":
|
|
78
|
+
value = await promptBoolean(rl, label, defaultValue);
|
|
79
|
+
break;
|
|
80
|
+
case "select":
|
|
81
|
+
if (!options || options.length === 0) {
|
|
82
|
+
throw new Error(`Select field "${key}" has no options`);
|
|
83
|
+
}
|
|
84
|
+
value = await promptSelect(rl, label, options, defaultValue);
|
|
85
|
+
break;
|
|
86
|
+
default:
|
|
87
|
+
throw new Error(`Unknown field type: ${type}`);
|
|
88
|
+
}
|
|
89
|
+
// Validation
|
|
90
|
+
if (required && (value === undefined || value === null || value === "")) {
|
|
91
|
+
console.log(` ⚠️ ${label} is required`);
|
|
92
|
+
return await promptField(rl, field);
|
|
93
|
+
}
|
|
94
|
+
if (validate) {
|
|
95
|
+
const error = validate(value);
|
|
96
|
+
if (error) {
|
|
97
|
+
console.log(` ⚠️ ${error}`);
|
|
98
|
+
return await promptField(rl, field);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Prompt user for plugin configuration interactively.
|
|
105
|
+
*
|
|
106
|
+
* @param pluginId - Plugin identifier
|
|
107
|
+
* @param manifest - Plugin manifest with config schema
|
|
108
|
+
* @param options - Optional config values (pre-filled)
|
|
109
|
+
* @returns Configured values
|
|
110
|
+
*/
|
|
111
|
+
export async function promptPluginConfig(pluginId, manifest, options) {
|
|
112
|
+
const configFields = manifest.poolbot?.config?.fields || [];
|
|
113
|
+
if (configFields.length === 0) {
|
|
114
|
+
// No config fields - nothing to prompt
|
|
115
|
+
return options || {};
|
|
116
|
+
}
|
|
117
|
+
// Honor global --yes flag
|
|
118
|
+
if (isYes()) {
|
|
119
|
+
// Use defaults or provided options
|
|
120
|
+
const result = { ...options };
|
|
121
|
+
for (const field of configFields) {
|
|
122
|
+
if (!(field.key in result) && field.default !== undefined) {
|
|
123
|
+
result[field.key] = field.default;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
console.log("");
|
|
129
|
+
console.log(`Configuring plugin: ${pluginId}`);
|
|
130
|
+
if (manifest.name) {
|
|
131
|
+
console.log(` ${manifest.name}${manifest.version ? ` v${manifest.version}` : ""}`);
|
|
132
|
+
}
|
|
133
|
+
if (manifest.description) {
|
|
134
|
+
console.log(` ${manifest.description}`);
|
|
135
|
+
}
|
|
136
|
+
console.log("");
|
|
137
|
+
console.log("Enter configuration values (press Enter for defaults):");
|
|
138
|
+
console.log("─────────────────────────────────────────");
|
|
139
|
+
const rl = await createReadlineInterface();
|
|
140
|
+
const result = { ...options };
|
|
141
|
+
try {
|
|
142
|
+
for (const field of configFields) {
|
|
143
|
+
// Skip if already provided
|
|
144
|
+
if (field.key in result) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const value = await promptField(rl, field);
|
|
148
|
+
result[field.key] = value;
|
|
149
|
+
console.log("");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
rl.close();
|
|
154
|
+
}
|
|
155
|
+
console.log("─────────────────────────────────────────");
|
|
156
|
+
console.log("Configuration complete!");
|
|
157
|
+
console.log("");
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Display plugin configuration summary.
|
|
162
|
+
*/
|
|
163
|
+
export function displayPluginConfigSummary(pluginId, config) {
|
|
164
|
+
console.log("");
|
|
165
|
+
console.log(`Plugin Configuration: ${pluginId}`);
|
|
166
|
+
console.log("─────────────────────────────────────────");
|
|
167
|
+
const entries = Object.entries(config);
|
|
168
|
+
if (entries.length === 0) {
|
|
169
|
+
console.log(" (no configuration)");
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
for (const [key, value] of entries) {
|
|
173
|
+
const masked = key.toLowerCase().includes("secret") ||
|
|
174
|
+
key.toLowerCase().includes("token") ||
|
|
175
|
+
key.toLowerCase().includes("password") ||
|
|
176
|
+
key.toLowerCase().includes("key")
|
|
177
|
+
? "****"
|
|
178
|
+
: String(value);
|
|
179
|
+
console.log(` ${key}: ${masked}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
console.log("");
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Confirm plugin installation with config summary.
|
|
186
|
+
*/
|
|
187
|
+
export async function confirmPluginInstall(pluginId, config) {
|
|
188
|
+
displayPluginConfigSummary(pluginId, config);
|
|
189
|
+
const rl = await createReadlineInterface();
|
|
190
|
+
try {
|
|
191
|
+
const answer = (await rl.question("Proceed with installation? [Y/n]: ")).trim().toLowerCase();
|
|
192
|
+
return !answer || answer.startsWith("y");
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
rl.close();
|
|
196
|
+
}
|
|
197
|
+
}
|