tabminal 1.2.8 → 1.3.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/Dockerfile ADDED
@@ -0,0 +1,30 @@
1
+ FROM node:latest
2
+
3
+ WORKDIR /app
4
+
5
+ # Copy package files first for caching
6
+ COPY package.json package-lock.json ./
7
+
8
+ # Install dependencies
9
+ # Using 'npm install -g .' later to mimic npx/global install behavior
10
+ RUN npm install
11
+
12
+ # Install cloudflared
13
+ RUN curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && \
14
+ dpkg -i cloudflared.deb && \
15
+ rm cloudflared.deb
16
+
17
+ # Copy source code
18
+ COPY . .
19
+
20
+ # Install the project globally so 'tabminal' command is available
21
+ RUN npm install -g .
22
+
23
+ # Expose the default port
24
+ EXPOSE 9846
25
+
26
+ # Set the entrypoint to the Tabminal CLI
27
+ ENTRYPOINT ["tabminal"]
28
+
29
+ # Default command (can be overridden)
30
+ CMD ["--help"]
package/README.md CHANGED
@@ -105,6 +105,7 @@ You can configure Tabminal via command-line arguments, environment variables, or
105
105
  | `-o`, `--openai-key` | `TABMINAL_OPENAI_KEY` | OpenAI API Key (Mutually exclusive with OpenRouter) | `null` |
106
106
  | `-u`, `--openai-api` | `TABMINAL_OPENAI_API` | OpenAI Base API URL (Optional) | `null` |
107
107
  | `-m`, `--model` | `TABMINAL_MODEL` | AI Model ID | `gpt-5.2` (OpenAI) / `gemini-3-flash-preview` (OpenRouter) |
108
+ | `-f`, `--cloudflare-key` | `TABMINAL_CLOUDFLARE_KEY` | Cloudflare Tunnel Token | `null` |
108
109
  | `-g`, `--google-key` | `TABMINAL_GOOGLE_KEY` | Google Search API Key | `null` |
109
110
  | `-c`, `--google-cx` | `TABMINAL_GOOGLE_CX` | Google Search Engine ID (CX) | `null` |
110
111
  | `-d`, `--debug` | `TABMINAL_DEBUG` | Enable debug logs | `false` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tabminal",
3
- "version": "1.2.8",
3
+ "version": "1.3.2",
4
4
  "description": "A modern, persistent web terminal with multi-tab support and real-time system monitoring.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/config.mjs CHANGED
@@ -17,7 +17,8 @@ const DEFAULT_CONFIG = {
17
17
  googleKey: null,
18
18
  googleCx: null,
19
19
  openaiKey: null,
20
- openaiApi: null
20
+ openaiApi: null,
21
+ cloudflareKey: null
21
22
  };
22
23
 
23
24
  function loadJson(filePath) {
@@ -86,6 +87,10 @@ function loadConfig() {
86
87
  type: 'string',
87
88
  short: 'u'
88
89
  },
90
+ 'cloudflare-key': {
91
+ type: 'string',
92
+ short: 'f'
93
+ },
89
94
  model: {
90
95
  type: 'string',
91
96
  short: 'm'
@@ -127,6 +132,7 @@ Options:
127
132
  --openrouter-key, -k Set OpenRouter API Key
128
133
  --openai-key, -o Set OpenAI API Key
129
134
  --openai-api, -u Set OpenAI API Base URL
135
+ --cloudflare-key, -f Set Cloudflare Tunnel Token
130
136
  --model, -m Set AI Model
131
137
  --google-key, -g Set Google Search API Key
132
138
  --google-cx, -c Set Google Search Engine ID
@@ -149,6 +155,7 @@ Options:
149
155
  if (finalConfig['openrouter-key']) finalConfig.openrouterKey = finalConfig['openrouter-key'];
150
156
  if (finalConfig['openai-key']) finalConfig.openaiKey = finalConfig['openai-key'];
151
157
  if (finalConfig['openai-api']) finalConfig.openaiApi = finalConfig['openai-api'];
158
+ if (finalConfig['cloudflare-key']) finalConfig.cloudflareKey = finalConfig['cloudflare-key'];
152
159
  if (finalConfig['google-key']) finalConfig.googleKey = finalConfig['google-key'];
153
160
  if (finalConfig['google-cx']) finalConfig.googleCx = finalConfig['google-cx'];
154
161
 
@@ -176,6 +183,9 @@ Options:
176
183
  if (args['openai-api']) {
177
184
  finalConfig.openaiApi = args['openai-api'];
178
185
  }
186
+ if (args['cloudflare-key']) {
187
+ finalConfig.cloudflareKey = args['cloudflare-key'];
188
+ }
179
189
  if (args.model) {
180
190
  finalConfig.model = args.model;
181
191
  }
@@ -198,6 +208,7 @@ Options:
198
208
  if (process.env.TABMINAL_OPENROUTER_KEY) finalConfig.openrouterKey = process.env.TABMINAL_OPENROUTER_KEY;
199
209
  if (process.env.TABMINAL_OPENAI_KEY) finalConfig.openaiKey = process.env.TABMINAL_OPENAI_KEY;
200
210
  if (process.env.TABMINAL_OPENAI_API) finalConfig.openaiApi = process.env.TABMINAL_OPENAI_API;
211
+ if (process.env.TABMINAL_CLOUDFLARE_KEY) finalConfig.cloudflareKey = process.env.TABMINAL_CLOUDFLARE_KEY;
201
212
  if (process.env.TABMINAL_MODEL) finalConfig.model = process.env.TABMINAL_MODEL;
202
213
  if (process.env.TABMINAL_DEBUG) finalConfig.debug = true;
203
214
  if (process.env.TABMINAL_GOOGLE_KEY) finalConfig.googleKey = process.env.TABMINAL_GOOGLE_KEY;
package/src/server.mjs CHANGED
@@ -18,7 +18,7 @@ import { config } from './config.mjs';
18
18
  import { authMiddleware, verifyClient } from './auth.mjs';
19
19
  import { setupFsRoutes } from './fs-routes.mjs';
20
20
  import * as persistence from './persistence.mjs';
21
- import { alan, web } from 'utilitas';
21
+ import { alan, network, web } from 'utilitas';
22
22
 
23
23
  const __filename = fileURLToPath(import.meta.url);
24
24
  const __dirname = path.dirname(__filename);
@@ -64,6 +64,15 @@ if (config.openrouterKey) {
64
64
  }
65
65
  }
66
66
 
67
+ if (config.cloudflareKey) {
68
+ try {
69
+ network.cfTunnel(config.cloudflareKey);
70
+ console.log('[Server] Cloudflare Tunnel initialized');
71
+ } catch (e) {
72
+ console.error('[Server] Failed to initialize Cloudflare Tunnel:', e.message);
73
+ }
74
+ }
75
+
67
76
  if (!config.acceptTerms) {
68
77
  console.error(`
69
78
  [SECURITY WARNING]