samarthya-bot 2.2.0 → 2.3.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +340 -353
  3. package/backend/bin/samarthya.js +29 -10
  4. package/backend/config/constants.js +4 -4
  5. package/backend/controllers/chatController.js +72 -0
  6. package/backend/controllers/telegramController.js +8 -0
  7. package/backend/package-lock.json +2 -2
  8. package/backend/package.json +2 -2
  9. package/backend/public/assets/index-DiMx9ERJ.css +1 -0
  10. package/backend/public/assets/index-Dn5WYZTH.js +32 -0
  11. package/backend/public/index.html +186 -16
  12. package/backend/public/robots.txt +32 -0
  13. package/backend/public/sitemap.xml +39 -0
  14. package/backend/services/agent/commandService.js +168 -0
  15. package/backend/services/llm/llmService.js +8 -0
  16. package/backend/services/planner/plannerService.js +17 -0
  17. package/backend/services/security/sandboxService.js +11 -4
  18. package/backend/services/system/platform.js +150 -0
  19. package/backend/services/tools/toolRegistry.js +523 -37
  20. package/backend/services/worker/workerClient.js +141 -29
  21. package/package.json +2 -2
  22. package/backend/public/assets/index-6PCzI3K2.js +0 -40
  23. package/backend/public/assets/index-6TF5jVRQ.js +0 -149
  24. package/backend/public/assets/index-B0U7rt6f.js +0 -46
  25. package/backend/public/assets/index-BF0RZh9i.js +0 -149
  26. package/backend/public/assets/index-BFRAq8Y1.js +0 -149
  27. package/backend/public/assets/index-CGw8cc8z.js +0 -149
  28. package/backend/public/assets/index-Ckf0GO1B.css +0 -1
  29. package/backend/public/assets/index-Cx0Ei-z7.js +0 -149
  30. package/backend/public/assets/index-DIPdcLv-.js +0 -25
  31. package/backend/public/assets/index-Da1E-MYB.js +0 -53
  32. package/backend/public/assets/index-DdCKkq38.js +0 -149
  33. package/backend/public/assets/index-Do4jNsZS.js +0 -19
  34. package/backend/public/assets/index-DyjpBYmS.js +0 -51
  35. package/backend/public/assets/index-DzlXcaXT.js +0 -149
  36. package/backend/public/assets/index-J7XSVHCz.css +0 -1
  37. package/backend/public/assets/index-Ui-pyZvK.js +0 -25
  38. package/backend/public/assets/index-kzffNwzo.js +0 -149
@@ -1,18 +1,188 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <meta name="description" content="SamarthyaBot - Privacy-first Personal AI Operator built for Indian workflows. Hindi, Hinglish & English support." />
8
- <meta name="theme-color" content="#0f0f23" />
9
- <link rel="manifest" href="/manifest.json" />
10
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Noto+Sans+Devanagari:wght@400;500;600;700&display=swap" rel="stylesheet">
11
- <title>SamarthyaBot - समर्थ्य बोट | Personal AI Operator</title>
12
- <script type="module" crossorigin src="/assets/index-BFRAq8Y1.js"></script>
13
- <link rel="stylesheet" crossorigin href="/assets/index-J7XSVHCz.css">
14
- </head>
15
- <body>
16
- <div id="root"></div>
17
- </body>
18
- </html>
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+
9
+ <!-- Primary SEO Meta Tags -->
10
+ <title>SamarthyaBot Privacy-First AI Agent OS | Self-Hosted AI Operating System | Made in India</title>
11
+ <meta name="description"
12
+ content="SamarthyaBot is a privacy-first, self-hosted AI operating system. Multi-agent RPA engine with Telegram, Discord, browser automation, SSH deployment, encrypted memory, and Indian workflow support (GST, UPI, IRCTC). Supports Gemini, Claude, GPT, Ollama. Free and open-source." />
13
+ <meta name="keywords"
14
+ content="SamarthyaBot, AI agent, AI operating system, self-hosted AI, privacy AI, local AI, chatbot, Telegram bot, Discord bot, RPA, robotic process automation, browser automation, Puppeteer, SSH deployment, encrypted memory, Gemini, Claude, GPT, Ollama, DeepSeek, OpenRouter, Indian AI, Hindi AI, GST calculator, UPI, IRCTC, Node.js, React, MongoDB, open source, Made in India" />
15
+ <meta name="author" content="Bishnu Prasad Sahu" />
16
+ <meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" />
17
+ <link rel="canonical" href="https://github.com/mebishnusahu0595/SamarthyaBot" />
18
+ <meta name="theme-color" content="#0f0f23" />
19
+
20
+ <!-- Open Graph / Facebook -->
21
+ <meta property="og:type" content="website" />
22
+ <meta property="og:url" content="https://github.com/mebishnusahu0595/SamarthyaBot" />
23
+ <meta property="og:title" content="SamarthyaBot — Privacy-First AI Agent OS | Made in India" />
24
+ <meta property="og:description"
25
+ content="Self-hosted multi-agent AI operating system with Telegram, Discord, browser automation, SSH deployment, and Indian workflow support. Supports 9 AI providers including Gemini, Claude, GPT, Ollama (offline). Free and open-source." />
26
+ <meta property="og:image"
27
+ content="https://raw.githubusercontent.com/mebishnusahu0595/SamarthyaBot/main/backend/public/logo.png" />
28
+ <meta property="og:site_name" content="SamarthyaBot" />
29
+ <meta property="og:locale" content="en_IN" />
30
+
31
+ <!-- Twitter Card -->
32
+ <meta name="twitter:card" content="summary_large_image" />
33
+ <meta name="twitter:url" content="https://github.com/mebishnusahu0595/SamarthyaBot" />
34
+ <meta name="twitter:title" content="SamarthyaBot — Privacy-First AI Agent OS" />
35
+ <meta name="twitter:description"
36
+ content="Self-hosted AI operating system with Telegram, Discord, browser automation, SSH, encrypted memory. 9 AI providers. Free, open-source, Made in India." />
37
+ <meta name="twitter:image"
38
+ content="https://raw.githubusercontent.com/mebishnusahu0595/SamarthyaBot/main/backend/public/logo.png" />
39
+
40
+ <!-- JSON-LD Structured Data for AI Search Engines (GEO) -->
41
+ <script type="application/ld+json">
42
+ {
43
+ "@context": "https://schema.org",
44
+ "@type": "SoftwareApplication",
45
+ "name": "SamarthyaBot",
46
+ "alternateName": ["समर्थ्य बोट", "Samarthya Bot", "SamarthyaBot AI"],
47
+ "description": "SamarthyaBot is a privacy-first, self-hosted AI operating system built for Indian developers. It features multi-agent RPA automation, browser control via Puppeteer, SSH deployment, encrypted memory, voice transcription, and supports 9 AI providers including Gemini, Claude, GPT, and Ollama (offline).",
48
+ "url": "https://github.com/mebishnusahu0595/SamarthyaBot",
49
+ "downloadUrl": "https://www.npmjs.com/package/samarthya-bot",
50
+ "installUrl": "https://www.npmjs.com/package/samarthya-bot",
51
+ "applicationCategory": "DeveloperApplication",
52
+ "applicationSubCategory": "AI Agent, RPA, Automation, Chatbot",
53
+ "operatingSystem": "Linux, macOS, Windows",
54
+ "softwareVersion": "2.2.0",
55
+ "softwareRequirements": "Node.js >= 20.0.0, MongoDB",
56
+ "programmingLanguage": ["JavaScript", "Go", "React"],
57
+ "isAccessibleForFree": true,
58
+ "license": "https://opensource.org/licenses/MIT",
59
+ "inLanguage": ["en", "hi"],
60
+ "offers": {
61
+ "@type": "Offer",
62
+ "price": "0",
63
+ "priceCurrency": "USD",
64
+ "availability": "https://schema.org/InStock"
65
+ },
66
+ "author": {
67
+ "@type": "Person",
68
+ "name": "Bishnu Prasad Sahu",
69
+ "url": "https://github.com/mebishnusahu0595",
70
+ "nationality": {
71
+ "@type": "Country",
72
+ "name": "India"
73
+ }
74
+ },
75
+ "publisher": {
76
+ "@type": "Person",
77
+ "name": "Bishnu Prasad Sahu"
78
+ },
79
+ "datePublished": "2026-02-25",
80
+ "dateModified": "2026-03-05",
81
+ "codeRepository": "https://github.com/mebishnusahu0595/SamarthyaBot",
82
+ "keywords": "AI agent, AI operating system, self-hosted AI, privacy-first AI, local AI, RPA, chatbot, Telegram bot, Discord bot, Puppeteer, SSH deployment, encrypted memory, Gemini, Claude, GPT, Ollama, DeepSeek, Indian AI, Hindi, GST, UPI, Node.js, React, MongoDB, open source, Made in India, samarthya, samarthyabot",
83
+ "featureList": [
84
+ "Multi-agent RPA engine — writes code, commits to GitHub, deploys autonomously",
85
+ "9 AI providers — Gemini, Claude, GPT, Ollama, DeepSeek, Qwen, OpenRouter, Groq, Mistral",
86
+ "Real browser automation via Puppeteer — scrape, click, navigate",
87
+ "SSH deployment to remote servers with password or PEM key",
88
+ "AES-256-CBC encrypted memory in MongoDB",
89
+ "Telegram and Discord bot integrations",
90
+ "Voice transcription via Groq/Whisper",
91
+ "Indian workflow automation — GST, UPI, IRCTC, Hindi/Hinglish",
92
+ "Drop-in JavaScript plugin system",
93
+ "Go micro-worker for live terminal streaming",
94
+ "Workspace security sandbox",
95
+ "Heartbeat periodic autonomous tasks",
96
+ "Beautiful React web dashboard with dark theme"
97
+ ]
98
+ }
99
+ </script>
100
+
101
+ <!-- FAQ Structured Data for Google & AI Search -->
102
+ <script type="application/ld+json">
103
+ {
104
+ "@context": "https://schema.org",
105
+ "@type": "FAQPage",
106
+ "mainEntity": [
107
+ {
108
+ "@type": "Question",
109
+ "name": "What is SamarthyaBot?",
110
+ "acceptedAnswer": {
111
+ "@type": "Answer",
112
+ "text": "SamarthyaBot is a privacy-first, self-hosted AI operating system that runs locally on your machine. It combines chatbot capabilities with full RPA (Robotic Process Automation) — meaning it can write code, deploy servers, control browsers, send emails, and automate Indian workflows like GST and UPI."
113
+ }
114
+ },
115
+ {
116
+ "@type": "Question",
117
+ "name": "How do I install SamarthyaBot?",
118
+ "acceptedAnswer": {
119
+ "@type": "Answer",
120
+ "text": "Install SamarthyaBot with a single NPM command: npm install -g samarthya-bot. Then run 'samarthya onboard' for guided setup. Requires Node.js 20+ and MongoDB."
121
+ }
122
+ },
123
+ {
124
+ "@type": "Question",
125
+ "name": "Is SamarthyaBot free?",
126
+ "acceptedAnswer": {
127
+ "@type": "Answer",
128
+ "text": "Yes, SamarthyaBot is 100% free and open-source under the MIT license. It supports free AI providers like Google Gemini and Ollama (fully offline)."
129
+ }
130
+ },
131
+ {
132
+ "@type": "Question",
133
+ "name": "Does SamarthyaBot work offline?",
134
+ "acceptedAnswer": {
135
+ "@type": "Answer",
136
+ "text": "Yes! Using Ollama as the AI provider, SamarthyaBot runs 100% offline with zero data leakage. No internet connection required after initial setup."
137
+ }
138
+ },
139
+ {
140
+ "@type": "Question",
141
+ "name": "What AI models does SamarthyaBot support?",
142
+ "acceptedAnswer": {
143
+ "@type": "Answer",
144
+ "text": "SamarthyaBot supports 9 AI providers with 20+ models: Google Gemini, Ollama (local), Anthropic Claude, OpenAI GPT, DeepSeek, Qwen, OpenRouter (100+ models), Groq, and Mistral."
145
+ }
146
+ },
147
+ {
148
+ "@type": "Question",
149
+ "name": "Does SamarthyaBot support Hindi?",
150
+ "acceptedAnswer": {
151
+ "@type": "Answer",
152
+ "text": "Yes! SamarthyaBot has first-class support for Hindi, Hinglish, and English. It's built specifically for Indian developers with Indian workflow support including GST, UPI, and IRCTC."
153
+ }
154
+ },
155
+ {
156
+ "@type": "Question",
157
+ "name": "Is my data safe with SamarthyaBot?",
158
+ "acceptedAnswer": {
159
+ "@type": "Answer",
160
+ "text": "Absolutely. SamarthyaBot runs entirely on your local machine. All memories are encrypted with AES-256-CBC. Dangerous commands are blocked by regex blacklists. Your data never leaves your device."
161
+ }
162
+ },
163
+ {
164
+ "@type": "Question",
165
+ "name": "How is SamarthyaBot different from ChatGPT?",
166
+ "acceptedAnswer": {
167
+ "@type": "Answer",
168
+ "text": "Unlike ChatGPT, SamarthyaBot runs locally on your machine, can execute real actions (deploy code, send emails, control browsers), supports Indian workflows (GST, UPI), works offline via Ollama, and your data never leaves your device."
169
+ }
170
+ }
171
+ ]
172
+ }
173
+ </script>
174
+
175
+ <!-- Fonts & PWA -->
176
+ <link rel="manifest" href="/manifest.json" />
177
+ <link
178
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Noto+Sans+Devanagari:wght@400;500;600;700&display=swap"
179
+ rel="stylesheet">
180
+ <script type="module" crossorigin src="/assets/index-Dn5WYZTH.js"></script>
181
+ <link rel="stylesheet" crossorigin href="/assets/index-DiMx9ERJ.css">
182
+ </head>
183
+
184
+ <body>
185
+ <div id="root"></div>
186
+ </body>
187
+
188
+ </html>
@@ -0,0 +1,32 @@
1
+ # SamarthyaBot Robots.txt
2
+ # Privacy-First AI Agent OS - https://github.com/mebishnusahu0595/SamarthyaBot
3
+
4
+ User-agent: *
5
+ Allow: /
6
+
7
+ # Allow all major search engines and AI crawlers
8
+ User-agent: Googlebot
9
+ Allow: /
10
+
11
+ User-agent: Bingbot
12
+ Allow: /
13
+
14
+ User-agent: GPTBot
15
+ Allow: /
16
+
17
+ User-agent: ChatGPT-User
18
+ Allow: /
19
+
20
+ User-agent: Google-Extended
21
+ Allow: /
22
+
23
+ User-agent: PerplexityBot
24
+ Allow: /
25
+
26
+ User-agent: ClaudeBot
27
+ Allow: /
28
+
29
+ User-agent: Applebot-Extended
30
+ Allow: /
31
+
32
+ Sitemap: https://github.com/mebishnusahu0595/SamarthyaBot
@@ -0,0 +1,39 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
+ <url>
4
+ <loc>https://github.com/mebishnusahu0595/SamarthyaBot</loc>
5
+ <lastmod>2026-03-05</lastmod>
6
+ <changefreq>weekly</changefreq>
7
+ <priority>1.0</priority>
8
+ </url>
9
+ <url>
10
+ <loc>https://www.npmjs.com/package/samarthya-bot</loc>
11
+ <lastmod>2026-03-05</lastmod>
12
+ <changefreq>weekly</changefreq>
13
+ <priority>0.9</priority>
14
+ </url>
15
+ <url>
16
+ <loc>https://github.com/mebishnusahu0595/SamarthyaBot/blob/main/README.md</loc>
17
+ <lastmod>2026-03-05</lastmod>
18
+ <changefreq>weekly</changefreq>
19
+ <priority>0.8</priority>
20
+ </url>
21
+ <url>
22
+ <loc>https://github.com/mebishnusahu0595/SamarthyaBot/blob/main/CONTRIBUTING.md</loc>
23
+ <lastmod>2026-03-05</lastmod>
24
+ <changefreq>monthly</changefreq>
25
+ <priority>0.6</priority>
26
+ </url>
27
+ <url>
28
+ <loc>https://github.com/mebishnusahu0595/SamarthyaBot/blob/main/SECURITY.md</loc>
29
+ <lastmod>2026-03-05</lastmod>
30
+ <changefreq>monthly</changefreq>
31
+ <priority>0.6</priority>
32
+ </url>
33
+ <url>
34
+ <loc>https://github.com/mebishnusahu0595/SamarthyaBot/blob/main/CHANGELOG.md</loc>
35
+ <lastmod>2026-03-05</lastmod>
36
+ <changefreq>weekly</changefreq>
37
+ <priority>0.7</priority>
38
+ </url>
39
+ </urlset>
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Chat Slash-Command Handler (OpenClaw-style control commands)
3
+ * ------------------------------------------------------------------
4
+ * Lets users control the agent directly from any channel (Web / Telegram
5
+ * / Discord) using `/command` syntax — without spending an LLM call.
6
+ *
7
+ * Supported:
8
+ * /help Show this help
9
+ * /status Agent status: provider, model, pack, host OS
10
+ * /tools | /skills List the tools available in the current pack
11
+ * /pack [name] Show or switch the active tool pack
12
+ * /model Show the active AI provider + model
13
+ * /whoami Show the current user + permissions
14
+ * /clear | /reset | /new Start a fresh conversation
15
+ * /memory Show how many memories are stored
16
+ * /version Show SamarthyaBot version
17
+ */
18
+
19
+ const path = require('path');
20
+ const toolRegistry = require('../tools/toolRegistry');
21
+ const platform = require('../system/platform');
22
+ const { TOOL_PACKS } = require('../../config/constants');
23
+
24
+ let VERSION = '0.0.0';
25
+ try {
26
+ VERSION = require(path.join(__dirname, '../../../package.json')).version;
27
+ } catch (_) { /* ignore */ }
28
+
29
+ function isCommand(message) {
30
+ return typeof message === 'string' && message.trim().startsWith('/');
31
+ }
32
+
33
+ /**
34
+ * Handle a slash command.
35
+ * @returns {{ handled: boolean, response?: string, action?: string }}
36
+ * `action` is an optional signal the caller can act on (e.g. 'new_conversation').
37
+ */
38
+ async function handleCommand(message, user = {}) {
39
+ const raw = message.trim();
40
+ const [cmdToken, ...rest] = raw.slice(1).split(/\s+/);
41
+ const cmd = (cmdToken || '').toLowerCase();
42
+ const arg = rest.join(' ').trim();
43
+ const activePack = user.activePack || 'personal';
44
+
45
+ switch (cmd) {
46
+ case 'help':
47
+ case 'commands':
48
+ case 'h':
49
+ return {
50
+ handled: true,
51
+ response:
52
+ `🤖 **SamarthyaBot Commands**\n\n` +
53
+ `\`/status\` — agent status (provider, model, OS)\n` +
54
+ `\`/tools\` — list available skills in your pack\n` +
55
+ `\`/pack [name]\` — show/switch tool pack (student, business, developer, personal)\n` +
56
+ `\`/model\` — show active AI model\n` +
57
+ `\`/whoami\` — your profile & permissions\n` +
58
+ `\`/memory\` — stored memory count\n` +
59
+ `\`/new\` (or \`/clear\`, \`/reset\`) — start a fresh chat\n` +
60
+ `\`/version\` — SamarthyaBot version\n\n` +
61
+ `_Type any normal message to talk to the AI agent._`
62
+ };
63
+
64
+ case 'status':
65
+ case 'stat': {
66
+ const provider = (process.env.ACTIVE_PROVIDER || 'gemini').toUpperCase();
67
+ const model = process.env.ACTIVE_MODEL || process.env.OLLAMA_MODEL || 'gemini-2.5-flash';
68
+ const offline = process.env.USE_OLLAMA === 'true';
69
+ const toolCount = toolRegistry.getToolsForPack(activePack).length;
70
+ return {
71
+ handled: true,
72
+ response:
73
+ `🟢 **SamarthyaBot is ONLINE**\n\n` +
74
+ `🧠 Provider: **${provider}**${offline ? ' (offline)' : ''}\n` +
75
+ `🤖 Model: **${model}**\n` +
76
+ `🎒 Active Pack: **${activePack}** (${toolCount} skills)\n` +
77
+ `💻 Host: **${platform.describe()}**\n` +
78
+ `📦 Version: **v${VERSION}**`
79
+ };
80
+ }
81
+
82
+ case 'tools':
83
+ case 'skills': {
84
+ const tools = toolRegistry.getToolsForPack(activePack);
85
+ const list = tools
86
+ .map(t => `• \`${t.name}\` — ${t.description?.split('.')[0] || ''}`)
87
+ .join('\n');
88
+ return {
89
+ handled: true,
90
+ response: `🛠️ **${tools.length} skills available** (pack: ${activePack})\n\n${list}`
91
+ };
92
+ }
93
+
94
+ case 'pack': {
95
+ if (!arg) {
96
+ const names = Object.keys(TOOL_PACKS).map(k => `• **${k}** — ${TOOL_PACKS[k].description}`).join('\n');
97
+ return {
98
+ handled: true,
99
+ response: `🎒 Active pack: **${activePack}**\n\nAvailable packs:\n${names}\n\n_Switch with_ \`/pack <name>\``
100
+ };
101
+ }
102
+ const target = arg.toLowerCase();
103
+ if (!TOOL_PACKS[target]) {
104
+ return { handled: true, response: `❌ Unknown pack "${target}". Options: ${Object.keys(TOOL_PACKS).join(', ')}` };
105
+ }
106
+ // Persist the switch when the user object is a saveable model.
107
+ try {
108
+ user.activePack = target;
109
+ if (typeof user.save === 'function') await user.save();
110
+ } catch (_) { /* best effort */ }
111
+ return {
112
+ handled: true,
113
+ action: 'switch_pack',
114
+ actionValue: target,
115
+ response: `✅ Switched to **${target}** pack (${TOOL_PACKS[target].tools.length} skills).`
116
+ };
117
+ }
118
+
119
+ case 'model': {
120
+ const provider = (process.env.ACTIVE_PROVIDER || 'gemini').toUpperCase();
121
+ const model = process.env.ACTIVE_MODEL || process.env.OLLAMA_MODEL || 'gemini-2.5-flash';
122
+ return {
123
+ handled: true,
124
+ response: `🤖 Active model: **${model}** via **${provider}**\n\n_Change it from the CLI:_ \`samarthya model\``
125
+ };
126
+ }
127
+
128
+ case 'whoami': {
129
+ const name = user.name || user.username || 'User';
130
+ const perms = user.permissions ? JSON.stringify(user.permissions) : 'defaults';
131
+ return {
132
+ handled: true,
133
+ response: `👤 **${name}**\n🎒 Pack: ${activePack}\n🗣️ Language: ${user.language || 'auto'}\n🔐 Permissions: ${perms}`
134
+ };
135
+ }
136
+
137
+ case 'memory':
138
+ case 'mem': {
139
+ let count = 'unknown';
140
+ try {
141
+ const Memory = require('../../models/Memory');
142
+ count = await Memory.countDocuments({ userId: user._id || user.id });
143
+ } catch (_) { /* ignore */ }
144
+ return { handled: true, response: `🧠 You have **${count}** stored memories.` };
145
+ }
146
+
147
+ case 'new':
148
+ case 'clear':
149
+ case 'reset':
150
+ return {
151
+ handled: true,
152
+ action: 'new_conversation',
153
+ response: `🆕 Started a fresh conversation. Previous context cleared.`
154
+ };
155
+
156
+ case 'version':
157
+ case 'v':
158
+ return { handled: true, response: `📦 SamarthyaBot **v${VERSION}** — Made in India 🇮🇳` };
159
+
160
+ default:
161
+ return {
162
+ handled: true,
163
+ response: `❓ Unknown command \`/${cmd}\`. Type \`/help\` to see all commands.`
164
+ };
165
+ }
166
+ }
167
+
168
+ module.exports = { isCommand, handleCommand };
@@ -1,4 +1,5 @@
1
1
  const { GoogleGenAI } = require("@google/genai");
2
+ const platform = require("../system/platform");
2
3
 
3
4
  class LLMService {
4
5
  constructor() {
@@ -60,6 +61,13 @@ You are intelligent, helpful, and respectful. You understand Indian culture, fes
60
61
 
61
62
  CURRENT DATE & TIME (IST): ${currentDateTime}
62
63
 
64
+ HOST ENVIRONMENT: ${platform.describe()}
65
+ OS COMMAND RULE: This machine runs **${platform.OS.toUpperCase()}**. When using run_command / devops_execute_stream, ALWAYS use shell commands valid for ${platform.OS}.
66
+ ${platform.isWindows
67
+ ? ' • Windows: use `dir`, `type`, `copy`, `del`, `move`, `where`, PowerShell cmdlets. Do NOT use ls/cat/rm/grep.'
68
+ : ' • Unix (' + platform.OS + '): use `ls`, `cat`, `cp`, `mv`, `grep`, `find`. Do NOT use Windows-only commands.'}
69
+ • To open a URL/file/app, prefer the \`open_path\` tool (it auto-picks start/open/xdg-open).
70
+
63
71
  USER PROFILE:
64
72
  - Name: ${user.name || 'User'}
65
73
  - Language: ${user.language || 'hinglish'}
@@ -2,6 +2,7 @@ const llmService = require('../llm/llmService');
2
2
  const toolRegistry = require('../tools/toolRegistry');
3
3
  const securityService = require('../security/securityService');
4
4
  const memoryService = require('../memory/memoryService');
5
+ const commandService = require('../agent/commandService');
5
6
  const AuditLog = require('../../models/AuditLog');
6
7
 
7
8
  class PlannerService {
@@ -27,6 +28,22 @@ class PlannerService {
27
28
  language: llmService.detectLanguage(userMessage)
28
29
  };
29
30
 
31
+ // Step 0: Intercept slash-commands (instant, no LLM call) — works on
32
+ // every channel (Web / Telegram / Discord) since they all route here.
33
+ if (commandService.isCommand(userMessage)) {
34
+ try {
35
+ const cmd = await commandService.handleCommand(userMessage, user);
36
+ if (cmd.handled) {
37
+ result.response = cmd.response;
38
+ result.command = { action: cmd.action || null, value: cmd.actionValue || null };
39
+ return result;
40
+ }
41
+ } catch (e) {
42
+ result.response = `⚠️ Command error: ${e.message}`;
43
+ return result;
44
+ }
45
+ }
46
+
30
47
  // Step 1: Security scan on user input
31
48
  const inputScan = securityService.scanForSensitiveData(userMessage);
32
49
  if (inputScan.length > 0) {
@@ -42,14 +42,21 @@ class SandboxService {
42
42
  if (!this.enabled) return { allowed: true, reason: 'Sandbox disabled' };
43
43
 
44
44
  const resolvedPath = path.resolve(filePath);
45
- const resolvedWorkspace = path.resolve(this.workspace);
46
45
 
47
- if (resolvedPath.startsWith(resolvedWorkspace)) {
46
+ // True containment check: the path must equal the directory or sit
47
+ // inside it (boundary-aware), so siblings like
48
+ // `.../SamarthyaBot_Files_evil` do NOT pass a naive startsWith().
49
+ const isInside = (child, parent) => {
50
+ const rel = path.relative(parent, child);
51
+ return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));
52
+ };
53
+
54
+ if (isInside(resolvedPath, path.resolve(this.workspace))) {
48
55
  return { allowed: true, reason: 'Path is within workspace' };
49
56
  }
50
57
 
51
- // Allow /tmp for scratch files
52
- if (resolvedPath.startsWith('/tmp') || resolvedPath.startsWith(os.tmpdir())) {
58
+ // Allow the OS temp directory for scratch files
59
+ if (isInside(resolvedPath, os.tmpdir())) {
53
60
  return { allowed: true, reason: 'Path is in temp directory' };
54
61
  }
55
62