mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-11 02:33:51 +08:00
feat: Enhance CLI components with icons and improve file editing capabilities
- Added icons to the CLI History and CLI Tools headers for better UI representation. - Updated CLI Status component to include tool-specific classes for styling. - Refactored CCW Install Panel to improve layout and functionality, including upgrade and uninstall buttons. - Enhanced the edit-file tool with new features: - Support for creating parent directories when writing files. - Added dryRun mode for previewing changes without modifying files. - Implemented a unified diff output for changes made. - Enabled multi-edit support in update mode. - Introduced a new Smart Search Tool with multiple search modes (auto, exact, fuzzy, semantic, graph) and intent classification. - Created a Write File Tool to handle file creation and overwriting with backup options.
This commit is contained in:
152
ccw/src/tools/write-file.js
Normal file
152
ccw/src/tools/write-file.js
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* Write File Tool - Create or overwrite files
|
||||
*
|
||||
* Features:
|
||||
* - Create new files or overwrite existing
|
||||
* - Auto-create parent directories
|
||||
* - Support for text content with proper encoding
|
||||
* - Optional backup before overwrite
|
||||
*/
|
||||
|
||||
import { writeFileSync, readFileSync, existsSync, mkdirSync, renameSync } from 'fs';
|
||||
import { resolve, isAbsolute, dirname, basename } from 'path';
|
||||
|
||||
/**
|
||||
* Ensure parent directory exists
|
||||
* @param {string} filePath - Path to file
|
||||
*/
|
||||
function ensureDir(filePath) {
|
||||
const dir = dirname(filePath);
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create backup of existing file
|
||||
* @param {string} filePath - Path to file
|
||||
* @returns {string|null} - Backup path or null if no backup created
|
||||
*/
|
||||
function createBackup(filePath) {
|
||||
if (!existsSync(filePath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const dir = dirname(filePath);
|
||||
const name = basename(filePath);
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||
const backupPath = resolve(dir, `.${name}.${timestamp}.bak`);
|
||||
|
||||
try {
|
||||
const content = readFileSync(filePath);
|
||||
writeFileSync(backupPath, content);
|
||||
return backupPath;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create backup: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute write file operation
|
||||
* @param {Object} params - Parameters
|
||||
* @returns {Promise<Object>} - Result
|
||||
*/
|
||||
async function execute(params) {
|
||||
const {
|
||||
path: filePath,
|
||||
content,
|
||||
createDirectories = true,
|
||||
backup = false,
|
||||
encoding = 'utf8'
|
||||
} = params;
|
||||
|
||||
if (!filePath) {
|
||||
throw new Error('Parameter "path" is required');
|
||||
}
|
||||
|
||||
if (content === undefined) {
|
||||
throw new Error('Parameter "content" is required');
|
||||
}
|
||||
|
||||
// Resolve path
|
||||
const resolvedPath = isAbsolute(filePath) ? filePath : resolve(process.cwd(), filePath);
|
||||
const fileExists = existsSync(resolvedPath);
|
||||
|
||||
// Create parent directories if needed
|
||||
if (createDirectories) {
|
||||
ensureDir(resolvedPath);
|
||||
} else if (!existsSync(dirname(resolvedPath))) {
|
||||
throw new Error(`Parent directory does not exist: ${dirname(resolvedPath)}`);
|
||||
}
|
||||
|
||||
// Create backup if requested and file exists
|
||||
let backupPath = null;
|
||||
if (backup && fileExists) {
|
||||
backupPath = createBackup(resolvedPath);
|
||||
}
|
||||
|
||||
// Write file
|
||||
try {
|
||||
writeFileSync(resolvedPath, content, { encoding });
|
||||
|
||||
return {
|
||||
success: true,
|
||||
path: resolvedPath,
|
||||
created: !fileExists,
|
||||
overwritten: fileExists,
|
||||
backupPath,
|
||||
bytes: Buffer.byteLength(content, encoding),
|
||||
message: fileExists
|
||||
? `Successfully overwrote ${filePath}${backupPath ? ` (backup: ${backupPath})` : ''}`
|
||||
: `Successfully created ${filePath}`
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to write file: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write File Tool Definition
|
||||
*/
|
||||
export const writeFileTool = {
|
||||
name: 'write_file',
|
||||
description: `Create a new file or overwrite an existing file with content.
|
||||
|
||||
Features:
|
||||
- Creates parent directories automatically (configurable)
|
||||
- Optional backup before overwrite
|
||||
- Supports text content with proper encoding
|
||||
|
||||
Use with caution as it will overwrite existing files without warning unless backup is enabled.`,
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
path: {
|
||||
type: 'string',
|
||||
description: 'Path to the file to create or overwrite'
|
||||
},
|
||||
content: {
|
||||
type: 'string',
|
||||
description: 'Content to write to the file'
|
||||
},
|
||||
createDirectories: {
|
||||
type: 'boolean',
|
||||
description: 'Create parent directories if they do not exist (default: true)',
|
||||
default: true
|
||||
},
|
||||
backup: {
|
||||
type: 'boolean',
|
||||
description: 'Create backup of existing file before overwriting (default: false)',
|
||||
default: false
|
||||
},
|
||||
encoding: {
|
||||
type: 'string',
|
||||
description: 'File encoding (default: utf8)',
|
||||
default: 'utf8',
|
||||
enum: ['utf8', 'utf-8', 'ascii', 'latin1', 'binary', 'hex', 'base64']
|
||||
}
|
||||
},
|
||||
required: ['path', 'content']
|
||||
},
|
||||
execute
|
||||
};
|
||||
Reference in New Issue
Block a user