cloudforge-agent 0.1.0

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.
@@ -0,0 +1,207 @@
1
+ /**
2
+ * CloudForge Agent Terminal Manager
3
+ * Manages PTY terminal sessions
4
+ */
5
+ import pty from 'node-pty';
6
+ import * as fs from 'fs';
7
+ import { exec } from 'child_process';
8
+ import { promisify } from 'util';
9
+ import chalk from 'chalk';
10
+ const execAsync = promisify(exec);
11
+ export class TerminalManager {
12
+ sessions = new Map();
13
+ config;
14
+ constructor(config) {
15
+ this.config = config;
16
+ }
17
+ /**
18
+ * Spawn a new terminal session
19
+ */
20
+ spawn(sessionId, shell, cols, rows, cwd) {
21
+ if (this.sessions.has(sessionId)) {
22
+ throw new Error(`Session ${sessionId} already exists`);
23
+ }
24
+ if (this.config.debug) {
25
+ console.log(chalk.gray(`Spawning terminal: ${sessionId}, shell=${shell}, ${cols}x${rows}`));
26
+ }
27
+ // Spawn PTY process
28
+ const ptyProcess = pty.spawn(shell, [], {
29
+ name: 'xterm-256color',
30
+ cols,
31
+ rows,
32
+ cwd: cwd || this.config.homeDir,
33
+ env: {
34
+ ...process.env,
35
+ TERM: 'xterm-256color',
36
+ COLORTERM: 'truecolor',
37
+ LANG: process.env.LANG || 'en_US.UTF-8',
38
+ },
39
+ });
40
+ // Event callbacks
41
+ const dataCallbacks = [];
42
+ const exitCallbacks = [];
43
+ // Handle data from PTY
44
+ ptyProcess.onData((data) => {
45
+ for (const callback of dataCallbacks) {
46
+ callback(data);
47
+ }
48
+ });
49
+ // Handle PTY exit
50
+ ptyProcess.onExit(({ exitCode }) => {
51
+ if (this.config.debug) {
52
+ console.log(chalk.gray(`Terminal exited: ${sessionId}, code=${exitCode}`));
53
+ }
54
+ for (const callback of exitCallbacks) {
55
+ callback(exitCode);
56
+ }
57
+ });
58
+ // Create session object
59
+ const session = {
60
+ pty: ptyProcess,
61
+ sessionId,
62
+ onData: (callback) => {
63
+ dataCallbacks.push(callback);
64
+ },
65
+ onExit: (callback) => {
66
+ exitCallbacks.push(callback);
67
+ },
68
+ write: (data) => {
69
+ ptyProcess.write(data);
70
+ },
71
+ resize: (cols, rows) => {
72
+ if (this.config.debug) {
73
+ console.log(chalk.gray(`Terminal resize: ${sessionId}, ${cols}x${rows}`));
74
+ }
75
+ ptyProcess.resize(cols, rows);
76
+ },
77
+ kill: () => {
78
+ if (this.config.debug) {
79
+ console.log(chalk.gray(`Terminal kill: ${sessionId}`));
80
+ }
81
+ ptyProcess.kill();
82
+ },
83
+ };
84
+ this.sessions.set(sessionId, session);
85
+ return session;
86
+ }
87
+ /**
88
+ * Get a terminal session by ID
89
+ */
90
+ get(sessionId) {
91
+ return this.sessions.get(sessionId);
92
+ }
93
+ /**
94
+ * Check if a session exists
95
+ */
96
+ has(sessionId) {
97
+ return this.sessions.has(sessionId);
98
+ }
99
+ /**
100
+ * Remove a terminal session
101
+ */
102
+ remove(sessionId) {
103
+ return this.sessions.delete(sessionId);
104
+ }
105
+ /**
106
+ * Kill and remove a terminal session
107
+ */
108
+ kill(sessionId) {
109
+ const session = this.sessions.get(sessionId);
110
+ if (session) {
111
+ session.kill();
112
+ this.sessions.delete(sessionId);
113
+ return true;
114
+ }
115
+ return false;
116
+ }
117
+ /**
118
+ * Kill all terminal sessions
119
+ */
120
+ killAll() {
121
+ for (const [sessionId, session] of this.sessions) {
122
+ if (this.config.debug) {
123
+ console.log(chalk.gray(`Killing terminal: ${sessionId}`));
124
+ }
125
+ session.kill();
126
+ }
127
+ this.sessions.clear();
128
+ }
129
+ /**
130
+ * Get the number of active sessions
131
+ */
132
+ get count() {
133
+ return this.sessions.size;
134
+ }
135
+ /**
136
+ * Get all session IDs
137
+ */
138
+ get sessionIds() {
139
+ return Array.from(this.sessions.keys());
140
+ }
141
+ /**
142
+ * Get the current working directory of a terminal session.
143
+ * Uses /proc on Linux, lsof on macOS with child process tree traversal.
144
+ */
145
+ async getCwd(sessionId) {
146
+ const session = this.sessions.get(sessionId);
147
+ if (!session)
148
+ return null;
149
+ const pid = session.pty.pid;
150
+ try {
151
+ // Linux: read /proc/<pid>/cwd symlink (check child processes first)
152
+ try {
153
+ // Get the foreground child process (the actual shell, not pty wrapper)
154
+ const childCwd = await this.getChildCwd(pid);
155
+ if (childCwd && childCwd !== '/')
156
+ return childCwd;
157
+ return fs.readlinkSync(`/proc/${pid}/cwd`);
158
+ }
159
+ catch {
160
+ // Not Linux or /proc not available
161
+ }
162
+ // macOS: find the shell's child process and get its cwd
163
+ try {
164
+ // Get child processes of the pty process
165
+ const { stdout: children } = await execAsync(`pgrep -P ${pid} 2>/dev/null || echo ${pid}`, { encoding: 'utf8', timeout: 3000 });
166
+ const childPids = children.trim().split('\n').filter(Boolean);
167
+ // Use the last child (deepest in process tree)
168
+ const targetPid = childPids[childPids.length - 1] || String(pid);
169
+ const { stdout } = await execAsync(`lsof -a -d cwd -p ${targetPid} -Fn 2>/dev/null`, { encoding: 'utf8', timeout: 3000 });
170
+ // Parse: lines starting with 'n' after 'fcwd' line contain the path
171
+ const lines = stdout.split('\n');
172
+ for (let i = 0; i < lines.length; i++) {
173
+ if (lines[i] === 'fcwd' && i + 1 < lines.length && lines[i + 1].startsWith('n')) {
174
+ const cwd = lines[i + 1].substring(1);
175
+ if (cwd && cwd !== '/')
176
+ return cwd;
177
+ }
178
+ }
179
+ }
180
+ catch {
181
+ // lsof not available or failed
182
+ }
183
+ return null;
184
+ }
185
+ catch {
186
+ return null;
187
+ }
188
+ }
189
+ /**
190
+ * Get cwd from a child process (Linux /proc)
191
+ */
192
+ async getChildCwd(parentPid) {
193
+ try {
194
+ const { stdout } = await execAsync(`pgrep -P ${parentPid} 2>/dev/null`, { encoding: 'utf8', timeout: 2000 });
195
+ const childPids = stdout.trim().split('\n').filter(Boolean);
196
+ if (childPids.length > 0) {
197
+ const lastChild = childPids[childPids.length - 1];
198
+ return fs.readlinkSync(`/proc/${lastChild}/cwd`);
199
+ }
200
+ }
201
+ catch {
202
+ // No children or /proc not available
203
+ }
204
+ return null;
205
+ }
206
+ }
207
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * CloudForge Agent WebSocket Manager
3
+ * Handles connection to CloudForge server
4
+ */
5
+ import { AgentConfig } from './config.js';
6
+ import type { TerminalManager } from './terminal.js';
7
+ import type { FileManager } from './files.js';
8
+ import type { GitManager } from './git.js';
9
+ export declare class WebSocketManager {
10
+ private socket;
11
+ private config;
12
+ private terminalManager;
13
+ private fileManager;
14
+ private gitManager;
15
+ private reconnectAttempts;
16
+ private heartbeatTimer;
17
+ private isConnected;
18
+ constructor(config: AgentConfig, terminalManager: TerminalManager, fileManager: FileManager, gitManager: GitManager);
19
+ /**
20
+ * Connect to CloudForge server
21
+ */
22
+ connect(): Promise<void>;
23
+ /**
24
+ * Setup terminal event handlers
25
+ */
26
+ private setupTerminalHandlers;
27
+ /**
28
+ * Setup file event handlers
29
+ */
30
+ private setupFileHandlers;
31
+ /**
32
+ * Resolve git cwd - handles ~ expansion and field name compatibility
33
+ */
34
+ private resolveGitCwd;
35
+ /**
36
+ * Setup Git event handlers
37
+ */
38
+ private setupGitHandlers;
39
+ /**
40
+ * Send system info to server
41
+ */
42
+ private sendSystemInfo;
43
+ /**
44
+ * Start heartbeat timer
45
+ */
46
+ private startHeartbeat;
47
+ /**
48
+ * Stop heartbeat timer
49
+ */
50
+ private stopHeartbeat;
51
+ /**
52
+ * Disconnect from server
53
+ */
54
+ disconnect(): void;
55
+ /**
56
+ * Check if connected
57
+ */
58
+ get connected(): boolean;
59
+ }
60
+ //# sourceMappingURL=websocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,WAAW,EAA0B,MAAM,aAAa,CAAA;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,WAAW,CAAQ;gBAEf,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU;IAOnH;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiF9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAkH7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA4NzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAQrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsTxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;OAEG;IACH,OAAO,CAAC,cAAc;IAuBtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,UAAU,IAAI,IAAI;IAOlB;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;CACF"}