yo-bug 0.1.3 → 0.2.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.
- package/dist/src/server/proxy-server.d.ts.map +1 -1
- package/dist/src/server/proxy-server.js +58 -23
- package/dist/src/server/proxy-server.js.map +1 -1
- package/dist/src/server/sdk-serve.d.ts.map +1 -1
- package/dist/src/server/sdk-serve.js +12 -5
- package/dist/src/server/sdk-serve.js.map +1 -1
- package/dist/vibe-feedback.js +713 -212
- package/package.json +1 -1
- package/src/client/annotation-mode/toolbar.ts +53 -63
- package/src/client/core/i18n.ts +23 -29
- package/src/client/core/sdk.ts +21 -48
- package/src/client/styles/icons.ts +85 -0
- package/src/client/styles/sdk.css.ts +652 -100
- package/src/client/ui/checklist-panel.ts +35 -77
- package/src/client/ui/feedback-panel.ts +7 -1
- package/src/client/ui/floating-button.ts +7 -35
- package/src/client/ui/toast.ts +12 -1
- package/src/client/ui/verify-panel.ts +14 -26
- package/src/server/proxy-server.ts +62 -28
- package/src/server/sdk-serve.ts +14 -5
- package/src/server/html-injector.ts +0 -46
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-server.d.ts","sourceRoot":"","sources":["../../../src/server/proxy-server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAUpD,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"proxy-server.d.ts","sourceRoot":"","sources":["../../../src/server/proxy-server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAUpD,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA6GlD;AAED,wBAAgB,eAAe,IAAI,IAAI,CAStC;AAED,wBAAgB,cAAc,IAAI,OAAO,CAExC"}
|
|
@@ -3,8 +3,8 @@ import cors from 'cors';
|
|
|
3
3
|
import httpProxy from 'http-proxy';
|
|
4
4
|
import { createFeedbackRouter } from './feedback-api.js';
|
|
5
5
|
import { createSdkRouter } from './sdk-serve.js';
|
|
6
|
-
import { createHtmlInjector } from './html-injector.js';
|
|
7
6
|
const PROXY_PORT = 3695;
|
|
7
|
+
const INJECT_SCRIPT = `<script defer src="/vibe-feedback.js"></script>`;
|
|
8
8
|
let server = null;
|
|
9
9
|
let proxy = null;
|
|
10
10
|
export async function startProxyServer(targetPort, store) {
|
|
@@ -14,46 +14,81 @@ export async function startProxyServer(targetPort, store) {
|
|
|
14
14
|
const targetUrl = `http://localhost:${targetPort}`;
|
|
15
15
|
const proxyUrl = `http://localhost:${PROXY_PORT}`;
|
|
16
16
|
const app = express();
|
|
17
|
-
// CORS for SDK to submit feedback
|
|
18
17
|
app.use(cors());
|
|
19
|
-
// Parse JSON for feedback API
|
|
20
18
|
app.use(express.json({ limit: '10mb' }));
|
|
21
|
-
//
|
|
19
|
+
// Our own routes — served directly, not proxied
|
|
22
20
|
app.use(createSdkRouter());
|
|
23
|
-
// Feedback API routes
|
|
24
21
|
app.use(createFeedbackRouter(store));
|
|
25
|
-
// Create proxy
|
|
22
|
+
// Create proxy — let it handle responses by default (no selfHandleResponse)
|
|
26
23
|
proxy = httpProxy.createProxyServer({
|
|
27
24
|
target: targetUrl,
|
|
28
|
-
ws: true,
|
|
25
|
+
ws: true,
|
|
29
26
|
changeOrigin: true,
|
|
30
27
|
});
|
|
28
|
+
// Prevent upstream from sending compressed responses — we need raw HTML to inject SDK
|
|
29
|
+
proxy.on('proxyReq', (proxyReq) => {
|
|
30
|
+
proxyReq.setHeader('Accept-Encoding', 'identity');
|
|
31
|
+
});
|
|
31
32
|
proxy.on('error', (_err, _req, res) => {
|
|
32
33
|
if (res && 'writeHead' in res) {
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
try {
|
|
35
|
+
res.writeHead?.(502, { 'Content-Type': 'text/plain' });
|
|
36
|
+
res.end?.('Dev server not responding');
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
// Inject SDK into HTML responses using the modifyResponse approach
|
|
42
|
+
// We check Accept header on REQUEST to decide if we need to intercept
|
|
43
|
+
app.all('*', (req, res) => {
|
|
44
|
+
const accept = req.headers['accept'] || '';
|
|
45
|
+
const isHtmlRequest = accept.includes('text/html');
|
|
46
|
+
if (isHtmlRequest) {
|
|
47
|
+
// Potentially an HTML page — intercept to inject SDK
|
|
48
|
+
proxy.web(req, res, { selfHandleResponse: true });
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Static asset (JS/CSS/images/fonts/etc) — let proxy handle directly
|
|
52
|
+
proxy.web(req, res);
|
|
35
53
|
}
|
|
36
54
|
});
|
|
37
|
-
//
|
|
55
|
+
// Handle HTML injection in proxyRes (only fires for selfHandleResponse requests)
|
|
38
56
|
proxy.on('proxyRes', (proxyRes, _req, res) => {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
const statusCode = proxyRes.statusCode || 200;
|
|
58
|
+
const contentType = proxyRes.headers['content-type'] || '';
|
|
59
|
+
// Only inject into 2xx HTML responses
|
|
60
|
+
if (statusCode >= 200 && statusCode < 300 && contentType.includes('text/html')) {
|
|
61
|
+
// Buffer response, inject SDK, send
|
|
62
|
+
const chunks = [];
|
|
63
|
+
proxyRes.on('data', (chunk) => chunks.push(chunk));
|
|
64
|
+
proxyRes.on('end', () => {
|
|
65
|
+
let html = Buffer.concat(chunks).toString('utf-8');
|
|
66
|
+
if (html.includes('</body>')) {
|
|
67
|
+
html = html.replace('</body>', `${INJECT_SCRIPT}\n</body>`);
|
|
68
|
+
}
|
|
69
|
+
else if (html.includes('</html>')) {
|
|
70
|
+
html = html.replace('</html>', `${INJECT_SCRIPT}\n</html>`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
html += `\n${INJECT_SCRIPT}`;
|
|
74
|
+
}
|
|
75
|
+
// Copy headers except content-length (body size changed)
|
|
76
|
+
const headers = { ...proxyRes.headers };
|
|
77
|
+
delete headers['content-length'];
|
|
78
|
+
// Remove content-encoding since we decoded the buffer as utf-8
|
|
79
|
+
delete headers['content-encoding'];
|
|
80
|
+
delete headers['transfer-encoding'];
|
|
81
|
+
headers['content-length'] = String(Buffer.byteLength(html));
|
|
82
|
+
res.writeHead(statusCode, headers);
|
|
83
|
+
res.end(html);
|
|
84
|
+
});
|
|
44
85
|
}
|
|
45
86
|
else {
|
|
46
|
-
//
|
|
47
|
-
res.writeHead(
|
|
87
|
+
// Redirect or non-HTML — pass through as-is
|
|
88
|
+
res.writeHead(statusCode, proxyRes.headers);
|
|
48
89
|
proxyRes.pipe(res);
|
|
49
90
|
}
|
|
50
91
|
});
|
|
51
|
-
// All other requests → proxy to dev server
|
|
52
|
-
app.all('*', (req, res) => {
|
|
53
|
-
proxy.web(req, res, {
|
|
54
|
-
selfHandleResponse: true, // We handle response in proxyRes event
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
92
|
// Start server
|
|
58
93
|
await new Promise((resolve, reject) => {
|
|
59
94
|
server = app.listen(PROXY_PORT, () => resolve());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../../src/server/proxy-server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,SAAS,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../../src/server/proxy-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-serve.d.ts","sourceRoot":"","sources":["../../../src/server/sdk-serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKjC,wBAAgB,eAAe,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"sdk-serve.d.ts","sourceRoot":"","sources":["../../../src/server/sdk-serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKjC,wBAAgB,eAAe,IAAI,MAAM,CA2BxC"}
|
|
@@ -5,13 +5,20 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
export function createSdkRouter() {
|
|
6
6
|
const router = Router();
|
|
7
7
|
router.get('/vibe-feedback.js', (_req, res) => {
|
|
8
|
-
// Resolve SDK path relative to this file's location
|
|
9
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
// Try multiple possible locations:
|
|
10
|
+
// 1. Running from dist/src/server/ → ../../vibe-feedback.js (compiled, npm global)
|
|
11
|
+
// 2. Running from src/server/ via tsx → ../../dist/vibe-feedback.js (dev mode)
|
|
12
|
+
const candidates = [
|
|
13
|
+
path.resolve(__dirname, '../../vibe-feedback.js'), // dist/vibe-feedback.js from dist/src/server/
|
|
14
|
+
path.resolve(__dirname, '../../dist/vibe-feedback.js'), // from src/server/ (tsx dev)
|
|
15
|
+
path.resolve(__dirname, '../../../dist/vibe-feedback.js'), // fallback
|
|
16
|
+
];
|
|
17
|
+
const sdkPath = candidates.find((p) => fs.existsSync(p));
|
|
18
|
+
if (!sdkPath) {
|
|
19
|
+
return res.status(404).send(`// SDK not found. Searched: ${candidates.join(', ')}`);
|
|
13
20
|
}
|
|
14
|
-
res.setHeader('Content-Type', 'application/javascript');
|
|
21
|
+
res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
|
15
22
|
res.setHeader('Cache-Control', 'no-cache');
|
|
16
23
|
fs.createReadStream(sdkPath).pipe(res);
|
|
17
24
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-serve.js","sourceRoot":"","sources":["../../../src/server/sdk-serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC5C,
|
|
1
|
+
{"version":3,"file":"sdk-serve.js","sourceRoot":"","sources":["../../../src/server/sdk-serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAE/D,mCAAmC;QACnC,mFAAmF;QACnF,+EAA+E;QAC/E,MAAM,UAAU,GAAG;YACjB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,wBAAwB,CAAC,EAAO,8CAA8C;YACtG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,6BAA6B,CAAC,EAAG,6BAA6B;YACtF,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gCAAgC,CAAC,EAAE,WAAW;SACvE,CAAC;QAEF,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,+BAA+B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,uCAAuC,CAAC,CAAC;QACvE,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QAC3C,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|