{"repository":{"owner":"iamkaf","name":"gh-tree","description":"A minimalist API for fetching recursive file trees from public GitHub repositories.","stars":0,"forks":0,"watchers":0,"language":"TypeScript","default_branch":"main","html_url":"https://github.com/iamkaf/gh-tree","updated_at":"2026-03-07T09:46:07Z","homepage":"https://gh.kaf.sh","topics":["api","astro","cloudflare","github"],"license":"MIT License","readme":"# gh-tree\n\nA minimalist API for fetching recursive file trees from public GitHub repositories.\n\n## API\n\n### Endpoint\n\n```\nGET /api/:user/:repo\n```\n\n```\nGET /api/:user/:repo/contents?path=src/index.ts\n```\n\n### Query Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `depth` | number | Maximum tree depth (unlimited if omitted) |\n| `format` | string | Output format: `tree` (default) or `plain` |\n| `filter` | string | Glob pattern to filter files (e.g., `*.ts`, `src/*`) |\n\n### Response\n\n```json\n{\n  \"repository\": {\n    \"owner\": \"iamkaf\",\n    \"name\": \"gh-tree\",\n    \"description\": \"...\",\n    \"stars\": 42,\n    \"forks\": 10,\n    \"watchers\": 42,\n    \"language\": \"TypeScript\",\n    \"default_branch\": \"main\",\n    \"html_url\": \"https://github.com/iamkaf/gh-tree\",\n    \"updated_at\": \"2026-01-23T00:00:00Z\",\n    \"homepage\": null,\n    \"topics\": [\"api\", \"github\"],\n    \"license\": \"MIT\",\n    \"readme\": \"# gh-tree\\n\\n...\"\n  },\n  \"tree\": \"├── functions\\n│   └── api\\n│       ├── [user]\\n│       │   └── [repo].ts\\n│       └── types.ts\\n└── ...\",\n  \"files\": [\n    \"LICENSE\",\n    \"README.md\",\n    \"package.json\",\n    \"tsconfig.json\",\n    \"wrangler.toml\",\n    \"functions/api/types.ts\",\n    \"functions/api/[user]/[repo].ts\",\n    \"...\"\n  ],\n  \"stats\": {\n    \"total_files\": 42,\n    \"total_size\": 123456,\n    \"by_extension\": {\n      \".ts\": 15,\n      \".astro\": 3,\n      \".json\": 5,\n      \"(no extension)\": 4\n    }\n  },\n  \"meta\": {\n    \"cached\": false,\n    \"generated_at\": \"2026-01-23T00:00:00Z\",\n    \"truncated\": false,\n    \"params\": {\n      \"depth\": 2,\n      \"format\": \"tree\"\n    }\n  }\n}\n```\n\n### Examples\n\n```bash\n# Basic request\ncurl \"https://gh.kaf.sh/api/iamkaf/gh-tree\"\n\n# With depth limit\ncurl \"https://gh.kaf.sh/api/iamkaf/gh-tree?depth=2\"\n\n# Plain text format\ncurl \"https://gh.kaf.sh/api/iamkaf/gh-tree?format=plain\"\n\n# Filter by pattern\ncurl \"https://gh.kaf.sh/api/iamkaf/gh-tree?filter=*.ts\"\n\n# Combined parameters\ncurl \"https://gh.kaf.sh/api/iamkaf/gh-tree?depth=3&format=plain&filter=src/*\"\n\n# File contents\ncurl \"https://gh.kaf.sh/api/iamkaf/gh-tree/contents?path=functions/api/types.ts\"\n\n# File contents from a specific branch or tag\ncurl \"https://gh.kaf.sh/api/iamkaf/gh-tree/contents?path=README.md&ref=main\"\n```\n\n### File Contents Response\n\n```json\n{\n  \"path\": \"functions/api/types.ts\",\n  \"name\": \"types.ts\",\n  \"size\": 1234,\n  \"sha\": \"abc123\",\n  \"encoding\": \"utf-8\",\n  \"content\": \"export interface GitHubRepo { ... }\",\n  \"url\": \"https://api.github.com/repos/iamkaf/gh-tree/contents/functions/api/types.ts\",\n  \"html_url\": \"https://github.com/iamkaf/gh-tree/blob/main/functions/api/types.ts\",\n  \"download_url\": \"https://raw.githubusercontent.com/iamkaf/gh-tree/main/functions/api/types.ts\",\n  \"meta\": {\n    \"cached\": false,\n    \"generated_at\": \"2026-01-23T00:00:00Z\",\n    \"ref\": \"main\"\n  }\n}\n```\n\n```javascript\n// JavaScript/TypeScript\nfetch(\"https://gh.kaf.sh/api/iamkaf/gh-tree\")\n  .then(res => res.json())\n  .then(data => console.log(data));\n```\n\n```python\n# Python\nimport requests\n\nresponse = requests.get(\"https://gh.kaf.sh/api/iamkaf/gh-tree\")\ndata = response.json()\nprint(data)\n```\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run Astro dev server\nnpm run dev\n\n# Run Cloudflare Pages Functions locally (requires wrangler)\nnpx wrangler pages dev\n```\n\n## Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| `GITHUB_TOKEN` | GitHub Personal Access Token for increased rate limits |\n| `GH_TREE_CACHE` | Cloudflare KV namespace for response caching |\n\n## Deployment\n\nBuilt with [Astro](https://astro.build) and [Cloudflare Pages Functions](https://pages.cloudflare.com/functions/).\n"},"tree":"├── .vscode\n│   ├── extensions.json\n│   └── launch.json\n├── functions\n│   └── api\n│       ├── [user]\n│       │   ├── [repo]\n│       │   │   └── contents.ts\n│       │   └── [repo].ts\n│       └── types.ts\n├── public\n│   ├── favicon.ico\n│   └── favicon.svg\n├── src\n│   ├── layouts\n│   │   └── Layout.astro\n│   ├── pages\n│   │   └── index.astro\n│   ├── styles\n│   │   └── global.css\n│   └── types.ts\n├── .gitignore\n├── astro.config.mjs\n├── LICENSE\n├── package-lock.json\n├── package.json\n├── README.md\n├── tsconfig.json\n├── worker-configuration.d.ts\n└── wrangler.toml","files":[".gitignore","astro.config.mjs","LICENSE","package-lock.json","package.json","README.md","tsconfig.json","worker-configuration.d.ts","wrangler.toml",".vscode/extensions.json",".vscode/launch.json","public/favicon.ico","public/favicon.svg","src/types.ts","functions/api/types.ts","src/layouts/Layout.astro","src/pages/index.astro","src/styles/global.css","functions/api/[user]/[repo].ts","functions/api/[user]/[repo]/contents.ts"],"stats":{"total_files":20,"total_size":683716,"by_extension":{".gitignore":1,".json":5,"(no extension)":1,".md":1,".mjs":1,".ts":5,".ico":1,".svg":1,".astro":2,".css":1,".toml":1}},"meta":{"cached":false,"generated_at":"2026-05-09T02:37:31.140Z","truncated":false}}