stella-coder 5.3.1 → 5.3.3

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 (52) hide show
  1. package/COMMANDS.md +47 -0
  2. package/install-av.bat +17 -0
  3. package/install-stella-pkg.bat +21 -0
  4. package/oneline-av.ps1 +7 -0
  5. package/oneline-stella.ps1 +2 -0
  6. package/package.json +1 -1
  7. package/releases/stella-antivirus/database.mjs +871 -0
  8. package/releases/stella-antivirus/index.mjs +8 -0
  9. package/releases/stella-antivirus/install-av.bat +12 -0
  10. package/releases/stella-antivirus/scanner.mjs +591 -0
  11. package/releases/stella-antivirus/ui.mjs +570 -0
  12. package/releases/stella-antivirus.zip +0 -0
  13. package/releases/stella-coder/README.md +67 -0
  14. package/releases/stella-coder/adb.mjs +200 -0
  15. package/releases/stella-coder/autonomous-agent.mjs +550 -0
  16. package/releases/stella-coder/banner.mjs +46 -0
  17. package/releases/stella-coder/browser-control.mjs +274 -0
  18. package/releases/stella-coder/build.mjs +151 -0
  19. package/releases/stella-coder/charts.mjs +411 -0
  20. package/releases/stella-coder/coding-brain.mjs +753 -0
  21. package/releases/stella-coder/game-engine.mjs +708 -0
  22. package/releases/stella-coder/gdrive-backup.mjs +338 -0
  23. package/releases/stella-coder/git-api.mjs +407 -0
  24. package/releases/stella-coder/gmail.mjs +415 -0
  25. package/releases/stella-coder/home-assistant.mjs +168 -0
  26. package/releases/stella-coder/index.mjs +5810 -0
  27. package/releases/stella-coder/install-stella.bat +12 -0
  28. package/releases/stella-coder/markdown.mjs +100 -0
  29. package/releases/stella-coder/mcp.mjs +296 -0
  30. package/releases/stella-coder/package.json +67 -0
  31. package/releases/stella-coder/presentations.mjs +1106 -0
  32. package/releases/stella-coder/protect.mjs +182 -0
  33. package/releases/stella-coder/screen-monitor.mjs +334 -0
  34. package/releases/stella-coder/sea-config.json +5 -0
  35. package/releases/stella-coder/security.mjs +237 -0
  36. package/releases/stella-coder/subagents.mjs +142 -0
  37. package/releases/stella-coder/telegram-bot.mjs +824 -0
  38. package/releases/stella-coder/tg-server.mjs +116 -0
  39. package/releases/stella-coder/theme.mjs +91 -0
  40. package/releases/stella-coder/tools.mjs +3143 -0
  41. package/releases/stella-coder/web-parser.mjs +229 -0
  42. package/releases/stella-coder/yandex-maps.mjs +426 -0
  43. package/releases/stella-coder.zip +0 -0
  44. package/run-antivirus.bat +4 -0
  45. package/setup-antivirus.bat +64 -0
  46. package/setup-full.bat +65 -0
  47. package/setup-full.ps1 +84 -0
  48. package/setup-stella.bat +46 -0
  49. package/stella-cli/index.mjs +12 -2
  50. package/stella-cli/protect.mjs +182 -0
  51. package/stella.bat +3 -0
  52. package/tests/test-modules.mjs +101 -0
@@ -0,0 +1,274 @@
1
+ import { execSync, spawn } from "child_process"
2
+ import { writeFileSync, existsSync, mkdirSync } from "fs"
3
+ import { join } from "path"
4
+ import { homedir } from "os"
5
+ import http from "http"
6
+
7
+ const STELLA_DIR = join(homedir(), ".stella")
8
+ const BROWSER_DIR = join(STELLA_DIR, "browser")
9
+ const PROFILES_DIR = join(BROWSER_DIR, "profiles")
10
+
11
+ function ensureDir() {
12
+ if (!existsSync(BROWSER_DIR)) mkdirSync(BROWSER_DIR, { recursive: true })
13
+ if (!existsSync(PROFILES_DIR)) mkdirSync(PROFILES_DIR, { recursive: true })
14
+ }
15
+
16
+ function httpGet(url) {
17
+ return new Promise((resolve, reject) => {
18
+ http.get(url, (res) => {
19
+ let data = ""
20
+ res.on("data", (chunk) => data += chunk)
21
+ res.on("end", () => {
22
+ try { resolve(JSON.parse(data)) } catch { resolve(data) }
23
+ })
24
+ }).on("error", reject)
25
+ })
26
+ }
27
+
28
+ export class ChromeBrowser {
29
+ constructor() {
30
+ ensureDir()
31
+ this.ws = null
32
+ this.pageId = null
33
+ this.debugPort = 9222
34
+ this.proc = null
35
+ this.msgId = 0
36
+ this.callbacks = new Map()
37
+ }
38
+
39
+ async launch(headless = false) {
40
+ const chromePaths = [
41
+ "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
42
+ "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
43
+ join(homedir(), "AppData\\Local\\Google\\Chrome\\Application\\chrome.exe"),
44
+ "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
45
+ "C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe",
46
+ ]
47
+
48
+ let chromePath = null
49
+ for (const p of chromePaths) {
50
+ if (existsSync(p)) { chromePath = p; break }
51
+ }
52
+
53
+ if (!chromePath) {
54
+ return { success: false, error: "Chrome/Edge not found" }
55
+ }
56
+
57
+ const args = [
58
+ `--remote-debugging-port=${this.debugPort}`,
59
+ "--no-first-run",
60
+ "--no-default-browser-check",
61
+ headless ? "--headless=new" : "",
62
+ `--user-data-dir=${join(PROFILES_DIR, "default")}`,
63
+ "about:blank",
64
+ ].filter(Boolean)
65
+
66
+ this.proc = spawn(chromePath, args, { detached: true, stdio: "ignore" })
67
+ this.proc.unref()
68
+
69
+ await new Promise(r => setTimeout(r, 2000))
70
+
71
+ try {
72
+ const tabs = await httpGet(`http://127.0.0.1:${this.debugPort}/json`)
73
+ if (tabs && tabs.length > 0) {
74
+ this.pageId = tabs[0].id
75
+ return { success: true, port: this.debugPort, pid: this.proc.pid }
76
+ }
77
+ } catch (e) {
78
+ return { success: false, error: `Chrome launched but DevTools not ready: ${e.message}` }
79
+ }
80
+
81
+ return { success: true, port: this.debugPort }
82
+ }
83
+
84
+ async connect() {
85
+ try {
86
+ const tabs = await httpGet(`http://127.0.0.1:${this.debugPort}/json`)
87
+ if (!tabs || tabs.length === 0) {
88
+ return { success: false, error: "No tabs found. Launch Chrome first." }
89
+ }
90
+
91
+ const wsUrl = tabs[0].webSocketDebuggerUrl
92
+ if (!wsUrl) {
93
+ return { success: false, error: "WebSocket URL not available" }
94
+ }
95
+
96
+ return new Promise((resolve) => {
97
+ this.ws = new WebSocket(wsUrl)
98
+ this.ws.onopen = () => {
99
+ this.pageId = tabs[0].id
100
+ resolve({ success: true, title: tabs[0].title })
101
+ }
102
+ this.ws.onmessage = (event) => {
103
+ const msg = JSON.parse(typeof event.data === "string" ? event.data : event.data.toString())
104
+ if (msg.id && this.callbacks.has(msg.id)) {
105
+ this.callbacks.get(msg.id)(msg)
106
+ this.callbacks.delete(msg.id)
107
+ }
108
+ }
109
+ this.ws.onerror = (err) => {
110
+ resolve({ success: false, error: err.message || "WebSocket error" })
111
+ }
112
+ })
113
+ } catch (e) {
114
+ return { success: false, error: e.message }
115
+ }
116
+ }
117
+
118
+ async sendCommand(method, params = {}) {
119
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
120
+ const conn = await this.connect()
121
+ if (!conn.success) return { success: false, error: conn.error }
122
+ }
123
+
124
+ const id = ++this.msgId
125
+ return new Promise((resolve) => {
126
+ this.callbacks.set(id, (msg) => {
127
+ if (msg.error) {
128
+ resolve({ success: false, error: msg.error.message })
129
+ } else {
130
+ resolve({ success: true, result: msg.result })
131
+ }
132
+ })
133
+ this.ws.send(JSON.stringify({ id, method, params }))
134
+ setTimeout(() => {
135
+ if (this.callbacks.has(id)) {
136
+ this.callbacks.delete(id)
137
+ resolve({ success: false, error: "Command timeout" })
138
+ }
139
+ }, 30000)
140
+ })
141
+ }
142
+
143
+ async navigate(url) {
144
+ const result = await this.sendCommand("Page.navigate", { url })
145
+ if (result.success) await new Promise(r => setTimeout(r, 2000))
146
+ return result
147
+ }
148
+
149
+ async getPageContent() {
150
+ const result = await this.sendCommand("Runtime.evaluate", {
151
+ expression: "document.documentElement.outerHTML",
152
+ returnByValue: true,
153
+ })
154
+ return result.success ? { success: true, html: result.result?.value || "" } : result
155
+ }
156
+
157
+ async getText() {
158
+ const result = await this.sendCommand("Runtime.evaluate", {
159
+ expression: "document.body.innerText",
160
+ returnByValue: true,
161
+ })
162
+ return result.success ? { success: true, text: result.result?.value || "" } : result
163
+ }
164
+
165
+ async getTitle() {
166
+ const result = await this.sendCommand("Runtime.evaluate", {
167
+ expression: "document.title",
168
+ returnByValue: true,
169
+ })
170
+ return result.success ? { success: true, title: result.result?.value || "" } : result
171
+ }
172
+
173
+ async screenshot(path) {
174
+ const result = await this.sendCommand("Page.captureScreenshot", { format: "png" })
175
+ if (result.success && result.result?.data) {
176
+ const imgPath = path || join(BROWSER_DIR, `screenshot_${Date.now()}.png`)
177
+ writeFileSync(imgPath, Buffer.from(result.result.data, "base64"))
178
+ return { success: true, path: imgPath }
179
+ }
180
+ return result
181
+ }
182
+
183
+ async evaluate(expression) {
184
+ return await this.sendCommand("Runtime.evaluate", {
185
+ expression,
186
+ returnByValue: true,
187
+ awaitPromise: true,
188
+ })
189
+ }
190
+
191
+ async click(selector) {
192
+ const posResult = await this.sendCommand("Runtime.evaluate", {
193
+ expression: `(() => { const el = document.querySelector('${selector.replace(/'/g, "\\'")}'); if (!el) return null; const r = el.getBoundingClientRect(); return { x: r.x + r.width/2, y: r.y + r.height/2 }; })()`,
194
+ returnByValue: true,
195
+ })
196
+
197
+ if (!posResult.success || !posResult.result?.value) {
198
+ return { success: false, error: `Element not found: ${selector}` }
199
+ }
200
+
201
+ const { x, y } = posResult.result.value
202
+ await this.sendCommand("Input.dispatchMouseEvent", { type: "mousePressed", x, y, button: "left", clickCount: 1 })
203
+ await this.sendCommand("Input.dispatchMouseEvent", { type: "mouseReleased", x, y, button: "left", clickCount: 1 })
204
+ return { success: true, x, y }
205
+ }
206
+
207
+ async type(selector, text) {
208
+ await this.sendCommand("Runtime.evaluate", {
209
+ expression: `document.querySelector('${selector.replace(/'/g, "\\'")}')?.focus()`,
210
+ })
211
+ for (const char of text) {
212
+ await this.sendCommand("Input.dispatchKeyEvent", { type: "keyDown", text: char, key: char })
213
+ await this.sendCommand("Input.dispatchKeyEvent", { type: "keyUp", key: char })
214
+ }
215
+ return { success: true }
216
+ }
217
+
218
+ async scroll(deltaX = 0, deltaY = 300) {
219
+ await this.sendCommand("Input.dispatchMouseEvent", { type: "mouseWheel", x: 400, y: 400, deltaX, deltaY })
220
+ return { success: true }
221
+ }
222
+
223
+ async pressKey(key) {
224
+ const keys = {
225
+ enter: { key: "Enter", code: "Enter", windowsVirtualKeyCode: 13 },
226
+ tab: { key: "Tab", code: "Tab", windowsVirtualKeyCode: 9 },
227
+ escape: { key: "Escape", code: "Escape", windowsVirtualKeyCode: 27 },
228
+ backspace: { key: "Backspace", code: "Backspace", windowsVirtualKeyCode: 8 },
229
+ space: { key: " ", code: "Space", windowsVirtualKeyCode: 32 },
230
+ arrowup: { key: "ArrowUp", code: "ArrowUp", windowsVirtualKeyCode: 38 },
231
+ arrowdown: { key: "ArrowDown", code: "ArrowDown", windowsVirtualKeyCode: 40 },
232
+ }
233
+ const k = keys[key.toLowerCase()] || { key, code: `Key${key.toUpperCase()}` }
234
+ await this.sendCommand("Input.dispatchKeyEvent", { type: "keyDown", ...k })
235
+ await this.sendCommand("Input.dispatchKeyEvent", { type: "keyUp", ...k })
236
+ return { success: true }
237
+ }
238
+
239
+ async fillForm(fields) {
240
+ const results = []
241
+ for (const { selector, value } of fields) {
242
+ results.push({ selector, ...(await this.type(selector, value)) })
243
+ }
244
+ return { success: true, results }
245
+ }
246
+
247
+ async getLinks() {
248
+ const result = await this.sendCommand("Runtime.evaluate", {
249
+ expression: `Array.from(document.querySelectorAll('a[href]')).map(a => ({ text: a.innerText.trim().slice(0, 100), href: a.href })).filter(a => a.text).slice(0, 50)`,
250
+ returnByValue: true,
251
+ })
252
+ return result.success ? { success: true, links: result.result?.value || [] } : result
253
+ }
254
+
255
+ async getForms() {
256
+ const result = await this.sendCommand("Runtime.evaluate", {
257
+ expression: `Array.from(document.querySelectorAll('form')).map(f => ({ action: f.action, method: f.method, inputs: Array.from(f.querySelectorAll('input,textarea,select')).map(i => ({ name: i.name, type: i.type, placeholder: i.placeholder })) }))`,
258
+ returnByValue: true,
259
+ })
260
+ return result.success ? { success: true, forms: result.result?.value || [] } : result
261
+ }
262
+
263
+ close() {
264
+ if (this.ws) this.ws.close()
265
+ if (this.proc) this.proc.kill()
266
+ return { success: true }
267
+ }
268
+
269
+ static async listTabs(port = 9222) {
270
+ try { return await httpGet(`http://127.0.0.1:${port}/json`) } catch { return [] }
271
+ }
272
+ }
273
+
274
+ export default ChromeBrowser
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+ // Stella Coder — Build Script (SEA: Single Executable Application)
3
+ import fs from "node:fs"
4
+ import path from "node:path"
5
+ import { execSync } from "node:child_process"
6
+ import { fileURLToPath } from "node:url"
7
+
8
+ const __filename = fileURLToPath(import.meta.url)
9
+ const __dirname = path.dirname(__filename)
10
+
11
+ const DIST = path.join(__dirname, "..", "dist")
12
+ const SEA_BLOB = path.join(DIST, "sea-prep.blob")
13
+ const EXE_NAME = process.platform === "win32" ? "stella.exe" : "stella"
14
+ const OUTPUT = path.join(DIST, EXE_NAME)
15
+
16
+ console.log()
17
+ console.log("\x1b[38;2;167;139;250m ✦ Stella Coder — Build SEA Executable\x1b[0m")
18
+ console.log()
19
+
20
+ // 1. Clean dist
21
+ console.log(" [1/5] Очистка dist/...")
22
+ if (fs.existsSync(DIST)) fs.rmSync(DIST, { recursive: true })
23
+ fs.mkdirSync(DIST, { recursive: true })
24
+
25
+ // 2. Create single entry point that bundles all modules
26
+ console.log(" [2/5] Создание bundled entry point...")
27
+
28
+ const entryContent = `#!/usr/bin/env node
29
+ // Stella Coder — Bundled Single Executable
30
+ // This file bundles all CLI modules into one for SEA compilation
31
+
32
+ import { createRequire } from "node:module"
33
+ const require = createRequire(import.meta.url)
34
+
35
+ // Inline all modules
36
+ ${inlineModule("stella-cli/theme.mjs")}
37
+ ${inlineModule("stella-cli/banner.mjs")}
38
+ ${inlineModule("stella-cli/markdown.mjs")}
39
+ ${inlineModule("stella-cli/tools.mjs")}
40
+ ${inlineModule("stella-cli/security.mjs")}
41
+
42
+ // Re-export for index.mjs
43
+ export {
44
+ bold, dim, violet, purple, indigo, blue, cyan, green, red, yellow, gray, darkGray, white,
45
+ gradientLine, box, SPINNER_FRAMES, SPINNER_WORDS,
46
+ } from "./theme.mjs"
47
+
48
+ export { printBanner } from "./banner.mjs"
49
+ export { createStreamRenderer, renderMarkdown } from "./markdown.mjs"
50
+ export { createTools } from "./tools.mjs"
51
+ export {
52
+ verifyCodeIntegrity, getApiKey, saveApiKey, deleteApiKey,
53
+ getHardwareInfo, saveIntegrityHash,
54
+ } from "./security.mjs"
55
+ `
56
+
57
+ // Actually, for SEA we need a simpler approach — just copy all files to dist
58
+ console.log(" [2/5] Копирование модулей в dist/...")
59
+
60
+ const filesToCopy = [
61
+ "index.mjs",
62
+ "tools.mjs",
63
+ "banner.mjs",
64
+ "theme.mjs",
65
+ "markdown.mjs",
66
+ "security.mjs",
67
+ ]
68
+
69
+ for (const file of filesToCopy) {
70
+ const src = path.join(__dirname, file)
71
+ const dst = path.join(DIST, file)
72
+ if (fs.existsSync(src)) {
73
+ fs.copyFileSync(src, dst)
74
+ console.log(` ${file}`)
75
+ }
76
+ }
77
+
78
+ // Also copy antimalware directory
79
+ const antimalwareSrc = path.join(__dirname, "..", "antimalware")
80
+ const antimalwareDst = path.join(DIST, "antimalware")
81
+ if (fs.existsSync(antimalwareSrc)) {
82
+ fs.cpSync(antimalwareSrc, antimalwareDst, { recursive: true })
83
+ console.log(" antimalware/")
84
+ }
85
+
86
+ // 3. Create SEA blob
87
+ console.log(" [3/5] Создание SEA blob...")
88
+ const seaConfig = {
89
+ main: "index.mjs",
90
+ disableExperimentalSEAWarning: true,
91
+ }
92
+ fs.writeFileSync(path.join(DIST, "sea-config.json"), JSON.stringify(seaConfig, null, 2))
93
+
94
+ try {
95
+ execSync(`node --experimental-sea-config ${path.join(DIST, "sea-config.json")}`, {
96
+ cwd: DIST,
97
+ stdio: "inherit",
98
+ })
99
+ } catch (e) {
100
+ console.log(" ⚠ SEA config не поддерживается этой версией Node.js")
101
+ console.log(" Используйте Node.js 20+ или pkg для компиляции")
102
+ console.log()
103
+ console.log(" Альтернатива: npm install -g pkg && pkg --targets node18-win-x64 .")
104
+ console.log()
105
+ process.exit(0)
106
+ }
107
+
108
+ // 4. Copy node executable
109
+ console.log(" [4/5] Копирование Node.js executable...")
110
+ const nodeExe = process.execPath
111
+ const targetExe = path.join(DIST, EXE_NAME)
112
+ fs.copyFileSync(nodeExe, targetExe)
113
+
114
+ // 5. Inject SEA blob into executable
115
+ console.log(" [5/5] Инжектирование blob в executable...")
116
+ try {
117
+ const { execSync: exec } = await import("node:child_process")
118
+ if (process.platform === "win32") {
119
+ exec(`npx postject ${targetExe} NODE_SEA_BLOB ${SEA_BLOB} --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`, {
120
+ cwd: DIST,
121
+ stdio: "inherit",
122
+ })
123
+ } else {
124
+ exec(`npx postject ${targetExe} NODE_SEA_BLOB ${SEA_BLOB} --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`, {
125
+ cwd: DIST,
126
+ stdio: "inherit",
127
+ })
128
+ }
129
+ } catch (e) {
130
+ console.log(" ⚠ Postject не удался. Попробуйте:")
131
+ console.log(" npm install -g postject")
132
+ console.log(" postject stella.exe NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2")
133
+ }
134
+
135
+ // Cleanup
136
+ try { fs.unlinkSync(path.join(DIST, "sea-prep.blob")) } catch {}
137
+ try { fs.unlinkSync(path.join(DIST, "sea-config.json")) } catch {}
138
+
139
+ console.log()
140
+ console.log(`\x1b[38;2;0;200;100m ✓ Готово: ${OUTPUT}\x1b[0m`)
141
+ console.log(dim(` Размер: ${(fs.statSync(targetExe).size / 1024 / 1024).toFixed(1)} MB`))
142
+ console.log()
143
+
144
+ function inlineModule(relativePath) {
145
+ const fullPath = path.join(__dirname, "..", relativePath)
146
+ try {
147
+ return fs.readFileSync(fullPath, "utf8")
148
+ } catch {
149
+ return `// ${relativePath} not found`
150
+ }
151
+ }