Recursive directory copy (pure TypeScript, no external deps).
(src: string, dest: string)
| 37 | |
| 38 | /** Recursive directory copy (pure TypeScript, no external deps). */ |
| 39 | function copyDirSync(src: string, dest: string): void { |
| 40 | fs.mkdirSync(dest, { recursive: true }); |
| 41 | for (const entry of fs.readdirSync(src, { withFileTypes: true })) { |
| 42 | // Skip symlinks to avoid infinite recursion (e.g., .claude/skills/gstack → repo root) |
| 43 | if (entry.isSymbolicLink()) continue; |
| 44 | const srcPath = path.join(src, entry.name); |
| 45 | const destPath = path.join(dest, entry.name); |
| 46 | if (entry.isDirectory()) { |
| 47 | copyDirSync(srcPath, destPath); |
| 48 | } else { |
| 49 | fs.copyFileSync(srcPath, destPath); |
| 50 | } |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | /** Run a git command and return stdout. Throws on failure unless tolerateFailure is set. */ |
| 55 | function git(args: string[], cwd: string, tolerateFailure = false): string { |