peer-term 1.4.2 → 1.4.4
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/bin/peer-term.js +0 -0
- package/package.json +4 -4
- package/src/index.js +1 -1
- package/src/ui.js +166 -166
package/bin/peer-term.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "peer-term",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Share your terminal instantly using a 6-digit code or QR code. Encrypted. No config.",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/jay6205/
|
|
8
|
+
"url": "https://github.com/jay6205/Peer_term.git",
|
|
9
9
|
"directory": "host"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://github.com/jay6205/
|
|
11
|
+
"homepage": "https://github.com/jay6205/Peer_term#readme",
|
|
12
12
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/jay6205/
|
|
13
|
+
"url": "https://github.com/jay6205/Peer_term/issues"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"terminal",
|
package/src/index.js
CHANGED
|
@@ -717,7 +717,7 @@ class Session {
|
|
|
717
717
|
// Clean up reference if this was the pending socket
|
|
718
718
|
if (this._pendingReconnectWs === newWs) this._pendingReconnectWs = null;
|
|
719
719
|
});
|
|
720
|
-
} catch
|
|
720
|
+
} catch {
|
|
721
721
|
// Connection failed, next retry in 5s
|
|
722
722
|
}
|
|
723
723
|
}, 5000);
|
package/src/ui.js
CHANGED
|
@@ -1,166 +1,166 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PeerTerm — CLI UI Module
|
|
3
|
-
*
|
|
4
|
-
* Handles all terminal output formatting:
|
|
5
|
-
* - ASCII art banner
|
|
6
|
-
* - Session code display box
|
|
7
|
-
* - Help text
|
|
8
|
-
* - Version display
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import fs from 'fs';
|
|
12
|
-
import path from 'path';
|
|
13
|
-
import { fileURLToPath } from 'url';
|
|
14
|
-
import qrcode from 'qrcode-terminal';
|
|
15
|
-
|
|
16
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
-
const __dirname = path.dirname(__filename);
|
|
18
|
-
|
|
19
|
-
// ─── ASCII Banner ────────────────────────────────────────────────────────────
|
|
20
|
-
|
|
21
|
-
const BANNER = `
|
|
22
|
-
██████╗ ███████╗███████╗██████╗ ████████╗███████╗██████╗ ███╗ ███╗
|
|
23
|
-
██╔══██╗██╔════╝██╔════╝██╔══██╗╚══██╔══╝██╔════╝██╔══██╗████╗ ████║
|
|
24
|
-
██████╔╝█████╗ █████╗ ██████╔╝ ██║ █████╗ ██████╔╝██╔████╔██║
|
|
25
|
-
██╔═══╝ ██╔══╝ ██╔══╝ ██╔══██╗ ██║ ██╔══╝ ██╔══██╗██║╚██╔╝██║
|
|
26
|
-
██║ ███████╗███████╗██║ ██║ ██║ ███████╗██║ ██║██║ ╚═╝ ██║
|
|
27
|
-
╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
|
|
28
|
-
Terminal sharing. Instant. Encrypted.`;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Print the startup ASCII art banner.
|
|
32
|
-
*/
|
|
33
|
-
export function printBanner() {
|
|
34
|
-
console.log(BANNER);
|
|
35
|
-
console.log('');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// ─── Session Code Box ────────────────────────────────────────────────────────
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Print the bordered session information box.
|
|
42
|
-
*
|
|
43
|
-
* @param {Object} opts
|
|
44
|
-
* @param {string} opts.code - 6-digit session code
|
|
45
|
-
* @param {string} opts.expiry - Formatted expiry string (e.g. "5 minute(s)")
|
|
46
|
-
* @param {string} opts.mode - "Read-Write" or "Read-Only"
|
|
47
|
-
* @param {string} opts.shell - Shell path (e.g. "/bin/zsh")
|
|
48
|
-
* @param {string} [opts.startPath] - Starting directory for the session
|
|
49
|
-
* @param {string} [opts.shareUrl] - URL to share (e.g. "https://peerterm.dev")
|
|
50
|
-
*/
|
|
51
|
-
export async function printSessionBox({ code, expiry, rejoinWindow, mode, shell, startPath, shareUrl }) {
|
|
52
|
-
const spacedCode = code.split('').join(' ');
|
|
53
|
-
const url = shareUrl || 'https://peerterm.dev';
|
|
54
|
-
const joinUrl = `${url}?code=${code}`;
|
|
55
|
-
|
|
56
|
-
// Truncate long shell paths to keep box readable
|
|
57
|
-
const shellDisplay = shell.length > 24 ? '...' + shell.slice(-21) : shell;
|
|
58
|
-
|
|
59
|
-
// Truncate long start paths similarly
|
|
60
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
61
|
-
let pathDisplay = startPath || homeDir;
|
|
62
|
-
if (homeDir && pathDisplay.startsWith(homeDir)) {
|
|
63
|
-
pathDisplay = '~' + pathDisplay.slice(homeDir.length);
|
|
64
|
-
}
|
|
65
|
-
if (pathDisplay.length > 30) pathDisplay = '...' + pathDisplay.slice(-27);
|
|
66
|
-
|
|
67
|
-
// Calculate dynamic box width based on longest content
|
|
68
|
-
const infoLines = [
|
|
69
|
-
` Session Code: ${spacedCode}`,
|
|
70
|
-
` Expires in: ${expiry}`,
|
|
71
|
-
` Rejoin Window: ${rejoinWindow}`,
|
|
72
|
-
` Mode: ${mode}`,
|
|
73
|
-
` Shell: ${shellDisplay}`,
|
|
74
|
-
` Path: ${pathDisplay}`,
|
|
75
|
-
];
|
|
76
|
-
const shareLine = ` Share at: ${url}`;
|
|
77
|
-
const allLines = [...infoLines, shareLine];
|
|
78
|
-
const maxLen = Math.max(...allLines.map(l => l.length), 35);
|
|
79
|
-
const innerWidth = maxLen + 3; // padding on right
|
|
80
|
-
|
|
81
|
-
const hr = '─'.repeat(innerWidth);
|
|
82
|
-
const emptyLine = ' '.repeat(innerWidth);
|
|
83
|
-
|
|
84
|
-
console.log('');
|
|
85
|
-
console.log(` ┌${hr}┐`);
|
|
86
|
-
console.log(` │${emptyLine}│`);
|
|
87
|
-
for (const line of infoLines) {
|
|
88
|
-
console.log(` │${line.padEnd(innerWidth)}│`);
|
|
89
|
-
}
|
|
90
|
-
console.log(` │${emptyLine}│`);
|
|
91
|
-
console.log(` │${shareLine.padEnd(innerWidth)}│`);
|
|
92
|
-
console.log(` │${emptyLine}│`);
|
|
93
|
-
console.log(` └${hr}┘`);
|
|
94
|
-
console.log('');
|
|
95
|
-
|
|
96
|
-
// Render QR code for instant scan-to-join
|
|
97
|
-
try {
|
|
98
|
-
const qrString = await new Promise((resolve) => {
|
|
99
|
-
qrcode.generate(joinUrl, { small: true }, (qr) => {
|
|
100
|
-
resolve(qr);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
console.log(' Scan to join:');
|
|
105
|
-
console.log('');
|
|
106
|
-
// Indent each QR line for alignment with the box
|
|
107
|
-
const qrLines = qrString.split('\n');
|
|
108
|
-
for (const line of qrLines) {
|
|
109
|
-
if (line.length > 0) console.log(` ${line}`);
|
|
110
|
-
}
|
|
111
|
-
console.log('');
|
|
112
|
-
console.log(` Or open: ${joinUrl}`);
|
|
113
|
-
console.log('');
|
|
114
|
-
} catch {
|
|
115
|
-
// QR generation failed — not critical, code is still shown in the box
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// ─── Help Text ───────────────────────────────────────────────────────────────
|
|
120
|
-
|
|
121
|
-
const HELP_TEXT = `
|
|
122
|
-
Usage: peer-term [options]
|
|
123
|
-
|
|
124
|
-
Options:
|
|
125
|
-
--expiry <time> Session expiry time (e.g. 5m, 30s, 1h) [default: 5m]
|
|
126
|
-
--rejoin <time> Reconnection window (e.g. 5m, 1h, 6h) [default: 2m]
|
|
127
|
-
--readonly Share in view-only mode
|
|
128
|
-
--secure Enable fingerprint verification for MITM protection
|
|
129
|
-
--path <dir> Starting directory for the terminal session [default: home]
|
|
130
|
-
--relay <url> Custom relay server URL
|
|
131
|
-
--verbose Enable debug logging
|
|
132
|
-
--help Show this help message
|
|
133
|
-
--version Print version number
|
|
134
|
-
|
|
135
|
-
Examples:
|
|
136
|
-
peer-term Start session with defaults
|
|
137
|
-
peer-term --expiry 10m Custom expiry
|
|
138
|
-
peer-term --rejoin 30m Custom reconnection window
|
|
139
|
-
peer-term --readonly View-only session
|
|
140
|
-
peer-term --secure Require fingerprint verification
|
|
141
|
-
peer-term --path ~/projects Start in ~/projects
|
|
142
|
-
peer-term --verbose Debug logs
|
|
143
|
-
peer-term --relay wss://custom Use custom relay server
|
|
144
|
-
`;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Print CLI help text.
|
|
148
|
-
*/
|
|
149
|
-
export function printHelp() {
|
|
150
|
-
console.log(HELP_TEXT);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// ─── Version ─────────────────────────────────────────────────────────────────
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Print the version number from package.json.
|
|
157
|
-
*/
|
|
158
|
-
export function printVersion() {
|
|
159
|
-
try {
|
|
160
|
-
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
161
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
162
|
-
console.log(`peer-term v${pkg.version}`);
|
|
163
|
-
} catch {
|
|
164
|
-
console.log('peer-term (version unknown)');
|
|
165
|
-
}
|
|
166
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* PeerTerm — CLI UI Module
|
|
3
|
+
*
|
|
4
|
+
* Handles all terminal output formatting:
|
|
5
|
+
* - ASCII art banner
|
|
6
|
+
* - Session code display box
|
|
7
|
+
* - Help text
|
|
8
|
+
* - Version display
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
import qrcode from 'qrcode-terminal';
|
|
15
|
+
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = path.dirname(__filename);
|
|
18
|
+
|
|
19
|
+
// ─── ASCII Banner ────────────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
const BANNER = `
|
|
22
|
+
██████╗ ███████╗███████╗██████╗ ████████╗███████╗██████╗ ███╗ ███╗
|
|
23
|
+
██╔══██╗██╔════╝██╔════╝██╔══██╗╚══██╔══╝██╔════╝██╔══██╗████╗ ████║
|
|
24
|
+
██████╔╝█████╗ █████╗ ██████╔╝ ██║ █████╗ ██████╔╝██╔████╔██║
|
|
25
|
+
██╔═══╝ ██╔══╝ ██╔══╝ ██╔══██╗ ██║ ██╔══╝ ██╔══██╗██║╚██╔╝██║
|
|
26
|
+
██║ ███████╗███████╗██║ ██║ ██║ ███████╗██║ ██║██║ ╚═╝ ██║
|
|
27
|
+
╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
|
|
28
|
+
Terminal sharing. Instant. Encrypted.`;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Print the startup ASCII art banner.
|
|
32
|
+
*/
|
|
33
|
+
export function printBanner() {
|
|
34
|
+
console.log(BANNER);
|
|
35
|
+
console.log('');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ─── Session Code Box ────────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Print the bordered session information box.
|
|
42
|
+
*
|
|
43
|
+
* @param {Object} opts
|
|
44
|
+
* @param {string} opts.code - 6-digit session code
|
|
45
|
+
* @param {string} opts.expiry - Formatted expiry string (e.g. "5 minute(s)")
|
|
46
|
+
* @param {string} opts.mode - "Read-Write" or "Read-Only"
|
|
47
|
+
* @param {string} opts.shell - Shell path (e.g. "/bin/zsh")
|
|
48
|
+
* @param {string} [opts.startPath] - Starting directory for the session
|
|
49
|
+
* @param {string} [opts.shareUrl] - URL to share (e.g. "https://peerterm.dev")
|
|
50
|
+
*/
|
|
51
|
+
export async function printSessionBox({ code, expiry, rejoinWindow, mode, shell, startPath, shareUrl }) {
|
|
52
|
+
const spacedCode = code.split('').join(' ');
|
|
53
|
+
const url = shareUrl || 'https://peerterm.dev';
|
|
54
|
+
const joinUrl = `${url}?code=${code}`;
|
|
55
|
+
|
|
56
|
+
// Truncate long shell paths to keep box readable
|
|
57
|
+
const shellDisplay = shell.length > 24 ? '...' + shell.slice(-21) : shell;
|
|
58
|
+
|
|
59
|
+
// Truncate long start paths similarly
|
|
60
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
61
|
+
let pathDisplay = startPath || homeDir;
|
|
62
|
+
if (homeDir && pathDisplay.startsWith(homeDir)) {
|
|
63
|
+
pathDisplay = '~' + pathDisplay.slice(homeDir.length);
|
|
64
|
+
}
|
|
65
|
+
if (pathDisplay.length > 30) pathDisplay = '...' + pathDisplay.slice(-27);
|
|
66
|
+
|
|
67
|
+
// Calculate dynamic box width based on longest content
|
|
68
|
+
const infoLines = [
|
|
69
|
+
` Session Code: ${spacedCode}`,
|
|
70
|
+
` Expires in: ${expiry}`,
|
|
71
|
+
` Rejoin Window: ${rejoinWindow}`,
|
|
72
|
+
` Mode: ${mode}`,
|
|
73
|
+
` Shell: ${shellDisplay}`,
|
|
74
|
+
` Path: ${pathDisplay}`,
|
|
75
|
+
];
|
|
76
|
+
const shareLine = ` Share at: ${url}`;
|
|
77
|
+
const allLines = [...infoLines, shareLine];
|
|
78
|
+
const maxLen = Math.max(...allLines.map(l => l.length), 35);
|
|
79
|
+
const innerWidth = maxLen + 3; // padding on right
|
|
80
|
+
|
|
81
|
+
const hr = '─'.repeat(innerWidth);
|
|
82
|
+
const emptyLine = ' '.repeat(innerWidth);
|
|
83
|
+
|
|
84
|
+
console.log('');
|
|
85
|
+
console.log(` ┌${hr}┐`);
|
|
86
|
+
console.log(` │${emptyLine}│`);
|
|
87
|
+
for (const line of infoLines) {
|
|
88
|
+
console.log(` │${line.padEnd(innerWidth)}│`);
|
|
89
|
+
}
|
|
90
|
+
console.log(` │${emptyLine}│`);
|
|
91
|
+
console.log(` │${shareLine.padEnd(innerWidth)}│`);
|
|
92
|
+
console.log(` │${emptyLine}│`);
|
|
93
|
+
console.log(` └${hr}┘`);
|
|
94
|
+
console.log('');
|
|
95
|
+
|
|
96
|
+
// Render QR code for instant scan-to-join
|
|
97
|
+
try {
|
|
98
|
+
const qrString = await new Promise((resolve) => {
|
|
99
|
+
qrcode.generate(joinUrl, { small: true }, (qr) => {
|
|
100
|
+
resolve(qr);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
console.log(' Scan to join:');
|
|
105
|
+
console.log('');
|
|
106
|
+
// Indent each QR line for alignment with the box
|
|
107
|
+
const qrLines = qrString.split('\n');
|
|
108
|
+
for (const line of qrLines) {
|
|
109
|
+
if (line.length > 0) console.log(` ${line}`);
|
|
110
|
+
}
|
|
111
|
+
console.log('');
|
|
112
|
+
console.log(` Or open: ${joinUrl}`);
|
|
113
|
+
console.log('');
|
|
114
|
+
} catch {
|
|
115
|
+
// QR generation failed — not critical, code is still shown in the box
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ─── Help Text ───────────────────────────────────────────────────────────────
|
|
120
|
+
|
|
121
|
+
const HELP_TEXT = `
|
|
122
|
+
Usage: peer-term [options]
|
|
123
|
+
|
|
124
|
+
Options:
|
|
125
|
+
--expiry <time> Session expiry time (e.g. 5m, 30s, 1h) [default: 5m]
|
|
126
|
+
--rejoin <time> Reconnection window (e.g. 5m, 1h, 6h) [default: 2m]
|
|
127
|
+
--readonly Share in view-only mode
|
|
128
|
+
--secure Enable fingerprint verification for MITM protection
|
|
129
|
+
--path <dir> Starting directory for the terminal session [default: home]
|
|
130
|
+
--relay <url> Custom relay server URL
|
|
131
|
+
--verbose Enable debug logging
|
|
132
|
+
--help Show this help message
|
|
133
|
+
--version Print version number
|
|
134
|
+
|
|
135
|
+
Examples:
|
|
136
|
+
peer-term Start session with defaults
|
|
137
|
+
peer-term --expiry 10m Custom expiry
|
|
138
|
+
peer-term --rejoin 30m Custom reconnection window
|
|
139
|
+
peer-term --readonly View-only session
|
|
140
|
+
peer-term --secure Require fingerprint verification
|
|
141
|
+
peer-term --path ~/projects Start in ~/projects
|
|
142
|
+
peer-term --verbose Debug logs
|
|
143
|
+
peer-term --relay wss://custom Use custom relay server
|
|
144
|
+
`;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Print CLI help text.
|
|
148
|
+
*/
|
|
149
|
+
export function printHelp() {
|
|
150
|
+
console.log(HELP_TEXT);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ─── Version ─────────────────────────────────────────────────────────────────
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Print the version number from package.json.
|
|
157
|
+
*/
|
|
158
|
+
export function printVersion() {
|
|
159
|
+
try {
|
|
160
|
+
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
161
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
162
|
+
console.log(`peer-term v${pkg.version}`);
|
|
163
|
+
} catch {
|
|
164
|
+
console.log('peer-term (version unknown)');
|
|
165
|
+
}
|
|
166
|
+
}
|