bashbros 0.1.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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +453 -0
  3. package/dist/audit-MCFNGOIM.js +11 -0
  4. package/dist/audit-MCFNGOIM.js.map +1 -0
  5. package/dist/chunk-43W3RVEL.js +2910 -0
  6. package/dist/chunk-43W3RVEL.js.map +1 -0
  7. package/dist/chunk-4R4GV5V2.js +213 -0
  8. package/dist/chunk-4R4GV5V2.js.map +1 -0
  9. package/dist/chunk-7OCVIDC7.js +12 -0
  10. package/dist/chunk-7OCVIDC7.js.map +1 -0
  11. package/dist/chunk-CSRPOGHY.js +354 -0
  12. package/dist/chunk-CSRPOGHY.js.map +1 -0
  13. package/dist/chunk-DEAF6PYM.js +212 -0
  14. package/dist/chunk-DEAF6PYM.js.map +1 -0
  15. package/dist/chunk-DLP2O6PN.js +273 -0
  16. package/dist/chunk-DLP2O6PN.js.map +1 -0
  17. package/dist/chunk-GD5VNHIN.js +519 -0
  18. package/dist/chunk-GD5VNHIN.js.map +1 -0
  19. package/dist/chunk-ID2O2QTI.js +269 -0
  20. package/dist/chunk-ID2O2QTI.js.map +1 -0
  21. package/dist/chunk-J37RHCFJ.js +357 -0
  22. package/dist/chunk-J37RHCFJ.js.map +1 -0
  23. package/dist/chunk-SB4JS3GU.js +456 -0
  24. package/dist/chunk-SB4JS3GU.js.map +1 -0
  25. package/dist/chunk-SG752FZC.js +200 -0
  26. package/dist/chunk-SG752FZC.js.map +1 -0
  27. package/dist/cli.d.ts +2 -0
  28. package/dist/cli.js +2448 -0
  29. package/dist/cli.js.map +1 -0
  30. package/dist/config-CZMIGNPF.js +13 -0
  31. package/dist/config-CZMIGNPF.js.map +1 -0
  32. package/dist/config-parser-XHE7BC7H.js +13 -0
  33. package/dist/config-parser-XHE7BC7H.js.map +1 -0
  34. package/dist/db-EHQDB5OL.js +11 -0
  35. package/dist/db-EHQDB5OL.js.map +1 -0
  36. package/dist/display-IN4NRJJS.js +18 -0
  37. package/dist/display-IN4NRJJS.js.map +1 -0
  38. package/dist/engine-PKLXW6OF.js +9 -0
  39. package/dist/engine-PKLXW6OF.js.map +1 -0
  40. package/dist/index.d.ts +1498 -0
  41. package/dist/index.js +552 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/moltbot-DXZFVK3X.js +11 -0
  44. package/dist/moltbot-DXZFVK3X.js.map +1 -0
  45. package/dist/ollama-HY35OHW4.js +9 -0
  46. package/dist/ollama-HY35OHW4.js.map +1 -0
  47. package/dist/risk-scorer-Y6KF2XCZ.js +9 -0
  48. package/dist/risk-scorer-Y6KF2XCZ.js.map +1 -0
  49. package/dist/static/index.html +410 -0
  50. package/package.json +68 -0
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ __require
4
+ } from "./chunk-7OCVIDC7.js";
5
+
6
+ // src/audit.ts
7
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from "fs";
8
+ import { join } from "path";
9
+ import { homedir } from "os";
10
+ var MAX_LOG_SIZE = 10 * 1024 * 1024;
11
+ var MAX_ROTATED_LOGS = 5;
12
+ var AuditLogger = class {
13
+ constructor(policy) {
14
+ this.policy = policy;
15
+ const bashbrosDir = join(homedir(), ".bashbros");
16
+ if (!existsSync(bashbrosDir)) {
17
+ mkdirSync(bashbrosDir, { recursive: true, mode: 448 });
18
+ }
19
+ this.logPath = join(bashbrosDir, "audit.log");
20
+ this.lockPath = join(bashbrosDir, "audit.lock");
21
+ }
22
+ logPath;
23
+ lockPath;
24
+ log(entry) {
25
+ if (!this.policy.enabled) {
26
+ return;
27
+ }
28
+ const logLine = this.formatEntry(entry);
29
+ if (this.policy.destination === "local" || this.policy.destination === "both") {
30
+ this.writeLocal(logLine);
31
+ }
32
+ if (this.policy.destination === "remote" || this.policy.destination === "both") {
33
+ this.sendRemote(entry);
34
+ }
35
+ }
36
+ formatEntry(entry) {
37
+ const status = entry.allowed ? "ALLOWED" : "BLOCKED";
38
+ const violations = entry.violations.length > 0 ? ` [${entry.violations.map((v) => v.type).join(", ")}]` : "";
39
+ const sanitizedCommand = entry.command.replace(/[\x00-\x1f\x7f]/g, "").slice(0, 1e3);
40
+ return `[${entry.timestamp.toISOString()}] ${status}${violations} (${entry.duration}ms) ${sanitizedCommand}
41
+ `;
42
+ }
43
+ /**
44
+ * SECURITY FIX: Write with file locking and rotation
45
+ */
46
+ writeLocal(logLine) {
47
+ try {
48
+ this.acquireLock();
49
+ try {
50
+ this.rotateIfNeeded();
51
+ appendFileSync(this.logPath, logLine, { mode: 384 });
52
+ } finally {
53
+ this.releaseLock();
54
+ }
55
+ } catch (error) {
56
+ console.error("Failed to write audit log:", error);
57
+ }
58
+ }
59
+ /**
60
+ * Simple file-based locking
61
+ */
62
+ acquireLock() {
63
+ const maxAttempts = 10;
64
+ const waitMs = 50;
65
+ for (let i = 0; i < maxAttempts; i++) {
66
+ try {
67
+ writeFileSync(this.lockPath, String(process.pid), { flag: "wx" });
68
+ return;
69
+ } catch (error) {
70
+ if (error.code === "EEXIST") {
71
+ try {
72
+ const stats = statSync(this.lockPath);
73
+ if (Date.now() - stats.mtimeMs > 5e3) {
74
+ try {
75
+ __require("fs").unlinkSync(this.lockPath);
76
+ } catch {
77
+ }
78
+ }
79
+ } catch {
80
+ }
81
+ this.sleep(waitMs);
82
+ } else {
83
+ throw error;
84
+ }
85
+ }
86
+ }
87
+ console.warn("Could not acquire audit log lock, proceeding without");
88
+ }
89
+ releaseLock() {
90
+ try {
91
+ __require("fs").unlinkSync(this.lockPath);
92
+ } catch {
93
+ }
94
+ }
95
+ sleep(ms) {
96
+ const end = Date.now() + ms;
97
+ while (Date.now() < end) {
98
+ }
99
+ }
100
+ /**
101
+ * Rotate log if it exceeds max size
102
+ */
103
+ rotateIfNeeded() {
104
+ try {
105
+ if (!existsSync(this.logPath)) return;
106
+ const stats = statSync(this.logPath);
107
+ if (stats.size < MAX_LOG_SIZE) return;
108
+ for (let i = MAX_ROTATED_LOGS - 1; i >= 0; i--) {
109
+ const oldPath = i === 0 ? this.logPath : `${this.logPath}.${i}`;
110
+ const newPath = `${this.logPath}.${i + 1}`;
111
+ if (existsSync(oldPath)) {
112
+ if (i === MAX_ROTATED_LOGS - 1) {
113
+ __require("fs").unlinkSync(oldPath);
114
+ } else {
115
+ renameSync(oldPath, newPath);
116
+ }
117
+ }
118
+ }
119
+ } catch (error) {
120
+ console.error("Failed to rotate audit log:", error);
121
+ }
122
+ }
123
+ /**
124
+ * SECURITY FIX: Secure remote transmission with HTTPS enforcement
125
+ */
126
+ async sendRemote(entry) {
127
+ if (!this.policy.remotePath) {
128
+ return;
129
+ }
130
+ let url;
131
+ try {
132
+ url = new URL(this.policy.remotePath);
133
+ } catch {
134
+ console.error("Invalid remote audit URL");
135
+ return;
136
+ }
137
+ if (url.protocol !== "https:") {
138
+ console.error("Remote audit path must use HTTPS");
139
+ return;
140
+ }
141
+ const sanitizedEntry = {
142
+ timestamp: entry.timestamp.toISOString(),
143
+ command: entry.command.slice(0, 1e3),
144
+ // Limit size
145
+ allowed: entry.allowed,
146
+ violations: entry.violations.map((v) => ({
147
+ type: v.type,
148
+ rule: v.rule.slice(0, 200),
149
+ message: v.message.slice(0, 500)
150
+ })),
151
+ duration: entry.duration,
152
+ agent: entry.agent
153
+ };
154
+ try {
155
+ const controller = new AbortController();
156
+ const timeout = setTimeout(() => controller.abort(), 5e3);
157
+ await fetch(this.policy.remotePath, {
158
+ method: "POST",
159
+ headers: {
160
+ "Content-Type": "application/json",
161
+ "User-Agent": "BashBros/0.1.0"
162
+ },
163
+ body: JSON.stringify(sanitizedEntry),
164
+ signal: controller.signal
165
+ });
166
+ clearTimeout(timeout);
167
+ } catch (error) {
168
+ }
169
+ }
170
+ getLogPath() {
171
+ return this.logPath;
172
+ }
173
+ };
174
+ async function viewAudit(options) {
175
+ const logPath = join(homedir(), ".bashbros", "audit.log");
176
+ if (!existsSync(logPath)) {
177
+ console.log("No audit log found. Run some commands first.");
178
+ return;
179
+ }
180
+ const content = readFileSync(logPath, "utf-8");
181
+ let lines = content.trim().split("\n");
182
+ if (options.violations) {
183
+ lines = lines.filter((line) => line.includes("BLOCKED"));
184
+ }
185
+ const numLines = parseInt(options.lines, 10) || 50;
186
+ lines = lines.slice(-numLines);
187
+ for (const line of lines) {
188
+ if (line.includes("BLOCKED")) {
189
+ console.log("\x1B[31m" + line + "\x1B[0m");
190
+ } else {
191
+ console.log("\x1B[32m" + line + "\x1B[0m");
192
+ }
193
+ }
194
+ }
195
+
196
+ export {
197
+ AuditLogger,
198
+ viewAudit
199
+ };
200
+ //# sourceMappingURL=chunk-SG752FZC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/audit.ts"],"sourcesContent":["import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, statSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport type { AuditPolicy, AuditEntry } from './types.js'\n\n// Maximum log file size before rotation (10MB)\nconst MAX_LOG_SIZE = 10 * 1024 * 1024\n// Number of rotated logs to keep\nconst MAX_ROTATED_LOGS = 5\n\nexport class AuditLogger {\n private logPath: string\n private lockPath: string\n\n constructor(private policy: AuditPolicy) {\n const bashbrosDir = join(homedir(), '.bashbros')\n\n if (!existsSync(bashbrosDir)) {\n mkdirSync(bashbrosDir, { recursive: true, mode: 0o700 })\n }\n\n this.logPath = join(bashbrosDir, 'audit.log')\n this.lockPath = join(bashbrosDir, 'audit.lock')\n }\n\n log(entry: AuditEntry): void {\n if (!this.policy.enabled) {\n return\n }\n\n const logLine = this.formatEntry(entry)\n\n if (this.policy.destination === 'local' || this.policy.destination === 'both') {\n this.writeLocal(logLine)\n }\n\n if (this.policy.destination === 'remote' || this.policy.destination === 'both') {\n this.sendRemote(entry)\n }\n }\n\n private formatEntry(entry: AuditEntry): string {\n const status = entry.allowed ? 'ALLOWED' : 'BLOCKED'\n const violations = entry.violations.length > 0\n ? ` [${entry.violations.map(v => v.type).join(', ')}]`\n : ''\n\n // SECURITY: Sanitize command output (remove control characters)\n const sanitizedCommand = entry.command\n .replace(/[\\x00-\\x1f\\x7f]/g, '')\n .slice(0, 1000) // Limit command length in logs\n\n return `[${entry.timestamp.toISOString()}] ${status}${violations} (${entry.duration}ms) ${sanitizedCommand}\\n`\n }\n\n /**\n * SECURITY FIX: Write with file locking and rotation\n */\n private writeLocal(logLine: string): void {\n try {\n // Simple file-based locking\n this.acquireLock()\n\n try {\n // Check if rotation needed\n this.rotateIfNeeded()\n\n // Append to log\n appendFileSync(this.logPath, logLine, { mode: 0o600 })\n } finally {\n this.releaseLock()\n }\n } catch (error) {\n console.error('Failed to write audit log:', error)\n }\n }\n\n /**\n * Simple file-based locking\n */\n private acquireLock(): void {\n const maxAttempts = 10\n const waitMs = 50\n\n for (let i = 0; i < maxAttempts; i++) {\n try {\n // Try to create lock file exclusively\n writeFileSync(this.lockPath, String(process.pid), { flag: 'wx' })\n return\n } catch (error: any) {\n if (error.code === 'EEXIST') {\n // Lock exists, check if stale (older than 5 seconds)\n try {\n const stats = statSync(this.lockPath)\n if (Date.now() - stats.mtimeMs > 5000) {\n // Stale lock, remove it\n try {\n require('fs').unlinkSync(this.lockPath)\n } catch { /* ignore */ }\n }\n } catch { /* ignore */ }\n\n // Wait and retry\n this.sleep(waitMs)\n } else {\n throw error\n }\n }\n }\n\n // Fallback: proceed without lock (better than failing)\n console.warn('Could not acquire audit log lock, proceeding without')\n }\n\n private releaseLock(): void {\n try {\n require('fs').unlinkSync(this.lockPath)\n } catch { /* ignore */ }\n }\n\n private sleep(ms: number): void {\n const end = Date.now() + ms\n while (Date.now() < end) {\n // Busy wait (synchronous)\n }\n }\n\n /**\n * Rotate log if it exceeds max size\n */\n private rotateIfNeeded(): void {\n try {\n if (!existsSync(this.logPath)) return\n\n const stats = statSync(this.logPath)\n if (stats.size < MAX_LOG_SIZE) return\n\n // Rotate logs\n for (let i = MAX_ROTATED_LOGS - 1; i >= 0; i--) {\n const oldPath = i === 0 ? this.logPath : `${this.logPath}.${i}`\n const newPath = `${this.logPath}.${i + 1}`\n\n if (existsSync(oldPath)) {\n if (i === MAX_ROTATED_LOGS - 1) {\n // Delete oldest\n require('fs').unlinkSync(oldPath)\n } else {\n renameSync(oldPath, newPath)\n }\n }\n }\n } catch (error) {\n console.error('Failed to rotate audit log:', error)\n }\n }\n\n /**\n * SECURITY FIX: Secure remote transmission with HTTPS enforcement\n */\n private async sendRemote(entry: AuditEntry): Promise<void> {\n if (!this.policy.remotePath) {\n return\n }\n\n // SECURITY: Validate URL\n let url: URL\n try {\n url = new URL(this.policy.remotePath)\n } catch {\n console.error('Invalid remote audit URL')\n return\n }\n\n // SECURITY: Only allow HTTPS\n if (url.protocol !== 'https:') {\n console.error('Remote audit path must use HTTPS')\n return\n }\n\n // SECURITY: Sanitize entry before sending\n const sanitizedEntry = {\n timestamp: entry.timestamp.toISOString(),\n command: entry.command.slice(0, 1000), // Limit size\n allowed: entry.allowed,\n violations: entry.violations.map(v => ({\n type: v.type,\n rule: v.rule.slice(0, 200),\n message: v.message.slice(0, 500)\n })),\n duration: entry.duration,\n agent: entry.agent\n }\n\n try {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 5000) // 5s timeout\n\n await fetch(this.policy.remotePath, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'BashBros/0.1.0'\n },\n body: JSON.stringify(sanitizedEntry),\n signal: controller.signal\n })\n\n clearTimeout(timeout)\n } catch (error) {\n // Silently fail for remote - don't block main operation\n // Could implement retry queue here\n }\n }\n\n getLogPath(): string {\n return this.logPath\n }\n}\n\nexport async function viewAudit(options: { lines: string; violations: boolean }): Promise<void> {\n const logPath = join(homedir(), '.bashbros', 'audit.log')\n\n if (!existsSync(logPath)) {\n console.log('No audit log found. Run some commands first.')\n return\n }\n\n const content = readFileSync(logPath, 'utf-8')\n let lines = content.trim().split('\\n')\n\n if (options.violations) {\n lines = lines.filter(line => line.includes('BLOCKED'))\n }\n\n const numLines = parseInt(options.lines, 10) || 50\n lines = lines.slice(-numLines)\n\n for (const line of lines) {\n if (line.includes('BLOCKED')) {\n console.log('\\x1b[31m' + line + '\\x1b[0m') // Red\n } else {\n console.log('\\x1b[32m' + line + '\\x1b[0m') // Green\n }\n }\n}\n"],"mappings":"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","names":[]}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }