@shaykec/bridge 0.1.0 → 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/README.md +6 -0
- package/package.json +1 -1
- package/src/server.js +33 -1
package/README.md
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
# @shaykec/bridge
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@shaykec/bridge)
|
|
4
|
+
|
|
3
5
|
Communication hub for ClaudeTeach -- HTTP server with WebSocket, SSE, and REST endpoints. Routes visual commands from the Claude Code plugin to browser clients (canvas app and Chrome extension) and user events back.
|
|
4
6
|
|
|
7
|
+
```bash
|
|
8
|
+
npm install @shaykec/bridge
|
|
9
|
+
```
|
|
10
|
+
|
|
5
11
|
## Architecture
|
|
6
12
|
|
|
7
13
|
```
|
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
|
|
23
23
|
import { createServer } from 'http';
|
|
24
24
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'fs';
|
|
25
|
-
import { join, dirname, extname } from 'path';
|
|
25
|
+
import { join, dirname, extname, resolve } from 'path';
|
|
26
26
|
import { fileURLToPath } from 'url';
|
|
27
|
+
import { exec } from 'child_process';
|
|
27
28
|
import { WebSocketServer } from 'ws';
|
|
28
29
|
|
|
29
30
|
import {
|
|
@@ -253,6 +254,11 @@ function handleRequest(req, res, tierManager, router, options) {
|
|
|
253
254
|
return;
|
|
254
255
|
}
|
|
255
256
|
|
|
257
|
+
if (req.method === 'POST' && pathname === '/api/open-extension') {
|
|
258
|
+
handleApiOpenExtension(res);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
256
262
|
// --- Health check ---
|
|
257
263
|
if (req.method === 'GET' && pathname === '/health') {
|
|
258
264
|
sendJson(res, 200, {
|
|
@@ -458,6 +464,32 @@ function serveStatic(res, pathname) {
|
|
|
458
464
|
}
|
|
459
465
|
}
|
|
460
466
|
|
|
467
|
+
/**
|
|
468
|
+
* POST /api/open-extension — open extension folder + chrome://extensions in the OS.
|
|
469
|
+
* Triggered by the "Install Extension" button on the welcome page.
|
|
470
|
+
*/
|
|
471
|
+
function handleApiOpenExtension(res) {
|
|
472
|
+
const extensionDir = resolve(__dirname, '..', '..', 'extension');
|
|
473
|
+
if (!existsSync(join(extensionDir, 'manifest.json'))) {
|
|
474
|
+
sendJson(res, 404, { error: 'Extension directory not found' });
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const platform = process.platform;
|
|
479
|
+
if (platform === 'darwin') {
|
|
480
|
+
exec(`open "${extensionDir}"`);
|
|
481
|
+
exec('open -a "Google Chrome" "chrome://extensions"');
|
|
482
|
+
} else if (platform === 'linux') {
|
|
483
|
+
exec(`xdg-open "${extensionDir}"`);
|
|
484
|
+
exec('google-chrome "chrome://extensions" 2>/dev/null || chromium-browser "chrome://extensions" 2>/dev/null');
|
|
485
|
+
} else if (platform === 'win32') {
|
|
486
|
+
exec(`explorer "${extensionDir}"`);
|
|
487
|
+
exec('start chrome "chrome://extensions"');
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
sendJson(res, 200, { ok: true, path: extensionDir });
|
|
491
|
+
}
|
|
492
|
+
|
|
461
493
|
// --- Helpers ---
|
|
462
494
|
|
|
463
495
|
function readBody(req, callback) {
|