bangonit 0.4.3 → 0.5.2
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.
- package/README.md +2 -1
- package/app/desktopapp/dist/main/index.js +10 -4
- package/app/desktopapp/dist/main/ipc.js +9 -24
- package/app/desktopapp/dist/main/preload.js +0 -7
- package/app/desktopapp/dist/main/tabs.js +10 -5
- package/app/desktopapp/package.json +0 -1
- package/app/replay/dist/replay.js +2 -2
- package/app/webapp/.next/standalone/app/webapp/.next/BUILD_ID +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/app-build-manifest.json +11 -11
- package/app/webapp/.next/standalone/app/webapp/.next/app-path-routes-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/build-manifest.json +3 -3
- package/app/webapp/.next/standalone/app/webapp/.next/prerender-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/required-server-files.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found/page.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found.rsc +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/api/chat/route.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/api/screenshot/route.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app/page.js +6 -6
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app/page_client-reference-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app.rsc +2 -2
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/index.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/index.rsc +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/page.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app-paths-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/chunks/679.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/chunks/708.js +3 -3
- package/app/webapp/.next/standalone/app/webapp/.next/server/middleware-build-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/pages/404.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/pages/500.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/server-reference-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/app/page-533a30559a8f39fa.js +1 -0
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/layout-40f50d9380154ecf.js +1 -0
- package/app/webapp/.next/{static/chunks/main-app-106dd83f859b9dfa.js → standalone/app/webapp/.next/static/chunks/main-app-76384b941f0b51cb.js} +1 -1
- package/app/webapp/.next/standalone/app/webapp/package.json +2 -6
- package/app/webapp/.next/standalone/app/webapp/server.js +1 -1
- package/app/webapp/.next/standalone/package.json +18 -6
- package/app/webapp/.next/static/chunks/app/app/page-533a30559a8f39fa.js +1 -0
- package/app/webapp/.next/static/chunks/app/layout-40f50d9380154ecf.js +1 -0
- package/app/webapp/.next/{standalone/app/webapp/.next/static/chunks/main-app-106dd83f859b9dfa.js → static/chunks/main-app-76384b941f0b51cb.js} +1 -1
- package/app/webapp/package.json +2 -6
- package/app/webapp/skills/document-review.md +1 -0
- package/app/webapp/skills/gmail.md +2 -0
- package/app/webapp/src/app/globals.css +8 -3
- package/app/webapp/src/app/layout.tsx +2 -8
- package/app/webapp/src/shared/api/chat.ts +49 -25
- package/app/webapp/src/shared/api/screenshot.ts +11 -10
- package/app/webapp/src/shared/components/AppShell.tsx +80 -109
- package/app/webapp/src/shared/components/SessionView.tsx +335 -248
- package/app/webapp/src/shared/components/VirtualCursor.tsx +13 -14
- package/app/webapp/src/shared/lib/browser/cursor.ts +2 -7
- package/app/webapp/src/shared/lib/browser/index.ts +56 -36
- package/app/webapp/src/shared/lib/browser/mouse.ts +86 -21
- package/app/webapp/src/shared/lib/browser/navigate.ts +1 -4
- package/app/webapp/src/shared/lib/browser/recorder.ts +12 -5
- package/app/webapp/src/shared/lib/browser/screenshot.ts +4 -4
- package/app/webapp/src/shared/lib/browser/snapshot.ts +9 -5
- package/app/webapp/src/shared/lib/browser/tabs.ts +1 -1
- package/app/webapp/src/shared/lib/browser/types.ts +3 -2
- package/app/webapp/src/shared/lib/browser/wait.ts +1 -1
- package/app/webapp/src/shared/lib/recorder/session-recorder.ts +1 -1
- package/app/webapp/src/shared/types/global.d.ts +8 -19
- package/app/webapp/tailwind.config.js +1 -3
- package/bin/src/cli/bangonit.js +270 -177
- package/package.json +18 -6
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/app/page-03dbc2fc67c26b74.js +0 -1
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/layout-57acb80d8da0067a.js +0 -1
- package/app/webapp/.next/static/chunks/app/app/page-03dbc2fc67c26b74.js +0 -1
- package/app/webapp/.next/static/chunks/app/layout-57acb80d8da0067a.js +0 -1
- /package/app/webapp/.next/standalone/app/webapp/.next/static/{z2gRF0NKwztPLZ9d7ok06 → kz1a_SRPtSly3Fe8wHKDq}/_buildManifest.js +0 -0
- /package/app/webapp/.next/standalone/app/webapp/.next/static/{z2gRF0NKwztPLZ9d7ok06 → kz1a_SRPtSly3Fe8wHKDq}/_ssgManifest.js +0 -0
- /package/app/webapp/.next/static/{z2gRF0NKwztPLZ9d7ok06 → kz1a_SRPtSly3Fe8wHKDq}/_buildManifest.js +0 -0
- /package/app/webapp/.next/static/{z2gRF0NKwztPLZ9d7ok06 → kz1a_SRPtSly3Fe8wHKDq}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Today, two things gate that process: **testing** and **code review**. Both are s
|
|
|
39
39
|
|
|
40
40
|
The amount of AI-generated code is exploding. Coding agents are shipping real PRs today, and the volume is only going up. Code review cannot scale to match this. You can't 10x the volume of PRs and expect the same number of humans to review them thoughtfully. Inevitably, code review as we know it is going away, and the fastest teams today have already figured that out.
|
|
41
41
|
|
|
42
|
-
That leaves testing as the last line of defense. If you're not reading every line, you need confidence that the code
|
|
42
|
+
That leaves testing as the last line of defense. If you're not reading every line, you need confidence that the code _works_ — that it does what it claims, in a real browser, with real user interactions.
|
|
43
43
|
|
|
44
44
|
And let's be honest about unit tests: they don't prove much. Unit tests prove that your function returns the right value when you pass it the right mock. They don't prove your app works. Integration tests and end-to-end tests are the only real proof that your shit actually works — that a user can click a button, fill out a form, and get the result they expect.
|
|
45
45
|
|
|
@@ -224,6 +224,7 @@ retries: 1
|
|
|
224
224
|
---
|
|
225
225
|
|
|
226
226
|
## Steps
|
|
227
|
+
|
|
227
228
|
1. Navigate to http://localhost:3000
|
|
228
229
|
2. Verify the page loads with a heading and input field
|
|
229
230
|
3. Type "Buy groceries" and press Enter
|
|
@@ -39,6 +39,10 @@ const electron_1 = require("electron");
|
|
|
39
39
|
// Suppress Chromium/Electron debug log spam (dbus errors, GPU warnings, etc.)
|
|
40
40
|
electron_1.app.commandLine.appendSwitch("disable-logging");
|
|
41
41
|
electron_1.app.commandLine.appendSwitch("log-level", "3"); // fatal only
|
|
42
|
+
// CI environments often run without a user namespace; Electron needs --no-sandbox
|
|
43
|
+
if (process.env.CI) {
|
|
44
|
+
electron_1.app.commandLine.appendSwitch("no-sandbox");
|
|
45
|
+
}
|
|
42
46
|
const path = __importStar(require("path"));
|
|
43
47
|
const fs = __importStar(require("fs"));
|
|
44
48
|
const ipc_1 = require("./ipc");
|
|
@@ -161,9 +165,6 @@ function checkAllComplete() {
|
|
|
161
165
|
finish(allPassed);
|
|
162
166
|
}
|
|
163
167
|
async function createWindow() {
|
|
164
|
-
// Clear agent history from previous runs (browser state cleared per-agent via partitions)
|
|
165
|
-
const { clearStore } = await Promise.resolve().then(() => __importStar(require("./ipc")));
|
|
166
|
-
clearStore();
|
|
167
168
|
mainWindow = new electron_1.BrowserWindow({
|
|
168
169
|
width: 1400,
|
|
169
170
|
height: 900,
|
|
@@ -293,7 +294,12 @@ electron_1.ipcMain.on("test-result", (_, data) => {
|
|
|
293
294
|
summary: data.summary,
|
|
294
295
|
duration,
|
|
295
296
|
});
|
|
296
|
-
jsonLine("result", {
|
|
297
|
+
jsonLine("result", {
|
|
298
|
+
test: agentLabel(data.agentId),
|
|
299
|
+
status: data.status,
|
|
300
|
+
summary: data.summary,
|
|
301
|
+
durationMs: duration,
|
|
302
|
+
});
|
|
297
303
|
if (!rerunDetected)
|
|
298
304
|
checkAllComplete();
|
|
299
305
|
});
|
|
@@ -34,11 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
return result;
|
|
35
35
|
};
|
|
36
36
|
})();
|
|
37
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
38
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
39
|
-
};
|
|
40
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.clearStore = clearStore;
|
|
42
38
|
exports.setMainWindow = setMainWindow;
|
|
43
39
|
exports.setCwd = setCwd;
|
|
44
40
|
exports.setRunDir = setRunDir;
|
|
@@ -49,25 +45,21 @@ const electron_1 = require("electron");
|
|
|
49
45
|
const path = __importStar(require("path"));
|
|
50
46
|
const fs = __importStar(require("fs"));
|
|
51
47
|
const electron_2 = require("electron");
|
|
52
|
-
const electron_store_1 = __importDefault(require("electron-store"));
|
|
53
48
|
const child_process_1 = require("child_process");
|
|
54
49
|
const tabs_1 = require("./tabs");
|
|
55
|
-
const store = new electron_store_1.default();
|
|
56
50
|
let mainWindow = null;
|
|
57
51
|
let bangerCwd = process.cwd();
|
|
58
52
|
let runDir = null;
|
|
59
53
|
function findGitRoot(from) {
|
|
60
54
|
try {
|
|
61
55
|
return (0, child_process_1.execSync)("git rev-parse --show-toplevel", { cwd: from, stdio: ["ignore", "pipe", "ignore"] })
|
|
62
|
-
.toString()
|
|
56
|
+
.toString()
|
|
57
|
+
.trim();
|
|
63
58
|
}
|
|
64
59
|
catch {
|
|
65
60
|
return null;
|
|
66
61
|
}
|
|
67
62
|
}
|
|
68
|
-
function clearStore() {
|
|
69
|
-
store.clear();
|
|
70
|
-
}
|
|
71
63
|
function setMainWindow(win) {
|
|
72
64
|
mainWindow = win;
|
|
73
65
|
}
|
|
@@ -84,7 +76,7 @@ function sendToRenderer(channel, data) {
|
|
|
84
76
|
mainWindow?.webContents.send(channel, data);
|
|
85
77
|
}
|
|
86
78
|
function getWebappUrl() {
|
|
87
|
-
return
|
|
79
|
+
return process.env.WEBAPP_URL || "http://localhost:3002/app";
|
|
88
80
|
}
|
|
89
81
|
function registerIpcHandlers() {
|
|
90
82
|
// --- Tab management ---
|
|
@@ -223,7 +215,7 @@ function registerIpcHandlers() {
|
|
|
223
215
|
try {
|
|
224
216
|
real = fs.realpathSync(abs);
|
|
225
217
|
}
|
|
226
|
-
catch
|
|
218
|
+
catch {
|
|
227
219
|
throw new Error(`Upload file not found: ${abs}`);
|
|
228
220
|
}
|
|
229
221
|
if (!real.startsWith(sandboxRoot + path.sep) && real !== sandboxRoot) {
|
|
@@ -237,18 +229,8 @@ function registerIpcHandlers() {
|
|
|
237
229
|
const { getFileChooserState } = require("./tabs");
|
|
238
230
|
return getFileChooserState(agentId);
|
|
239
231
|
});
|
|
240
|
-
// --- Agent CRUD ---
|
|
241
|
-
electron_1.ipcMain.handle("get-agents", () => store.get("agents", []));
|
|
242
|
-
electron_1.ipcMain.handle("set-agents", (_, agents) => store.set("agents", agents));
|
|
243
|
-
// --- Agent session persistence ---
|
|
244
|
-
electron_1.ipcMain.handle("get-agent-session", (_, agentId) => store.get(`agentSessions.${agentId}`, null));
|
|
245
|
-
electron_1.ipcMain.handle("set-agent-session", (_, { agentId, session: sess }) => store.set(`agentSessions.${agentId}`, sess));
|
|
246
|
-
electron_1.ipcMain.handle("delete-agent-session", (_, agentId) => {
|
|
247
|
-
store.delete(`agentSessions.${agentId}`);
|
|
248
|
-
(0, tabs_1.destroyContext)(agentId);
|
|
249
|
-
});
|
|
250
232
|
electron_1.ipcMain.handle("clear-partition", async (_, agentId) => {
|
|
251
|
-
const partitionName = `
|
|
233
|
+
const partitionName = `agent-${agentId}`;
|
|
252
234
|
const ses = electron_1.session.fromPartition(partitionName);
|
|
253
235
|
await ses.clearStorageData();
|
|
254
236
|
await ses.clearCache();
|
|
@@ -284,7 +266,10 @@ function registerIpcHandlers() {
|
|
|
284
266
|
const parsed = JSON.parse(opts.data);
|
|
285
267
|
const agents = parsed.agents || [];
|
|
286
268
|
// Build slug map: agent id → filename
|
|
287
|
-
const slugify = (s) => s
|
|
269
|
+
const slugify = (s) => s
|
|
270
|
+
.toLowerCase()
|
|
271
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
272
|
+
.replace(/^-|-$/g, "") || "agent";
|
|
288
273
|
const usedSlugs = new Set();
|
|
289
274
|
const agentFiles = {};
|
|
290
275
|
for (const agent of agents) {
|
|
@@ -7,13 +7,6 @@ function onEvent(channel, cb) {
|
|
|
7
7
|
return () => ipcRenderer.removeListener(channel, handler);
|
|
8
8
|
}
|
|
9
9
|
contextBridge.exposeInMainWorld("bangonit", {
|
|
10
|
-
// Agent CRUD
|
|
11
|
-
getAgents: () => ipcRenderer.invoke("get-agents"),
|
|
12
|
-
setAgents: (agents) => ipcRenderer.invoke("set-agents", agents),
|
|
13
|
-
// Agent session persistence
|
|
14
|
-
getAgentSession: (agentId) => ipcRenderer.invoke("get-agent-session", agentId),
|
|
15
|
-
setAgentSession: (agentId, session) => ipcRenderer.invoke("set-agent-session", { agentId, session }),
|
|
16
|
-
deleteAgentSession: (agentId) => ipcRenderer.invoke("delete-agent-session", agentId),
|
|
17
10
|
// --- Low-level browser primitives ---
|
|
18
11
|
// CDP: send a raw CDP command to the active tab
|
|
19
12
|
cdpSend: (agentId, method, params) => ipcRenderer.invoke("cdp-send", { agentId, method, params }),
|
|
@@ -135,15 +135,18 @@ function setupCdp(wc, sendToRenderer, agentId, tabId) {
|
|
|
135
135
|
wc.debugger.sendCommand("Network.enable").catch((e) => console.error("[tabs] Network.enable failed:", e.message));
|
|
136
136
|
wc.debugger.sendCommand("Page.enable").catch((e) => console.error("[tabs] Page.enable failed:", e.message));
|
|
137
137
|
// Override dialogs
|
|
138
|
-
wc.debugger
|
|
138
|
+
wc.debugger
|
|
139
|
+
.sendCommand("Page.addScriptToEvaluateOnNewDocument", {
|
|
139
140
|
source: `(function() {
|
|
140
141
|
window.confirm = function() { return true; };
|
|
141
142
|
window.alert = function() {};
|
|
142
143
|
window.prompt = function(msg, def) { return def !== undefined ? String(def) : ''; };
|
|
143
144
|
})()`,
|
|
144
|
-
})
|
|
145
|
+
})
|
|
146
|
+
.catch((e) => console.error("[tabs] Page.addScriptToEvaluateOnNewDocument failed:", e.message));
|
|
145
147
|
// Intercept file chooser dialogs so the OS picker never appears
|
|
146
|
-
wc.debugger
|
|
148
|
+
wc.debugger
|
|
149
|
+
.sendCommand("Page.setInterceptFileChooserDialog", { enabled: true })
|
|
147
150
|
.catch((e) => console.error("[tabs] Page.setInterceptFileChooserDialog failed:", e.message));
|
|
148
151
|
wc.debugger.on("message", (_, method, params) => {
|
|
149
152
|
if (method === "Network.requestWillBeSent" ||
|
|
@@ -166,7 +169,8 @@ function addTab(ctx, tabId, wcId, sendToRenderer, agentId, initialUrl) {
|
|
|
166
169
|
if (!wc || wc.isDestroyed())
|
|
167
170
|
return;
|
|
168
171
|
// Clean user agent
|
|
169
|
-
const ua = wc
|
|
172
|
+
const ua = wc
|
|
173
|
+
.getUserAgent()
|
|
170
174
|
.replace(/\s*electron\/[\S]+/i, "")
|
|
171
175
|
.replace(/\s*bangonit\/[\S]+/i, "");
|
|
172
176
|
wc.setUserAgent(ua);
|
|
@@ -235,7 +239,8 @@ function addTab(ctx, tabId, wcId, sendToRenderer, agentId, initialUrl) {
|
|
|
235
239
|
wc.on("did-create-window", (popupWindow) => {
|
|
236
240
|
const popupWc = popupWindow.webContents;
|
|
237
241
|
const popupTabId = ctx.nextPopupId++;
|
|
238
|
-
const pua = popupWc
|
|
242
|
+
const pua = popupWc
|
|
243
|
+
.getUserAgent()
|
|
239
244
|
.replace(/\s*electron\/[\S]+/i, "")
|
|
240
245
|
.replace(/\s*bangonit\/[\S]+/i, "");
|
|
241
246
|
popupWc.setUserAgent(pua);
|