| 109 | } |
| 110 | |
| 111 | async function createZip(files: FileEntry[]): Promise<Buffer> { |
| 112 | const zip = new JSZip() |
| 113 | |
| 114 | const readme = `# Arctic Configuration Backup |
| 115 | Generated: ${new Date().toISOString()} |
| 116 | |
| 117 | ## Structure |
| 118 | |
| 119 | - global/ - Files from ~/.config/arctic/ |
| 120 | - project/ - Files from your project's .arctic/ directory and root config files |
| 121 | |
| 122 | ## Restore Instructions |
| 123 | |
| 124 | To restore this configuration, use the \`/config-import\` command (coming soon) or manually: |
| 125 | |
| 126 | 1. Extract this zip file |
| 127 | 2. Copy files from global/ to ~/.config/arctic/ |
| 128 | 3. Copy files from project/ to your project directory |
| 129 | |
| 130 | Note: Auth tokens are NOT included in this backup for security reasons. |
| 131 | ` |
| 132 | |
| 133 | zip.file("README.md", readme) |
| 134 | |
| 135 | for (const file of files) { |
| 136 | zip.file(file.relativePath, file.content) |
| 137 | log.debug("added to zip", { relativePath: file.relativePath }) |
| 138 | } |
| 139 | |
| 140 | const buffer = await zip.generateAsync({ |
| 141 | type: "nodebuffer", |
| 142 | compression: "DEFLATE", |
| 143 | compressionOptions: { |
| 144 | level: 9, |
| 145 | }, |
| 146 | }) |
| 147 | |
| 148 | return buffer |
| 149 | } |
| 150 | |
| 151 | export async function backup(): Promise<Buffer> { |
| 152 | log.info("starting config backup") |