@dmsdc-ai/aigentry-telepty 0.1.79 → 0.1.81
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 +113 -54
- package/cli.js +60 -37
- package/daemon.js +43 -4
- package/package.json +25 -4
package/README.md
CHANGED
|
@@ -1,92 +1,151 @@
|
|
|
1
|
-
#
|
|
1
|
+
# telepty
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Connect any terminal to any terminal, any machine.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
telepty is a lightweight PTY multiplexer and session bridge. It lets you spawn, attach to, and inject commands into terminal sessions — locally or across machines via Tailscale.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Built for AI CLI workflows (Claude Code, Codex, Gemini CLI), but works with any interactive terminal program.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Install
|
|
10
10
|
|
|
11
|
-
To install or update `telepty` on any machine (macOS, Linux, or Windows), just run the command for your OS. (Node.js will be automatically installed if you don't have it).
|
|
12
|
-
|
|
13
|
-
### For macOS and Linux (Ubuntu, CentOS, etc.)
|
|
14
|
-
Open your terminal and run:
|
|
15
11
|
```bash
|
|
12
|
+
# macOS / Linux
|
|
16
13
|
curl -fsSL https://raw.githubusercontent.com/dmsdc-ai/aigentry-telepty/main/install.sh | bash
|
|
17
|
-
```
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
Open PowerShell as Administrator and run:
|
|
21
|
-
```powershell
|
|
15
|
+
# Windows (PowerShell as Admin)
|
|
22
16
|
iwr -useb https://raw.githubusercontent.com/dmsdc-ai/aigentry-telepty/main/install.ps1 | iex
|
|
17
|
+
|
|
18
|
+
# Or via npm
|
|
19
|
+
npm install -g @dmsdc-ai/aigentry-telepty
|
|
23
20
|
```
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
The installer sets up telepty as a background service (`launchd` on macOS, `systemd` on Linux, detached process on Windows).
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
26
25
|
|
|
27
26
|
```bash
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
# 1. Start the daemon
|
|
28
|
+
telepty daemon
|
|
29
|
+
|
|
30
|
+
# 2. Wrap an existing CLI session for remote control
|
|
31
|
+
telepty allow --id my-session claude
|
|
32
|
+
|
|
33
|
+
# 3. List active sessions (local + Tailnet)
|
|
34
|
+
telepty list
|
|
30
35
|
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
# 4. Inject a prompt into a session
|
|
37
|
+
telepty inject my-session "explain this codebase"
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
# 5. Attach to a session interactively
|
|
40
|
+
telepty attach my-session
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```
|
|
42
|
+
# 6. Broadcast to all sessions
|
|
43
|
+
telepty broadcast "status report"
|
|
44
|
+
```
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
## Core Commands
|
|
47
|
+
|
|
48
|
+
| Command | Description |
|
|
49
|
+
|---------|-------------|
|
|
50
|
+
| `telepty daemon` | Start the background daemon (port 3848) |
|
|
51
|
+
| `telepty allow --id <name> <cmd>` | Wrap a CLI for inject control |
|
|
52
|
+
| `telepty spawn --id <name> <cmd>` | Spawn a new background session |
|
|
53
|
+
| `telepty list [--json]` | List sessions across all discovered hosts |
|
|
54
|
+
| `telepty attach [id[@host]]` | Attach to a session (interactive picker if no ID) |
|
|
55
|
+
| `telepty inject <id[@host]> "text"` | Inject text into a session |
|
|
56
|
+
| `telepty enter <id[@host]>` | Send Enter/Return to a session |
|
|
57
|
+
| `telepty multicast <id1,id2> "text"` | Inject into multiple sessions |
|
|
58
|
+
| `telepty broadcast "text"` | Inject into ALL sessions |
|
|
59
|
+
| `telepty rename <old> <new>` | Rename a session |
|
|
60
|
+
| `telepty read-screen <id> [--lines N]` | Read session screen buffer |
|
|
61
|
+
| `telepty reply "text"` | Reply to the last injector |
|
|
62
|
+
| `telepty monitor` | Real-time event billboard |
|
|
63
|
+
| `telepty listen` | Stream event bus as JSON |
|
|
64
|
+
| `telepty tui` | Full TUI dashboard |
|
|
65
|
+
| `telepty layout [grid\|tall\|stack]` | Arrange kitty windows |
|
|
66
|
+
| `telepty update` | Update to latest version |
|
|
67
|
+
|
|
68
|
+
## Cross-Machine Sessions
|
|
69
|
+
|
|
70
|
+
telepty auto-discovers sessions across your Tailnet. All commands (`list`, `attach`, `inject`, `rename`, `multicast`, `broadcast`) work seamlessly across machines.
|
|
71
|
+
|
|
72
|
+
When the same session ID exists on multiple hosts, disambiguate with `session_id@host`:
|
|
46
73
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
74
|
+
```bash
|
|
75
|
+
telepty inject my-session@macbook "hello"
|
|
76
|
+
telepty attach worker@server-01
|
|
77
|
+
```
|
|
51
78
|
|
|
52
|
-
|
|
79
|
+
## How It Works
|
|
53
80
|
|
|
54
|
-
|
|
81
|
+
```
|
|
82
|
+
CLI (telepty) ──> HTTP/WS ──> Daemon (:3848)
|
|
83
|
+
├── Session WebSocket (/api/sessions/:id)
|
|
84
|
+
├── Event Bus WebSocket (/api/bus)
|
|
85
|
+
└── REST API (/api/sessions/*)
|
|
86
|
+
```
|
|
55
87
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
-H "Content-Type: application/json" \
|
|
60
|
-
-d '{"prompt": "your command here"}'
|
|
61
|
-
```
|
|
88
|
+
- **`allow`** wraps a CLI process in a PTY bridge, enabling remote inject
|
|
89
|
+
- **`inject`** delivers text via the fastest available path: kitty terminal API, WebSocket, or UDS (Unix Domain Socket for embedded integrations)
|
|
90
|
+
- **`submit`** is handled separately from text injection for reliability across all AI CLIs
|
|
62
91
|
|
|
63
|
-
|
|
92
|
+
## Inject Delivery Paths
|
|
64
93
|
|
|
65
|
-
|
|
94
|
+
| Priority | Method | When |
|
|
95
|
+
|----------|--------|------|
|
|
96
|
+
| 1 | `kitty @ send-text` | Terminal supports kitty protocol |
|
|
97
|
+
| 2 | UDS (Unix Domain Socket) | Embedded IPC sessions (e.g. aterm) |
|
|
98
|
+
| 3 | WebSocket PTY write | Wrapped sessions via allow-bridge |
|
|
99
|
+
|
|
100
|
+
## AI CLI Integration
|
|
66
101
|
|
|
67
|
-
|
|
102
|
+
telepty works as a session bridge for AI CLIs. Use `allow` to wrap any CLI:
|
|
68
103
|
|
|
69
104
|
```bash
|
|
70
|
-
|
|
105
|
+
# Claude Code
|
|
106
|
+
telepty allow --id claude-main claude
|
|
107
|
+
|
|
108
|
+
# Codex
|
|
109
|
+
telepty allow --id codex-main codex
|
|
110
|
+
|
|
111
|
+
# Gemini CLI
|
|
112
|
+
telepty allow --id gemini-main gemini
|
|
71
113
|
```
|
|
72
114
|
|
|
73
|
-
|
|
115
|
+
Then inject prompts, read output, or attach from anywhere:
|
|
74
116
|
|
|
75
117
|
```bash
|
|
76
|
-
|
|
118
|
+
telepty inject claude-main "refactor the auth module"
|
|
119
|
+
telepty read-screen claude-main --lines 50
|
|
120
|
+
telepty attach claude-main
|
|
77
121
|
```
|
|
78
122
|
|
|
79
|
-
|
|
123
|
+
## Deliberation (Multi-Session Discussion)
|
|
80
124
|
|
|
81
|
-
|
|
125
|
+
Coordinate structured discussions across multiple AI sessions:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
telepty deliberate --topic "API design for v2" --sessions claude-1,claude-2,codex-1
|
|
129
|
+
telepty deliberate status
|
|
130
|
+
telepty deliberate end <thread_id>
|
|
131
|
+
```
|
|
82
132
|
|
|
83
133
|
## Skill Installation
|
|
84
134
|
|
|
85
|
-
|
|
135
|
+
telepty ships with packaged skills for Claude Code, Codex, and Gemini CLI. Run the interactive installer:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
telepty
|
|
139
|
+
# Choose "Install telepty skills"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Testing
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
npm test # 70 tests (node:test)
|
|
146
|
+
npm run test:watch # Watch mode
|
|
147
|
+
```
|
|
86
148
|
|
|
87
|
-
|
|
149
|
+
## License
|
|
88
150
|
|
|
89
|
-
|
|
90
|
-
- which packaged skills to install
|
|
91
|
-
- which target clients to install into (`Claude Code`, `Codex`, `Gemini`)
|
|
92
|
-
- whether each target uses a global path, the current project path, or a custom path
|
|
151
|
+
ISC
|
package/cli.js
CHANGED
|
@@ -2711,43 +2711,66 @@ Discuss the following topic from your project's perspective. Engage with other s
|
|
|
2711
2711
|
}
|
|
2712
2712
|
|
|
2713
2713
|
console.log(`
|
|
2714
|
-
\x1b[
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
telepty daemon Start the background daemon
|
|
2718
|
-
telepty spawn --id <id> <command> [args...] Spawn a new background
|
|
2719
|
-
telepty allow [--id <id>] [--auto-restart] <command> [args...]
|
|
2720
|
-
telepty list [--json] List
|
|
2721
|
-
telepty attach [id[@host]] Attach
|
|
2722
|
-
telepty
|
|
2723
|
-
telepty
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
telepty
|
|
2727
|
-
telepty
|
|
2728
|
-
telepty
|
|
2729
|
-
telepty
|
|
2730
|
-
telepty
|
|
2731
|
-
telepty
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
telepty
|
|
2735
|
-
telepty
|
|
2736
|
-
telepty
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2714
|
+
\x1b[1mtelepty\x1b[0m — Connect any terminal to any terminal, any machine.
|
|
2715
|
+
|
|
2716
|
+
\x1b[1mSession Management:\x1b[0m
|
|
2717
|
+
telepty daemon Start the background daemon (port 3848)
|
|
2718
|
+
telepty spawn --id <id> <command> [args...] Spawn a new background session
|
|
2719
|
+
telepty allow [--id <id>] [--auto-restart] <command> [args...] Wrap a CLI for remote control
|
|
2720
|
+
telepty list [--json] List sessions (local + Tailnet)
|
|
2721
|
+
telepty attach [id[@host]] Attach interactively (picker if no ID)
|
|
2722
|
+
telepty rename <old_id[@host]> <new_id> Rename a session
|
|
2723
|
+
telepty session info <id[@host]> [--json] Show session metadata
|
|
2724
|
+
|
|
2725
|
+
\x1b[1mInject & Communicate:\x1b[0m
|
|
2726
|
+
telepty inject [--ref [file]] [--from <id>] <id[@host]> "<prompt>" Inject text
|
|
2727
|
+
telepty enter <id[@host]> Send Enter/Return
|
|
2728
|
+
telepty reply "<text>" Reply to last injector
|
|
2729
|
+
telepty multicast <id1,id2> "<prompt>" Inject into multiple sessions
|
|
2730
|
+
telepty broadcast [--ref [file]] "<prompt>" Inject into ALL sessions
|
|
2731
|
+
telepty read-screen <id[@host]> [--lines N] Read session screen buffer
|
|
2732
|
+
|
|
2733
|
+
\x1b[1mCross-Machine:\x1b[0m
|
|
2734
|
+
telepty connect <user@host> [--name N] [--port P] SSH tunnel to remote host
|
|
2735
|
+
telepty disconnect <name> | --all Disconnect remote host
|
|
2736
|
+
telepty peers [--remove <name>] List connected peers
|
|
2737
|
+
|
|
2738
|
+
\x1b[1mMonitoring:\x1b[0m
|
|
2739
|
+
telepty tui Full TUI dashboard
|
|
2740
|
+
telepty monitor Real-time event billboard
|
|
2741
|
+
telepty listen Stream event bus as JSON
|
|
2742
|
+
|
|
2743
|
+
\x1b[1mHandoff:\x1b[0m
|
|
2744
|
+
telepty handoff list [--status=S] List handoffs
|
|
2745
|
+
telepty handoff drop [options] Create handoff from synthesis
|
|
2746
|
+
telepty handoff claim <id> [--agent=S] Claim a pending handoff
|
|
2747
|
+
telepty handoff status <id> [status] Get/update handoff status
|
|
2748
|
+
|
|
2749
|
+
\x1b[1mDeliberation:\x1b[0m
|
|
2750
|
+
telepty deliberate --topic "..." [--sessions s1,s2] Start multi-session discussion
|
|
2751
|
+
telepty deliberate status [thread_id] Show thread details
|
|
2752
|
+
telepty deliberate end <thread_id> Close a thread
|
|
2753
|
+
|
|
2754
|
+
\x1b[1mOther:\x1b[0m
|
|
2755
|
+
telepty update Update to latest version
|
|
2756
|
+
telepty layout [grid|tall|stack] Arrange terminal windows
|
|
2757
|
+
telepty status-report --phase <p> [options] Emit structured status event
|
|
2758
|
+
|
|
2759
|
+
\x1b[1mExamples:\x1b[0m
|
|
2760
|
+
\x1b[2m# Wrap Claude Code for remote control\x1b[0m
|
|
2761
|
+
telepty allow --id my-claude claude
|
|
2762
|
+
|
|
2763
|
+
\x1b[2m# Send a prompt to a session\x1b[0m
|
|
2764
|
+
telepty inject my-claude "explain the auth module"
|
|
2765
|
+
|
|
2766
|
+
\x1b[2m# Read what a session is showing\x1b[0m
|
|
2767
|
+
telepty read-screen my-claude --lines 30
|
|
2768
|
+
|
|
2769
|
+
\x1b[2m# Broadcast to all sessions\x1b[0m
|
|
2770
|
+
telepty broadcast "status report please"
|
|
2771
|
+
|
|
2772
|
+
\x1b[2m# Inject into a session on another machine\x1b[0m
|
|
2773
|
+
telepty inject my-claude@server-01 "run the tests"
|
|
2751
2774
|
`);
|
|
2752
2775
|
}
|
|
2753
2776
|
|
package/daemon.js
CHANGED
|
@@ -13,6 +13,7 @@ const terminalBackend = require('./terminal-backend');
|
|
|
13
13
|
const config = getConfig();
|
|
14
14
|
const EXPECTED_TOKEN = config.authToken;
|
|
15
15
|
const MACHINE_ID = process.env.TELEPTY_MACHINE_ID || os.hostname();
|
|
16
|
+
const net = require('net');
|
|
16
17
|
const fs = require('fs');
|
|
17
18
|
const SESSION_PERSIST_PATH = require('path').join(os.homedir(), '.config', 'aigentry-telepty', 'sessions.json');
|
|
18
19
|
const SESSION_STALE_SECONDS = Math.max(1, Number(process.env.TELEPTY_SESSION_STALE_SECONDS || 60));
|
|
@@ -34,6 +35,8 @@ function persistSessions() {
|
|
|
34
35
|
cmuxSurfaceId: s.cmuxSurfaceId || null,
|
|
35
36
|
termProgram: s.termProgram || null,
|
|
36
37
|
term: s.term || null,
|
|
38
|
+
delivery: s.delivery || null,
|
|
39
|
+
deliveryEndpoint: s.deliveryEndpoint || null,
|
|
37
40
|
createdAt: s.createdAt,
|
|
38
41
|
lastActivityAt: s.lastActivityAt || null,
|
|
39
42
|
lastConnectedAt: s.lastConnectedAt || null,
|
|
@@ -219,7 +222,7 @@ function getSessionHealthStatus(session, options = {}) {
|
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
if (session.type === 'aterm') {
|
|
222
|
-
if (session.deliveryEndpoint) {
|
|
225
|
+
if (session.deliveryEndpoint || (session.delivery && session.delivery.address)) {
|
|
223
226
|
return 'CONNECTED';
|
|
224
227
|
}
|
|
225
228
|
if (disconnectedMs !== null && disconnectedMs >= staleMs) {
|
|
@@ -426,6 +429,33 @@ function emitInjectFailureEvent(sessionId, code, error, extra = {}, session = nu
|
|
|
426
429
|
|
|
427
430
|
async function writeDataToSession(id, session, data) {
|
|
428
431
|
if (session.type === 'aterm') {
|
|
432
|
+
// UDS delivery via net.connect()
|
|
433
|
+
if (session.delivery && session.delivery.transport === 'unix_socket' && session.delivery.address) {
|
|
434
|
+
return new Promise((resolve) => {
|
|
435
|
+
const payload = JSON.stringify({ text: data, session_id: id }) + '\n';
|
|
436
|
+
const timeout = setTimeout(() => {
|
|
437
|
+
sock.destroy();
|
|
438
|
+
resolve(buildErrorBody('TIMEOUT', 'UDS delivery timed out.', { httpStatus: 504 }));
|
|
439
|
+
}, DELIVERY_TIMEOUT_MS);
|
|
440
|
+
const sock = net.connect(session.delivery.address, () => {
|
|
441
|
+
sock.end(payload);
|
|
442
|
+
});
|
|
443
|
+
sock.on('data', () => {}); // drain
|
|
444
|
+
sock.on('end', () => {
|
|
445
|
+
clearTimeout(timeout);
|
|
446
|
+
resolve({ success: true });
|
|
447
|
+
});
|
|
448
|
+
sock.on('error', (err) => {
|
|
449
|
+
clearTimeout(timeout);
|
|
450
|
+
resolve(buildErrorBody('DISCONNECTED', 'UDS endpoint is unreachable.', {
|
|
451
|
+
httpStatus: 503,
|
|
452
|
+
detail: err.message
|
|
453
|
+
}));
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// HTTP delivery (backward compat)
|
|
429
459
|
if (!session.deliveryEndpoint) {
|
|
430
460
|
return buildErrorBody('DISCONNECTED', 'Delivery endpoint is missing.', { httpStatus: 503 });
|
|
431
461
|
}
|
|
@@ -504,7 +534,7 @@ async function deliverInjectionToSession(id, session, prompt, options = {}) {
|
|
|
504
534
|
strategy: session.type === 'wrapped'
|
|
505
535
|
? 'ws_split_cr'
|
|
506
536
|
: session.type === 'aterm'
|
|
507
|
-
? 'aterm_endpoint'
|
|
537
|
+
? (session.delivery && session.delivery.transport === 'unix_socket' ? 'aterm_uds' : 'aterm_endpoint')
|
|
508
538
|
: 'pty_split_cr',
|
|
509
539
|
submit: options.noEnter ? 'skipped' : 'deferred'
|
|
510
540
|
};
|
|
@@ -568,6 +598,7 @@ function serializeSession(id, session, options = {}) {
|
|
|
568
598
|
idleSeconds,
|
|
569
599
|
active_clients: session.clients ? session.clients.size : 0,
|
|
570
600
|
ready: session.ready || false,
|
|
601
|
+
delivery: session.delivery || null,
|
|
571
602
|
deliveryEndpoint: session.deliveryEndpoint || null,
|
|
572
603
|
healthStatus,
|
|
573
604
|
healthReason,
|
|
@@ -787,6 +818,12 @@ app.post('/api/sessions/register', (req, res) => {
|
|
|
787
818
|
if (Object.prototype.hasOwnProperty.call(req.body, 'term')) existing.term = term || null;
|
|
788
819
|
if (req.body.delivery_type) existing.type = req.body.delivery_type;
|
|
789
820
|
if (req.body.delivery_endpoint) existing.deliveryEndpoint = req.body.delivery_endpoint;
|
|
821
|
+
if (req.body.delivery) {
|
|
822
|
+
existing.delivery = req.body.delivery;
|
|
823
|
+
if (!existing.deliveryEndpoint && req.body.delivery.address) {
|
|
824
|
+
existing.deliveryEndpoint = req.body.delivery.address;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
790
827
|
if (req.body.delivery_type === 'aterm') {
|
|
791
828
|
existing.ready = true;
|
|
792
829
|
markSessionConnected(existing);
|
|
@@ -795,7 +832,8 @@ app.post('/api/sessions/register', (req, res) => {
|
|
|
795
832
|
return res.status(200).json({ session_id, type: existing.type, command: existing.command, cwd: existing.cwd, reregistered: true });
|
|
796
833
|
}
|
|
797
834
|
|
|
798
|
-
const { delivery_type, delivery_endpoint } = req.body;
|
|
835
|
+
const { delivery_type, delivery_endpoint, delivery } = req.body;
|
|
836
|
+
const resolvedEndpoint = delivery_endpoint || (delivery && delivery.address) || null;
|
|
799
837
|
const sessionRecord = {
|
|
800
838
|
id: session_id,
|
|
801
839
|
type: delivery_type || 'wrapped',
|
|
@@ -808,7 +846,8 @@ app.post('/api/sessions/register', (req, res) => {
|
|
|
808
846
|
cmuxSurfaceId: cmux_surface_id || null,
|
|
809
847
|
termProgram: term_program || null,
|
|
810
848
|
term: term || null,
|
|
811
|
-
|
|
849
|
+
delivery: delivery || null,
|
|
850
|
+
deliveryEndpoint: resolvedEndpoint,
|
|
812
851
|
createdAt: new Date().toISOString(),
|
|
813
852
|
lastActivityAt: new Date().toISOString(),
|
|
814
853
|
lastConnectedAt: delivery_type === 'aterm' ? new Date().toISOString() : null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dmsdc-ai/aigentry-telepty",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.81",
|
|
4
4
|
"main": "daemon.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"aigentry-telepty": "install.js",
|
|
@@ -12,10 +12,31 @@
|
|
|
12
12
|
"test:watch": "node --test --watch test/auth.test.js test/daemon.test.js test/daemon-singleton.test.js test/cli.test.js test/skill-installer.test.js test/interactive-terminal.test.js test/runtime-info.test.js test/session-routing.test.js",
|
|
13
13
|
"test:ci": "node --test --test-reporter=spec test/auth.test.js test/daemon.test.js test/daemon-singleton.test.js test/cli.test.js test/skill-installer.test.js test/interactive-terminal.test.js test/runtime-info.test.js test/session-routing.test.js"
|
|
14
14
|
},
|
|
15
|
-
"keywords": [
|
|
16
|
-
|
|
15
|
+
"keywords": [
|
|
16
|
+
"pty",
|
|
17
|
+
"terminal",
|
|
18
|
+
"session",
|
|
19
|
+
"multiplexer",
|
|
20
|
+
"remote",
|
|
21
|
+
"inject",
|
|
22
|
+
"ai-cli",
|
|
23
|
+
"claude",
|
|
24
|
+
"codex",
|
|
25
|
+
"gemini",
|
|
26
|
+
"cross-machine",
|
|
27
|
+
"tailscale"
|
|
28
|
+
],
|
|
29
|
+
"author": "dmsdc-ai",
|
|
17
30
|
"license": "ISC",
|
|
18
|
-
"description": "",
|
|
31
|
+
"description": "Universal terminal session bridge — connect any terminal to any terminal, any machine",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/dmsdc-ai/aigentry-telepty.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/dmsdc-ai/aigentry-telepty#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/dmsdc-ai/aigentry-telepty/issues"
|
|
39
|
+
},
|
|
19
40
|
"dependencies": {
|
|
20
41
|
"blessed": "^0.1.81",
|
|
21
42
|
"cors": "^2.8.6",
|