@poolzin/pool-bot 2026.4.43 → 2026.4.45
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/agents/model-catalog-gemma4.d.ts +6 -0
- package/dist/agents/model-catalog-gemma4.d.ts.map +1 -0
- package/dist/agents/model-catalog-gemma4.js +17 -0
- package/dist/agents/model-catalog.d.ts.map +1 -1
- package/dist/agents/model-catalog.js +7 -0
- package/dist/agents/tools/music-edit-tool.d.ts +9 -0
- package/dist/agents/tools/music-edit-tool.d.ts.map +1 -0
- package/dist/agents/tools/music-edit-tool.js +46 -0
- package/dist/agents/tools/video-edit-tool.d.ts +9 -0
- package/dist/agents/tools/video-edit-tool.d.ts.map +1 -0
- package/dist/agents/tools/video-edit-tool.js +46 -0
- package/dist/build-info.json +3 -3
- package/dist/cli/completion.d.ts +15 -0
- package/dist/cli/completion.d.ts.map +1 -0
- package/dist/cli/completion.js +183 -0
- package/dist/cli/onboard-cli.d.ts +20 -0
- package/dist/cli/onboard-cli.d.ts.map +1 -0
- package/dist/cli/onboard-cli.js +443 -0
- package/dist/cli/plugins-config-tui.d.ts.map +1 -1
- package/dist/cli/plugins-config-tui.js +1 -1
- package/dist/cli/program/register.subclis.d.ts.map +1 -1
- package/dist/cli/program/register.subclis.js +18 -0
- package/dist/cli/sessions-checkpoints-cli.d.ts +6 -0
- package/dist/cli/sessions-checkpoints-cli.d.ts.map +1 -0
- package/dist/cli/sessions-checkpoints-cli.js +117 -0
- package/dist/cli/webhooks-cli.d.ts +13 -0
- package/dist/cli/webhooks-cli.d.ts.map +1 -1
- package/dist/cli/webhooks-cli.js +323 -130
- package/dist/errors/user-friendly-errors.d.ts +23 -0
- package/dist/errors/user-friendly-errors.d.ts.map +1 -0
- package/dist/errors/user-friendly-errors.js +182 -0
- package/dist/infra/net/fetch-guard.d.ts.map +1 -1
- package/dist/memory/wiki/store.d.ts +53 -0
- package/dist/memory/wiki/store.d.ts.map +1 -0
- package/dist/memory/wiki/store.js +222 -0
- package/dist/memory/wiki/types.d.ts +57 -0
- package/dist/memory/wiki/types.d.ts.map +1 -0
- package/dist/memory/wiki/types.js +6 -0
- package/dist/plugins/webhook-ingress.d.ts +104 -0
- package/dist/plugins/webhook-ingress.d.ts.map +1 -0
- package/dist/plugins/webhook-ingress.js +287 -0
- package/dist/providers/ollama-vision.d.ts +30 -0
- package/dist/providers/ollama-vision.d.ts.map +1 -0
- package/dist/providers/ollama-vision.js +62 -0
- package/dist/sessions/checkpoints.d.ts +76 -0
- package/dist/sessions/checkpoints.d.ts.map +1 -0
- package/dist/sessions/checkpoints.js +162 -0
- package/dist/slack/channel.d.ts.map +1 -1
- package/dist/slack/channel.js +13 -2
- package/package.json +1 -1
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guided Onboarding CLI - Step-by-step PoolBot setup wizard
|
|
3
|
+
*
|
|
4
|
+
* Interactive wizard that guides users through:
|
|
5
|
+
* 1. System checks
|
|
6
|
+
* 2. Gateway setup
|
|
7
|
+
* 3. Model/auth configuration
|
|
8
|
+
* 4. Channel setup (Telegram, Discord, etc.)
|
|
9
|
+
* 5. Memory/skills configuration
|
|
10
|
+
* 6. Final validation
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* poolbot onboard # Full interactive onboarding
|
|
14
|
+
* poolbot onboard --skip-gateway # Skip gateway setup
|
|
15
|
+
* poolbot onboard --skip-channels # Skip channel setup
|
|
16
|
+
* poolbot onboard --yes # Use defaults (non-interactive)
|
|
17
|
+
*/
|
|
18
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
19
|
+
import readline from "node:readline/promises";
|
|
20
|
+
import { loadConfig, writeConfigFile } from "../config/config.js";
|
|
21
|
+
import { defaultRuntime } from "../runtime.js";
|
|
22
|
+
import { theme } from "../terminal/theme.js";
|
|
23
|
+
import { danger, success } from "../globals.js";
|
|
24
|
+
import { formatDocsLink } from "../terminal/links.js";
|
|
25
|
+
import { isYes } from "../globals.js";
|
|
26
|
+
async function createReadlineInterface() {
|
|
27
|
+
return readline.createInterface({ input, output });
|
|
28
|
+
}
|
|
29
|
+
function printHeader() {
|
|
30
|
+
console.log("");
|
|
31
|
+
console.log(theme.heading("🎱 Welcome to Pool Bot Onboarding!"));
|
|
32
|
+
console.log(theme.muted("─────────────────────────────────────────"));
|
|
33
|
+
console.log("");
|
|
34
|
+
console.log("This wizard will guide you through setting up Pool Bot.");
|
|
35
|
+
console.log("Press Ctrl+C at any time to exit.");
|
|
36
|
+
console.log("");
|
|
37
|
+
}
|
|
38
|
+
function printStepHeader(step, total, title) {
|
|
39
|
+
console.log("");
|
|
40
|
+
console.log(theme.heading(`Step ${step}/${total}: ${title}`));
|
|
41
|
+
console.log(theme.muted("─────────────────────────────────────────"));
|
|
42
|
+
}
|
|
43
|
+
function printSuccess(message) {
|
|
44
|
+
console.log("");
|
|
45
|
+
console.log(success(`✓ ${message}`));
|
|
46
|
+
}
|
|
47
|
+
function printWarning(message) {
|
|
48
|
+
console.log("");
|
|
49
|
+
console.log(theme.warn(`⚠ ${message}`));
|
|
50
|
+
}
|
|
51
|
+
function printError(message) {
|
|
52
|
+
console.log("");
|
|
53
|
+
console.log(danger(`✗ ${message}`));
|
|
54
|
+
}
|
|
55
|
+
async function promptYesNo(rl, question, defaultYes = true) {
|
|
56
|
+
if (isYes())
|
|
57
|
+
return true;
|
|
58
|
+
const suffix = defaultYes ? " [Y/n]" : " [y/N]";
|
|
59
|
+
const answer = (await rl.question(`${question}${suffix}: `)).trim().toLowerCase();
|
|
60
|
+
if (!answer)
|
|
61
|
+
return defaultYes;
|
|
62
|
+
return answer.startsWith("y");
|
|
63
|
+
}
|
|
64
|
+
async function promptText(rl, question, defaultValue, required = false) {
|
|
65
|
+
if (isYes() && defaultValue)
|
|
66
|
+
return defaultValue;
|
|
67
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : "";
|
|
68
|
+
while (true) {
|
|
69
|
+
const answer = (await rl.question(`${question}${suffix}: `)).trim();
|
|
70
|
+
if (answer || !required) {
|
|
71
|
+
return answer || defaultValue || "";
|
|
72
|
+
}
|
|
73
|
+
console.log(theme.warn("This field is required. Please enter a value."));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function promptSelect(rl, question, options, defaultValue) {
|
|
77
|
+
if (isYes() && defaultValue)
|
|
78
|
+
return defaultValue;
|
|
79
|
+
console.log(question);
|
|
80
|
+
options.forEach((opt, i) => {
|
|
81
|
+
const defaultMarker = opt.value === defaultValue ? theme.success(" (default)") : "";
|
|
82
|
+
console.log(` ${i + 1}. ${opt.label}${defaultMarker}`);
|
|
83
|
+
});
|
|
84
|
+
while (true) {
|
|
85
|
+
const answer = (await rl.question("Select option (number): ")).trim();
|
|
86
|
+
if (!answer && defaultValue)
|
|
87
|
+
return defaultValue;
|
|
88
|
+
const index = Number.parseInt(answer, 10) - 1;
|
|
89
|
+
if (!Number.isNaN(index) && index >= 0 && index < options.length) {
|
|
90
|
+
return options[index].value;
|
|
91
|
+
}
|
|
92
|
+
console.log(theme.warn("Invalid selection. Please enter a number."));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Step 1: System Checks
|
|
96
|
+
async function runSystemChecks(_options) {
|
|
97
|
+
printStepHeader(1, 6, "System Checks");
|
|
98
|
+
const checks = [
|
|
99
|
+
{
|
|
100
|
+
name: "Node.js version",
|
|
101
|
+
pass: process.version.startsWith("v22") || process.version.startsWith("v20"),
|
|
102
|
+
},
|
|
103
|
+
{ name: "Home directory", pass: Boolean(process.env.HOME) },
|
|
104
|
+
{ name: "Config directory writable", pass: true }, // Assume OK for now
|
|
105
|
+
];
|
|
106
|
+
// Validation result tracking
|
|
107
|
+
for (const check of checks) {
|
|
108
|
+
const icon = check.pass ? theme.success("✓") : theme.warn("⚠");
|
|
109
|
+
console.log(` ${icon} ${check.name}${check.message ? `: ${check.message}` : ""}`);
|
|
110
|
+
// Track failures
|
|
111
|
+
}
|
|
112
|
+
printSuccess("System checks complete");
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
// Step 2: Gateway Setup
|
|
116
|
+
async function runGatewaySetup(_options) {
|
|
117
|
+
if (_options.skipGateway) {
|
|
118
|
+
printWarning("Skipping gateway setup (--skip-gateway)");
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
printStepHeader(2, 6, "Gateway Configuration");
|
|
122
|
+
const rl = await createReadlineInterface();
|
|
123
|
+
const config = loadConfig();
|
|
124
|
+
try {
|
|
125
|
+
console.log("");
|
|
126
|
+
console.log("Pool Bot uses a gateway to manage agents and channels.");
|
|
127
|
+
console.log("");
|
|
128
|
+
// Gateway mode
|
|
129
|
+
const mode = await promptSelect(rl, "Gateway mode:", [
|
|
130
|
+
{ value: "local", label: "Local (run on this machine)" },
|
|
131
|
+
{ value: "remote", label: "Remote (connect to existing gateway)" },
|
|
132
|
+
], config.gateway?.mode || "local");
|
|
133
|
+
if (!config.gateway)
|
|
134
|
+
config.gateway = {};
|
|
135
|
+
config.gateway.mode = mode;
|
|
136
|
+
if (mode === "local") {
|
|
137
|
+
// Local gateway setup
|
|
138
|
+
const port = await promptText(rl, "Gateway port", "18789");
|
|
139
|
+
config.gateway.port = Number.parseInt(port, 10);
|
|
140
|
+
// Auth mode
|
|
141
|
+
const authMode = await promptSelect(rl, "Authentication mode:", [
|
|
142
|
+
{ value: "token", label: "Token-based (recommended)" },
|
|
143
|
+
{ value: "password", label: "Password-based" },
|
|
144
|
+
], "token");
|
|
145
|
+
if (!config.gateway.auth)
|
|
146
|
+
config.gateway.auth = {};
|
|
147
|
+
config.gateway.auth.mode = authMode;
|
|
148
|
+
if (authMode === "token") {
|
|
149
|
+
const token = await promptText(rl, "Gateway token (min 16 chars)", undefined, true);
|
|
150
|
+
if (token.length < 16) {
|
|
151
|
+
printError("Token must be at least 16 characters");
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
config.gateway.auth.token = token;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Remote gateway setup
|
|
159
|
+
const url = await promptText(rl, "Gateway URL (wss://...)", undefined, true);
|
|
160
|
+
config.gateway.remote = { url };
|
|
161
|
+
const token = await promptText(rl, "Gateway token", undefined, true);
|
|
162
|
+
config.gateway.remote.token = token;
|
|
163
|
+
}
|
|
164
|
+
writeConfigFile(config);
|
|
165
|
+
printSuccess("Gateway configured");
|
|
166
|
+
}
|
|
167
|
+
finally {
|
|
168
|
+
rl.close();
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
// Step 3: Model & Auth Setup
|
|
173
|
+
async function runModelSetup(_options) {
|
|
174
|
+
if (_options.skipModels) {
|
|
175
|
+
printWarning("Skipping model setup (--skip-models)");
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
printStepHeader(3, 6, "Model & Authentication");
|
|
179
|
+
const rl = await createReadlineInterface();
|
|
180
|
+
const config = loadConfig();
|
|
181
|
+
try {
|
|
182
|
+
console.log("");
|
|
183
|
+
console.log("Configure your preferred AI model provider.");
|
|
184
|
+
console.log("");
|
|
185
|
+
// Provider selection
|
|
186
|
+
const provider = await promptSelect(rl, "Model provider:", [
|
|
187
|
+
{ value: "anthropic", label: "Anthropic (Claude)" },
|
|
188
|
+
{ value: "openai", label: "OpenAI (GPT)" },
|
|
189
|
+
{ value: "google", label: "Google (Gemini)" },
|
|
190
|
+
{ value: "moonshotai", label: "MoonshotAI (Kimi)" },
|
|
191
|
+
{ value: "zai", label: "Z.AI (GLM)" },
|
|
192
|
+
], "anthropic");
|
|
193
|
+
if (!config.auth)
|
|
194
|
+
config.auth = {};
|
|
195
|
+
if (!config.auth.profiles)
|
|
196
|
+
config.auth.profiles = {};
|
|
197
|
+
// Provider-specific setup
|
|
198
|
+
if (provider === "anthropic") {
|
|
199
|
+
console.log("");
|
|
200
|
+
console.log("Anthropic API Key:");
|
|
201
|
+
console.log(" Get your key at: https://console.anthropic.com/account/keys");
|
|
202
|
+
console.log("");
|
|
203
|
+
const _apiKey = await promptText(rl, "API Key", undefined, true);
|
|
204
|
+
config.auth.profiles["anthropic:default"] = {
|
|
205
|
+
provider: "anthropic",
|
|
206
|
+
mode: "api_key",
|
|
207
|
+
};
|
|
208
|
+
// Store actual API key in auth-profiles.json (separate from config)
|
|
209
|
+
// For now, just set up the profile reference
|
|
210
|
+
if (!config.agents)
|
|
211
|
+
config.agents = {};
|
|
212
|
+
if (!config.agents.defaults)
|
|
213
|
+
config.agents.defaults = {};
|
|
214
|
+
config.agents.defaults.model = {
|
|
215
|
+
primary: "anthropic/claude-sonnet-4-6",
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
else if (provider === "openai") {
|
|
219
|
+
console.log("");
|
|
220
|
+
console.log("OpenAI API Key:");
|
|
221
|
+
console.log(" Get your key at: https://platform.openai.com/api-keys");
|
|
222
|
+
console.log("");
|
|
223
|
+
const _apiKey = await promptText(rl, "API Key", undefined, true);
|
|
224
|
+
config.auth.profiles["openai:default"] = {
|
|
225
|
+
provider: "openai",
|
|
226
|
+
mode: "api_key",
|
|
227
|
+
};
|
|
228
|
+
if (!config.agents)
|
|
229
|
+
config.agents = {};
|
|
230
|
+
if (!config.agents.defaults)
|
|
231
|
+
config.agents.defaults = {};
|
|
232
|
+
config.agents.defaults.model = {
|
|
233
|
+
primary: "openai/gpt-5",
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
// Add more providers as needed...
|
|
237
|
+
writeConfigFile(config);
|
|
238
|
+
printSuccess("Model configured");
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
rl.close();
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
// Step 4: Channel Setup
|
|
246
|
+
async function runChannelSetup(_options) {
|
|
247
|
+
if (_options.skipChannels) {
|
|
248
|
+
printWarning("Skipping channel setup (--skip-channels)");
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
printStepHeader(4, 6, "Messaging Channels");
|
|
252
|
+
const rl = await createReadlineInterface();
|
|
253
|
+
const config = loadConfig();
|
|
254
|
+
try {
|
|
255
|
+
console.log("");
|
|
256
|
+
console.log("Configure messaging channels for Pool Bot to communicate.");
|
|
257
|
+
console.log("You can skip this and configure channels later.");
|
|
258
|
+
console.log("");
|
|
259
|
+
if (!config.channels)
|
|
260
|
+
config.channels = {};
|
|
261
|
+
// Telegram
|
|
262
|
+
const setupTelegram = await promptYesNo(rl, "Set up Telegram bot?", false);
|
|
263
|
+
if (setupTelegram) {
|
|
264
|
+
console.log("");
|
|
265
|
+
console.log("Telegram Bot Token:");
|
|
266
|
+
console.log(" Create a bot with @BotFather and get the token");
|
|
267
|
+
console.log("");
|
|
268
|
+
const token = await promptText(rl, "Bot Token", undefined, true);
|
|
269
|
+
config.channels.telegram = {
|
|
270
|
+
enabled: true,
|
|
271
|
+
accounts: {
|
|
272
|
+
default: {
|
|
273
|
+
token,
|
|
274
|
+
enabled: true,
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
printSuccess("Telegram configured");
|
|
279
|
+
}
|
|
280
|
+
// Discord
|
|
281
|
+
const setupDiscord = await promptYesNo(rl, "Set up Discord bot?", false);
|
|
282
|
+
if (setupDiscord) {
|
|
283
|
+
console.log("");
|
|
284
|
+
console.log("Discord Bot Token:");
|
|
285
|
+
console.log(" Create an app at https://discord.com/developers/applications");
|
|
286
|
+
console.log("");
|
|
287
|
+
const token = await promptText(rl, "Bot Token", undefined, true);
|
|
288
|
+
config.channels.discord = {
|
|
289
|
+
enabled: true,
|
|
290
|
+
accounts: {
|
|
291
|
+
default: {
|
|
292
|
+
token,
|
|
293
|
+
enabled: true,
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
printSuccess("Discord configured");
|
|
298
|
+
}
|
|
299
|
+
// More channels can be added...
|
|
300
|
+
writeConfigFile(config);
|
|
301
|
+
printSuccess("Channels configured");
|
|
302
|
+
}
|
|
303
|
+
finally {
|
|
304
|
+
rl.close();
|
|
305
|
+
}
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
// Step 5: Memory & Skills
|
|
309
|
+
async function runMemorySkillsSetup(_options) {
|
|
310
|
+
if (_options.skipMemory && _options.skipSkills) {
|
|
311
|
+
printWarning("Skipping memory & skills setup (--skip-memory --skip-skills)");
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
printStepHeader(5, 6, "Memory & Skills");
|
|
315
|
+
const rl = await createReadlineInterface();
|
|
316
|
+
const config = loadConfig();
|
|
317
|
+
try {
|
|
318
|
+
console.log("");
|
|
319
|
+
console.log("Configure memory and skills for Pool Bot.");
|
|
320
|
+
console.log("");
|
|
321
|
+
// Memory
|
|
322
|
+
if (!_options.skipMemory) {
|
|
323
|
+
const enableMemory = await promptYesNo(rl, "Enable session memory?", true);
|
|
324
|
+
if (!config.memory)
|
|
325
|
+
config.memory = {};
|
|
326
|
+
config.memory.backend = enableMemory ? "builtin" : undefined;
|
|
327
|
+
if (enableMemory) {
|
|
328
|
+
printSuccess("Memory enabled");
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// Skills
|
|
332
|
+
if (!_options.skipSkills) {
|
|
333
|
+
const autoSkills = await promptYesNo(rl, "Auto-enable recommended skills?", true);
|
|
334
|
+
if (!config.skills)
|
|
335
|
+
config.skills = {};
|
|
336
|
+
// Skills auto-enable is handled by skills.auto in entries config
|
|
337
|
+
if (autoSkills) {
|
|
338
|
+
printSuccess("Skills auto-enable enabled");
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
writeConfigFile(config);
|
|
342
|
+
printSuccess("Memory & skills configured");
|
|
343
|
+
}
|
|
344
|
+
finally {
|
|
345
|
+
rl.close();
|
|
346
|
+
}
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
// Step 6: Final Validation
|
|
350
|
+
async function runFinalValidation(_options) {
|
|
351
|
+
printStepHeader(6, 6, "Final Validation");
|
|
352
|
+
const config = loadConfig();
|
|
353
|
+
console.log("");
|
|
354
|
+
console.log("Validating configuration...");
|
|
355
|
+
console.log("");
|
|
356
|
+
const checks = [
|
|
357
|
+
{ name: "Gateway configured", pass: Boolean(config.gateway) },
|
|
358
|
+
{ name: "Model configured", pass: Boolean(config.agents?.defaults?.model?.primary) },
|
|
359
|
+
{ name: "Auth profiles", pass: Object.keys(config.auth?.profiles || {}).length > 0 },
|
|
360
|
+
];
|
|
361
|
+
if (config.channels?.telegram) {
|
|
362
|
+
checks.push({ name: "Telegram configured", pass: true });
|
|
363
|
+
}
|
|
364
|
+
if (config.channels?.discord) {
|
|
365
|
+
checks.push({ name: "Discord configured", pass: true });
|
|
366
|
+
}
|
|
367
|
+
// Validation result tracking
|
|
368
|
+
for (const check of checks) {
|
|
369
|
+
const icon = check.pass ? theme.success("✓") : theme.warn("⚠");
|
|
370
|
+
console.log(` ${icon} ${check.name}${check.message ? `: ${check.message}` : ""}`);
|
|
371
|
+
// Track failures
|
|
372
|
+
}
|
|
373
|
+
console.log("");
|
|
374
|
+
printSuccess("All validations passed!");
|
|
375
|
+
// Print summary
|
|
376
|
+
console.log("");
|
|
377
|
+
console.log(theme.heading("🎉 Onboarding Complete!"));
|
|
378
|
+
console.log(theme.muted("─────────────────────────────────────────"));
|
|
379
|
+
console.log("");
|
|
380
|
+
console.log("Next steps:");
|
|
381
|
+
console.log("");
|
|
382
|
+
console.log(` 1. Start the gateway: ${theme.command("poolbot gateway run")}`);
|
|
383
|
+
console.log(` 2. Check status: ${theme.command("poolbot status")}`);
|
|
384
|
+
console.log(` 3. Send a message: ${theme.command("poolbot message send 'Hello!'")}`);
|
|
385
|
+
console.log("");
|
|
386
|
+
console.log(`For more help: ${formatDocsLink("/start/getting-started", "docs.molt.bot/start/getting-started")}`);
|
|
387
|
+
console.log("");
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
390
|
+
// Main onboarding function
|
|
391
|
+
async function runOnboarding(_options) {
|
|
392
|
+
printHeader();
|
|
393
|
+
const steps = [
|
|
394
|
+
{ name: "system", description: "System checks", run: runSystemChecks },
|
|
395
|
+
{ name: "gateway", description: "Gateway setup", run: runGatewaySetup },
|
|
396
|
+
{ name: "models", description: "Model & auth", run: runModelSetup },
|
|
397
|
+
{ name: "channels", description: "Channels", run: runChannelSetup },
|
|
398
|
+
{ name: "memory", description: "Memory & skills", run: runMemorySkillsSetup },
|
|
399
|
+
{ name: "validation", description: "Final validation", run: runFinalValidation },
|
|
400
|
+
];
|
|
401
|
+
// Step counter
|
|
402
|
+
for (const step of steps) {
|
|
403
|
+
// Next step
|
|
404
|
+
try {
|
|
405
|
+
const success = await step.run(_options);
|
|
406
|
+
if (!success) {
|
|
407
|
+
printError(`Step failed: ${step.name}`);
|
|
408
|
+
console.log("");
|
|
409
|
+
console.log("You can restart onboarding with: poolbot onboard");
|
|
410
|
+
defaultRuntime.exit(1);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
printError(`Step error: ${step.name} - ${error instanceof Error ? error.message : String(error)}`);
|
|
416
|
+
defaultRuntime.exit(1);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
defaultRuntime.exit(0);
|
|
421
|
+
}
|
|
422
|
+
export function registerOnboardCli(program) {
|
|
423
|
+
program
|
|
424
|
+
.command("onboard")
|
|
425
|
+
.description("Interactive setup wizard for new Pool Bot installations")
|
|
426
|
+
.option("--skip-gateway", "Skip gateway setup")
|
|
427
|
+
.option("--skip-channels", "Skip channel setup")
|
|
428
|
+
.option("--skip-models", "Skip model setup")
|
|
429
|
+
.option("--skip-memory", "Skip memory setup")
|
|
430
|
+
.option("--skip-skills", "Skip skills setup")
|
|
431
|
+
.option("--yes", "Use defaults without prompting (non-interactive)")
|
|
432
|
+
.addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/start/onboarding", "docs.molt.bot/start/onboarding")}\n` +
|
|
433
|
+
`${theme.muted("Tip:")} Use --skip-* flags to skip specific steps\n`)
|
|
434
|
+
.action(async (opts) => {
|
|
435
|
+
try {
|
|
436
|
+
await runOnboarding(opts);
|
|
437
|
+
}
|
|
438
|
+
catch (error) {
|
|
439
|
+
defaultRuntime.error(`Onboarding failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
440
|
+
defaultRuntime.exit(1);
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
}
|
|
@@ -1 +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;
|
|
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;AAiIlD;;;;;;;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,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAsB7F;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,OAAO,CAAC,CAUlB"}
|
|
@@ -59,7 +59,7 @@ async function promptSelect(rl, question, options, defaultValue) {
|
|
|
59
59
|
return options[index];
|
|
60
60
|
}
|
|
61
61
|
async function promptField(rl, field) {
|
|
62
|
-
const { key, label, description, type, default: defaultValue, options, required, validate } = field;
|
|
62
|
+
const { key, label, description, type, default: defaultValue, options, required, validate, } = field;
|
|
63
63
|
if (description) {
|
|
64
64
|
console.log(` ${label}: ${description}`);
|
|
65
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.subclis.d.ts","sourceRoot":"","sources":["../../../src/cli/program/register.subclis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,KAAK,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAElE,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;CAC3B,CAAC;
|
|
1
|
+
{"version":3,"file":"register.subclis.d.ts","sourceRoot":"","sources":["../../../src/cli/program/register.subclis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,KAAK,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAElE,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;CAC3B,CAAC;AA2UF,wBAAgB,gBAAgB,IAAI,WAAW,EAAE,CAEhD;AAED,wBAAgB,gCAAgC,IAAI,MAAM,EAAE,CAE3D;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ3F;AAaD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE,MAAM,EAAiB,QAkBrF"}
|
|
@@ -290,6 +290,24 @@ const entries = [
|
|
|
290
290
|
mod.registerInferCli(program);
|
|
291
291
|
},
|
|
292
292
|
},
|
|
293
|
+
{
|
|
294
|
+
name: "sessions",
|
|
295
|
+
description: "Manage session checkpoints (branch/restore)",
|
|
296
|
+
hasSubcommands: true,
|
|
297
|
+
register: async (program) => {
|
|
298
|
+
const mod = await import("../sessions-checkpoints-cli.js");
|
|
299
|
+
mod.registerSessionCheckpointsCli(program);
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "webhooks",
|
|
304
|
+
description: "Manage webhook ingress routes (TaskFlows via HTTP)",
|
|
305
|
+
hasSubcommands: true,
|
|
306
|
+
register: async (program) => {
|
|
307
|
+
const mod = await import("../webhooks-cli.js");
|
|
308
|
+
mod.registerWebhooksCli(program);
|
|
309
|
+
},
|
|
310
|
+
},
|
|
293
311
|
{
|
|
294
312
|
name: "completion",
|
|
295
313
|
description: "Generate shell completion script",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions-checkpoints-cli.d.ts","sourceRoot":"","sources":["../../src/cli/sessions-checkpoints-cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBzC,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,QAgH7D"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Checkpoints CLI
|
|
3
|
+
*/
|
|
4
|
+
import { loadConfig } from "../config/config.js";
|
|
5
|
+
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
|
|
6
|
+
import { defaultRuntime } from "../runtime.js";
|
|
7
|
+
import { theme } from "../terminal/theme.js";
|
|
8
|
+
import { danger, info, success } from "../globals.js";
|
|
9
|
+
import { formatDocsLink } from "../terminal/links.js";
|
|
10
|
+
import { listAllCheckpoints, listSessionCheckpoints, getCheckpoint, pruneOldCheckpoints, getCheckpointStats, } from "../sessions/checkpoints.js";
|
|
11
|
+
import { runCommandWithRuntime } from "./cli-utils.js";
|
|
12
|
+
function runSessionCommand(action) {
|
|
13
|
+
return runCommandWithRuntime(defaultRuntime, action);
|
|
14
|
+
}
|
|
15
|
+
export function registerSessionCheckpointsCli(program) {
|
|
16
|
+
const checkpoints = program
|
|
17
|
+
.command("checkpoints")
|
|
18
|
+
.description("Manage session checkpoints (list/show/prune)")
|
|
19
|
+
.addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/sessions/checkpoints", "docs.molt.bot/sessions/checkpoints")}\n`);
|
|
20
|
+
checkpoints
|
|
21
|
+
.command("list")
|
|
22
|
+
.description("List session checkpoints")
|
|
23
|
+
.option("--json", "Output JSON", false)
|
|
24
|
+
.option("--session <key>", "Filter by session key")
|
|
25
|
+
.option("--limit <n>", "Maximum checkpoints to return", "50")
|
|
26
|
+
.action(async (opts) => {
|
|
27
|
+
await runSessionCommand(async () => {
|
|
28
|
+
const config = loadConfig();
|
|
29
|
+
const workspaceDir = resolveAgentWorkspaceDir(config, "main");
|
|
30
|
+
const checkpointsList = opts.session
|
|
31
|
+
? listSessionCheckpoints(workspaceDir, opts.session)
|
|
32
|
+
: listAllCheckpoints(workspaceDir, Number.parseInt(opts.limit || "50", 10));
|
|
33
|
+
if (opts.json) {
|
|
34
|
+
defaultRuntime.log(JSON.stringify(checkpointsList, null, 2));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
defaultRuntime.log("");
|
|
38
|
+
defaultRuntime.log(theme.heading("Session Checkpoints"));
|
|
39
|
+
defaultRuntime.log(theme.muted("─────────────────────────────────────────"));
|
|
40
|
+
if (checkpointsList.length === 0) {
|
|
41
|
+
defaultRuntime.log(info("No checkpoints found."));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
for (const checkpoint of checkpointsList) {
|
|
45
|
+
const date = new Date(checkpoint.createdAt).toLocaleString();
|
|
46
|
+
const reason = checkpoint.reason === "auto-compaction" ? "🔄 auto" : `📌 ${checkpoint.reason}`;
|
|
47
|
+
defaultRuntime.log(` ${theme.success("●")} ${checkpoint.id.substring(0, 12)}... | ${reason} | ${date}`);
|
|
48
|
+
if (checkpoint.metadata?.model)
|
|
49
|
+
defaultRuntime.log(theme.muted(` Model: ${checkpoint.metadata.model}`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const stats = getCheckpointStats(workspaceDir);
|
|
53
|
+
defaultRuntime.log(theme.muted(`Total: ${stats.total} checkpoints`));
|
|
54
|
+
defaultRuntime.exit(0);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
checkpoints
|
|
58
|
+
.command("show <id>")
|
|
59
|
+
.description("Show checkpoint details")
|
|
60
|
+
.option("--json", "Output JSON", false)
|
|
61
|
+
.action(async (id, opts) => {
|
|
62
|
+
await runSessionCommand(async () => {
|
|
63
|
+
const config = loadConfig();
|
|
64
|
+
const workspaceDir = resolveAgentWorkspaceDir(config, "main");
|
|
65
|
+
const checkpoint = getCheckpoint(workspaceDir, id);
|
|
66
|
+
if (!checkpoint) {
|
|
67
|
+
defaultRuntime.log(danger(`Checkpoint "${id}" not found.`));
|
|
68
|
+
defaultRuntime.exit(1);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (opts.json) {
|
|
72
|
+
defaultRuntime.log(JSON.stringify(checkpoint, null, 2));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
defaultRuntime.log("");
|
|
76
|
+
defaultRuntime.log(theme.heading(`Checkpoint: ${checkpoint.id}`));
|
|
77
|
+
defaultRuntime.log(theme.muted("─────────────────────────────────────────"));
|
|
78
|
+
defaultRuntime.log(` Session: ${checkpoint.sessionKey}`);
|
|
79
|
+
defaultRuntime.log(` Reason: ${checkpoint.reason}`);
|
|
80
|
+
defaultRuntime.log(` Created: ${new Date(checkpoint.createdAt).toLocaleString()}`);
|
|
81
|
+
if (checkpoint.metadata?.model)
|
|
82
|
+
defaultRuntime.log(` Model: ${checkpoint.metadata.model}`);
|
|
83
|
+
if (checkpoint.metadata?.note)
|
|
84
|
+
defaultRuntime.log(` Note: ${checkpoint.metadata.note}`);
|
|
85
|
+
defaultRuntime.exit(0);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
checkpoints
|
|
89
|
+
.command("prune")
|
|
90
|
+
.description("Prune old checkpoints")
|
|
91
|
+
.option("--age <days>", "Prune checkpoints older than N days", "30")
|
|
92
|
+
.option("--yes", "Skip confirmation", false)
|
|
93
|
+
.action(async (opts) => {
|
|
94
|
+
await runSessionCommand(async () => {
|
|
95
|
+
const config = loadConfig();
|
|
96
|
+
const workspaceDir = resolveAgentWorkspaceDir(config, "main");
|
|
97
|
+
const ageDays = Number.parseInt(opts.age || "30", 10);
|
|
98
|
+
const maxAgeMs = ageDays * 24 * 60 * 60 * 1000;
|
|
99
|
+
if (!opts.yes) {
|
|
100
|
+
const stats = getCheckpointStats(workspaceDir);
|
|
101
|
+
defaultRuntime.log("");
|
|
102
|
+
defaultRuntime.log(danger(`⚠️ This will prune checkpoints older than ${ageDays} days`));
|
|
103
|
+
defaultRuntime.log(`Current checkpoints: ${stats.total}`);
|
|
104
|
+
if (stats.oldest)
|
|
105
|
+
defaultRuntime.log(`Oldest: ${new Date(stats.oldest).toLocaleDateString()}`);
|
|
106
|
+
defaultRuntime.log("");
|
|
107
|
+
defaultRuntime.log(info("Use --yes to skip this confirmation."));
|
|
108
|
+
defaultRuntime.exit(1);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const pruned = pruneOldCheckpoints(workspaceDir, maxAgeMs);
|
|
112
|
+
defaultRuntime.log("");
|
|
113
|
+
defaultRuntime.log(success(`Pruned ${pruned} old checkpoint(s).`));
|
|
114
|
+
defaultRuntime.exit(0);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook CLI - Manage webhook ingress routes
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* poolbot webhooks list # List all webhook routes
|
|
6
|
+
* poolbot webhooks create <path> # Create webhook route
|
|
7
|
+
* poolbot webhooks show <id> # Show webhook details
|
|
8
|
+
* poolbot webhooks delete <id> # Delete webhook route
|
|
9
|
+
* poolbot webhooks enable <id> # Enable webhook route
|
|
10
|
+
* poolbot webhooks disable <id> # Disable webhook route
|
|
11
|
+
* poolbot webhooks stats # Show webhook statistics
|
|
12
|
+
* poolbot webhooks serve # Start webhook server
|
|
13
|
+
*/
|
|
1
14
|
import type { Command } from "commander";
|
|
2
15
|
export declare function registerWebhooksCli(program: Command): void;
|
|
3
16
|
//# sourceMappingURL=webhooks-cli.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks-cli.d.ts","sourceRoot":"","sources":["../../src/cli/webhooks-cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"webhooks-cli.d.ts","sourceRoot":"","sources":["../../src/cli/webhooks-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,QA4WnD"}
|