@tongil_kim/clautunnel 0.1.9
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 +74 -0
- package/bin/clautunnel +3 -0
- package/dist/index.d.ts +151 -0
- package/dist/index.js +3168 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# ClauTunnel
|
|
2
|
+
|
|
3
|
+
Remote monitoring and control for Claude Code CLI from your mobile device.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
**npm (Recommended)**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @tongil_kim/clautunnel
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Homebrew (macOS)**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
brew tap TongilKim/clautunnel
|
|
17
|
+
brew install clautunnel
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Setup
|
|
21
|
+
|
|
22
|
+
Run the setup command to configure your Supabase credentials:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
clautunnel setup
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
You'll need:
|
|
29
|
+
- **Supabase Project URL**: Dashboard → Settings → API (e.g., `https://xxxx.supabase.co`)
|
|
30
|
+
- **Supabase Anon Key**: Dashboard → Settings → API → `anon` `public` key
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Authenticate
|
|
36
|
+
clautunnel login
|
|
37
|
+
|
|
38
|
+
# Start a session
|
|
39
|
+
clautunnel start
|
|
40
|
+
|
|
41
|
+
# Start in daemon mode (background)
|
|
42
|
+
clautunnel start --daemon
|
|
43
|
+
|
|
44
|
+
# Prevent sleep while running (macOS)
|
|
45
|
+
clautunnel start --prevent-sleep
|
|
46
|
+
|
|
47
|
+
# Check status
|
|
48
|
+
clautunnel status
|
|
49
|
+
|
|
50
|
+
# Stop the daemon
|
|
51
|
+
clautunnel stop
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Features
|
|
55
|
+
|
|
56
|
+
- Real-time terminal output streaming to mobile
|
|
57
|
+
- Send input from mobile to CLI
|
|
58
|
+
- Push notifications for task completion, errors, and input prompts
|
|
59
|
+
- Automatic reconnection with exponential backoff
|
|
60
|
+
- Sleep prevention option for long-running tasks
|
|
61
|
+
|
|
62
|
+
## Requirements
|
|
63
|
+
|
|
64
|
+
- Node.js 18+
|
|
65
|
+
- Claude Code CLI installed
|
|
66
|
+
|
|
67
|
+
## Links
|
|
68
|
+
|
|
69
|
+
- [GitHub Repository](https://github.com/TongilKim/clautunnel)
|
|
70
|
+
- [Mobile App](https://github.com/TongilKim/clautunnel/tree/main/apps/mobile)
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT
|
package/bin/clautunnel
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { SupabaseClient } from '@supabase/supabase-js';
|
|
4
|
+
import { PermissionMode, SlashCommand, ModelInfo, InteractiveCommandData, InteractiveCommandType, InteractiveResult, UserQuestionData, PermissionRequestData, ToolUseData, Session, SessionStatus, Machine, MachineStatus, ImageAttachment } from 'clautunnel-shared';
|
|
5
|
+
|
|
6
|
+
interface ConfigData {
|
|
7
|
+
machineId?: string;
|
|
8
|
+
sessionTokens?: {
|
|
9
|
+
accessToken: string;
|
|
10
|
+
refreshToken: string;
|
|
11
|
+
};
|
|
12
|
+
supabaseUrl?: string;
|
|
13
|
+
supabaseAnonKey?: string;
|
|
14
|
+
}
|
|
15
|
+
declare class Config {
|
|
16
|
+
private configDir;
|
|
17
|
+
private configFile;
|
|
18
|
+
private data;
|
|
19
|
+
constructor(configDir?: string);
|
|
20
|
+
private loadConfig;
|
|
21
|
+
private saveConfig;
|
|
22
|
+
getSupabaseUrl(): string;
|
|
23
|
+
getSupabaseAnonKey(): string;
|
|
24
|
+
setSupabaseCredentials(credentials: {
|
|
25
|
+
url: string;
|
|
26
|
+
anonKey: string;
|
|
27
|
+
}): void;
|
|
28
|
+
isConfigured(): boolean;
|
|
29
|
+
requireConfiguration(): void;
|
|
30
|
+
getMachineId(): string | undefined;
|
|
31
|
+
setMachineId(machineId: string): void;
|
|
32
|
+
getSessionTokens(): ConfigData['sessionTokens'] | undefined;
|
|
33
|
+
setSessionTokens(tokens: ConfigData['sessionTokens']): void;
|
|
34
|
+
setSession(tokens: {
|
|
35
|
+
accessToken: string;
|
|
36
|
+
refreshToken: string;
|
|
37
|
+
}): void;
|
|
38
|
+
clearSessionTokens(): void;
|
|
39
|
+
}
|
|
40
|
+
declare function getConfig(): Config;
|
|
41
|
+
|
|
42
|
+
declare class Logger {
|
|
43
|
+
private silent;
|
|
44
|
+
private debugEnabled;
|
|
45
|
+
constructor();
|
|
46
|
+
private formatTimestamp;
|
|
47
|
+
private formatMessage;
|
|
48
|
+
debug(message: string, data?: object): void;
|
|
49
|
+
info(message: string, data?: object): void;
|
|
50
|
+
warn(message: string, data?: object): void;
|
|
51
|
+
error(message: string, data?: object): void;
|
|
52
|
+
}
|
|
53
|
+
declare function getLogger(): Logger;
|
|
54
|
+
|
|
55
|
+
interface RealtimeClientOptions {
|
|
56
|
+
supabase: SupabaseClient;
|
|
57
|
+
sessionId: string;
|
|
58
|
+
}
|
|
59
|
+
declare class RealtimeClient extends EventEmitter {
|
|
60
|
+
private supabase;
|
|
61
|
+
private sessionId;
|
|
62
|
+
private outputChannel;
|
|
63
|
+
private inputChannel;
|
|
64
|
+
private presenceChannel;
|
|
65
|
+
private seq;
|
|
66
|
+
private realtimeEnabled;
|
|
67
|
+
constructor(options: RealtimeClientOptions);
|
|
68
|
+
connect(): Promise<void>;
|
|
69
|
+
disconnect(): Promise<void>;
|
|
70
|
+
broadcast(content: string): Promise<void>;
|
|
71
|
+
broadcastMode(mode: PermissionMode): Promise<void>;
|
|
72
|
+
broadcastCommands(commands: SlashCommand[]): Promise<void>;
|
|
73
|
+
broadcastModel(model: string): Promise<void>;
|
|
74
|
+
broadcastModels(models: ModelInfo[]): Promise<void>;
|
|
75
|
+
broadcastSystem(content: string): Promise<void>;
|
|
76
|
+
broadcastInteractiveResponse(data: InteractiveCommandData): Promise<void>;
|
|
77
|
+
broadcastInteractiveConfirm(command: InteractiveCommandType, result: InteractiveResult): Promise<void>;
|
|
78
|
+
broadcastResumeHistory(historySessionId: string): Promise<void>;
|
|
79
|
+
broadcastUserQuestion(questionData: UserQuestionData): Promise<void>;
|
|
80
|
+
broadcastPermissionRequest(requestData: PermissionRequestData): Promise<void>;
|
|
81
|
+
broadcastToolUse(toolUseData: ToolUseData): Promise<void>;
|
|
82
|
+
broadcastComplete(): Promise<void>;
|
|
83
|
+
broadcastSessionTitle(title: string): Promise<void>;
|
|
84
|
+
broadcastQueued(): Promise<void>;
|
|
85
|
+
broadcastError(errorMessage: string, errorCode?: string): Promise<void>;
|
|
86
|
+
getSeq(): number;
|
|
87
|
+
isConnected(): boolean;
|
|
88
|
+
isRealtimeEnabled(): boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface SessionManagerOptions {
|
|
92
|
+
supabase: SupabaseClient;
|
|
93
|
+
}
|
|
94
|
+
declare class SessionManager {
|
|
95
|
+
private supabase;
|
|
96
|
+
constructor(options: SessionManagerOptions);
|
|
97
|
+
createSession(machineId: string, workingDirectory?: string): Promise<Session>;
|
|
98
|
+
endSession(sessionId: string): Promise<void>;
|
|
99
|
+
getSession(sessionId: string): Promise<Session | null>;
|
|
100
|
+
updateSessionStatus(sessionId: string, status: SessionStatus): Promise<void>;
|
|
101
|
+
updateSessionModel(sessionId: string, model: string): Promise<void>;
|
|
102
|
+
updateSdkSessionId(sessionId: string, sdkSessionId: string): Promise<void>;
|
|
103
|
+
updateSessionTitle(sessionId: string, title: string): Promise<void>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
interface MachineManagerOptions {
|
|
107
|
+
supabase: SupabaseClient;
|
|
108
|
+
}
|
|
109
|
+
declare class MachineManager {
|
|
110
|
+
private supabase;
|
|
111
|
+
constructor(options: MachineManagerOptions);
|
|
112
|
+
registerMachine(userId: string, name?: string, machineId?: string): Promise<Machine>;
|
|
113
|
+
getMachine(machineId: string): Promise<Machine | null>;
|
|
114
|
+
updateMachineStatus(machineId: string, status: MachineStatus): Promise<void>;
|
|
115
|
+
heartbeat(machineId: string): Promise<void>;
|
|
116
|
+
listMachines(userId: string): Promise<Machine[]>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
interface DaemonOptions {
|
|
120
|
+
supabase: SupabaseClient;
|
|
121
|
+
userId: string;
|
|
122
|
+
machineId?: string;
|
|
123
|
+
machineName?: string;
|
|
124
|
+
cwd: string;
|
|
125
|
+
hybrid?: boolean;
|
|
126
|
+
}
|
|
127
|
+
declare class Daemon extends EventEmitter {
|
|
128
|
+
private options;
|
|
129
|
+
private sdkSession;
|
|
130
|
+
private sessionManager;
|
|
131
|
+
private machineManager;
|
|
132
|
+
private configManager;
|
|
133
|
+
private realtimeClient;
|
|
134
|
+
private machine;
|
|
135
|
+
private session;
|
|
136
|
+
private running;
|
|
137
|
+
private commandsBroadcast;
|
|
138
|
+
private sdkCommandsBroadcast;
|
|
139
|
+
private titleSet;
|
|
140
|
+
constructor(options: DaemonOptions);
|
|
141
|
+
start(): Promise<void>;
|
|
142
|
+
stop(): Promise<void>;
|
|
143
|
+
sendPrompt(prompt: string, attachments?: ImageAttachment[]): Promise<void>;
|
|
144
|
+
isRunning(): boolean;
|
|
145
|
+
getSession(): Session | null;
|
|
146
|
+
getMachine(): Machine | null;
|
|
147
|
+
private broadcastCommands;
|
|
148
|
+
private broadcastModels;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { Config, Daemon, Logger, MachineManager, RealtimeClient, SessionManager, getConfig, getLogger };
|