botworker 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/bin/botworker.mjs +245 -0
- package/lib/api.js +46 -0
- package/lib/config.js +32 -0
- package/package.json +31 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 BotWorker
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# BotWorker CLI
|
|
2
|
+
|
|
3
|
+
שוחח עם הבוטים שלך מ-[BotWorker](https://botworker.dev) ישירות מהטרמינל.
|
|
4
|
+
|
|
5
|
+
## התקנה
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g botworker
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
או הרצה חד-פעמית ללא התקנה:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx botworker chat "שלום"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## התחברות
|
|
18
|
+
|
|
19
|
+
ההתחברות מתבצעת עם שם + אימייל **@gmail.com**. נשלח קוד בן 6 תווים לאימייל:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
botworker config --name "ישראל ישראלי"
|
|
23
|
+
botworker config --email you@gmail.com # שולח קוד 6 תווים לאימייל
|
|
24
|
+
botworker login # הזן את הקוד מהמייל
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
לחלופין, התחברות ידנית עם API key מהדשבורד:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
botworker config --api-key bw_live_xxxxxxxx
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## שימוש
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
botworker bots # רשימת הבוטים שלך
|
|
37
|
+
botworker use <BOT_ID> # בחירת הבוט הפעיל
|
|
38
|
+
botworker chat "מה השעות שלכם?" # שליחת הודעה אחת
|
|
39
|
+
botworker # מצב שיחה אינטראקטיבי
|
|
40
|
+
botworker whoami # פרטי החשבון
|
|
41
|
+
botworker logout # ניתוק
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## חיוב (Pay Per Use)
|
|
45
|
+
|
|
46
|
+
כל בקשה צורכת קרדיטים מהמכסה של הבוט. כשנגמרים הקרדיטים תוחזר שגיאה `402` —
|
|
47
|
+
ניתן להגדיל את המכסה ברכישת חבילת קרדיטים בדשבורד.
|
|
48
|
+
|
|
49
|
+
## משתני סביבה
|
|
50
|
+
|
|
51
|
+
- `BOTWORKER_API_BASE` — לשינוי כתובת ה-API (ברירת מחדל: שרת BotWorker).
|
|
52
|
+
|
|
53
|
+
## הגדרות
|
|
54
|
+
|
|
55
|
+
ההגדרות נשמרות מקומית ב-`~/.botworker/config.json` (הרשאות `600`).
|
|
56
|
+
|
|
57
|
+
## רישיון
|
|
58
|
+
|
|
59
|
+
MIT
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* BotWorker CLI
|
|
4
|
+
* --------------
|
|
5
|
+
* Talk to your BotWorker bots from the terminal.
|
|
6
|
+
*
|
|
7
|
+
* Quick start:
|
|
8
|
+
* npm install -g botworker
|
|
9
|
+
* botworker config --name "Your Name"
|
|
10
|
+
* botworker config --email you@gmail.com # sends a 6-char code to your gmail
|
|
11
|
+
* botworker login # paste the code from the email
|
|
12
|
+
* botworker bots # list your bots
|
|
13
|
+
* botworker use <BOT_ID> # pick the active bot
|
|
14
|
+
* botworker chat "שלום, מה אתה יודע לעשות?"
|
|
15
|
+
* botworker # interactive chat
|
|
16
|
+
*/
|
|
17
|
+
import readline from "node:readline";
|
|
18
|
+
import { loadConfig, saveConfig, clearConfig, CONFIG_FILE } from "../lib/config.js";
|
|
19
|
+
import { requestCode, verifyCode, listBots, chat } from "../lib/api.js";
|
|
20
|
+
|
|
21
|
+
const GMAIL_RE = /@gmail\.com$/i;
|
|
22
|
+
|
|
23
|
+
function ask(prompt, { hidden = false } = {}) {
|
|
24
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
25
|
+
if (hidden) {
|
|
26
|
+
const onData = (char) => {
|
|
27
|
+
const s = String(char);
|
|
28
|
+
if (s === "\n" || s === "\r" || s === "\u0004") process.stdout.write("\n");
|
|
29
|
+
else process.stdout.write("\u001b[2K\u001b[200D" + prompt + "*".repeat(rl.line.length));
|
|
30
|
+
};
|
|
31
|
+
process.stdin.on("data", onData);
|
|
32
|
+
return new Promise((res) =>
|
|
33
|
+
rl.question(prompt, (a) => {
|
|
34
|
+
process.stdin.removeListener("data", onData);
|
|
35
|
+
rl.close();
|
|
36
|
+
res(a);
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return new Promise((res) => rl.question(prompt, (a) => { rl.close(); res(a); }));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function parseFlags(args) {
|
|
44
|
+
const out = {};
|
|
45
|
+
for (let i = 0; i < args.length; i++) {
|
|
46
|
+
const a = args[i];
|
|
47
|
+
if (a.startsWith("--")) {
|
|
48
|
+
const key = a.slice(2);
|
|
49
|
+
const val = args[i + 1] && !args[i + 1].startsWith("--") ? args[++i] : true;
|
|
50
|
+
out[key] = val;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function requireAuth(cfg) {
|
|
57
|
+
if (!cfg.token) {
|
|
58
|
+
console.error("❌ אינך מחובר. הרץ: botworker config --email you@gmail.com ואז botworker login");
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function cmdConfig(cfg, rest) {
|
|
64
|
+
const flags = parseFlags(rest);
|
|
65
|
+
if (flags.name) cfg.name = String(flags.name);
|
|
66
|
+
if (flags["api-key"]) {
|
|
67
|
+
cfg.token = String(flags["api-key"]);
|
|
68
|
+
saveConfig(cfg);
|
|
69
|
+
console.log("✅ API key נשמר.");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (flags.email) {
|
|
73
|
+
const email = String(flags.email);
|
|
74
|
+
if (!GMAIL_RE.test(email)) {
|
|
75
|
+
console.error("❌ האימייל חייב להיות כתובת @gmail.com");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
cfg.email = email;
|
|
79
|
+
saveConfig(cfg);
|
|
80
|
+
console.log(`📧 שולח קוד בן 6 תווים אל ${email} ...`);
|
|
81
|
+
const { ok, data } = await requestCode(cfg.name, email);
|
|
82
|
+
if (!ok) {
|
|
83
|
+
console.error("❌", (data && data.error) || "שליחת הקוד נכשלה");
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
console.log("✅ הקוד נשלח. הרץ עכשיו: botworker login");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
saveConfig(cfg);
|
|
90
|
+
console.log("✅ ההגדרות נשמרו ב-", CONFIG_FILE);
|
|
91
|
+
console.log({ name: cfg.name, email: cfg.email, botId: cfg.botId, connected: !!cfg.token });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function cmdLogin(cfg) {
|
|
95
|
+
if (!cfg.email) {
|
|
96
|
+
console.error("❌ הגדר קודם אימייל: botworker config --email you@gmail.com");
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
const code = (await ask("🔑 הזן את הקוד בן 6 התווים מהמייל: ")).trim();
|
|
100
|
+
if (code.length !== 6) {
|
|
101
|
+
console.error("❌ הקוד חייב להיות בן 6 תווים.");
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const { ok, data } = await verifyCode(cfg.email, code);
|
|
105
|
+
if (!ok || !data.token) {
|
|
106
|
+
console.error("❌", (data && data.error) || "אימות נכשל");
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
cfg.token = data.token;
|
|
110
|
+
saveConfig(cfg);
|
|
111
|
+
console.log("✅ התחברת בהצלחה! הרץ: botworker bots");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function cmdBots(cfg) {
|
|
115
|
+
requireAuth(cfg);
|
|
116
|
+
const { ok, data } = await listBots(cfg.token);
|
|
117
|
+
if (!ok) {
|
|
118
|
+
console.error("❌", (data && data.error) || "טעינת הבוטים נכשלה");
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
const bots = data.bots || [];
|
|
122
|
+
if (!bots.length) {
|
|
123
|
+
console.log("אין לך בוטים זמינים עדיין.");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
console.log("\nהבוטים שלך:");
|
|
127
|
+
for (const b of bots) {
|
|
128
|
+
const active = b.id === cfg.botId ? " ← פעיל" : "";
|
|
129
|
+
console.log(` • ${b.name} (${b.id})${active}`);
|
|
130
|
+
}
|
|
131
|
+
console.log("\nבחר בוט עם: botworker use <BOT_ID>\n");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function cmdUse(cfg, rest) {
|
|
135
|
+
const botId = (rest[0] || "").trim();
|
|
136
|
+
if (!botId) {
|
|
137
|
+
console.error('שימוש: botworker use <BOT_ID>');
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
cfg.botId = botId;
|
|
141
|
+
saveConfig(cfg);
|
|
142
|
+
console.log("✅ הבוט הפעיל הוא כעת:", botId);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function send(cfg, message, history) {
|
|
146
|
+
requireAuth(cfg);
|
|
147
|
+
if (!cfg.botId) {
|
|
148
|
+
console.error("❌ לא נבחר בוט. הרץ: botworker bots ואז botworker use <BOT_ID>");
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
const { ok, status, data } = await chat(cfg.token, cfg.botId, message, history);
|
|
152
|
+
if (status === 402) {
|
|
153
|
+
console.error("⚠️ נגמרו הקרדיטים (Pay Per Use). קנה חבילת קרדיטים בדשבורד כדי להמשיך.");
|
|
154
|
+
process.exit(2);
|
|
155
|
+
}
|
|
156
|
+
if (status === 401) {
|
|
157
|
+
console.error("❌ פג תוקף ההתחברות. הרץ שוב: botworker login");
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
if (!ok || data.success === false) {
|
|
161
|
+
console.error("❌", (data && (data.error?.message || data.error)) || `HTTP ${status}`);
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
return String(data.reply || "");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function cmdChat(cfg, rest) {
|
|
168
|
+
const message = rest.join(" ").trim();
|
|
169
|
+
if (!message) {
|
|
170
|
+
console.error('שימוש: botworker chat "ההודעה שלך"');
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
const reply = await send(cfg, message, []);
|
|
174
|
+
console.log("\n🤖 " + reply + "\n");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function cmdInteractive(cfg) {
|
|
178
|
+
console.log("BotWorker CLI — מצב שיחה. הקלד 'exit' ליציאה.\n");
|
|
179
|
+
const history = [];
|
|
180
|
+
// eslint-disable-next-line no-constant-condition
|
|
181
|
+
while (true) {
|
|
182
|
+
const message = (await ask("👤 ")).trim();
|
|
183
|
+
if (!message || message === "exit" || message === "quit") break;
|
|
184
|
+
const reply = await send(cfg, message, history);
|
|
185
|
+
console.log("🤖 " + reply + "\n");
|
|
186
|
+
history.push({ role: "user", content: message });
|
|
187
|
+
history.push({ role: "assistant", content: reply });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function cmdHelp() {
|
|
192
|
+
console.log(`BotWorker CLI
|
|
193
|
+
|
|
194
|
+
שימוש:
|
|
195
|
+
botworker config --name "Your Name"
|
|
196
|
+
botworker config --email you@gmail.com שולח קוד בן 6 תווים לאימייל
|
|
197
|
+
botworker login הזנת הקוד וקבלת גישה
|
|
198
|
+
botworker config --api-key bw_live_xxx התחברות ידנית עם API key
|
|
199
|
+
botworker bots רשימת הבוטים שלך
|
|
200
|
+
botworker use <BOT_ID> בחירת הבוט הפעיל
|
|
201
|
+
botworker chat "ההודעה שלך" שליחת הודעה אחת
|
|
202
|
+
botworker מצב שיחה אינטראקטיבי
|
|
203
|
+
botworker whoami הצגת פרטי החשבון
|
|
204
|
+
botworker logout ניתוק ומחיקת ההגדרות
|
|
205
|
+
`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async function main() {
|
|
209
|
+
const [cmd, ...rest] = process.argv.slice(2);
|
|
210
|
+
const cfg = loadConfig();
|
|
211
|
+
|
|
212
|
+
switch (cmd) {
|
|
213
|
+
case "config":
|
|
214
|
+
return cmdConfig(cfg, rest);
|
|
215
|
+
case "login":
|
|
216
|
+
return cmdLogin(cfg);
|
|
217
|
+
case "bots":
|
|
218
|
+
return cmdBots(cfg);
|
|
219
|
+
case "use":
|
|
220
|
+
return cmdUse(cfg, rest);
|
|
221
|
+
case "chat":
|
|
222
|
+
return cmdChat(cfg, rest);
|
|
223
|
+
case "whoami":
|
|
224
|
+
console.log({ name: cfg.name, email: cfg.email, botId: cfg.botId, connected: !!cfg.token });
|
|
225
|
+
return;
|
|
226
|
+
case "logout":
|
|
227
|
+
clearConfig();
|
|
228
|
+
console.log("✅ התנתקת. ההגדרות נמחקו.");
|
|
229
|
+
return;
|
|
230
|
+
case "help":
|
|
231
|
+
case "--help":
|
|
232
|
+
case "-h":
|
|
233
|
+
return cmdHelp();
|
|
234
|
+
case undefined:
|
|
235
|
+
return cmdInteractive(cfg);
|
|
236
|
+
default:
|
|
237
|
+
console.error(`פקודה לא מוכרת: ${cmd}\n`);
|
|
238
|
+
return cmdHelp();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
main().catch((e) => {
|
|
243
|
+
console.error("שגיאה:", e.message);
|
|
244
|
+
process.exit(1);
|
|
245
|
+
});
|
package/lib/api.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const BASE =
|
|
2
|
+
process.env.BOTWORKER_API_BASE ||
|
|
3
|
+
"https://gvmrylxlzktfsuzznmbc.supabase.co/functions/v1";
|
|
4
|
+
|
|
5
|
+
export const ENDPOINTS = {
|
|
6
|
+
authRequest: `${BASE}/cli-auth-request`,
|
|
7
|
+
authVerify: `${BASE}/cli-auth-verify`,
|
|
8
|
+
chat: `${BASE}/custom-bot-chat`,
|
|
9
|
+
bots: `${BASE}/cli-list-bots`,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
async function call(url, body, token) {
|
|
13
|
+
const headers = { "Content-Type": "application/json" };
|
|
14
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
15
|
+
const res = await fetch(url, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers,
|
|
18
|
+
body: JSON.stringify(body || {}),
|
|
19
|
+
});
|
|
20
|
+
const data = await res.json().catch(() => ({}));
|
|
21
|
+
return { status: res.status, ok: res.ok, data };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Step 1: send a 6-character code to the user's gmail. */
|
|
25
|
+
export function requestCode(name, email) {
|
|
26
|
+
return call(ENDPOINTS.authRequest, { name, email });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Step 2: verify the code and receive a CLI token. */
|
|
30
|
+
export function verifyCode(email, code) {
|
|
31
|
+
return call(ENDPOINTS.authVerify, { email, code });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** List the bots the authenticated user owns or rents. */
|
|
35
|
+
export function listBots(token) {
|
|
36
|
+
return call(ENDPOINTS.bots, {}, token);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Send a chat message to a bot. */
|
|
40
|
+
export function chat(token, botId, message, history) {
|
|
41
|
+
return call(
|
|
42
|
+
ENDPOINTS.chat,
|
|
43
|
+
{ bot_id: botId, message, history: (history || []).slice(-8) },
|
|
44
|
+
token,
|
|
45
|
+
);
|
|
46
|
+
}
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
export const CONFIG_DIR = path.join(os.homedir(), ".botworker");
|
|
6
|
+
export const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
7
|
+
|
|
8
|
+
export function loadConfig() {
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
|
|
11
|
+
} catch {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function saveConfig(cfg) {
|
|
17
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
18
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2));
|
|
19
|
+
try {
|
|
20
|
+
fs.chmodSync(CONFIG_FILE, 0o600);
|
|
21
|
+
} catch {
|
|
22
|
+
/* windows */
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function clearConfig() {
|
|
27
|
+
try {
|
|
28
|
+
fs.unlinkSync(CONFIG_FILE);
|
|
29
|
+
} catch {
|
|
30
|
+
/* noop */
|
|
31
|
+
}
|
|
32
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "botworker",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "BotWorker CLI — chat with your BotWorker bots straight from the terminal.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"botworker": "bin/botworker.mjs",
|
|
8
|
+
"BotWorker": "bin/botworker.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/",
|
|
12
|
+
"lib/",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"botworker",
|
|
21
|
+
"cli",
|
|
22
|
+
"chatbot",
|
|
23
|
+
"ai",
|
|
24
|
+
"bot"
|
|
25
|
+
],
|
|
26
|
+
"homepage": "https://botworker.dev",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"scripts": {
|
|
29
|
+
"start": "node bin/botworker.mjs"
|
|
30
|
+
}
|
|
31
|
+
}
|