samarthya-bot 1.1.0 → 1.1.2

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/README.md CHANGED
@@ -34,7 +34,7 @@ SamarthyaBot is built for developers. The best way to start is the **CLI Wizard*
34
34
 
35
35
  ### 📦 Install (Global)
36
36
 
37
- Runtime: **Node JS ≥ 20** and **MongoDB** (Local).
37
+ Runtime: **Node 20 LTS** (Officially Supported/Recommended) and **MongoDB** (Local).
38
38
 
39
39
  ```bash
40
40
  npm install -g samarthya-bot
@@ -42,10 +42,13 @@ npm install -g samarthya-bot
42
42
  # Start the interactive setup
43
43
  samarthya onboard
44
44
 
45
- # Launch the engine and dashboard
45
+ # Launch the engine and dashboard (Terminal 1)
46
46
  samarthya gateway
47
+
48
+ # Expose to internet & setup Telegram Webhook (Terminal 2)
49
+ samarthya tunnel
47
50
  ```
48
- *The wizard guides you through API keys (Gemini/Ollama) and system permissions.*
51
+ *The wizard guides you through API keys (Gemini/Ollama, Telegram Bot Token) and system permissions.*
49
52
 
50
53
  ### 🛠️ From Source (Development)
51
54
 
@@ -86,7 +89,8 @@ npm run dev
86
89
  | `samarthya gateway` | Run the backend control plane and serve the Dashboard. |
87
90
  | `samarthya status` | Display the status of background jobs and the engine. |
88
91
  | `samarthya stop` | Gracefully shut down all background autonomous agents. |
89
- | `samarthya model [name]` | Swap between LLM providers (e.g. `ollama`, `gemini`). |
92
+ | `samarthya model` | Swap between LLM providers (e.g. `ollama`, `gemini`). |
93
+ | `samarthya tunnel` | Expose gateway to internet. **(Must run in a separate terminal)** |
90
94
 
91
95
  ---
92
96
 
@@ -99,6 +103,9 @@ If you are running from source or manual setup, create a `.env` file in the `bac
99
103
  GEMINI_API_KEY=your_gemini_api_key_here
100
104
  MEMORY_ENCRYPTION_KEY=your_32_char_secret_key
101
105
 
106
+ # Optional (For Remote Access)
107
+ TELEGRAM_BOT_TOKEN=your_telegram_bot_api_key
108
+
102
109
  # Optional
103
110
  MONGO_URI=mongodb://localhost:27017/samarthya
104
111
  PORT=5000
@@ -106,7 +113,13 @@ USE_OLLAMA=false
106
113
  ACTIVE_PROVIDER=gemini # or ollama
107
114
  ```
108
115
 
109
- *Note: The `samarthya onboard` command handles these for you automatically!*
116
+ ### 📱 Telegram Integration
117
+ To connect SamarthyaBot to Telegram:
118
+ 1. Get a bot token from [@BotFather](https://t.me/BotFather).
119
+ 2. The `samarthya onboard` wizard will automatically ask for this token.
120
+ 3. Run `samarthya gateway` in your **first terminal**.
121
+ 4. Run `samarthya tunnel` in a **new, separate terminal**.
122
+ 5. Samarthya will automatically create a secure tunnel and link your bot!
110
123
 
111
124
  ---
112
125
 
@@ -16,8 +16,8 @@ OLLAMA_MODEL=llama3.2
16
16
  ACTIVE_PROVIDER=gemini
17
17
  ACTIVE_MODEL=gemini-2.5-flash-lite
18
18
 
19
- # Optional Telegram Remote Control
20
- # TELEGRAM_BOT_TOKEN=your_telegram_bot_token
19
+ # Optional Telegram Remote Control (Connect via 'samarthya tunnel')
20
+ TELEGRAM_BOT_TOKEN=your_telegram_bot_api_key
21
21
 
22
22
  # Node Environment
23
23
  NODE_ENV=production
@@ -12,8 +12,15 @@ const backendDir = path.join(__dirname, '..');
12
12
  // Helper to check if server is already running on port 5000
13
13
  const isServerRunning = () => {
14
14
  try {
15
- execSync('fuser 5000/tcp 2>/dev/null');
16
- return true;
15
+ if (process.platform === 'win32') {
16
+ const output = execSync('netstat -ano | findstr :5000', { encoding: 'utf-8' });
17
+ return output.includes('LISTENING');
18
+ } else {
19
+ // macOS and Linux
20
+ // Using lsof as it's more standard across unix than fuser
21
+ execSync('lsof -i:5000 -t 2>/dev/null');
22
+ return true;
23
+ }
17
24
  } catch {
18
25
  return false;
19
26
  }
@@ -79,6 +86,7 @@ switch (command) {
79
86
  const anthropicKey = await question('🔑 Enter Anthropic (Claude) API Key (or press Enter to skip): ');
80
87
  const groqKey = await question('🔑 Enter Groq API Key (or press Enter to skip): ');
81
88
  const openAiKey = await question('🔑 Enter OpenAI API Key (or press Enter to skip): ');
89
+ const telegramToken = await question('🤖 Enter Telegram Bot Token (or press Enter to skip): ');
82
90
 
83
91
  const envPath = path.join(backendDir, '.env');
84
92
  let envVars = {};
@@ -113,6 +121,7 @@ switch (command) {
113
121
  if (anthropicKey.trim()) envVars['ANTHROPIC_API_KEY'] = anthropicKey.trim();
114
122
  if (groqKey.trim()) envVars['GROQ_API_KEY'] = groqKey.trim();
115
123
  if (openAiKey.trim()) envVars['OPENAI_API_KEY'] = openAiKey.trim();
124
+ if (telegramToken.trim()) envVars['TELEGRAM_BOT_TOKEN'] = telegramToken.trim();
116
125
 
117
126
  if (!envVars['GEMINI_API_KEY']) envVars['GEMINI_API_KEY'] = 'dummy';
118
127
 
@@ -297,7 +306,11 @@ switch (command) {
297
306
 
298
307
  try { require('dotenv').config({ path: path.join(backendDir, '.env') }); } catch (e) { }
299
308
 
300
- const tunnelProcess = spawn('npx', ['localtunnel', '--port', '5000'], { stdio: 'pipe' });
309
+ const isWindows = process.platform === 'win32';
310
+ const tunnelProcess = spawn('npm', ['exec', 'localtunnel', '--', '--port', '5000'], {
311
+ stdio: 'pipe',
312
+ shell: isWindows
313
+ });
301
314
 
302
315
  tunnelProcess.stdout.on('data', async (data) => {
303
316
  const output = data.toString();
@@ -346,7 +359,23 @@ switch (command) {
346
359
  if (isServerRunning()) {
347
360
  console.log('🛑 Stopping SamarthyaBot Gateway...');
348
361
  try {
349
- execSync('fuser -k 5000/tcp 2>/dev/null');
362
+ if (process.platform === 'win32') {
363
+ // Find PID of process listening on port 5000 and kill it
364
+ const netstatOut = execSync('netstat -ano | findstr :5000', { encoding: 'utf-8' });
365
+ const lines = netstatOut.split('\\n');
366
+ for (const line of lines) {
367
+ if (line.includes('LISTENING')) {
368
+ const parts = line.trim().split(/\\s+/);
369
+ const pid = parts[parts.length - 1];
370
+ if (pid && pid !== '0') {
371
+ execSync(`taskkill /PID ${pid} /F`, { stdio: 'ignore' });
372
+ }
373
+ }
374
+ }
375
+ } else {
376
+ // macOS and Linux
377
+ execSync('lsof -t -i:5000 | xargs kill -9 2>/dev/null || fuser -k 5000/tcp 2>/dev/null');
378
+ }
350
379
  console.log('✅ Gateway stopped successfully.');
351
380
  } catch (e) {
352
381
  console.log('❌ Failed to stop gateway gracefully. Process might already be dead.');
@@ -360,7 +389,21 @@ switch (command) {
360
389
  console.log('🔄 Restarting SamarthyaBot Gateway...');
361
390
  if (isServerRunning()) {
362
391
  try {
363
- execSync('fuser -k 5000/tcp 2>/dev/null');
392
+ if (process.platform === 'win32') {
393
+ const netstatOut = execSync('netstat -ano | findstr :5000', { encoding: 'utf-8' });
394
+ const lines = netstatOut.split('\\n');
395
+ for (const line of lines) {
396
+ if (line.includes('LISTENING')) {
397
+ const parts = line.trim().split(/\\s+/);
398
+ const pid = parts[parts.length - 1];
399
+ if (pid && pid !== '0') {
400
+ execSync(`taskkill /PID ${pid} /F`, { stdio: 'ignore' });
401
+ }
402
+ }
403
+ }
404
+ } else {
405
+ execSync('lsof -t -i:5000 | xargs kill -9 2>/dev/null || fuser -k 5000/tcp 2>/dev/null');
406
+ }
364
407
  } catch (e) { /* ignore */ }
365
408
  }
366
409
  // Give it a moment to free the port
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "samarthya-bot",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Privacy-First Local Agentic OS & Command Center",
5
5
  "main": "backend/server.js",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "samarthya-bot",
38
38
  "ollama"
39
39
  ],
40
- "author": "Bishnu Sahu",
40
+ "author": "Bishnu Prasad Sahu",
41
41
  "license": "MIT",
42
42
  "engines": {
43
43
  "node": ">=20.0.0"