[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KMCGHPM768YFDXNJD7T2SA":3,"skill-same:01M6KMCGHPM768YFDXNJD7T2SA":62},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":21,"linkOnly":22,"markdownContent":23,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":13,"repositoryHtmlUrl":28,"repositoryHomepageUrl":6,"ownerHtmlUrl":29,"ownerBlogUrl":6,"ownerDescription":30,"updatedAt":31,"install":32,"resources":45},"01M6KMCGHPM768YFDXNJD7T2SA","file-operations",null,"ahvcxa\u002Fagents-runtime","ahvcxa","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F66177097?v=4","01M6KMC1M42AY53F851R4PYQ86","BATUHAN INAN","01M6KMC1QYQESNZDK2PP0J9FJG",0,"MIT","https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftemplate\u002F.agents\u002Ffile-operations\u002FSKILL.md",[],[18,19,20],"file","file operations","operations","2026-11-10 10:12:30",false,"# File Operations Skill\n\nRead, write, append, and delete files with sandbox mode protection. All operations are restricted to the `\u002F.agents\u002Fworkspace\u002F` directory.\n\n## Quick Start\n\n```javascript\nconst { execute } = require('.\u002F.agents\u002Fskills\u002Ffile-operations\u002Fhandler');\n\n\u002F\u002F Read a file\nconst result = await execute({\n  operation: 'read',\n  path: 'data.json'\n});\n\nif (result.success) {\n  console.log(result.data.content);\n} else {\n  console.error('Error:', result.error.code);\n}\n```\n\n## Features\n\n### ✅ Sandbox Mode\n- **Restricted Access**: All operations confined to `\u002F.agents\u002Fworkspace\u002F` directory\n- **Path Traversal Prevention**: `..\u002F` attacks are blocked\n- **Blocked Files**: No access to `.env`, `.git`, `node_modules`, etc.\n- **Safe by Default**: No symlink following, limited permissions\n\n### ✅ Security\n- **Size Limits**: Maximum 10MB per file to prevent exhaustion\n- **Permission Control**: Files created with restricted permissions (0644)\n- **Validation**: All paths normalized and validated\n- **Audit Trail**: All operations logged (in logging skill)\n\n### ✅ Reliability\n- **Atomic Operations**: Use standard Node.js fs API\n- **Error Handling**: Clear error codes for all failure modes\n- **Metadata Capture**: File stats (size, created, modified dates)\n\n## Parameters\n\n| Parameter | Type | Default | Required | Description |\n|-----------|------|---------|----------|-------------|\n| **operation** | string | - | ✅ | Operation: read, write, append, delete, exists, list |\n| **path** | string | - | ✅ | File\u002Fdirectory path (relative, within sandbox) |\n| **content** | string | - | - | File content (write\u002Fappend operations) |\n| **encoding** | string | utf-8 | - | File encoding (utf-8, ascii, base64) |\n| **createDirs** | boolean | false | - | Create parent directories (write\u002Fappend only) |\n\n## Operations\n\n### READ - Get file contents\n\n```javascript\nconst result = await execute({\n  operation: 'read',\n  path: 'config.json',\n  encoding: 'utf-8'\n});\n\n\u002F\u002F Response\n{\n  success: true,\n  data: {\n    content: '{\"app\": \"example\"}',\n    size: 20,\n    created: '2026-04-06T12:00:00.000Z',\n    modified: '2026-04-07T14:30:00.000Z'\n  }\n}\n```\n\n### WRITE - Create or overwrite file\n\n```javascript\nconst result = await execute({\n  operation: 'write',\n  path: 'output.txt',\n  content: 'Hello, World!',\n  createDirs: true  \u002F\u002F Create parent dirs if needed\n});\n\n\u002F\u002F Response\n{\n  success: true,\n  data: {\n    path: 'output.txt',\n    size: 13\n  }\n}\n```\n\n### APPEND - Add content to file\n\n```javascript\nconst result = await execute({\n  operation: 'append',\n  path: 'logs.txt',\n  content: '[INFO] Application started\\n'\n});\n\n\u002F\u002F Response\n{\n  success: true,\n  data: {\n    path: 'logs.txt',\n    size: 1024  \u002F\u002F Total file size after append\n  }\n}\n```\n\n### DELETE - Remove file\n\n```javascript\nconst result = await execute({\n  operation: 'delete',\n  path: 'temp-data.json'\n});\n\n\u002F\u002F Response\n{\n  success: true,\n  data: {\n    deleted: true\n  }\n}\n```\n\n### EXISTS - Check if file\u002Fdirectory exists\n\n```javascript\nconst result = await execute({\n  operation: 'exists',\n  path: 'config.json'\n});\n\n\u002F\u002F Response\n{\n  success: true,\n  data: {\n    exists: true  \u002F\u002F or false\n  }\n}\n```\n\n### LIST - Directory contents\n\n```javascript\nconst result = await execute({\n  operation: 'list',\n  path: 'data'  \u002F\u002F or '.' for root\n});\n\n\u002F\u002F Response\n{\n  success: true,\n  data: {\n    files: ['config.json', 'data.csv'],\n    directories: ['logs', 'cache'],\n    count: 4\n  }\n}\n```\n\n## Response Format\n\n### Success Response\n\n```javascript\n{\n  success: true,\n  data: {\n    \u002F\u002F Structure varies by operation\n    content: \"...\",     \u002F\u002F read\n    path: \"...\",        \u002F\u002F write\u002Fappend\n    exists: true,       \u002F\u002F exists\n    deleted: true,      \u002F\u002F delete\n    files: [...],       \u002F\u002F list\n    directories: [...]\n  },\n  error: null,\n  metadata: {\n    executionTime: 5,\n    timestamp: \"2026-04-07T...\"\n  }\n}\n```\n\n### Error Response\n\n```javascript\n{\n  success: false,\n  data: null,\n  error: {\n    code: \"FILE_NOT_FOUND\",\n    message: \"File or directory not found\",\n    details: {\n      nodeError: \"ENOENT\"\n    }\n  },\n  metadata: {\n    executionTime: 2,\n    timestamp: \"2026-04-07T...\"\n  }\n}\n```\n\n## Error Codes\n\n| Code | Cause | Notes |\n|------|-------|-------|\n| **FILE_NOT_FOUND** | File doesn't exist | Check path and parent directory |\n| **PERMISSION_DENIED** | Cannot access file | Check permissions in workspace |\n| **IS_DIRECTORY** | Path is a directory, not a file | Use list operation instead |\n| **NOT_DIRECTORY** | Path is not a directory | Use file operations instead |\n| **FILE_TOO_LARGE** | File exceeds 10MB limit | Split into smaller files |\n| **SANDBOX_VIOLATION** | Path outside workspace | All operations confined to \u002F.agents\u002Fworkspace\u002F |\n| **PATH_TRAVERSAL_ATTEMPT** | `..\u002F` or absolute path used | Use relative paths only |\n| **BLOCKED_FILE** | Access to restricted file | .env, .git, etc. are blocked |\n| **FILE_OPERATION_FAILED** | Generic file system error | Check error details |\n\n## Workspace Directory\n\nAll operations use this directory:\n\n```\n\u002F.agents\u002Fworkspace\u002F\n├── config.json\n├── data\u002F\n│   ├── users.csv\n│   └── settings.json\n├── logs\u002F\n│   └── app.log\n└── cache\u002F\n    └── ...\n```\n\nCreate and organize your files here. The workspace persists between agent executions.\n\n## Examples\n\n### 1. Read JSON Configuration\n\n```javascript\nconst result = await execute({\n  operation: 'read',\n  path: 'config.json'\n});\n\nif (result.success) {\n  const config = JSON.parse(result.data.content);\n  console.log('API URL:', config.apiUrl);\n}\n```\n\n### 2. Write Results to File\n\n```javascript\nconst results = { processed: 100, errors: 2 };\n\nawait execute({\n  operation: 'write',\n  path: 'results.json',\n  content: JSON.stringify(results, null, 2),\n  createDirs: true\n});\n```\n\n### 3. Append Log Entry\n\n```javascript\nconst timestamp = new Date().toISOString();\nconst logEntry = `[${timestamp}] Processing completed\\n`;\n\nawait execute({\n  operation: 'append',\n  path: 'logs\u002Fapp.log',\n  content: logEntry,\n  createDirs: true\n});\n```\n\n### 4. Process Multiple Files\n\n```javascript\n\u002F\u002F List files in data directory\nconst listResult = await execute({\n  operation: 'list',\n  path: 'data'\n});\n\n\u002F\u002F Process each CSV file\nfor (const file of listResult.data.files.filter(f => f.endsWith('.csv'))) {\n  const readResult = await execute({\n    operation: 'read',\n    path: `data\u002F${file}`\n  });\n  \n  if (readResult.success) {\n    \u002F\u002F Process CSV content\n    const lines = readResult.data.content.split('\\n');\n    console.log(`${file}: ${lines.length} lines`);\n  }\n}\n```\n\n### 5. Safe File Update with Backup\n\n```javascript\n\u002F\u002F Create backup\nconst original = await execute({\n  operation: 'read',\n  path: 'important.json'\n});\n\nawait execute({\n  operation: 'write',\n  path: 'important.json.backup',\n  content: original.data.content\n});\n\n\u002F\u002F Update original\nawait execute({\n  operation: 'write',\n  path: 'important.json',\n  content: JSON.stringify(newData, null, 2)\n});\n```\n\n### 6. Check Before Creating\n\n```javascript\nconst checkResult = await execute({\n  operation: 'exists',\n  path: 'output.csv'\n});\n\nif (!checkResult.data.exists) {\n  \u002F\u002F Create new file\n  await execute({\n    operation: 'write',\n    path: 'output.csv',\n    content: 'header1,header2\\n'\n  });\n} else {\n  \u002F\u002F Append to existing\n  await execute({\n    operation: 'append',\n    path: 'output.csv',\n    content: 'value1,value2\\n'\n  });\n}\n```\n\n### 7. Large File Handling\n\n```javascript\n\u002F\u002F For files > 10MB, write in chunks\nconst largeData = generateData(); \u002F\u002F In parts\nconst chunkSize = 5 * 1024 * 1024; \u002F\u002F 5MB\n\nfor (let i = 0; i \u003C largeData.length; i += chunkSize) {\n  const chunk = largeData.slice(i, i + chunkSize);\n  \n  if (i === 0) {\n    \u002F\u002F First chunk: write (overwrite)\n    await execute({\n      operation: 'write',\n      path: 'large-file.bin',\n      content: chunk\n    });\n  } else {\n    \u002F\u002F Subsequent chunks: append\n    await execute({\n      operation: 'append',\n      path: 'large-file.bin',\n      content: chunk\n    });\n  }\n}\n```\n\n## Security Best Practices\n\n### 1. Validate File Paths\n\n```javascript\n\u002F\u002F Good - Safe relative path\nawait execute({\n  operation: 'read',\n  path: 'config.json'\n});\n\n\u002F\u002F Bad - Absolute path (blocked)\nawait execute({\n  operation: 'read',\n  path: '\u002Fetc\u002Fpasswd'  \u002F\u002F ERROR: Sandbox violation\n});\n\n\u002F\u002F Bad - Path traversal (blocked)\nawait execute({\n  operation: 'read',\n  path: '..\u002F..\u002F.env'   \u002F\u002F ERROR: Path traversal\n});\n```\n\n### 2. Don't Store Secrets\n\n```javascript\n\u002F\u002F Good - Store in environment or secure vault\nconst apiKey = process.env.API_KEY;\n\n\u002F\u002F Bad - Don't write secrets to files\nawait execute({\n  operation: 'write',\n  path: 'api-key.txt',\n  content: apiKey  \u002F\u002F SECURITY RISK\n});\n```\n\n### 3. Sanitize User Input\n\n```javascript\n\u002F\u002F Good - Validate filename\nfunction getSafePath(userInput) {\n  const sanitized = path.basename(userInput); \u002F\u002F Remove path components\n  if (!sanitized || sanitized.startsWith('.')) {\n    throw new Error('Invalid filename');\n  }\n  return `data\u002F${sanitized}`;\n}\n\n\u002F\u002F Bad - Use user input directly\nconst userFile = userInput;  \u002F\u002F Could be '..\u002F..\u002F.env'\nawait execute({\n  operation: 'read',\n  path: userFile  \u002F\u002F Vulnerable!\n});\n```\n\n### 4. Handle Errors Safely\n\n```javascript\n\u002F\u002F Good - Check for specific errors\nconst result = await execute({\n  operation: 'read',\n  path: userProvidedPath\n});\n\nif (result.error?.code === 'SANDBOX_VIOLATION') {\n  console.error('Attempted sandbox escape');\n} else if (!result.success) {\n  console.error('File operation failed:', result.error.message);\n}\n\n\u002F\u002F Bad - Log entire error object\nconsole.error('Error:', result);  \u002F\u002F Could expose secrets\n```\n\n## Limitations\n\n1. **Sandbox Only**: All operations in `\u002F.agents\u002Fworkspace\u002F` directory\n2. **No Symlinks**: Symbolic links are not followed\n3. **10MB Limit**: Maximum file size per operation\n4. **No Binary**: Only text encoding supported (utf-8, ascii, base64)\n5. **No Permissions**: Cannot change file ownership or detailed permissions\n6. **No Streaming**: Entire file loaded into memory\n\n## Performance Tips\n\n1. **Batch Operations**: Use list() to read directory structure once\n2. **Size Check**: Check file size before read operations on large files\n3. **Append Efficiently**: Use append() for log files instead of read-modify-write\n4. **No Realtime Monitoring**: Use filesystem polling for file changes\n5. **Chunk Large Data**: Split > 5MB data into chunks\n\n## Related Skills\n\n- **data-transform**: Parse JSON\u002FCSV files\n- **logging**: Write structured logs\n- **http-request**: Save HTTP responses\n- **system-command**: Process files with CLI tools\n\n## Troubleshooting\n\n### \"SANDBOX_VIOLATION\" Error\n\n**Cause**: Attempted to access file outside `\u002F.agents\u002Fworkspace\u002F`\n\n**Solution**: Use relative paths within sandbox\n\n```javascript\n\u002F\u002F ✅ Correct\nawait execute({ operation: 'read', path: 'data.json' });\n\n\u002F\u002F ❌ Wrong\nawait execute({ operation: 'read', path: '\u002Fhome\u002Fuser\u002Ffile.json' });\n```\n\n### \"FILE_NOT_FOUND\" Error\n\n**Cause**: File doesn't exist\n\n**Solution**: Check path or create with write operation\n\n```javascript\nconst exists = await execute({ operation: 'exists', path: 'file.txt' });\nif (!exists.data.exists) {\n  await execute({\n    operation: 'write',\n    path: 'file.txt',\n    content: 'initial content'\n  });\n}\n```\n\n### \"FILE_TOO_LARGE\" Error\n\n**Cause**: File exceeds 10MB limit\n\n**Solution**: Use streaming or process in chunks (see examples)\n\n---\n\n**Version**: 1.0.0  \n**Last Updated**: 2026-04-07\n",{},"main","f660bfb38f1f58be7aa35b3e67f77b2add4b048a","template\u002F.agents\u002Ffile-operations","https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime","https:\u002F\u002Fgithub.com\u002Fahvcxa","🍀 Data Scientist 🍀","2026-04-13 01:43:13",{"source":7,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add ahvcxa\u002Fagents-runtime --skill file-operations",{"tool":38,"command":39},"bunx","bunx skills add ahvcxa\u002Fagents-runtime --skill file-operations",{"tool":41,"command":42},"pnpm","pnpm dlx skills add ahvcxa\u002Fagents-runtime --skill file-operations","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftemplate\u002F.agents\u002Ffile-operations\u002FSKILL.md",true,[46,52,56],{"path":47,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":50,"sourceHtmlUrl":51},"__tests__\u002Fhandler.test.js","SCRIPT","脚本",1679,"https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftemplate\u002F.agents\u002Ffile-operations\u002F__tests__\u002Fhandler.test.js",{"path":53,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":54,"sourceHtmlUrl":55},"handler.js",8064,"https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftemplate\u002F.agents\u002Ffile-operations\u002Fhandler.js",{"path":57,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":61},"manifest.json","REFERENCE","参考文档",4397,"https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftemplate\u002F.agents\u002Ffile-operations\u002Fmanifest.json",[63,74,87,100,112,119],{"skillNo":64,"name":65,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":66,"categories":67,"keywords":68,"publishedAt":21},"01M6KMDCFV4G3TY0VCFA65NVA4","security-audit","https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fproject\u002F.agents\u002Fskills\u002Fsecurity-audit\u002FSKILL.md",[],[69,70,71,72,65,73],"security","audit","security audit","analysis","true",{"skillNo":75,"name":76,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":84,"publishedAt":21},"01M6KMD96V3XP64WZR6MJQQZ8M","refactor","https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fproject\u002F.agents\u002Fskills\u002Frefactor\u002FSKILL.md",[79],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000007","代码审查","SCENARIO","使用场景",[76,85,86],"false","transformation",{"skillNo":88,"name":89,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":97,"publishedAt":21},"01M6KMD7A4W1DAJPQBAHVXCNBR","code-analysis","https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fproject\u002F.agents\u002Fskills\u002Fcode-analysis\u002FSKILL.md",[92],{"categoryNo":93,"categoryName":94,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[72,98,99,73,89],"code","code analysis",{"skillNo":101,"name":102,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":108,"publishedAt":21},"01M6KMD5AF1W8X1EFVZB0HS0JP","test-generator","https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftemplate\u002F.agents\u002Ftest-generator\u002FSKILL.md",[105],{"categoryNo":106,"categoryName":107,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000008","测试与质量",[109,110,111],"generator","test generator","test",{"skillNo":113,"name":65,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":21},"01M6KMD1Q19ES77DCKNZXCRTQA","https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftemplate\u002F.agents\u002Fsecurity-audit\u002FSKILL.md",[],[71,70,69,117,73,118,65,72],"handler","js",{"skillNo":120,"name":76,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":124,"publishedAt":21},"01M6KMCYTX2FXC810HE6RXTYTH","https:\u002F\u002Fgithub.com\u002Fahvcxa\u002Fagents-runtime\u002Fblob\u002Fmain\u002Ftemplate\u002F.agents\u002Frefactor\u002FSKILL.md",[123],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},[76,117,85,86,125,118,126],"patch","refactoring"]