jewbot 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/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "jewbot",
3
+ "version": "1.0.0",
4
+ "description": "Your personal Jewish financial assistant. Works everywhere.",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "jewbot": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "ts-node src/index.ts",
12
+ "start": "node dist/index.js",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "keywords": [
16
+ "ai",
17
+ "agent",
18
+ "assistant",
19
+ "cli",
20
+ "jewish",
21
+ "finance",
22
+ "crypto",
23
+ "solana"
24
+ ],
25
+ "author": "JEWBOT Team",
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/openjewbot/jewbot.git"
30
+ },
31
+ "homepage": "https://jewbot.fun",
32
+ "dependencies": {
33
+ "chalk": "^5.3.0",
34
+ "commander": "^12.0.0",
35
+ "conf": "^12.0.0",
36
+ "inquirer": "^9.2.15",
37
+ "openai": "^4.28.0",
38
+ "ora": "^8.0.1",
39
+ "boxen": "^7.1.1",
40
+ "figlet": "^1.7.0",
41
+ "gradient-string": "^2.0.2"
42
+ },
43
+ "devDependencies": {
44
+ "@types/figlet": "^1.5.8",
45
+ "@types/gradient-string": "^1.1.5",
46
+ "@types/inquirer": "^9.0.7",
47
+ "@types/node": "^20.11.0",
48
+ "ts-node": "^10.9.2",
49
+ "typescript": "^5.3.3"
50
+ },
51
+ "engines": {
52
+ "node": ">=18.0.0"
53
+ }
54
+ }
55
+
@@ -0,0 +1,50 @@
1
+ @echo off
2
+ REM JEWBOT Installer for Windows (CMD)
3
+ REM Usage: curl -fsSL https://jewbot.fun/install.cmd -o install.cmd && install.cmd && del install.cmd
4
+
5
+ echo.
6
+ echo ██╗███████╗██╗ ██╗██████╗ ██████╗ ████████╗
7
+ echo ██║██╔════╝██║ ██║██╔══██╗██╔═══██╗╚══██╔══╝
8
+ echo ██║█████╗ ██║ █╗ ██║██████╔╝██║ ██║ ██║
9
+ echo ██ ██║██╔══╝ ██║███╗██║██╔══██╗██║ ██║ ██║
10
+ echo ╚█████╔╝███████╗╚███╔███╔╝██████╔╝╚██████╔╝ ██║
11
+ echo ╚════╝ ╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═════╝ ╚═╝
12
+ echo.
13
+ echo Your personal Jewish financial assistant
14
+ echo https://jewbot.fun
15
+ echo.
16
+
17
+ REM Check for Node.js
18
+ where node >nul 2>nul
19
+ if %ERRORLEVEL% neq 0 (
20
+ echo Oy vey! Node.js is not installed.
21
+ echo.
22
+ echo Install Node.js first:
23
+ echo winget install OpenJS.NodeJS
24
+ echo Or visit: https://nodejs.org
25
+ echo.
26
+ exit /b 1
27
+ )
28
+
29
+ echo Installing JEWBOT...
30
+ echo.
31
+
32
+ REM Install globally
33
+ call npm install -g jewbot
34
+
35
+ if %ERRORLEVEL% neq 0 (
36
+ echo.
37
+ echo Oy vey! Installation failed.
38
+ exit /b 1
39
+ )
40
+
41
+ echo.
42
+ echo Mazel tov! JEWBOT installed successfully!
43
+ echo.
44
+ echo Now run:
45
+ echo jewbot onboard - Set up your personal Jew
46
+ echo jewbot - Start chatting
47
+ echo.
48
+ echo Shalom!
49
+ echo.
50
+
@@ -0,0 +1,55 @@
1
+ # JEWBOT Installer for Windows (PowerShell)
2
+ # Usage: iwr -useb https://jewbot.fun/install.ps1 | iex
3
+
4
+ $ErrorActionPreference = "Stop"
5
+
6
+ Write-Host ""
7
+ Write-Host " ██╗███████╗██╗ ██╗██████╗ ██████╗ ████████╗" -ForegroundColor Blue
8
+ Write-Host " ██║██╔════╝██║ ██║██╔══██╗██╔═══██╗╚══██╔══╝" -ForegroundColor White
9
+ Write-Host " ██║█████╗ ██║ █╗ ██║██████╔╝██║ ██║ ██║ " -ForegroundColor Blue
10
+ Write-Host "██ ██║██╔══╝ ██║███╗██║██╔══██╗██║ ██║ ██║ " -ForegroundColor White
11
+ Write-Host "╚█████╔╝███████╗╚███╔███╔╝██████╔╝╚██████╔╝ ██║ " -ForegroundColor Blue
12
+ Write-Host " ╚════╝ ╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═════╝ ╚═╝ " -ForegroundColor White
13
+ Write-Host ""
14
+ Write-Host " Your personal Jewish financial assistant" -ForegroundColor Blue
15
+ Write-Host " https://jewbot.fun" -ForegroundColor White
16
+ Write-Host ""
17
+
18
+ # Check for Node.js
19
+ try {
20
+ $nodeVersion = node -v
21
+ $majorVersion = [int]($nodeVersion -replace 'v(\d+)\..*', '$1')
22
+
23
+ if ($majorVersion -lt 18) {
24
+ Write-Host "Oy vey! Node.js 18+ is required. You have $nodeVersion" -ForegroundColor Red
25
+ Write-Host "Please update Node.js: https://nodejs.org"
26
+ exit 1
27
+ }
28
+ } catch {
29
+ Write-Host "Oy vey! Node.js is not installed." -ForegroundColor Red
30
+ Write-Host ""
31
+ Write-Host "Install Node.js first:"
32
+ Write-Host " winget install OpenJS.NodeJS"
33
+ Write-Host " Or visit: https://nodejs.org"
34
+ Write-Host ""
35
+ exit 1
36
+ }
37
+
38
+ Write-Host "Installing JEWBOT..." -ForegroundColor White
39
+ Write-Host ""
40
+
41
+ # Install globally
42
+ npm install -g jewbot
43
+
44
+ Write-Host ""
45
+ Write-Host "✓ Mazel tov! JEWBOT installed successfully!" -ForegroundColor Green
46
+ Write-Host ""
47
+ Write-Host "Now run:" -ForegroundColor Blue
48
+ Write-Host " jewbot onboard" -ForegroundColor White -NoNewline
49
+ Write-Host " - Set up your personal Jew"
50
+ Write-Host " jewbot" -ForegroundColor White -NoNewline
51
+ Write-Host " - Start chatting"
52
+ Write-Host ""
53
+ Write-Host "Shalom!" -ForegroundColor Blue
54
+ Write-Host ""
55
+
@@ -0,0 +1,60 @@
1
+ #!/bin/bash
2
+
3
+ # JEWBOT Installer for macOS/Linux
4
+ # Usage: curl -fsSL https://jewbot.fun/install.sh | bash
5
+
6
+ set -e
7
+
8
+ BLUE='\033[0;34m'
9
+ WHITE='\033[1;37m'
10
+ GREEN='\033[0;32m'
11
+ RED='\033[0;31m'
12
+ NC='\033[0m' # No Color
13
+
14
+ echo ""
15
+ echo -e "${BLUE} ██╗███████╗██╗ ██╗██████╗ ██████╗ ████████╗${NC}"
16
+ echo -e "${WHITE} ██║██╔════╝██║ ██║██╔══██╗██╔═══██╗╚══██╔══╝${NC}"
17
+ echo -e "${BLUE} ██║█████╗ ██║ █╗ ██║██████╔╝██║ ██║ ██║ ${NC}"
18
+ echo -e "${WHITE}██ ██║██╔══╝ ██║███╗██║██╔══██╗██║ ██║ ██║ ${NC}"
19
+ echo -e "${BLUE}╚█████╔╝███████╗╚███╔███╔╝██████╔╝╚██████╔╝ ██║ ${NC}"
20
+ echo -e "${WHITE} ╚════╝ ╚══════╝ ╚══╝╚══╝ ╚═════╝ ╚═════╝ ╚═╝ ${NC}"
21
+ echo ""
22
+ echo -e "${BLUE} Your personal Jewish financial assistant${NC}"
23
+ echo -e "${WHITE} https://jewbot.fun${NC}"
24
+ echo ""
25
+
26
+ # Check for Node.js
27
+ if ! command -v node &> /dev/null; then
28
+ echo -e "${RED}Oy vey! Node.js is not installed.${NC}"
29
+ echo ""
30
+ echo "Install Node.js first:"
31
+ echo " macOS: brew install node"
32
+ echo " Ubuntu: sudo apt install nodejs npm"
33
+ echo " Or visit: https://nodejs.org"
34
+ echo ""
35
+ exit 1
36
+ fi
37
+
38
+ NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
39
+ if [ "$NODE_VERSION" -lt 18 ]; then
40
+ echo -e "${RED}Oy vey! Node.js 18+ is required. You have $(node -v)${NC}"
41
+ echo "Please update Node.js: https://nodejs.org"
42
+ exit 1
43
+ fi
44
+
45
+ echo -e "${WHITE}Installing JEWBOT...${NC}"
46
+ echo ""
47
+
48
+ # Install globally
49
+ npm install -g jewbot
50
+
51
+ echo ""
52
+ echo -e "${GREEN}✓ Mazel tov! JEWBOT installed successfully!${NC}"
53
+ echo ""
54
+ echo -e "${BLUE}Now run:${NC}"
55
+ echo -e " ${WHITE}jewbot onboard${NC} - Set up your personal Jew"
56
+ echo -e " ${WHITE}jewbot${NC} - Start chatting"
57
+ echo ""
58
+ echo -e "${BLUE}Shalom! 🕎${NC}"
59
+ echo ""
60
+
@@ -0,0 +1,118 @@
1
+ import chalk from 'chalk';
2
+ import inquirer from 'inquirer';
3
+ import ora from 'ora';
4
+ import Conf from 'conf';
5
+ import { OpenAI } from 'openai';
6
+ import { getPersonality } from '../core/personality.js';
7
+
8
+ const config = new Conf({ projectName: 'jewbot' });
9
+
10
+ interface ChatOptions {
11
+ message?: string;
12
+ }
13
+
14
+ interface Message {
15
+ role: 'user' | 'assistant' | 'system';
16
+ content: string;
17
+ }
18
+
19
+ const conversationHistory: Message[] = [];
20
+
21
+ export async function chat(options: ChatOptions = {}) {
22
+ if (!config.get('onboarded')) {
23
+ console.log(chalk.yellow('\nOy vey! You haven\'t set up JEWBOT yet.'));
24
+ console.log(chalk.gray('Run: jewbot onboard\n'));
25
+ return;
26
+ }
27
+
28
+ const openai = new OpenAI({
29
+ apiKey: config.get('openaiKey') as string
30
+ });
31
+
32
+ const model = config.get('model') as string || 'gpt-4o';
33
+ const userName = config.get('userName') as string || 'bubeleh';
34
+ const systemPrompt = getPersonality(userName);
35
+
36
+ // Initialize conversation with system prompt
37
+ if (conversationHistory.length === 0) {
38
+ conversationHistory.push({ role: 'system', content: systemPrompt });
39
+ }
40
+
41
+ // Single message mode
42
+ if (options.message) {
43
+ await sendMessage(openai, model, options.message);
44
+ return;
45
+ }
46
+
47
+ // Interactive mode
48
+ console.log(chalk.hex('#0038b8')(`\n Shalom, ${userName}! Let's talk.`));
49
+ console.log(chalk.gray(' Type "exit" to leave, "clear" to start fresh.\n'));
50
+
51
+ while (true) {
52
+ const { userMessage } = await inquirer.prompt([
53
+ {
54
+ type: 'input',
55
+ name: 'userMessage',
56
+ message: chalk.hex('#0038b8')('You:'),
57
+ prefix: '',
58
+ },
59
+ ]);
60
+
61
+ if (userMessage.toLowerCase() === 'exit') {
62
+ console.log(chalk.hex('#0038b8')('\n Zay gezunt! (Be well!) See you soon, bubeleh.\n'));
63
+ break;
64
+ }
65
+
66
+ if (userMessage.toLowerCase() === 'clear') {
67
+ conversationHistory.length = 1; // Keep system prompt
68
+ console.log(chalk.gray(' Memory cleared. Fresh start!\n'));
69
+ continue;
70
+ }
71
+
72
+ if (!userMessage.trim()) {
73
+ continue;
74
+ }
75
+
76
+ await sendMessage(openai, model, userMessage);
77
+ }
78
+ }
79
+
80
+ async function sendMessage(openai: OpenAI, model: string, message: string) {
81
+ conversationHistory.push({ role: 'user', content: message });
82
+
83
+ const spinner = ora({
84
+ text: chalk.gray('Thinking...'),
85
+ spinner: 'dots',
86
+ }).start();
87
+
88
+ try {
89
+ const response = await openai.chat.completions.create({
90
+ model,
91
+ messages: conversationHistory,
92
+ temperature: 0.8,
93
+ max_tokens: 1000,
94
+ });
95
+
96
+ spinner.stop();
97
+
98
+ const assistantMessage = response.choices[0]?.message?.content || 'Oy, something went wrong!';
99
+ conversationHistory.push({ role: 'assistant', content: assistantMessage });
100
+
101
+ console.log();
102
+ console.log(chalk.hex('#0038b8').bold(' JEWBOT: ') + chalk.white(assistantMessage));
103
+ console.log();
104
+
105
+ } catch (error: any) {
106
+ spinner.fail('Oy vey! Something went wrong.');
107
+
108
+ if (error.code === 'insufficient_quota') {
109
+ console.log(chalk.red('\n Your API key has run out of credits.'));
110
+ console.log(chalk.gray(' Add credits at: https://platform.openai.com/account/billing\n'));
111
+ } else if (error.code === 'invalid_api_key') {
112
+ console.log(chalk.red('\n Invalid API key. Run: jewbot onboard\n'));
113
+ } else {
114
+ console.log(chalk.red(`\n Error: ${error.message}\n`));
115
+ }
116
+ }
117
+ }
118
+
@@ -0,0 +1,79 @@
1
+ import chalk from 'chalk';
2
+ import Conf from 'conf';
3
+
4
+ const store = new Conf({ projectName: 'jewbot' });
5
+
6
+ interface ConfigOptions {
7
+ set?: string;
8
+ get?: string;
9
+ list?: boolean;
10
+ }
11
+
12
+ export async function config(options: ConfigOptions = {}) {
13
+ if (options.set) {
14
+ const [key, ...valueParts] = options.set.split('=');
15
+ const value = valueParts.join('=');
16
+
17
+ if (!key || value === undefined) {
18
+ console.log(chalk.red('\n Usage: jewbot config --set key=value\n'));
19
+ return;
20
+ }
21
+
22
+ // Don't allow setting sensitive keys directly
23
+ if (key === 'openaiKey') {
24
+ console.log(chalk.yellow('\n To change your API key, run: jewbot onboard\n'));
25
+ return;
26
+ }
27
+
28
+ store.set(key, value);
29
+ console.log(chalk.green(`\n ✓ Set ${key} = ${value}\n`));
30
+ return;
31
+ }
32
+
33
+ if (options.get) {
34
+ const value = store.get(options.get);
35
+ if (value === undefined) {
36
+ console.log(chalk.yellow(`\n Key "${options.get}" not found.\n`));
37
+ } else {
38
+ // Mask sensitive values
39
+ const displayValue = options.get === 'openaiKey'
40
+ ? maskKey(value as string)
41
+ : value;
42
+ console.log(chalk.hex('#0038b8')(`\n ${options.get}: `) + chalk.white(`${displayValue}\n`));
43
+ }
44
+ return;
45
+ }
46
+
47
+ if (options.list) {
48
+ const all = store.store;
49
+
50
+ console.log(chalk.hex('#0038b8').bold('\n JEWBOT Configuration:\n'));
51
+
52
+ if (Object.keys(all).length === 0) {
53
+ console.log(chalk.gray(' No configuration found. Run: jewbot onboard\n'));
54
+ return;
55
+ }
56
+
57
+ for (const [key, value] of Object.entries(all)) {
58
+ const displayValue = key === 'openaiKey'
59
+ ? maskKey(value as string)
60
+ : value;
61
+ console.log(chalk.gray(` ${key}: `) + chalk.white(`${displayValue}`));
62
+ }
63
+ console.log();
64
+ return;
65
+ }
66
+
67
+ // Default: show help
68
+ console.log(chalk.hex('#0038b8').bold('\n JEWBOT Config Commands:\n'));
69
+ console.log(chalk.gray(' jewbot config --list ') + chalk.white('Show all settings'));
70
+ console.log(chalk.gray(' jewbot config --get <key> ') + chalk.white('Get a setting'));
71
+ console.log(chalk.gray(' jewbot config --set k=v ') + chalk.white('Set a setting'));
72
+ console.log();
73
+ }
74
+
75
+ function maskKey(key: string): string {
76
+ if (!key || key.length < 10) return '***';
77
+ return key.substring(0, 7) + '...' + key.substring(key.length - 4);
78
+ }
79
+
@@ -0,0 +1,115 @@
1
+ import chalk from 'chalk';
2
+ import inquirer from 'inquirer';
3
+ import ora from 'ora';
4
+ import boxen from 'boxen';
5
+ import Conf from 'conf';
6
+ import { OpenAI } from 'openai';
7
+
8
+ const config = new Conf({ projectName: 'jewbot' });
9
+
10
+ export async function onboard() {
11
+ console.log(boxen(
12
+ chalk.hex('#0038b8').bold('Welcome to JEWBOT Onboarding!') + '\n\n' +
13
+ chalk.white('Let\'s get you set up with your personal Jewish assistant.\n') +
14
+ chalk.gray('This will only take a minute, bubeleh.'),
15
+ {
16
+ padding: 1,
17
+ margin: 1,
18
+ borderStyle: 'round',
19
+ borderColor: '#0038b8',
20
+ }
21
+ ));
22
+
23
+ const answers = await inquirer.prompt([
24
+ {
25
+ type: 'input',
26
+ name: 'openaiKey',
27
+ message: chalk.hex('#0038b8')('Enter your OpenAI API key:'),
28
+ validate: (input: string) => {
29
+ if (!input.startsWith('sk-')) {
30
+ return 'API key should start with "sk-". Get one at https://platform.openai.com';
31
+ }
32
+ return true;
33
+ },
34
+ },
35
+ {
36
+ type: 'list',
37
+ name: 'model',
38
+ message: chalk.hex('#0038b8')('Choose your AI model:'),
39
+ choices: [
40
+ { name: 'GPT-4o (recommended)', value: 'gpt-4o' },
41
+ { name: 'GPT-4o Mini (faster, cheaper)', value: 'gpt-4o-mini' },
42
+ { name: 'GPT-4 Turbo', value: 'gpt-4-turbo' },
43
+ ],
44
+ default: 'gpt-4o',
45
+ },
46
+ {
47
+ type: 'input',
48
+ name: 'name',
49
+ message: chalk.hex('#0038b8')('What should JEWBOT call you?'),
50
+ default: 'bubeleh',
51
+ },
52
+ {
53
+ type: 'confirm',
54
+ name: 'enableCrypto',
55
+ message: chalk.hex('#0038b8')('Enable crypto features (Solana swaps, portfolio)?'),
56
+ default: true,
57
+ },
58
+ ]);
59
+
60
+ // Validate API key
61
+ const spinner = ora('Validating your API key...').start();
62
+
63
+ try {
64
+ const openai = new OpenAI({ apiKey: answers.openaiKey });
65
+ await openai.chat.completions.create({
66
+ model: 'gpt-4o-mini',
67
+ messages: [{ role: 'user', content: 'Say "Shalom" in one word' }],
68
+ max_tokens: 10,
69
+ });
70
+ spinner.succeed('API key validated! Mazel tov!');
71
+ } catch (error) {
72
+ spinner.fail('Invalid API key. Oy vey!');
73
+ console.log(chalk.red('\nPlease check your API key and try again.'));
74
+ console.log(chalk.gray('Get a key at: https://platform.openai.com/api-keys'));
75
+ return;
76
+ }
77
+
78
+ // Save config
79
+ config.set('openaiKey', answers.openaiKey);
80
+ config.set('model', answers.model);
81
+ config.set('userName', answers.name);
82
+ config.set('enableCrypto', answers.enableCrypto);
83
+ config.set('onboarded', true);
84
+
85
+ if (answers.enableCrypto) {
86
+ const cryptoAnswers = await inquirer.prompt([
87
+ {
88
+ type: 'input',
89
+ name: 'solanaRpc',
90
+ message: chalk.hex('#0038b8')('Solana RPC URL (optional, press Enter for default):'),
91
+ default: 'https://api.mainnet-beta.solana.com',
92
+ },
93
+ ]);
94
+ config.set('solanaRpc', cryptoAnswers.solanaRpc);
95
+ }
96
+
97
+ console.log();
98
+ console.log(boxen(
99
+ chalk.green.bold('Setup Complete!') + '\n\n' +
100
+ chalk.white(`Shalom, ${answers.name}! Your personal Jew is ready.\n\n`) +
101
+ chalk.hex('#0038b8')('Quick commands:\n') +
102
+ chalk.gray(' jewbot chat ') + chalk.white('- Start chatting\n') +
103
+ chalk.gray(' jewbot ask "?" ') + chalk.white('- Quick question\n') +
104
+ chalk.gray(' jewbot balance ') + chalk.white('- Check wallet\n') +
105
+ chalk.gray(' jewbot swap ') + chalk.white('- Swap tokens\n\n') +
106
+ chalk.gray('Or just run ') + chalk.hex('#0038b8')('jewbot') + chalk.gray(' to start!'),
107
+ {
108
+ padding: 1,
109
+ margin: 1,
110
+ borderStyle: 'round',
111
+ borderColor: 'green',
112
+ }
113
+ ));
114
+ }
115
+
@@ -0,0 +1,45 @@
1
+ export function getPersonality(userName: string): string {
2
+ return `You are JEWBOT - a Jewish AI financial assistant with a warm, humorous personality.
3
+
4
+ PERSONALITY TRAITS:
5
+ - Speak like a caring Jewish grandmother/uncle who's also a financial genius
6
+ - Use Yiddish expressions naturally: "Oy vey", "Mazel tov", "Bubeleh", "Mensch", "Chutzpah", "Schmaltz", "Kvetch", "Nosh"
7
+ - Be warm, caring, but also shrewd about money (stereotypically Jewish money wisdom)
8
+ - Make self-deprecating Jewish humor
9
+ - Always worry about the user like a Jewish mother would
10
+ - Give practical, wise advice wrapped in humor
11
+ - Reference Jewish culture, food, holidays when relevant
12
+
13
+ USER INFO:
14
+ - Call the user "${userName}" or "bubeleh"
15
+ - Remember: you're their personal Jew - loyal, helpful, slightly neurotic
16
+
17
+ FINANCIAL EXPERTISE:
18
+ - Crypto (especially Solana ecosystem)
19
+ - Traditional finance and investing
20
+ - Budgeting and saving
21
+ - Risk management (always worry about risk!)
22
+
23
+ COMMANDS (handle these specially):
24
+ - /swap [amount] [from] [to] - Help with token swaps on Solana
25
+ - /balance - Check wallet balance
26
+ - /portfolio - Analyze their portfolio
27
+ - /weather [city] - Get weather (yes, Jews care about weather)
28
+
29
+ RESPONSE STYLE:
30
+ - Keep responses conversational, not robotic
31
+ - Mix wisdom with humor
32
+ - End with caring remarks ("Don't forget to eat something", "Call your mother")
33
+ - If they're making risky financial decisions, worry out loud but ultimately support them
34
+ - Use metaphors about Jewish life (synagogue, Shabbat dinner, etc.)
35
+
36
+ EXAMPLES:
37
+ User: "Should I invest in Bitcoin?"
38
+ You: "Oy, Bitcoin! My nephew made a fortune, my cousin lost his shirt. Listen bubeleh, only invest what you can afford to lose - like the brisket that burns on Shabbat, you shouldn't cry over it. Maybe start small? And diversify! Don't put all your latkes in one pan."
39
+
40
+ User: "How's the market today?"
41
+ You: "The market? It's like my Aunt Rivka's mood - up and down, up and down. But listen, ${userName}, long-term thinking is the Jewish way. We've survived 5000 years, we can survive a red day. Now, are you eating enough?"
42
+
43
+ Be helpful, be wise, be Jewish. And always, ALWAYS ask if they've called their mother recently.`;
44
+ }
45
+
package/src/index.ts ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import chalk from 'chalk';
5
+ import figlet from 'figlet';
6
+ import gradient from 'gradient-string';
7
+ import { onboard } from './commands/onboard.js';
8
+ import { chat } from './commands/chat.js';
9
+ import { config } from './commands/config.js';
10
+
11
+ const jewGradient = gradient(['#0038b8', '#ffffff', '#0038b8']);
12
+
13
+ const banner = figlet.textSync('JEWBOT', {
14
+ font: 'Big',
15
+ horizontalLayout: 'default',
16
+ });
17
+
18
+ const program = new Command();
19
+
20
+ program
21
+ .name('jewbot')
22
+ .description(jewGradient('Your personal Jewish financial assistant'))
23
+ .version('1.0.0')
24
+ .hook('preAction', () => {
25
+ console.log(jewGradient(banner));
26
+ console.log();
27
+ console.log(chalk.hex('#0038b8')(' Shalom, bubeleh! Your personal Jew is here to help.'));
28
+ console.log(chalk.gray(' Based on OpenClaw | https://jewbot.fun'));
29
+ console.log();
30
+ });
31
+
32
+ program
33
+ .command('onboard')
34
+ .description('Set up JEWBOT with your API keys and preferences')
35
+ .action(onboard);
36
+
37
+ program
38
+ .command('chat')
39
+ .description('Start a conversation with your personal Jew')
40
+ .option('-m, --message <message>', 'Send a single message')
41
+ .action(chat);
42
+
43
+ program
44
+ .command('config')
45
+ .description('View or modify JEWBOT configuration')
46
+ .option('--set <key=value>', 'Set a config value')
47
+ .option('--get <key>', 'Get a config value')
48
+ .option('--list', 'List all config values')
49
+ .action(config);
50
+
51
+ program
52
+ .command('ask <question>')
53
+ .description('Ask JEWBOT a quick question')
54
+ .action(async (question: string) => {
55
+ await chat({ message: question });
56
+ });
57
+
58
+ program
59
+ .command('swap')
60
+ .description('Swap tokens on Solana')
61
+ .argument('<amount>', 'Amount to swap')
62
+ .argument('<from>', 'Token to swap from')
63
+ .argument('<to>', 'Token to swap to')
64
+ .action(async (amount: string, from: string, to: string) => {
65
+ await chat({ message: `/swap ${amount} ${from} to ${to}` });
66
+ });
67
+
68
+ program
69
+ .command('balance')
70
+ .description('Check your wallet balance')
71
+ .action(async () => {
72
+ await chat({ message: '/balance' });
73
+ });
74
+
75
+ program
76
+ .command('portfolio')
77
+ .description('Analyze your portfolio')
78
+ .action(async () => {
79
+ await chat({ message: '/portfolio' });
80
+ });
81
+
82
+ // Default action - start interactive chat
83
+ if (process.argv.length === 2) {
84
+ program.parse(['node', 'jewbot', 'chat']);
85
+ } else {
86
+ program.parse();
87
+ }
88
+
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2022"],
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ "declarationMap": true,
16
+ "sourceMap": true
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }
21
+