{"id":49145062,"url":"https://github.com/sinameraji/kimiflare","last_synced_at":"2026-06-13T02:04:51.090Z","repository":{"id":352895955,"uuid":"1216978255","full_name":"sinameraji/kimiflare","owner":"sinameraji","description":"Terminal based coding agent \u0026 harness running on your own Cloudflare account. No middleman.","archived":false,"fork":false,"pushed_at":"2026-06-11T08:14:54.000Z","size":12835,"stargazers_count":155,"open_issues_count":11,"forks_count":14,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-11T08:15:26.687Z","etag":null,"topics":["agents","ai","aigateway","cloudflare","harness","kimi-k26","moonshot","vibe-coding","workers-ai"],"latest_commit_sha":null,"homepage":"https://kimiflare.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sinameraji.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["sinameraji"]}},"created_at":"2026-04-21T12:26:17.000Z","updated_at":"2026-06-11T08:13:44.000Z","dependencies_parsed_at":"2026-05-17T07:03:20.650Z","dependency_job_id":null,"html_url":"https://github.com/sinameraji/kimiflare","commit_stats":null,"previous_names":["sinameraji/kimiflare"],"tags_count":128,"template":false,"template_full_name":null,"purl":"pkg:github/sinameraji/kimiflare","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinameraji%2Fkimiflare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinameraji%2Fkimiflare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinameraji%2Fkimiflare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinameraji%2Fkimiflare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sinameraji","download_url":"https://codeload.github.com/sinameraji/kimiflare/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinameraji%2Fkimiflare/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34269365,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","ai","aigateway","cloudflare","harness","kimi-k26","moonshot","vibe-coding","workers-ai"],"created_at":"2026-04-22T03:00:44.707Z","updated_at":"2026-06-13T02:04:51.084Z","avatar_url":"https://github.com/sinameraji.png","language":"TypeScript","funding_links":["https://github.com/sponsors/sinameraji"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/logo.png\" alt=\"kimiflare\" width=\"180\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/kimiflare\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/kimiflare?style=flat-square\u0026color=cb3837\" alt=\"npm version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/kimiflare\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/kimiflare?style=flat-square\u0026color=cb3837\" alt=\"npm downloads\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/sinameraji/kimiflare/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/sinameraji/kimiflare?style=flat-square\u0026color=2ea44f\" alt=\"license\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/node-%3E%3D20-339933?style=flat-square\u0026logo=nodedotjs\u0026logoColor=white\" alt=\"Node.js \u003e= 20\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/typescript-5.7-3178c6?style=flat-square\u0026logo=typescript\u0026logoColor=white\" alt=\"TypeScript\"\u003e\n  \u003ca href=\"https://developers.cloudflare.com/workers-ai/models/kimi-k2\"\u003e\u003cimg src=\"https://img.shields.io/badge/powered%20by-Kimi%20K2.7-f59e0b?style=flat-square\" alt=\"Powered by Kimi K2.7\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eA terminal coding agent powered by \u003ca href=\"https://developers.cloudflare.com/workers-ai/models/kimi-k2\"\u003eKimi K2.7\u003c/a\u003e on \u003ca href=\"https://developers.cloudflare.com/workers-ai/\"\u003eCloudflare Workers AI\u003c/a\u003e — with optional routing through your own \u003ca href=\"https://developers.cloudflare.com/ai-gateway/\"\u003eAI Gateway\u003c/a\u003e for first-class observability, caching, and authoritative cost.\u003c/strong\u003e\u003cbr\u003e\n  All on your Cloudflare account.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/screenshot.png\" alt=\"kimiflare TUI\" width=\"900\"\u003e\n\u003c/p\u003e\n\n## How it works\n\nYou bring your own Cloudflare **Account ID** + **API Token**. KimiFlare calls **Workers AI** directly by default — fastest path, fewest moving parts. You can optionally turn on routing through an **AI Gateway** in your account (provisioned or reused on first run) for observability, caching, and cost reporting. Either way, nothing leaves your Cloudflare tenancy.\n\nWith AI Gateway enabled you get this for free:\n\n- **Per-request logs** with full payload, latency, and status — visible in the Cloudflare dashboard\n- **Response caching** with configurable TTL (`/gateway cache-ttl \u003cseconds\u003e`)\n- **Authoritative per-turn cost** pulled from the Gateway logs API — no estimates\n- **Cache-hit ratio and per-feature cost breakdown** in `/cost`\n- **Auto-tagging** of every request with `feature` / `sessionId` / `turnIdx` metadata for downstream attribution\n\n## What to remember\n\n- **262k context window** — Read entire modules, large configs, and full stack traces without the model losing track.\n- **Image understanding** — Drop image paths (PNG, JPG, WebP, GIF, BMP up to 5 MB) into any prompt. Great for UI reviews, diagrams, and screenshots.\n- **Plan / Edit / Auto modes** — `plan` is a whitelist-only research mode: only read-only tools (read, glob, grep, web search, GitHub read-only, browser fetch) are allowed. Writes, edits, mutating bash, MCP tools, and LSP renames are all blocked. `edit` (default) prompts per mutating call. `auto` approves everything for trusted tasks.\n- **Windows support** — OS-aware shell auto-detects `cmd.exe` / PowerShell on Windows, `bash` on Unix. The `bash` tool works out of the box on all platforms.\n- **Message queuing** — Submit multiple messages while the agent is busy; they queue and auto-drain. Escape interrupts the current turn but preserves the queue.\n- **Smart permission modal** — Denying a tool opens inline feedback so you can tell the agent what to do instead. Keyboard-native navigation (`↑/↓`, `j/k`, `Alt+1/2/3`).\n- **Loop guardrails** — Agent hard-stops when all tools in a turn are blocked, preventing infinite token-burning cycles.\n- **Persistent all-time cost history** — Append-only `history.jsonl` tracks daily usage forever, so `/cost` shows true all-time and monthly totals that survive across sessions and version updates.\n- **Live, gateway-confirmed cost tracking** — Status bar shows a fast local estimate (`≈$0.12`) that flips to the real, Cloudflare-billed number once the AI Gateway log reconciles. Per-turn latency renders next to cost.\n- **LSP + MCP** — Semantic code intelligence (hover, go-to-definition, references, diagnostics) via Language Server Protocol. Extend with external tools via Model Context Protocol.\n- **Local structured memory** — SQLite + embeddings cross-session memory. The agent recalls facts, instructions, and preferences across sessions via `remember`, `recall`, and `forget` tools.\n- **Web search, GitHub, and headless browser** — Research the web, read GitHub repos, and fetch JavaScript-rendered pages without leaving your terminal.\n\n## Recently shipped\n\n- **OS-aware shell with Windows support** — Auto-detects `cmd.exe`, PowerShell, or bash based on platform. Override with `KIMIFLARE_SHELL` or `/shell`.\n- **Smart permission modal with inline feedback** — Deny a tool and immediately tell the agent what to do instead. Keyboard-native navigation with `↑/↓`, `j/k`, `Alt+1/2/3`.\n- **True message queuing** — Enter queues messages while the agent is busy; Escape interrupts and auto-drains the queue.\n- **Hard-stop loop guardrail** — Stops token-burning cycles when all tools in a turn are blocked.\n- **Persistent all-time usage history** — `history.jsonl` tracks daily usage forever; `/cost` shows true all-time and monthly totals.\n- **Humanized Cloudflare API errors** — Actionable error codes and structured error display instead of raw JSON dumps.\n- **429 rate limit retry** — Automatic backoff and retry when Cloudflare rate-limits requests.\n- **Tool state visualization** — Queued, rejected, and cancelled tools are clearly labeled in the TUI.\n- **Paste preview placeholders** — Pasted content shows a snippet preview with sequential IDs instead of random hashes.\n- **Headless SDK** — Programmatic `createAgentSession` API and JSONL-over-stdio RPC mode for building on top of KimiFlare.\n\nSee the full changelog at [github.com/sinameraji/kimiflare/releases](https://github.com/sinameraji/kimiflare/releases).\n\n## Quick start\n\n```sh\nnpm install -g kimiflare\nkimiflare\n```\n\nOn first run, an interactive onboarding wizard collects your Cloudflare credentials and provisions (or picks) an AI Gateway. That's it.\n\nOr run without installing:\n\n```sh\nnpx kimiflare\n```\n\nRequires Node.js ≥ 20.\n\n### Cloudflare API token\n\nThe onboarding wizard provisions or picks an AI Gateway in your account. Your Cloudflare API token needs:\n\n- `Workers AI:Read`\n- `AI Gateway:Read` (to list gateways)\n- `AI Gateway:Edit` (to create gateways)\n\nEdit your token at: https://dash.cloudflare.com/profile/api-tokens\n\nOnce configured, `/cost` shows the Gateway-confirmed totals, cache hit ratio, per-feature breakdown, and direct dashboard links to each request log. `/gateway status` shows the current TTL, skip-cache flag, metadata tags, and live cache-hit ratio.\n\n### Model\n\nKimiFlare runs on **Kimi K2.7** via Cloudflare Workers AI — no API key needed beyond your Cloudflare token:\n\n- `@cf/moonshotai/kimi-k2.7-code` — 262k context, reasoning, tools, vision\n\n`@cf/moonshotai/kimi-k2.6` and `@cf/moonshotai/kimi-k2.5` are also available.\n\n### One-shot mode\n\n```sh\nkimiflare -p \"summarize PLAN.md\"                    # stream answer to stdout\nkimiflare -p \"...\" --dangerously-allow-all          # auto-approve mutating tools (for scripts)\nkimiflare -p \"...\" --reasoning                      # include chain-of-thought in stderr\n```\n\n### Headless SDK\n\nUse KimiFlare programmatically from your own application — no TUI required.\n\n```ts\nimport { createAgentSession } from \"kimiflare/sdk\";\n\nconst { session } = await createAgentSession({\n  cwd: \"/path/to/project\",\n  config: {\n    accountId: process.env.CLOUDFLARE_ACCOUNT_ID,\n    apiToken: process.env.CLOUDFLARE_API_TOKEN,\n    aiGatewayId: process.env.CLOUDFLARE_AI_GATEWAY_ID,\n    model: \"@cf/moonshotai/kimi-k2.7-code\",\n  },\n});\n\n// Stream every event: text deltas, tool calls, tasks, usage\nsession.subscribe((event) =\u003e {\n  console.log(event.type, event);\n});\n\n// Send a prompt\nawait session.prompt(\"Refactor auth to JWT + Redis\");\n\n// Mid-flight correction while the agent is still running\nawait session.steer(\"Use Redis instead of in-memory store\");\n\n// After the turn finishes\nawait session.followUp(\"Also add unit tests\");\n\n// Clean up\nsession.dispose();\n```\n\n**Key features:**\n- `subscribe()` — receive typed events (`text_delta`, `tool_call`, `tool_result`, `task_update`, `usage`, `warning`, `error`, `done`, etc.)\n- `prompt()` / `steer()` / `followUp()` — full conversation lifecycle\n- `pause()` / `resume()` — graceful preemption\n- `getStatus()` / `getUsage()` — inspect session state\n- Custom `permissionHandler` — decide programmatically whether to allow mutating tools\n- Optional `memoryEnabled`, `lspEnabled`, `costAttribution` flags\n\n#### SDK Authentication\n\nThe SDK needs a Cloudflare **Account ID**, **API Token**, and AI Gateway ID. Credentials are resolved in this priority order:\n\n1. **Explicit `config` object** (recommended for apps)\n2. **Environment variables**: `CLOUDFLARE_ACCOUNT_ID` / `CF_ACCOUNT_ID`, `CLOUDFLARE_API_TOKEN` / `CF_API_TOKEN`\n3. **Config file**: `~/.config/kimiflare/config.json`\n\n**For Electron / desktop apps**, we recommend storing credentials in the OS keychain (e.g. Electron `safeStorage` or `keytar`) and passing them explicitly:\n\n```ts\nimport { createAgentSession } from \"kimiflare/sdk\";\n\nconst accountId = await keytar.getPassword(\"kimiflare\", \"accountId\");\nconst apiToken = await keytar.getPassword(\"kimiflare\", \"apiToken\");\n\nconst { session } = await createAgentSession({\n  cwd: projectPath,\n  config: { accountId, apiToken },\n});\n```\n\n#### RPC mode (subprocess)\n\nIf you need process isolation or a non-Node consumer, run KimiFlare in JSONL-over-stdio RPC mode:\n\n```sh\nnode bin/kimiflare.mjs --mode rpc\n```\n\n```ts\nimport { spawn } from \"node:child_process\";\n\nconst proc = spawn(\"npx\", [\"kimiflare\", \"--mode\", \"rpc\"], {\n  cwd: projectPath,\n  stdio: [\"pipe\", \"pipe\", \"pipe\"],\n});\n\n// Read events\nproc.stdout.on(\"data\", (chunk) =\u003e {\n  for (const line of chunk.toString().split(\"\\n\")) {\n    if (!line.trim()) continue;\n    const event = JSON.parse(line);\n    console.log(event.type, event);\n  }\n});\n\n// Send commands\nproc.stdin.write(JSON.stringify({ type: \"new_session\" }) + \"\\n\");\nproc.stdin.write(JSON.stringify({ type: \"prompt\", message: \"Hello\" }) + \"\\n\");\n\n// Resolve a permission request\nproc.stdin.write(\n  JSON.stringify({ type: \"resolve_permission\", requestId: \"req_0\", decision: \"allow\" }) + \"\\n\"\n);\n```\n\n### Image understanding\n\n```sh\nkimiflare\n› fix the layout bug in this screenshot docs/bug.png\n› convert this mockup design.png to Tailwind HTML\n```\n\n## Slash commands\n\n| Command | Effect |\n|---------|--------|\n| `/mode edit\\|plan\\|auto` | Switch permission mode |\n| `/shell auto\\|bash\\|cmd\\|powershell` | Show or set the shell for the bash tool |\n| `/thinking low\\|medium\\|high` | Reasoning effort (persists) |\n| `/theme` | Interactive theme picker (`Ctrl+T`) |\n| `/resume` | Pick a past conversation to restore |\n| `/compact` | Summarize older turns to free context |\n| `/init` | Scan repo and write `KIMI.md` project context |\n| `/memory` | Show memory stats and search |\n| `/mcp list` / `/mcp reload` | Manage MCP servers |\n| `/reasoning` | Toggle chain-of-thought display |\n| `/cost` | Show Gateway-confirmed cost, cache hit ratio, and per-feature breakdown |\n| `/gateway status` | Show AI Gateway config and live cache-hit ratio |\n| `/update` | Check for updates |\n| `/help` | List all commands |\n\n## Keyboard shortcuts\n\n| Shortcut | Action |\n|----------|--------|\n| `Ctrl+C` / `Esc` | Interrupt current turn when busy; exit when idle |\n| `Ctrl+R` | Toggle reasoning display |\n| `Ctrl+O` | Toggle verbose tool output |\n| `Ctrl+T` | Open theme picker |\n| `Shift+Tab` | Cycle mode (edit → plan → auto) |\n| `↑` / `↓` | Walk prompt history |\n\n## Logs\n\nKimiFlare writes structured JSON logs of agent-side activity (tool calls,\npermission decisions, MCP/LSP lifecycle, session events, errors) to\n`~/.config/kimiflare/logs/\u003cdate\u003e.jsonl`, one file per day, with 7-day\nretention pruned automatically at startup.\n\nThe logs deliberately exclude prompts and completions — those live in\n[Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/)\nalready, and each log entry includes the Gateway `request_id` so you\ncan join them when you need the network side.\n\n```sh\nkimiflare logs path             # today's file\nkimiflare logs dir              # log directory\nkimiflare logs prune            # delete files older than 7 days\n\n# Tail this session's activity, formatted:\ntail -f $(kimiflare logs path) | jq\n\n# Find the slowest tool calls in the last day:\njq -r 'select(.event == \"tool:end\") | \"\\(.data.duration_ms)\\t\\(.data.tool)\"' \\\n  $(kimiflare logs path) | sort -rn | head\n```\n\nDisable the file sink entirely with `KIMIFLARE_LOG_SINK=off`. The\nseparate `KIMIFLARE_LOG_LEVEL` env var (default `off`) controls stderr\noutput — independent of the file sink.\n\n### Shipping to an OpenTelemetry collector\n\nIf you set `KIMIFLARE_OTEL_ENDPOINT`, KimiFlare also ships each log\nentry to that endpoint over [OTLP/HTTP](https://opentelemetry.io/docs/specs/otlp/)\nso it lands in Datadog, Honeycomb, Grafana Loki, an internal collector,\nor any other backend that speaks OTel. Batched every 5 s (or every\n100 entries, whichever first) and best-effort — never blocks the agent\nloop.\n\n```sh\n# Full path:\nexport KIMIFLARE_OTEL_ENDPOINT=\"https://otel.example.com/v1/logs\"\n# Or just the base URL (we auto-append /v1/logs):\nexport KIMIFLARE_OTEL_ENDPOINT=\"https://otel.example.com\"\n\n# Optional headers (comma-separated key=value pairs) — e.g. for auth:\nexport KIMIFLARE_OTEL_HEADERS=\"Authorization=Bearer xyz,X-Tenant=acme\"\n```\n\nEach log entry maps to one OTel `LogRecord`. Correlation IDs\n(`session_id`, `turn_id`, `request_id`) become record attributes,\n`data.*` fields are flattened to attributes with type-preserving\nencoding, and a `service.name=kimiflare` + `service.version` pair sits\non the resource. The same `request_id` joins to Cloudflare AI Gateway's\nper-request log without any extra work.\n\n## Hooks\n\nKimiFlare can fire shell commands at five points in an agent turn,\nconfigured per-project (`.kimiflare/settings.json`) or globally\n(`~/.config/kimiflare/settings.json`):\n\n| Event              | Fires when                                      | Veto? |\n|--------------------|-------------------------------------------------|-------|\n| `PreToolUse`       | A tool call is about to run                     | Yes   |\n| `PostToolUse`      | A tool call just finished                       | No    |\n| `UserPromptSubmit` | You hit Enter on a prompt                       | Yes   |\n| `Stop`             | A turn ended cleanly                            | No    |\n| `PreCompact`       | Auto-compaction is about to run                 | No    |\n\nHooks receive the event payload as JSON on stdin **and** as\n`KIMIFLARE_HOOK_*` env vars (for shell-one-liner ergonomics).\nNon-zero exit on a veto event cancels the underlying action and\nsurfaces the hook's stdout as the rejection reason.\n\n### Browse + enable from the TUI\n\n```text\n/hooks                            # list configured hooks\n/hooks recommended                # list starter hooks shipped with kimiflare\n/hooks enable stop-bell           # enable one (writes to .kimiflare/settings.json)\n/hooks enable stop-bell global    # ...or the global file\n/hooks disable stop-bell\n/hooks path                       # print settings.json paths\n/hooks reload                     # re-read settings.json after a manual edit\n```\n\nThe recommended catalog includes terminal bells / macOS notifications\non `Stop`, secret-file guards on `PreToolUse` (e.g. block edits to\n`*.env`), auto-format-with-prettier on `PostToolUse`, and a tool-call\naudit log. All ship disabled — `/hooks recommended` lists them.\n\n### Schema example\n\n```json\n{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"id\": \"no-secrets\",\n        \"matcher\": \"^(edit|write)$\",\n        \"command\": \"case \\\"$KIMIFLARE_HOOK_PATH\\\" in *.env|*.pem) echo 'blocked'; exit 1;; esac\"\n      }\n    ],\n    \"PostToolUse\": [\n      {\n        \"id\": \"format-ts\",\n        \"matcher\": \"^(edit|write)$\",\n        \"command\": \"npx --no-install prettier --write \\\"$KIMIFLARE_HOOK_PATH\\\" \u003e/dev/null 2\u003e\u00261 || true\"\n      }\n    ],\n    \"Stop\": [\n      { \"id\": \"bell\", \"command\": \"printf '\\\\a'\" }\n    ]\n  }\n}\n```\n\nPer-hook fields:\n- `command` (required) — the shell command.\n- `matcher` (optional) — anchored regex matched against the tool name\n  for `PreToolUse` / `PostToolUse`. Ignored for other events.\n- `id` (optional) — stable handle for `/hooks enable|disable`.\n  Auto-derived from `event + command` when omitted.\n- `enabled` (default `true`) — set `false` to keep a hook in config\n  but skip it.\n- `timeoutMs` (default `30000`) — hard kill if the hook hangs.\n- `description` (optional) — shown by `/hooks list`.\n\nHooks are always-on infrastructure: they fire whether the TUI is open\nor kimiflare is running in `--print` mode. They also fire for tool\ncalls generated from inside the Code Mode sandbox (heavy-tier turns),\nbecause hook firing lives on the `ToolExecutor` itself — every call\npath uses the same plumbing.\n\nWhen intent classification has assigned a tier, hook payloads include\nit as `tier: \"light\" | \"medium\" | \"heavy\"` (on `UserPromptSubmit`,\n`PreToolUse`, `PostToolUse`) and as `$KIMIFLARE_HOOK_TIER`. Useful for\n\"skip auto-format on light turns\" or \"audit every heavy-turn write.\"\n\nSDK consumers opt in to hooks with `enableHooks: true` on\n`createAgentSession`. Default is off because the SDK is a primitive,\nnot the TUI.\n\n## Development\n\n```sh\ngit clone https://github.com/sinameraji/kimiflare\ncd kimiflare\nnpm install\nnpm run build\nnpm link\n```\n\nScripts:\n- `npm run build` — bundle with tsup\n- `npm run dev` — run via tsx\n- `npm run typecheck` — `tsc --noEmit`\n- `npm test` — run tests\n\n## Contributing\n\n1. Fork the repository\n2. Create a branch: `git checkout -b feat/your-feature`\n3. Make your changes\n4. Run `npm run typecheck` and `npm run build`\n5. Commit with [Conventional Commits](https://www.conventionalcommits.org/)\n6. Open a Pull Request\n\n---\n\nBuilt by [Sina Meraji](https://github.com/sinameraji) and [contributors](https://github.com/sinameraji/kimiflare/graphs/contributors) · MIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsinameraji%2Fkimiflare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsinameraji%2Fkimiflare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsinameraji%2Fkimiflare/lists"}