@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 CHANGED
@@ -1,7 +1,13 @@
1
1
  # @shaykec/bridge
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@shaykec/bridge)](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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaykec/bridge",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Communication hub — HTTP + WebSocket + SSE server with template engine",
6
6
  "main": "src/server.js",
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) {