@prmichaelsen/acp-mcp 0.7.1 → 1.0.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.
@@ -1,107 +0,0 @@
1
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
- import { SSHConnectionManager } from '../utils/ssh-connection.js';
3
- import { logger } from '../utils/logger.js';
4
-
5
- export const acpRemoteWriteFileTool: Tool = {
6
- name: 'acp_remote_write_file',
7
- description: 'Write file contents to the remote machine via SSH',
8
- inputSchema: {
9
- type: 'object',
10
- properties: {
11
- path: {
12
- type: 'string',
13
- description: 'Absolute path to file',
14
- },
15
- content: {
16
- type: 'string',
17
- description: 'File contents to write',
18
- },
19
- encoding: {
20
- type: 'string',
21
- description: 'File encoding (default: utf-8)',
22
- default: 'utf-8',
23
- },
24
- createDirs: {
25
- type: 'boolean',
26
- description: 'Create parent directories if they don\'t exist (default: false)',
27
- default: false,
28
- },
29
- backup: {
30
- type: 'boolean',
31
- description: 'Backup existing file before overwriting (default: false)',
32
- default: false,
33
- },
34
- },
35
- required: ['path', 'content'],
36
- },
37
- };
38
-
39
- interface WriteFileArgs {
40
- path: string;
41
- content: string;
42
- encoding?: string;
43
- createDirs?: boolean;
44
- backup?: boolean;
45
- }
46
-
47
- interface WriteFileResult {
48
- success: boolean;
49
- bytesWritten: number;
50
- backupPath?: string;
51
- }
52
-
53
- /**
54
- * Handle the acp_remote_write_file tool invocation
55
- * Writes file contents to the remote machine via SSH
56
- *
57
- * @param args - Tool arguments containing path, content, and options
58
- * @param sshConnection - SSH connection manager for remote operations
59
- */
60
- export async function handleAcpRemoteWriteFile(
61
- args: any,
62
- sshConnection: SSHConnectionManager
63
- ): Promise<{ content: Array<{ type: string; text: string }> }> {
64
- const { path, content, encoding = 'utf-8', createDirs = false, backup = false } = args as WriteFileArgs;
65
-
66
- logger.debug('Writing remote file', { path, contentSize: content.length, encoding, createDirs, backup });
67
-
68
- try {
69
- const result = await sshConnection.writeFile(path, content, {
70
- encoding,
71
- createDirs,
72
- backup,
73
- });
74
-
75
- logger.debug('File write successful', { path, bytesWritten: result.bytesWritten, backupPath: result.backupPath });
76
-
77
- const output: WriteFileResult = {
78
- success: result.success,
79
- bytesWritten: result.bytesWritten,
80
- backupPath: result.backupPath,
81
- };
82
-
83
- return {
84
- content: [
85
- {
86
- type: 'text',
87
- text: JSON.stringify(output, null, 2),
88
- },
89
- ],
90
- };
91
- } catch (error) {
92
- const errorMessage = error instanceof Error ? error.message : String(error);
93
- logger.error('File write error', { path, error: errorMessage });
94
- return {
95
- content: [
96
- {
97
- type: 'text',
98
- text: JSON.stringify({
99
- success: false,
100
- bytesWritten: 0,
101
- error: errorMessage,
102
- }, null, 2),
103
- },
104
- ],
105
- };
106
- }
107
- }
@@ -1,123 +0,0 @@
1
- /**
2
- * Comprehensive file entry with metadata
3
- */
4
- export interface FileEntry {
5
- /** Filename (without path) */
6
- name: string;
7
-
8
- /** Absolute path to file */
9
- path: string;
10
-
11
- /** File type */
12
- type: 'file' | 'directory' | 'symlink' | 'other';
13
-
14
- /** File size in bytes */
15
- size: number;
16
-
17
- /** File permissions */
18
- permissions: {
19
- /** Octal mode (e.g., 0o644) */
20
- mode: number;
21
-
22
- /** Human-readable string (e.g., "rw-r--r--") */
23
- string: string;
24
-
25
- /** Owner permissions */
26
- owner: {
27
- read: boolean;
28
- write: boolean;
29
- execute: boolean;
30
- };
31
-
32
- /** Group permissions */
33
- group: {
34
- read: boolean;
35
- write: boolean;
36
- execute: boolean;
37
- };
38
-
39
- /** Others permissions */
40
- others: {
41
- read: boolean;
42
- write: boolean;
43
- execute: boolean;
44
- };
45
- };
46
-
47
- /** File ownership */
48
- owner: {
49
- /** User ID */
50
- uid: number;
51
-
52
- /** Group ID */
53
- gid: number;
54
- };
55
-
56
- /** File timestamps */
57
- timestamps: {
58
- /** Last access time (ISO 8601) */
59
- accessed: string;
60
-
61
- /** Last modification time (ISO 8601) */
62
- modified: string;
63
- };
64
- }
65
-
66
- /**
67
- * Convert Unix mode to human-readable permission string
68
- * @param mode - Unix file mode (e.g., 33188 for -rw-r--r--)
69
- * @returns Permission string (e.g., "rw-r--r--")
70
- */
71
- export function modeToPermissionString(mode: number): string {
72
- const perms = [
73
- (mode & 0o400) ? 'r' : '-',
74
- (mode & 0o200) ? 'w' : '-',
75
- (mode & 0o100) ? 'x' : '-',
76
- (mode & 0o040) ? 'r' : '-',
77
- (mode & 0o020) ? 'w' : '-',
78
- (mode & 0o010) ? 'x' : '-',
79
- (mode & 0o004) ? 'r' : '-',
80
- (mode & 0o002) ? 'w' : '-',
81
- (mode & 0o001) ? 'x' : '-',
82
- ];
83
- return perms.join('');
84
- }
85
-
86
- /**
87
- * Parse Unix mode into structured permissions object
88
- * @param mode - Unix file mode
89
- * @returns Structured permissions object
90
- */
91
- export function parsePermissions(mode: number) {
92
- return {
93
- mode,
94
- string: modeToPermissionString(mode),
95
- owner: {
96
- read: (mode & 0o400) !== 0,
97
- write: (mode & 0o200) !== 0,
98
- execute: (mode & 0o100) !== 0,
99
- },
100
- group: {
101
- read: (mode & 0o040) !== 0,
102
- write: (mode & 0o020) !== 0,
103
- execute: (mode & 0o010) !== 0,
104
- },
105
- others: {
106
- read: (mode & 0o004) !== 0,
107
- write: (mode & 0o002) !== 0,
108
- execute: (mode & 0o001) !== 0,
109
- },
110
- };
111
- }
112
-
113
- /**
114
- * Determine file type from SFTP stats
115
- * @param stats - SFTP file stats
116
- * @returns File type string
117
- */
118
- export function getFileType(stats: any): 'file' | 'directory' | 'symlink' | 'other' {
119
- if (stats.isDirectory()) return 'directory';
120
- if (stats.isFile()) return 'file';
121
- if (stats.isSymbolicLink()) return 'symlink';
122
- return 'other';
123
- }