or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connection-management.mddirectory-operations.mdfile-management.mdfile-operations.mdfilesystem-info.mdindex.mdstream-operations.md

file-management.mddocs/

0

# File Management

1

2

File management operations including deletion, renaming, permission changes, and remote file copying with advanced features like atomic operations.

3

4

## Capabilities

5

6

### Delete File

7

8

Deletes a file from the remote server with optional error suppression for missing files.

9

10

```javascript { .api }

11

/**

12

* Delete a file on the remote SFTP server

13

* @param remotePath - Path to file to delete

14

* @param notFoundOK - If true, ignore "file not found" errors (default: false)

15

* @param addListeners - Whether to add event listeners (default: true)

16

* @returns Promise resolving to success message

17

*/

18

delete(remotePath, notFoundOK = false, addListeners = true): Promise<String>;

19

```

20

21

**Usage Examples:**

22

23

```javascript

24

// Delete existing file

25

await sftp.delete('/remote/old-file.txt');

26

27

// Delete file, ignore if it doesn't exist

28

await sftp.delete('/remote/maybe-exists.txt', true);

29

30

// Safe deletion with existence check

31

const exists = await sftp.exists('/remote/temp-file.dat');

32

if (exists === '-') {

33

await sftp.delete('/remote/temp-file.dat');

34

console.log('Temporary file deleted');

35

}

36

37

// Bulk deletion with error handling

38

const filesToDelete = ['/remote/file1.txt', '/remote/file2.txt', '/remote/file3.txt'];

39

for (const file of filesToDelete) {

40

try {

41

await sftp.delete(file, true); // Ignore missing files

42

console.log(`Deleted: ${file}`);

43

} catch (err) {

44

console.error(`Failed to delete ${file}: ${err.message}`);

45

}

46

}

47

```

48

49

### Rename File

50

51

Renames or moves a file/directory on the remote server.

52

53

```javascript { .api }

54

/**

55

* Rename a file or directory on the remote server

56

* @param fromPath - Current path of file/directory

57

* @param toPath - New path for file/directory

58

* @param addListeners - Whether to add event listeners (default: true)

59

* @returns Promise resolving to success message

60

*/

61

rename(fromPath, toPath, addListeners = true): Promise<String>;

62

```

63

64

**Usage Examples:**

65

66

```javascript

67

// Simple file rename

68

await sftp.rename('/remote/old-name.txt', '/remote/new-name.txt');

69

70

// Move file to different directory

71

await sftp.rename('/remote/temp/file.dat', '/remote/archive/file.dat');

72

73

// Rename directory

74

await sftp.rename('/remote/old-folder', '/remote/new-folder');

75

76

// Safe rename with existence checks

77

const source = '/remote/source.txt';

78

const destination = '/remote/destination.txt';

79

80

const sourceExists = await sftp.exists(source);

81

const destExists = await sftp.exists(destination);

82

83

if (sourceExists === '-' && destExists === false) {

84

await sftp.rename(source, destination);

85

console.log('File renamed successfully');

86

} else if (destExists !== false) {

87

console.error('Destination already exists');

88

} else {

89

console.error('Source file does not exist');

90

}

91

```

92

93

### POSIX Rename

94

95

Performs atomic rename using the POSIX rename extension (SSH 4.8+).

96

97

```javascript { .api }

98

/**

99

* Rename using POSIX atomic rename extension

100

* @param fromPath - Current path of file/directory

101

* @param toPath - New path for file/directory

102

* @param addListeners - Whether to add event listeners (default: true)

103

* @returns Promise resolving to success message

104

*/

105

posixRename(fromPath, toPath, addListeners = true): Promise<String>;

106

```

107

108

**Important Note**: This method requires SSH server version 4.8 or higher with the posix-rename@openssh.com extension.

109

110

**Usage Examples:**

111

112

```javascript

113

// Atomic file rename (overwrites destination if exists)

114

await sftp.posixRename('/remote/temp.txt', '/remote/final.txt');

115

116

// Atomic directory rename

117

await sftp.posixRename('/remote/temp-dir', '/remote/final-dir');

118

119

// Safe atomic rename with server capability check

120

try {

121

await sftp.posixRename('/remote/source.dat', '/remote/target.dat');

122

console.log('Atomic rename completed');

123

} catch (err) {

124

if (err.message.includes('not supported')) {

125

console.log('Server does not support POSIX rename, using regular rename');

126

await sftp.rename('/remote/source.dat', '/remote/target.dat');

127

} else {

128

throw err;

129

}

130

}

131

```

132

133

### Change Permissions

134

135

Changes file or directory permissions on the remote server.

136

137

```javascript { .api }

138

/**

139

* Change permissions of remote file or directory

140

* @param rPath - Path to remote file/directory

141

* @param mode - New permissions (octal number or string)

142

* @param addListeners - Whether to add event listeners (default: true)

143

* @returns Promise resolving to success message

144

*/

145

chmod(rPath, mode, addListeners = true): Promise<String>;

146

```

147

148

**Usage Examples:**

149

150

```javascript

151

// Set file permissions using octal notation

152

await sftp.chmod('/remote/script.sh', 0o755); // rwxr-xr-x

153

154

// Set permissions using string notation

155

await sftp.chmod('/remote/data.txt', '644'); // rw-r--r--

156

157

// Make file executable

158

await sftp.chmod('/remote/program', 0o755);

159

160

// Remove write permissions for group and others

161

await sftp.chmod('/remote/private.txt', 0o600); // rw-------

162

163

// Bulk permission changes

164

const scripts = await sftp.list('/remote/scripts');

165

for (const file of scripts) {

166

if (file.type === '-' && file.name.endsWith('.sh')) {

167

await sftp.chmod(`/remote/scripts/${file.name}`, 0o755);

168

console.log(`Made ${file.name} executable`);

169

}

170

}

171

```

172

173

### Remote Copy

174

175

Creates a copy of a remote file on the remote server without downloading/uploading.

176

177

```javascript { .api }

178

/**

179

* Create a remote copy of a remote file

180

* @param src - Source file path on remote server

181

* @param dst - Destination file path on remote server

182

* @returns Promise resolving to success message

183

*/

184

rcopy(src, dst): Promise<String>;

185

```

186

187

**Usage Examples:**

188

189

```javascript

190

// Create backup copy

191

await sftp.rcopy('/remote/important.txt', '/remote/important.txt.backup');

192

193

// Copy to different directory

194

await sftp.rcopy('/remote/config.json', '/remote/backup/config.json');

195

196

// Copy with timestamp

197

const timestamp = new Date().toISOString().replace(/[:.]/g, '-');

198

const backupName = `/remote/data-${timestamp}.json`;

199

await sftp.rcopy('/remote/data.json', backupName);

200

201

// Safe copy with checks

202

const source = '/remote/master.conf';

203

const backup = '/remote/master.conf.bak';

204

205

const sourceExists = await sftp.exists(source);

206

const backupExists = await sftp.exists(backup);

207

208

if (sourceExists === '-') {

209

if (backupExists !== false) {

210

// Remove old backup first

211

await sftp.delete(backup);

212

}

213

await sftp.rcopy(source, backup);

214

console.log('Backup created successfully');

215

}

216

```

217

218

## Permission Management

219

220

### Octal Permission Values

221

222

Common permission patterns:

223

224

```javascript

225

// File permissions

226

0o644 // rw-r--r-- (readable by all, writable by owner)

227

0o600 // rw------- (readable/writable by owner only)

228

0o755 // rwxr-xr-x (executable by all, writable by owner)

229

0o700 // rwx------ (full access by owner only)

230

231

// Directory permissions

232

0o755 // rwxr-xr-x (standard directory permissions)

233

0o750 // rwxr-x--- (accessible by owner and group)

234

0o700 // rwx------ (accessible by owner only)

235

```

236

237

### Permission Checking and Setting

238

239

```javascript

240

// Check current permissions before changing

241

const stats = await sftp.stat('/remote/file.txt');

242

const currentMode = stats.mode & parseInt('777', 8);

243

console.log(`Current permissions: ${currentMode.toString(8)}`);

244

245

// Set restrictive permissions for sensitive files

246

if (stats.isFile && currentMode !== 0o600) {

247

await sftp.chmod('/remote/file.txt', 0o600);

248

console.log('Set restrictive permissions');

249

}

250

```

251

252

## Advanced File Management Patterns

253

254

### Atomic File Updates

255

256

```javascript

257

// Safe file update pattern using temporary file and rename

258

const targetFile = '/remote/config.json';

259

const tempFile = `/remote/config.json.tmp.${Date.now()}`;

260

261

try {

262

// Upload new content to temporary file

263

await sftp.put('/local/new-config.json', tempFile);

264

265

// Verify upload succeeded

266

const exists = await sftp.exists(tempFile);

267

if (exists === '-') {

268

// Atomically replace original file

269

await sftp.posixRename(tempFile, targetFile);

270

console.log('File updated atomically');

271

}

272

} catch (err) {

273

// Clean up temporary file on error

274

await sftp.delete(tempFile, true);

275

throw err;

276

}

277

```

278

279

### Backup Before Modify

280

281

```javascript

282

// Create backup before modifying important files

283

const originalFile = '/remote/database.conf';

284

const backupFile = `/remote/database.conf.backup.${Date.now()}`;

285

286

// Create backup

287

await sftp.rcopy(originalFile, backupFile);

288

289

try {

290

// Modify original file

291

await sftp.put('/local/new-database.conf', originalFile);

292

console.log('Configuration updated successfully');

293

} catch (err) {

294

// Restore from backup on error

295

console.log('Update failed, restoring backup');

296

await sftp.rename(backupFile, originalFile);

297

throw err;

298

}

299

```

300

301

### Cleanup Operations

302

303

```javascript

304

// Clean up old backup files

305

const backupPattern = /\.backup\.\d+$/;

306

const files = await sftp.list('/remote/backups');

307

308

const oldBackups = files.filter(file => {

309

if (file.type !== '-') return false;

310

if (!backupPattern.test(file.name)) return false;

311

312

// Keep backups newer than 7 days

313

const weekOld = Date.now() - (7 * 24 * 60 * 60 * 1000);

314

return file.modifyTime < weekOld;

315

});

316

317

for (const backup of oldBackups) {

318

await sftp.delete(`/remote/backups/${backup.name}`);

319

console.log(`Deleted old backup: ${backup.name}`);

320

}

321

```

322

323

## Error Handling

324

325

File management errors provide detailed context:

326

327

- `ENOENT`: File or directory does not exist

328

- `EACCES`: Permission denied

329

- `EEXIST`: Destination already exists (rename)

330

- `EISDIR`: Operation not supported on directory

331

- `ENOTDIR`: Parent is not a directory

332

- `EXDEV`: Cross-device operation not supported

333

- Server-specific errors for unsupported operations