termbeam 1.12.2 → 1.12.3

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 (30) hide show
  1. package/bin/termbeam.js +6 -6
  2. package/package.json +11 -8
  3. package/src/{cli.js → cli/index.js} +3 -3
  4. package/src/{service.js → cli/service.js} +1 -1
  5. package/src/{auth.js → server/auth.js} +1 -1
  6. package/src/{server.js → server/index.js} +6 -6
  7. package/src/{preview.js → server/preview.js} +1 -1
  8. package/src/{routes.js → server/routes.js} +8 -10
  9. package/src/{sessions.js → server/sessions.js} +2 -2
  10. package/src/{websocket.js → server/websocket.js} +1 -1
  11. package/src/{tunnel.js → tunnel/index.js} +2 -2
  12. package/src/{devtunnel-install.js → tunnel/install.js} +1 -1
  13. package/src/{version.js → utils/version.js} +2 -2
  14. /package/{public-react → public}/assets/index-Cqt1eZ9m.js +0 -0
  15. /package/{public-react → public}/assets/index-CvJLM67e.css +0 -0
  16. /package/{public-react → public}/icons/icon-192.png +0 -0
  17. /package/{public-react → public}/icons/icon-512.png +0 -0
  18. /package/{public-react → public}/icons/icon.svg +0 -0
  19. /package/{public-react → public}/index.html +0 -0
  20. /package/{public-react → public}/manifest.webmanifest +0 -0
  21. /package/{public-react → public}/registerSW.js +0 -0
  22. /package/{public-react → public}/sw.js +0 -0
  23. /package/src/{client.js → cli/client.js} +0 -0
  24. /package/src/{interactive.js → cli/interactive.js} +0 -0
  25. /package/src/{prompts.js → cli/prompts.js} +0 -0
  26. /package/src/{resume.js → cli/resume.js} +0 -0
  27. /package/src/{git.js → utils/git.js} +0 -0
  28. /package/src/{logger.js → utils/logger.js} +0 -0
  29. /package/src/{shells.js → utils/shells.js} +0 -0
  30. /package/src/{update-check.js → utils/update-check.js} +0 -0
package/bin/termbeam.js CHANGED
@@ -3,19 +3,19 @@
3
3
  // Dispatch subcommands before loading the server
4
4
  const subcommand = (process.argv[2] || '').toLowerCase();
5
5
  if (subcommand === 'service') {
6
- const { run } = require('../src/service');
6
+ const { run } = require('../src/cli/service');
7
7
  run(process.argv.slice(3)).catch((err) => {
8
8
  console.error(err.message);
9
9
  process.exit(1);
10
10
  });
11
11
  } else if (subcommand === 'resume' || subcommand === 'attach') {
12
- const { resume } = require('../src/resume');
12
+ const { resume } = require('../src/cli/resume');
13
13
  resume(process.argv.slice(3)).catch((err) => {
14
14
  console.error(err.message);
15
15
  process.exit(1);
16
16
  });
17
17
  } else if (subcommand === 'list') {
18
- const { list } = require('../src/resume');
18
+ const { list } = require('../src/cli/resume');
19
19
  list().catch((err) => {
20
20
  console.error(err.message);
21
21
  process.exit(1);
@@ -29,10 +29,10 @@ if (subcommand === 'service') {
29
29
  process.exit(1);
30
30
  }
31
31
 
32
- const { createTermBeamServer } = require('../src/server.js');
32
+ const { createTermBeamServer } = require('../src/server');
33
33
  const { parseArgs } = require('../src/cli');
34
- const { runInteractiveSetup } = require('../src/interactive');
35
- const { readConnectionConfig } = require('../src/resume');
34
+ const { runInteractiveSetup } = require('../src/cli/interactive');
35
+ const { readConnectionConfig } = require('../src/cli/resume');
36
36
  const http = require('http');
37
37
 
38
38
  function httpPost(url, headers) {
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "termbeam",
3
- "version": "1.12.2",
3
+ "version": "1.12.3",
4
4
  "description": "Beam your terminal to any device — mobile-optimized web terminal with multi-session support",
5
- "main": "src/server.js",
5
+ "main": "src/server/index.js",
6
6
  "bin": {
7
7
  "termbeam": "./bin/termbeam.js"
8
8
  },
9
9
  "scripts": {
10
10
  "start": "node bin/termbeam.js",
11
11
  "dev": "node bin/termbeam.js --generate-password",
12
- "test": "node -e \"require('child_process').execFileSync(process.execPath,['--test',...require('fs').readdirSync('test').filter(f=>f.endsWith('.test.js')&&!f.startsWith('e2e-')&&f!=='devtunnel-install.test.js').map(f=>'test/'+f)],{stdio:'inherit'})\"",
13
- "test:coverage": "c8 --exclude=src/tunnel.js --exclude=src/devtunnel-install.js --exclude=test --reporter=text --reporter=lcov --reporter=json-summary --reporter=json node -e \"require('child_process').execFileSync(process.execPath,['--test','--test-reporter=spec','--test-reporter-destination=stdout',...require('fs').readdirSync('test').filter(f=>f.endsWith('.test.js')&&!f.startsWith('e2e-')&&f!=='devtunnel-install.test.js').map(f=>'test/'+f)],{stdio:'inherit'})\"",
12
+ "test": "node -e \"const{execFileSync:r}=require('child_process'),{readdirSync:d,statSync:s}=require('fs'),{join:j}=require('path');function f(p){let a=[];for(const e of d(p)){const c=j(p,e);s(c).isDirectory()?a.push(...f(c)):e.endsWith('.test.js')&&!e.startsWith('e2e-')&&e!=='devtunnel-install.test.js'&&a.push(c)}return a}r(process.execPath,['--test',...f('test')],{stdio:'inherit'})\"",
13
+ "test:coverage": "c8 --exclude=src/tunnel/ --exclude=test --reporter=text --reporter=lcov --reporter=json-summary --reporter=json node -e \"const{execFileSync:r}=require('child_process'),{readdirSync:d,statSync:s}=require('fs'),{join:j}=require('path');function f(p){let a=[];for(const e of d(p)){const c=j(p,e);s(c).isDirectory()?a.push(...f(c)):e.endsWith('.test.js')&&!e.startsWith('e2e-')&&e!=='devtunnel-install.test.js'&&a.push(c)}return a}r(process.execPath,['--test','--test-reporter=spec','--test-reporter-destination=stdout',...f('test')],{stdio:'inherit'})\"",
14
14
  "prepare": "husky",
15
15
  "format": "prettier --write .",
16
- "lint": "node --check src/*.js bin/*.js",
17
- "build:frontend": "cd frontend && npm ci && npm run build",
16
+ "lint": "node --check src/server/*.js src/cli/*.js src/tunnel/*.js src/utils/*.js bin/*.js",
17
+ "build:frontend": "cd src/frontend && npm ci && npm run build",
18
18
  "prepublishOnly": "npm run build:frontend && npm test",
19
19
  "postinstall": "node -e \"try{const p=require('path'),fs=require('fs'),r=require.resolve('node-pty/package.json'),d=p.join(p.dirname(r),'prebuilds');if(fs.existsSync(d)){for(const a of fs.readdirSync(d)){const s=p.join(d,a,'spawn-helper');try{fs.chmodSync(s,0o755)}catch{}}}}catch{}\""
20
20
  },
@@ -52,8 +52,11 @@
52
52
  },
53
53
  "files": [
54
54
  "bin/",
55
- "src/",
56
- "public-react/",
55
+ "src/server/",
56
+ "src/cli/",
57
+ "src/tunnel/",
58
+ "src/utils/",
59
+ "public/",
57
60
  "LICENSE",
58
61
  "README.md"
59
62
  ],
@@ -2,7 +2,7 @@ const os = require('os');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
  const crypto = require('crypto');
5
- const log = require('./logger');
5
+ const log = require('../utils/logger');
6
6
 
7
7
  function printHelp() {
8
8
  console.log(`
@@ -280,7 +280,7 @@ function parseArgs() {
280
280
  printHelp();
281
281
  process.exit(0);
282
282
  } else if (args[i] === '--version' || args[i] === '-v') {
283
- const { getVersion } = require('./version');
283
+ const { getVersion } = require('../utils/version');
284
284
  console.log(`termbeam v${getVersion()}`);
285
285
  process.exit(0);
286
286
  } else if (args[i] === '--generate-password') {
@@ -353,7 +353,7 @@ function parseArgs() {
353
353
  const shell = filteredArgs[0] || defaultShell;
354
354
  const shellArgs = filteredArgs.slice(1);
355
355
 
356
- const { getVersion } = require('./version');
356
+ const { getVersion } = require('../utils/version');
357
357
  const version = getVersion();
358
358
 
359
359
  return {
@@ -90,7 +90,7 @@ function buildArgs(config) {
90
90
  }
91
91
 
92
92
  function generateEcosystem(config) {
93
- const entry = require.resolve('../bin/termbeam.js');
93
+ const entry = require.resolve('../../bin/termbeam.js');
94
94
  const args = buildArgs(config);
95
95
  const env = {};
96
96
  if (config.cwd) env.TERMBEAM_CWD = config.cwd;
@@ -1,5 +1,5 @@
1
1
  const crypto = require('crypto');
2
- const log = require('./logger');
2
+ const log = require('../utils/logger');
3
3
 
4
4
  const LOGIN_HTML = `<!DOCTYPE html>
5
5
  <html lang="en">
@@ -8,15 +8,15 @@ const http = require('http');
8
8
  const { WebSocketServer } = require('ws');
9
9
  const QRCode = require('qrcode');
10
10
 
11
- const { parseArgs } = require('./cli');
11
+ const { parseArgs } = require('../cli');
12
12
  const { createAuth } = require('./auth');
13
13
  const { SessionManager } = require('./sessions');
14
14
  const { setupRoutes, cleanupUploadedFiles } = require('./routes');
15
15
  const { setupWebSocket } = require('./websocket');
16
- const { startTunnel, cleanupTunnel, findDevtunnel } = require('./tunnel');
16
+ const { startTunnel, cleanupTunnel, findDevtunnel } = require('../tunnel');
17
17
  const { createPreviewProxy } = require('./preview');
18
- const { writeConnectionConfig, removeConnectionConfig } = require('./resume');
19
- const { checkForUpdate, detectInstallMethod } = require('./update-check');
18
+ const { writeConnectionConfig, removeConnectionConfig } = require('../cli/resume');
19
+ const { checkForUpdate, detectInstallMethod } = require('../utils/update-check');
20
20
 
21
21
  // --- Helpers ---
22
22
  function getLocalIP() {
@@ -47,7 +47,7 @@ function confirmPublicTunnel() {
47
47
  */
48
48
  function createTermBeamServer(overrides = {}) {
49
49
  const config = overrides.config || parseArgs();
50
- const log = require('./logger');
50
+ const log = require('../utils/logger');
51
51
  if (config.logLevel) log.setLevel(config.logLevel);
52
52
  const auth = createAuth(config.password);
53
53
  const sessions = new SessionManager();
@@ -118,7 +118,7 @@ function createTermBeamServer(overrides = {}) {
118
118
  async function start() {
119
119
  // If tunnel mode is on but devtunnel is missing, offer to install it
120
120
  if (config.useTunnel && !findDevtunnel()) {
121
- const { promptInstall } = require('./devtunnel-install');
121
+ const { promptInstall } = require('../tunnel/install');
122
122
  const installed = await promptInstall();
123
123
  if (!installed) {
124
124
  log.error('❌ DevTunnel CLI is not available.');
@@ -1,6 +1,6 @@
1
1
  const http = require('http');
2
2
  const express = require('express');
3
- const log = require('./logger');
3
+ const log = require('../utils/logger');
4
4
 
5
5
  const PROXY_TIMEOUT = 10_000;
6
6
 
@@ -3,12 +3,11 @@ const os = require('os');
3
3
  const fs = require('fs');
4
4
  const crypto = require('crypto');
5
5
  const express = require('express');
6
- const { detectShells } = require('./shells');
7
- const log = require('./logger');
6
+ const { detectShells } = require('../utils/shells');
7
+ const log = require('../utils/logger');
8
8
  const rateLimit = require('express-rate-limit');
9
9
 
10
- const REACT_DIR = path.join(__dirname, '..', 'public-react');
11
- const PUBLIC_DIR = path.join(__dirname, '..', 'public');
10
+ const PUBLIC_DIR = path.join(__dirname, '..', '..', 'public');
12
11
  const uploadedFiles = new Map(); // id -> filepath
13
12
 
14
13
  const IMAGE_SIGNATURES = [
@@ -54,8 +53,7 @@ function setupRoutes(app, { auth, sessions, config, state }) {
54
53
  res.status(429).json({ error: 'Too many requests, please try again later.' }),
55
54
  });
56
55
 
57
- // Serve static files — React build first, then public for shared assets (icons, manifest)
58
- app.use(express.static(REACT_DIR, { index: false }));
56
+ // Serve static files
59
57
  app.use(express.static(PUBLIC_DIR, { index: false }));
60
58
 
61
59
  // Login page
@@ -85,13 +83,13 @@ function setupRoutes(app, { auth, sessions, config, state }) {
85
83
 
86
84
  // Version API
87
85
  app.get('/api/version', (_req, res) => {
88
- const { getVersion } = require('./version');
86
+ const { getVersion } = require('../utils/version');
89
87
  res.json({ version: getVersion() });
90
88
  });
91
89
 
92
90
  // Update check API
93
91
  app.get('/api/update-check', apiRateLimit, auth.middleware, async (req, res) => {
94
- const { checkForUpdate, detectInstallMethod } = require('./update-check');
92
+ const { checkForUpdate, detectInstallMethod } = require('../utils/update-check');
95
93
  const force = req.query.force === 'true';
96
94
 
97
95
  try {
@@ -138,10 +136,10 @@ function setupRoutes(app, { auth, sessions, config, state }) {
138
136
 
139
137
  // Pages — always serve React SPA
140
138
  app.get('/', pageRateLimit, autoLogin, auth.middleware, (_req, res) =>
141
- res.sendFile('index.html', { root: REACT_DIR }),
139
+ res.sendFile('index.html', { root: PUBLIC_DIR }),
142
140
  );
143
141
  app.get('/terminal', pageRateLimit, autoLogin, auth.middleware, (_req, res) =>
144
- res.sendFile('index.html', { root: REACT_DIR }),
142
+ res.sendFile('index.html', { root: PUBLIC_DIR }),
145
143
  );
146
144
 
147
145
  // Share token — generates a temporary share token for the share button
@@ -2,8 +2,8 @@ const crypto = require('crypto');
2
2
  const path = require('path');
3
3
  const { exec } = require('child_process');
4
4
  const pty = require('node-pty');
5
- const log = require('./logger');
6
- const { getGitInfo } = require('./git');
5
+ const log = require('../utils/logger');
6
+ const { getGitInfo } = require('../utils/git');
7
7
 
8
8
  // Cache git info per session to avoid blocking the event loop on every list() call.
9
9
  // lsof + git commands take ~200-500ms and block WebSocket traffic, causing
@@ -1,4 +1,4 @@
1
- const log = require('./logger');
1
+ const log = require('../utils/logger');
2
2
 
3
3
  const ACTIVE_THRESHOLD = 60000; // 60 seconds
4
4
 
@@ -2,8 +2,8 @@ const { execSync, execFileSync, spawn } = require('child_process');
2
2
  const path = require('path');
3
3
  const fs = require('fs');
4
4
  const os = require('os');
5
- const log = require('./logger');
6
- const { promptInstall } = require('./devtunnel-install');
5
+ const log = require('../utils/logger');
6
+ const { promptInstall } = require('./install');
7
7
 
8
8
  const TUNNEL_CONFIG_DIR = path.join(os.homedir(), '.termbeam');
9
9
  const TUNNEL_CONFIG_PATH = path.join(TUNNEL_CONFIG_DIR, 'tunnel.json');
@@ -3,7 +3,7 @@ const path = require('path');
3
3
  const os = require('os');
4
4
  const readline = require('readline');
5
5
  const { execSync, execFileSync } = require('child_process');
6
- const log = require('./logger');
6
+ const log = require('../utils/logger');
7
7
 
8
8
  const INSTALL_DIR = path.join(os.homedir(), 'bin');
9
9
 
@@ -2,7 +2,7 @@ const path = require('path');
2
2
  const { execSync } = require('child_process');
3
3
 
4
4
  function getVersion() {
5
- const pkg = require(path.join(__dirname, '..', 'package.json'));
5
+ const pkg = require(path.join(__dirname, '..', '..', 'package.json'));
6
6
  const base = pkg.version;
7
7
 
8
8
  // If installed via npm (global or npx), use the package version as-is
@@ -14,7 +14,7 @@ function getVersion() {
14
14
  // This avoids drift between package.json and tagged releases.
15
15
  try {
16
16
  const gitDesc = execSync('git describe --tags --always --dirty', {
17
- cwd: path.join(__dirname, '..'),
17
+ cwd: path.join(__dirname, '..', '..'),
18
18
  encoding: 'utf-8',
19
19
  stdio: ['pipe', 'pipe', 'pipe'],
20
20
  }).trim();
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes