brosh 0.2.2 → 0.2.4

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 (42) hide show
  1. package/README.github.md +169 -0
  2. package/README.md +18 -141
  3. package/README.npm.md +58 -0
  4. package/dist/lib.d.ts +1 -1
  5. package/dist/lib.d.ts.map +1 -1
  6. package/dist/lib.js +1 -1
  7. package/dist/lib.js.map +1 -1
  8. package/dist/terminal/index.d.ts +1 -1
  9. package/dist/terminal/index.d.ts.map +1 -1
  10. package/dist/terminal/index.js +1 -1
  11. package/dist/terminal/index.js.map +1 -1
  12. package/dist/terminal/session.d.ts +14 -1
  13. package/dist/terminal/session.d.ts.map +1 -1
  14. package/dist/terminal/session.js +263 -78
  15. package/dist/terminal/session.js.map +1 -1
  16. package/package.json +7 -4
  17. package/packages/desktop-electron/build/afterInstall-linux.sh +4 -0
  18. package/packages/desktop-electron/build/afterPack.cjs +29 -19
  19. package/packages/desktop-electron/build/entitlements.mac.inherit.plist +14 -0
  20. package/packages/desktop-electron/build/entitlements.mac.plist +16 -0
  21. package/packages/desktop-electron/package-lock.json +666 -165
  22. package/packages/desktop-electron/package.json +53 -14
  23. package/packages/desktop-electron/scripts/bundle-main.mjs +97 -0
  24. package/packages/desktop-electron/scripts/bytecode-compiler.cjs +3 -0
  25. package/packages/desktop-electron/scripts/fix-dev-entitlements.js +56 -0
  26. package/packages/desktop-electron/vite.config.ts +13 -0
  27. package/packaging/aur/.SRCINFO +20 -0
  28. package/packaging/aur/PKGBUILD +26 -0
  29. package/vendor/xterm-headless-5.5.0.tgz +0 -0
  30. package/vendor/xterm-xterm-5.5.0.tgz +0 -0
  31. package/website/CNAME +1 -0
  32. package/website/assets/images/.gitkeep +0 -0
  33. package/website/assets/videos/.gitkeep +0 -0
  34. package/website/css/styles.css +735 -0
  35. package/website/gpg.key +37 -0
  36. package/website/index.html +314 -0
  37. package/website/install.sh.asc +16 -0
  38. package/website/js/main.js +293 -0
  39. package/website/rpm/brosh.repo +6 -0
  40. package/website/uninstall.sh +10 -0
  41. package/packages/desktop-electron/tests/main/error-triage/buildTriagePrompt.test.ts +0 -133
  42. package/packages/desktop-electron/tests/main/error-triage/parseTriageResponse.test.ts +0 -123
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ echo "Removing brosh..."
4
+ if command -v dnf >/dev/null 2>&1; then
5
+ sudo dnf remove -y brosh-desktop 2>/dev/null || true
6
+ sudo rm -f /etc/yum.repos.d/brosh.repo
7
+ else
8
+ sudo apt remove -y brosh-desktop 2>/dev/null || sudo dpkg -r brosh-desktop 2>/dev/null || true
9
+ fi
10
+ echo "brosh removed."
@@ -1,133 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { buildTriagePrompt } from '../../../src/main/error-triage.js';
3
-
4
- /**
5
- * Tests for the error triage prompt builder.
6
- *
7
- * buildTriagePrompt creates the prompt sent to Claude for error triage,
8
- * including command text, exit code, and recent terminal output.
9
- */
10
-
11
- describe('buildTriagePrompt', () => {
12
- describe('prompt structure', () => {
13
- it('should include command, exit code, and output', () => {
14
- const prompt = buildTriagePrompt('npm run build', 1, 'Error: Module not found');
15
-
16
- expect(prompt).toContain('npm run build');
17
- expect(prompt).toContain('Exit code: 1');
18
- expect(prompt).toContain('Error: Module not found');
19
- });
20
-
21
- it('should include JSON response format instructions', () => {
22
- const prompt = buildTriagePrompt('ls /nonexistent', 2, 'No such file');
23
-
24
- expect(prompt).toContain('shouldNotify');
25
- expect(prompt).toContain('message');
26
- expect(prompt).toContain('JSON');
27
- });
28
-
29
- it('should include guidance for shouldNotify=true cases', () => {
30
- const prompt = buildTriagePrompt('node app.js', 1, 'crash');
31
-
32
- expect(prompt).toContain('Module/package not found');
33
- expect(prompt).toContain('Permission denied');
34
- expect(prompt).toContain('Syntax errors');
35
- });
36
-
37
- it('should include guidance for shouldNotify=false cases', () => {
38
- const prompt = buildTriagePrompt('grep pattern file', 1, '');
39
-
40
- expect(prompt).toContain('grep');
41
- expect(prompt).toContain('Ctrl+C');
42
- });
43
- });
44
-
45
- describe('command handling', () => {
46
- it('should handle null command', () => {
47
- const prompt = buildTriagePrompt(null, 1, 'some error');
48
-
49
- expect(prompt).toContain('Command: unknown');
50
- });
51
-
52
- it('should handle empty string command', () => {
53
- const prompt = buildTriagePrompt('', 1, 'some error');
54
-
55
- // Empty string is falsy, should fall back to "unknown"
56
- expect(prompt).toContain('Command: unknown');
57
- });
58
-
59
- it('should include the actual command when provided', () => {
60
- const prompt = buildTriagePrompt('python -m pytest tests/', 1, 'FAILED');
61
-
62
- expect(prompt).toContain('Command: python -m pytest tests/');
63
- });
64
- });
65
-
66
- describe('exit code handling', () => {
67
- it('should include various exit codes', () => {
68
- expect(buildTriagePrompt('cmd', 1, 'err')).toContain('Exit code: 1');
69
- expect(buildTriagePrompt('cmd', 2, 'err')).toContain('Exit code: 2');
70
- expect(buildTriagePrompt('cmd', 127, 'err')).toContain('Exit code: 127');
71
- expect(buildTriagePrompt('cmd', 139, 'err')).toContain('Exit code: 139');
72
- });
73
- });
74
-
75
- describe('output handling', () => {
76
- it('should trim whitespace from output', () => {
77
- const prompt = buildTriagePrompt('cmd', 1, ' \n error message \n ');
78
-
79
- // The output should be trimmed
80
- expect(prompt).toContain('error message');
81
- // Should be wrapped in code fences
82
- expect(prompt).toContain('```');
83
- });
84
-
85
- it('should handle empty output', () => {
86
- const prompt = buildTriagePrompt('cmd', 1, '');
87
-
88
- expect(prompt).toContain('Exit code: 1');
89
- // Should still have code fence structure even if empty
90
- expect(prompt).toContain('```');
91
- });
92
-
93
- it('should handle multi-line output', () => {
94
- const output = [
95
- 'Error: Cannot find module "express"',
96
- ' at Function._resolveFilename (node:internal/modules/cjs/loader:1405:15)',
97
- ' at Function._load (node:internal/modules/cjs/loader:1215:37)',
98
- ].join('\n');
99
-
100
- const prompt = buildTriagePrompt('node server.js', 1, output);
101
-
102
- expect(prompt).toContain('Cannot find module');
103
- expect(prompt).toContain('_resolveFilename');
104
- });
105
-
106
- it('should preserve output with special characters', () => {
107
- const output = 'Error: Expected "}" but found "<EOF>"';
108
- const prompt = buildTriagePrompt('node -e "{"', 1, output);
109
-
110
- expect(prompt).toContain('Expected');
111
- });
112
- });
113
-
114
- describe('default behavior guidance', () => {
115
- it('should default to shouldNotify=true', () => {
116
- const prompt = buildTriagePrompt('cmd', 1, 'error');
117
-
118
- expect(prompt).toContain('DEFAULT: shouldNotify=true');
119
- });
120
-
121
- it('should mention that most non-zero exit codes indicate real problems', () => {
122
- const prompt = buildTriagePrompt('cmd', 1, 'error');
123
-
124
- expect(prompt).toContain('real problems');
125
- });
126
-
127
- it('should advise notifying when in doubt', () => {
128
- const prompt = buildTriagePrompt('cmd', 1, 'error');
129
-
130
- expect(prompt).toContain('When in doubt, notify');
131
- });
132
- });
133
- });
@@ -1,123 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
-
3
- /**
4
- * Tests for triage response parsing.
5
- *
6
- * parseTriageResponse is not exported directly, so we test it
7
- * through the module's behavior by examining the expected parsing patterns.
8
- */
9
-
10
- // Since parseTriageResponse is private, test the expected parsing patterns
11
- describe('Triage Response Parsing Patterns', () => {
12
- describe('envelope format (claude --output-format json)', () => {
13
- it('should parse standard envelope with result string', () => {
14
- const envelope = {
15
- result: '{"shouldNotify": true, "message": "Module not found: express"}',
16
- };
17
- const innerJson = envelope.result;
18
- const parsed = JSON.parse(innerJson);
19
-
20
- expect(parsed.shouldNotify).toBe(true);
21
- expect(parsed.message).toBe('Module not found: express');
22
- });
23
-
24
- it('should handle direct format (no envelope)', () => {
25
- const direct = {
26
- shouldNotify: false,
27
- message: '',
28
- };
29
-
30
- expect(typeof direct.shouldNotify).toBe('boolean');
31
- expect(direct.shouldNotify).toBe(false);
32
- });
33
- });
34
-
35
- describe('inner JSON parsing', () => {
36
- it('should parse clean JSON', () => {
37
- const json = '{"shouldNotify": true, "message": "Permission denied on /etc/config"}';
38
- const parsed = JSON.parse(json);
39
-
40
- expect(parsed.shouldNotify).toBe(true);
41
- expect(parsed.message).toContain('Permission denied');
42
- });
43
-
44
- it('should handle markdown code fence wrapping', () => {
45
- const wrapped = '```json\n{"shouldNotify": true, "message": "Syntax error"}\n```';
46
- const cleaned = wrapped
47
- .replace(/^```(?:json)?\s*\n?/, '')
48
- .replace(/\n?```\s*$/, '');
49
- const parsed = JSON.parse(cleaned);
50
-
51
- expect(parsed.shouldNotify).toBe(true);
52
- expect(parsed.message).toBe('Syntax error');
53
- });
54
-
55
- it('should handle code fence without language tag', () => {
56
- const wrapped = '```\n{"shouldNotify": false, "message": ""}\n```';
57
- const cleaned = wrapped
58
- .replace(/^```(?:json)?\s*\n?/, '')
59
- .replace(/\n?```\s*$/, '');
60
- const parsed = JSON.parse(cleaned);
61
-
62
- expect(parsed.shouldNotify).toBe(false);
63
- });
64
-
65
- it('should reject missing shouldNotify field', () => {
66
- const json = '{"message": "some error"}';
67
- const parsed = JSON.parse(json);
68
-
69
- expect(typeof parsed.shouldNotify).not.toBe('boolean');
70
- });
71
-
72
- it('should handle empty message for shouldNotify=false', () => {
73
- const json = '{"shouldNotify": false, "message": ""}';
74
- const parsed = JSON.parse(json);
75
-
76
- expect(parsed.shouldNotify).toBe(false);
77
- expect(parsed.message).toBe('');
78
- });
79
- });
80
-
81
- describe('error scenarios', () => {
82
- it('should handle empty stdout', () => {
83
- const trimmed = ''.trim();
84
- expect(trimmed).toBe('');
85
- // parseTriageResponse returns null for empty input
86
- });
87
-
88
- it('should handle malformed JSON', () => {
89
- const malformed = '{"shouldNotify": true, message: broken}';
90
- expect(() => JSON.parse(malformed)).toThrow();
91
- });
92
-
93
- it('should handle non-JSON responses', () => {
94
- const text = 'The command failed because the module was not found.';
95
- expect(() => JSON.parse(text)).toThrow();
96
- });
97
- });
98
-
99
- describe('TriageResult contract', () => {
100
- it('should always have boolean shouldNotify', () => {
101
- const results = [
102
- { shouldNotify: true, message: 'Error occurred' },
103
- { shouldNotify: false, message: '' },
104
- ];
105
-
106
- for (const result of results) {
107
- expect(typeof result.shouldNotify).toBe('boolean');
108
- expect(typeof result.message).toBe('string');
109
- }
110
- });
111
-
112
- it('should coerce message to string', () => {
113
- // The actual code does String(parsed.message || "")
114
- const coerce = (val: unknown) => String(val || '');
115
-
116
- expect(coerce('hello')).toBe('hello');
117
- expect(coerce(undefined)).toBe('');
118
- expect(coerce(null)).toBe('');
119
- expect(coerce('')).toBe('');
120
- expect(coerce(42)).toBe('42');
121
- });
122
- });
123
- });