bangonit 0.2.2 → 0.3.1

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/README.md +80 -59
  2. package/app/desktopapp/dist/main/index.js +10 -161
  3. package/app/desktopapp/dist/main/ipc.js +0 -20
  4. package/app/desktopapp/dist/main/preload.js +0 -2
  5. package/app/desktopapp/dist/main/tabs.js +0 -10
  6. package/app/desktopapp/dist/shared/args.js +21 -0
  7. package/app/desktopapp/package.json +1 -1
  8. package/app/replay/dist/replay.css +1 -1
  9. package/app/replay/dist/replay.js +20 -20
  10. package/app/webapp/.next/BUILD_ID +1 -1
  11. package/app/webapp/.next/app-build-manifest.json +7 -7
  12. package/app/webapp/.next/app-path-routes-manifest.json +1 -1
  13. package/app/webapp/.next/build-manifest.json +2 -2
  14. package/app/webapp/.next/next-minimal-server.js.nft.json +1 -1
  15. package/app/webapp/.next/next-server.js.nft.json +1 -1
  16. package/app/webapp/.next/prerender-manifest.json +1 -1
  17. package/app/webapp/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/app/webapp/.next/server/app/_not-found.html +1 -1
  19. package/app/webapp/.next/server/app/_not-found.rsc +1 -1
  20. package/app/webapp/.next/server/app/app/page.js +3 -7
  21. package/app/webapp/.next/server/app/app/page_client-reference-manifest.js +1 -1
  22. package/app/webapp/.next/server/app/app.html +1 -1
  23. package/app/webapp/.next/server/app/app.rsc +2 -2
  24. package/app/webapp/.next/server/app/index.html +1 -1
  25. package/app/webapp/.next/server/app/index.rsc +1 -1
  26. package/app/webapp/.next/server/app/page_client-reference-manifest.js +1 -1
  27. package/app/webapp/.next/server/app-paths-manifest.json +3 -3
  28. package/app/webapp/.next/server/chunks/708.js +1 -1
  29. package/app/webapp/.next/server/functions-config-manifest.json +1 -1
  30. package/app/webapp/.next/server/pages/404.html +1 -1
  31. package/app/webapp/.next/server/pages/500.html +1 -1
  32. package/app/webapp/.next/server/pages-manifest.json +1 -1
  33. package/app/webapp/.next/server/server-reference-manifest.json +1 -1
  34. package/app/webapp/.next/static/chunks/app/app/page-0e096497dcb81dae.js +1 -0
  35. package/app/webapp/.next/static/css/{869d3ff23c36c4b5.css → 38219627f55424f2.css} +1 -1
  36. package/app/webapp/.next/trace +2 -2
  37. package/app/webapp/package.json +7 -2
  38. package/app/webapp/src/shared/api/chat.ts +2 -11
  39. package/app/webapp/src/shared/components/AppShell.tsx +21 -1
  40. package/app/webapp/src/shared/components/SessionView.tsx +37 -65
  41. package/app/webapp/src/shared/lib/browser/mouse.ts +1 -1
  42. package/app/webapp/src/shared/lib/browser/recorder.ts +3 -3
  43. package/app/webapp/src/shared/types/global.d.ts +0 -3
  44. package/bin/app/desktopapp/src/shared/args.js +21 -0
  45. package/bin/bangonit.js +334 -283
  46. package/bin/src/cli/bangonit.js +767 -0
  47. package/package.json +11 -3
  48. package/app/webapp/.next/static/chunks/app/app/page-d38c1e48d37def82.js +0 -1
  49. /package/app/webapp/.next/static/{VAxJ7wm0K-fSKpsIoB9lY → Qq0OvlQijtcR84Dg9Dgp0}/_buildManifest.js +0 -0
  50. /package/app/webapp/.next/static/{VAxJ7wm0K-fSKpsIoB9lY → Qq0OvlQijtcR84Dg9Dgp0}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -1,6 +1,27 @@
1
1
  # Bang On It!
2
2
 
3
- Bang On It! bangs on your apps so you don't have to. It's an AI-powered E2E testing tool that launches a real browser, reads your test plan, and executes it autonomously — clicking, typing, navigating, and verifying everything works.
3
+ Bang On It! bangs on your apps so you don't have to.
4
+
5
+ Bang On It! replaces annoying manual QA and flakey end-to-end tests with a CLI-friendly AI agent that launches a real browser, reads your test plan, and executes it autonomously — clicking, typing, navigating, and verifying everything works.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+
11
+ # Run a single test
12
+ npx bangonit run \
13
+ --plan "Go to localhost:3000, login as test@test.com (password: 12345), \
14
+ and click all the buttons in the dashboard and make sure they work"
15
+
16
+ # Run a suite of test plans
17
+ npx bangonit run testplans/*.md --concurrency 3
18
+
19
+ # Record a video of your test run in the recordings/ directory
20
+ npx bangonit run testplans/*.md --record
21
+
22
+ # Initialize your project with full CI integration and S3 video recording storage
23
+ npx bangonit init
24
+ ```
4
25
 
5
26
  ## Why This Matters
6
27
 
@@ -36,7 +57,7 @@ npm install -g bangonit
36
57
 
37
58
  The package provides three aliases: `bangonit`, `bang-on-it`, and `boi`.
38
59
 
39
- ## Quick Start
60
+ ## Getting started
40
61
 
41
62
  ```bash
42
63
  # Launch the interactive UI
@@ -47,20 +68,20 @@ boi run testplans/checkout-flow.md
47
68
 
48
69
  # Run an inline test
49
70
  boi run --plan "Go to my-app.com, sign up with a test account, and verify the dashboard loads"
50
-
51
- # Auto-generate tests from your git changes
52
- boi run --auto
53
71
  ```
54
72
 
55
- ### With a config file
73
+ ### Set up a project
56
74
 
57
75
  ```bash
58
- # Create a .bangonit/config.toml config file
76
+ # Creates config, test plan directories, and optionally GitHub Actions CI
59
77
  boi init
60
78
 
61
- # Run all test plans in the configured directory
79
+ # Run all test plans
62
80
  boi run
63
81
 
82
+ # Run just the smoke tests
83
+ boi run testplans/smoke/
84
+
64
85
  # Filter test plans by name
65
86
  boi run -t checkout
66
87
  ```
@@ -71,9 +92,10 @@ Run `boi init` to create a `.bangonit/config.toml` in your project root:
71
92
 
72
93
  ```toml
73
94
  testplans = "testplans"
74
- anthropic_api_key = "${ANTHROPIC_API_KEY}" # reference env vars with ${VAR}
95
+ # recordings_dir = "recordings" # default
96
+ # anthropic_api_key = "${ANTHROPIC_API_KEY}"
75
97
 
76
- # Upload test recordings to S3 (or any S3-compatible provider)
98
+ # Optional: upload recordings to S3 (or any S3-compatible provider)
77
99
  [s3]
78
100
  bucket = "my-recordings"
79
101
  region = "us-east-1"
@@ -83,11 +105,13 @@ prefix = "bangonit"
83
105
  # secret_key = "${AWS_SECRET_ACCESS_KEY}"
84
106
  ```
85
107
 
86
- All fields are optional. The config is loaded from `.bangonit/config.toml` in the current directory by default, or from a custom path with `--config <path>`.
108
+ All fields are optional. The config is loaded from `.bangonit/config.toml` in the current directory (or any parent up to the repo root) by default, or from a custom path with `--config <path>`.
87
109
 
88
- Any string value supports `${ENV_VAR}` interpolation, so you can reference environment variables without committing secrets. The `[s3]` section configures where test recordings are uploaded and works with any S3-compatible provider — set `endpoint` for DigitalOcean Spaces, Backblaze B2, MinIO, etc.
110
+ Any string value supports `${ENV_VAR}` interpolation, so you can reference environment variables without committing secrets.
89
111
 
90
- When `testplans` is set and you run `boi run` without specifying files, it automatically discovers `.md` files in that directory. Without a config file, `boi run` launches the interactive UI.
112
+ - **`testplans`** directory of `.md` test plan files. When set, `boi run` auto-discovers plans. Without it, `boi run` launches the interactive UI.
113
+ - **`recordings_dir`** — where session recordings are written (default: `recordings`).
114
+ - **`[s3]`** — optional S3 upload for recordings. Works with any S3-compatible provider — set `endpoint` for DigitalOcean Spaces, Backblaze B2, MinIO, etc.
91
115
 
92
116
  ## How It Works
93
117
 
@@ -103,7 +127,25 @@ No selectors. No page objects. No flaky waits. Just describe what to test and le
103
127
 
104
128
  ## Test Plans
105
129
 
106
- Test plans are Markdown files. Put them in your `testplans/` directory (or wherever `.bangonit/config.toml` points).
130
+ Test plans are Markdown files. `boi init` creates a recommended two-tier structure:
131
+
132
+ ```
133
+ testplans/
134
+ smoke/ # is the app alive? — run on every push/PR
135
+ homepage.md
136
+ login.md
137
+ acceptance/ # does the app do what it should? — core user journeys
138
+ checkout.md
139
+ onboarding.md
140
+ regression/ # did we break something? — bug fixes, edge cases
141
+ issue-123.md
142
+ ```
143
+
144
+ - **Smoke** tests should be quick and focused — verify critical paths still work.
145
+ - **Acceptance** tests cover core user journeys and happy paths.
146
+ - **Regression** tests lock down bug fixes and edge cases so they don't recur.
147
+
148
+ Smoke tests run on every commit. The daily full run discovers everything recursively (smoke + acceptance + regression). Run `boi run testplans/smoke/` to run just the smoke tests.
107
149
 
108
150
  ```markdown
109
151
  ---
@@ -111,17 +153,15 @@ name: Add Todos
111
153
  retries: 1
112
154
  ---
113
155
 
114
- ## Setup
115
- Navigate to http://localhost:3000
116
-
117
- ## Test Steps
118
- 1. Verify the page loads with a heading and input field
119
- 2. Type "Buy groceries" and press Enter
120
- 3. Verify the todo appears in the list
121
- 4. Verify the footer shows "1 item left"
156
+ ## Steps
157
+ 1. Navigate to http://localhost:3000
158
+ 2. Verify the page loads with a heading and input field
159
+ 3. Type "Buy groceries" and press Enter
160
+ 4. Verify the todo appears in the list
161
+ 5. Verify the footer shows "1 item left"
122
162
  ```
123
163
 
124
- The `---` frontmatter is optional. `name` sets the display name, `retries` enables auto-retry on failure.
164
+ The `---` frontmatter is optional. `name` sets the display name, `retries` enables auto-retry on failure. You can also set retries for all tests via `--retries N` on the CLI (frontmatter takes precedence).
125
165
 
126
166
  ## Filtering Tests
127
167
 
@@ -139,24 +179,16 @@ boi run --filter checkout
139
179
 
140
180
  You can customize the AI agent's behavior per-project by creating a `.bangonit/system_prompt.md` file in your project root. This content is prepended to the agent's system prompt for all test runs in that directory.
141
181
 
142
- ## Session Recordings
143
-
144
- Record test runs for debugging and CI artifacts:
182
+ ## Claude Code Skills
145
183
 
146
- ```bash
147
- boi run testplans/checkout.md --record
148
- ```
184
+ `boi init` installs two [Claude Code](https://claude.com/claude-code) skills into your project:
149
185
 
150
- This creates a `recordings/{timestamp}/` directory with:
151
- - **`index.html`** — self-contained replay viewer (open in any browser)
152
- - **`clips/`** — WebM video clips of browser interactions with cursor composited in
153
- - **`data.json`** — timeline events, messages, console logs
186
+ - **`/test`** — Run tests locally. Pass file paths, directories, or a filter (e.g. `/test testplans/smoke/`, `/test -t login`).
187
+ - **`/create-test`** — Generate a new test plan from a description (e.g. `/create-test user can reset their password`). Reads your codebase to write accurate steps and places the file in the right directory.
154
188
 
155
- Upload recordings to S3 (or any S3-compatible provider) via config or CLI flag:
189
+ ## Session Recordings
156
190
 
157
- ```bash
158
- boi run --record --s3-bucket my-bucket
159
- ```
191
+ Record test runs with `--record`. Each recording produces a self-contained HTML replay viewer. Configure where they're saved with `recordings_dir` in your config, and optionally upload to S3 via the `[s3]` config section.
160
192
 
161
193
  ## CLI Reference
162
194
 
@@ -165,19 +197,18 @@ Usage: boi <command> [options]
165
197
 
166
198
  Commands:
167
199
  run [files...] [options] Run test plans (or launch interactive UI)
168
- init Create a .bangonit/config.toml config file
169
- init-ci Generate a GitHub Actions workflow
200
+ init Set up config, test plans, and optionally CI
170
201
 
171
202
  Run options:
172
203
  -t, --filter <text> Filter test plans by name substring
173
204
  --config <path> Path to config file (default: .bangonit/config.toml)
174
205
  --plan <text> Inline test plan (instead of file)
175
- --auto Auto-generate test plan from git state
206
+
176
207
  --prompt <text> Additional instructions appended to test plan
177
- --record Record session replay to recordings/ directory
178
- --s3-bucket <bucket> Upload recordings to S3 (overrides config)
208
+ --record Record session replay
209
+ --retries <n> Retry failed tests N times
179
210
  --headless Run without showing the browser window
180
- --exit Exit immediately after tests complete (for CI)
211
+ --exit Exit immediately after tests complete
181
212
  --json Stream NDJSON events to stdout
182
213
  --console Forward browser console logs to stdout
183
214
  --output <file> Write JSON results to file
@@ -186,26 +217,16 @@ Run options:
186
217
  --help Show this help message
187
218
  ```
188
219
 
189
- ## CI Usage
190
-
191
- Generate a GitHub Actions workflow:
192
-
193
- ```bash
194
- boi init-ci
195
- ```
220
+ In CI environments, `--headless` and `--exit` default to `true` automatically.
196
221
 
197
- Or run manually in CI:
222
+ ## CI Usage
198
223
 
199
- ```bash
200
- # Headless mode with timeout, exit on completion
201
- boi run --headless --exit --timeout 120
224
+ `boi init` optionally generates two GitHub Actions workflows:
202
225
 
203
- # JSON output for parsing
204
- boi run --headless --exit --json
226
+ - **Smoke tests** (`bangonit-smoke.yml`) — runs `testplans/smoke/` on every push and PR
227
+ - **Full tests** (`bangonit-full.yml`) — runs all test plans daily at 6pm local time
205
228
 
206
- # Record for artifacts
207
- boi run --headless --exit --record
208
- ```
229
+ In CI, `--headless` and `--exit` are enabled automatically.
209
230
 
210
231
  ## Multiple Tests
211
232
 
@@ -43,154 +43,16 @@ const path = __importStar(require("path"));
43
43
  const fs = __importStar(require("fs"));
44
44
  const ipc_1 = require("./ipc");
45
45
  const tabs_1 = require("./tabs");
46
+ const args_1 = require("../shared/args");
46
47
  let mainWindow = null;
48
+ // --- Parse args from env (set by CLI) ---
47
49
  function parseArgs() {
48
- const args = process.argv.slice(2).filter((a) => !a.startsWith("--remote-debugging-port"));
49
- const result = {
50
- testPlanFiles: [],
51
- headless: false,
52
- exit: false,
53
- json: false,
54
- console: false,
55
- record: false,
56
- auto: false,
57
- output: null,
58
- plan: null,
59
- prompt: null,
60
- concurrency: 1,
61
- timeout: 0,
62
- cwd: process.cwd(),
63
- };
64
- if (args.includes("--help") || args.includes("-h")) {
65
- console.log(`Usage: boi run [test-plan-files...] [options]
66
-
67
- Options:
68
- --plan <text> Inline test plan (instead of file)
69
- --auto Auto-generate test plan from git state
70
- --prompt <text> Additional instructions appended to test plan
71
- --record Record session replay to recordings/ directory
72
- --headless Run without showing the browser window
73
- --exit Exit immediately after tests complete (for CI)
74
- --json Stream NDJSON events to stdout
75
- --console Forward browser console logs to stdout
76
- --output <file> Write JSON results to file
77
- --concurrency <n> Number of parallel agents (default: 1)
78
- --timeout <seconds> Test timeout in seconds (0 = none)
79
- --cwd <dir> Working directory (default: current)
80
- --help Show this help message`);
81
- process.exit(0);
82
- }
83
- let i = 0;
84
- // Skip "run" subcommand if present
85
- if (args[i] === "run")
86
- i++;
87
- while (i < args.length) {
88
- const arg = args[i];
89
- if (arg === "--headless") {
90
- result.headless = true;
91
- }
92
- else if (arg === "--exit") {
93
- result.exit = true;
94
- }
95
- else if (arg === "--json") {
96
- result.json = true;
97
- }
98
- else if (arg === "--console") {
99
- result.console = true;
100
- }
101
- else if (arg === "--record") {
102
- result.record = true;
103
- }
104
- else if (arg === "--auto") {
105
- result.auto = true;
106
- }
107
- else if (arg === "--output" && i + 1 < args.length) {
108
- result.output = args[++i];
109
- }
110
- else if (arg === "--plan" && i + 1 < args.length) {
111
- result.plan = args[++i];
112
- }
113
- else if (arg === "--prompt" && i + 1 < args.length) {
114
- result.prompt = args[++i];
115
- }
116
- else if (arg === "--concurrency" && i + 1 < args.length) {
117
- result.concurrency = Math.max(1, parseInt(args[++i], 10) || 1);
118
- }
119
- else if (arg === "--timeout" && i + 1 < args.length) {
120
- result.timeout = Math.max(0, parseInt(args[++i], 10) || 0);
121
- }
122
- else if (arg === "--cwd" && i + 1 < args.length) {
123
- result.cwd = args[++i];
124
- }
125
- else if (!arg.startsWith("-")) {
126
- result.testPlanFiles.push(arg);
127
- }
128
- i++;
50
+ const raw = process.env[args_1.ELECTRON_ARGS_ENV];
51
+ if (!raw) {
52
+ console.error("Error: BANGONIT_ARGS environment variable not set. Run via the boi CLI.");
53
+ process.exit(1);
129
54
  }
130
- return result;
131
- }
132
- // --- Auto-generate test plan from git state ---
133
- async function generateTestPlan(cwd) {
134
- const { execSync } = require("child_process");
135
- const exec = (cmd) => {
136
- try {
137
- return execSync(cmd, { cwd, encoding: "utf-8", timeout: 10000 }).trim();
138
- }
139
- catch {
140
- return "";
141
- }
142
- };
143
- const diff = exec("git diff") + "\n" + exec("git diff --cached");
144
- const status = exec("git status --short");
145
- if (diff.trim() || status.trim()) {
146
- return `## Auto-generated test plan from uncommitted changes
147
-
148
- Analyze the following git changes and generate a comprehensive test plan. Then execute each test step.
149
-
150
- ### Git Status
151
- \`\`\`
152
- ${status}
153
- \`\`\`
154
-
155
- ### Git Diff
156
- \`\`\`
157
- ${diff.slice(0, 8000)}
158
- \`\`\`
159
-
160
- Generate test steps that verify the changes work correctly, then execute them.`;
161
- }
162
- const logDiff = exec("git log master..HEAD --oneline");
163
- const codeDiff = exec("git diff master...HEAD");
164
- if (logDiff || codeDiff) {
165
- return `## Auto-generated test plan from branch divergence
166
-
167
- Analyze the following commits diverging from master and generate a comprehensive test plan. Then execute each test step.
168
-
169
- ### Commits
170
- \`\`\`
171
- ${logDiff}
172
- \`\`\`
173
-
174
- ### Diff from master
175
- \`\`\`
176
- ${codeDiff.slice(0, 8000)}
177
- \`\`\`
178
-
179
- Generate test steps that verify these changes work correctly, then execute them.`;
180
- }
181
- const lastCommit = exec("git log -1 --format='%H %s'");
182
- const lastDiff = exec("git show HEAD --stat");
183
- return `## Auto-generated test plan from latest commit
184
-
185
- No test plan provided and no changes unmerged to master. Generating test plan from latest commit.
186
-
187
- ### Latest Commit
188
- \`\`\`
189
- ${lastCommit}
190
- ${lastDiff}
191
- \`\`\`
192
-
193
- Generate test steps that verify this commit works correctly, then execute them.`;
55
+ return args_1.electronArgsSchema.parse(JSON.parse(raw));
194
56
  }
195
57
  const cliArgs = parseArgs();
196
58
  function parseFrontmatter(content) {
@@ -321,7 +183,8 @@ async function createWindow() {
321
183
  // Create recordings directory if --record
322
184
  if (cliArgs.record) {
323
185
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
324
- const recordDir = path.join(cliArgs.cwd, "recordings", timestamp);
186
+ const baseDir = cliArgs.recordingsDir || path.join(cliArgs.cwd, "recordings");
187
+ const recordDir = path.join(baseDir, timestamp);
325
188
  fs.mkdirSync(recordDir, { recursive: true });
326
189
  (0, ipc_1.setRunDir)(recordDir);
327
190
  if (!cliArgs.json)
@@ -361,26 +224,12 @@ async function createWindow() {
361
224
  agentIndex: i,
362
225
  testPlan: parsed[i].body,
363
226
  name: parsed[i].frontmatter.name || names[i],
364
- retries: parsed[i].frontmatter.retries || 0,
227
+ retries: parsed[i].frontmatter.retries ?? cliArgs.retries,
365
228
  extraPrompt: cliArgs.prompt || undefined,
366
229
  record: cliArgs.record || undefined,
367
230
  });
368
231
  }
369
232
  }
370
- else if (cliArgs.auto) {
371
- // Auto-generate from git state
372
- const generated = await generateTestPlan(cliArgs.cwd);
373
- const fullPlan = cliArgs.prompt
374
- ? `${generated}\n\n## Additional Instructions\n${cliArgs.prompt}`
375
- : generated;
376
- expectedResults = 1;
377
- mainWindow.webContents.send("test-plan", {
378
- agentIndex: 0,
379
- testPlan: fullPlan,
380
- name: "auto-generated",
381
- record: cliArgs.record || undefined,
382
- });
383
- }
384
233
  // No test plans provided — interactive UI will show the prompt screen
385
234
  // Start timeout if specified
386
235
  if (cliArgs.timeout > 0) {
@@ -206,26 +206,6 @@ function registerIpcHandlers() {
206
206
  store.delete(`agentSessions.${agentId}`);
207
207
  (0, tabs_1.destroyContext)(agentId);
208
208
  });
209
- // --- Bash (per-agent) ---
210
- electron_1.ipcMain.handle("bash-exec", async (_, { agentId, command }) => {
211
- const ctx = (0, tabs_1.getOrCreateContext)(agentId);
212
- if (!ctx.bashInstance) {
213
- const { Bash, OverlayFs } = await Promise.resolve().then(() => __importStar(require("just-bash")));
214
- const overlay = new OverlayFs({ root: bangerCwd });
215
- const cwd = overlay.getMountPoint();
216
- ctx.bashInstance = new Bash({ fs: overlay, cwd });
217
- try {
218
- ctx.bashInstance.fs.mkdirSync("/home/user/downloads");
219
- }
220
- catch { }
221
- ctx.bashFs = ctx.bashInstance.fs;
222
- ctx.bashCwd = cwd;
223
- }
224
- const result = await ctx.bashInstance.exec(command, { cwd: ctx.bashCwd });
225
- return [result.stdout, result.stderr ? `stderr: ${result.stderr}` : "", `exit code: ${result.exitCode}`]
226
- .filter(Boolean)
227
- .join("\n");
228
- });
229
209
  electron_1.ipcMain.handle("clear-partition", async (_, agentId) => {
230
210
  const partitionName = `persist:agent-${agentId}`;
231
211
  const ses = electron_1.session.fromPartition(partitionName);
@@ -14,8 +14,6 @@ contextBridge.exposeInMainWorld("bangonit", {
14
14
  getAgentSession: (agentId) => ipcRenderer.invoke("get-agent-session", agentId),
15
15
  setAgentSession: (agentId, session) => ipcRenderer.invoke("set-agent-session", { agentId, session }),
16
16
  deleteAgentSession: (agentId) => ipcRenderer.invoke("delete-agent-session", agentId),
17
- // Bash (per-agent)
18
- bashExec: (agentId, command) => ipcRenderer.invoke("bash-exec", { agentId, command }),
19
17
  // --- Low-level browser primitives ---
20
18
  // CDP: send a raw CDP command to the active tab
21
19
  cdpSend: (agentId, method, params) => ipcRenderer.invoke("cdp-send", { agentId, method, params }),
@@ -53,12 +53,9 @@ function getOrCreateContext(agentId) {
53
53
  const ctx = {
54
54
  tabs: new Map(),
55
55
  activeTabId: null,
56
- bashInstance: null,
57
- bashCwd: null,
58
56
  nextPopupId: 10000,
59
57
  downloadsDir: null,
60
58
  downloadSessionsSetup: new WeakSet(),
61
- bashFs: null,
62
59
  };
63
60
  agentContexts.set(agentId, ctx);
64
61
  return ctx;
@@ -126,13 +123,6 @@ function setupDownloads(ctx, wc) {
126
123
  item.on("done", (_, state) => {
127
124
  entry.bytes = item.getReceivedBytes();
128
125
  entry.state = state === "completed" ? "completed" : "failed";
129
- if (state === "completed" && ctx.bashFs) {
130
- try {
131
- const data = fs.readFileSync(savePath);
132
- ctx.bashFs.writeFileSync(`/home/user/downloads/${filename}`, data);
133
- }
134
- catch { }
135
- }
136
126
  });
137
127
  });
138
128
  }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ELECTRON_ARGS_ENV = exports.electronArgsSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.electronArgsSchema = zod_1.z.object({
6
+ testPlanFiles: zod_1.z.array(zod_1.z.string()),
7
+ headless: zod_1.z.boolean(),
8
+ exit: zod_1.z.boolean(),
9
+ json: zod_1.z.boolean(),
10
+ console: zod_1.z.boolean(),
11
+ record: zod_1.z.boolean(),
12
+ retries: zod_1.z.number(),
13
+ output: zod_1.z.string().nullable(),
14
+ plan: zod_1.z.string().nullable(),
15
+ prompt: zod_1.z.string().nullable(),
16
+ concurrency: zod_1.z.number(),
17
+ timeout: zod_1.z.number(),
18
+ cwd: zod_1.z.string(),
19
+ recordingsDir: zod_1.z.string().nullable(),
20
+ });
21
+ exports.ELECTRON_ARGS_ENV = "BANGONIT_ARGS";
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "electron-store": "^8.1.0",
16
- "just-bash": "^2.13.1"
16
+ "zod": "^3.25.0"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/node": "^20.0.0",