Distilly
The 24K-star person-distillation engine rebuilt as a fail-closed TypeScript product most of its stargazers cannot install yet.
Distilly is the most rigorously engineered skill-adjacent product GearScope has tested at this maturity stage: 1,119 tests pass on a fresh clone, host installs fail closed instead of guessing, and the skill payload is byte-pinned by sha256 manifests. But the Developer Preview only installs on three exact host versions (Codex CLI 0.146.0, OpenClaw 2026.3.24, Hermes v0.9.0), ships no npm package or tagged release, and the 24K stars were earned by a legacy branch the project itself now places outside its security boundary. Try it if you match a recorded host or want a reference architecture; everyone else waits.
$git clone --branch distilly-plugin https://github.com/titanwings/distilly.git && cd distilly && corepack enable && pnpm install --frozen-lockfile && pnpm run build
Node 22.19+ or 24, pnpm 10.32+, then node packages/cli/lib/bin.js setup --host codex
$npx skills add titanwings/distilly --skill distilly --agent hermes-agent --copy --yes
lands ./.hermes/skills/distilly byte-identical, but the runtime still needs the build
$git clone --single-branch --branch dot-skill --depth 1 https://github.com/titanwings/distilly.git/distilly
outside the Preview's reviewed security boundary
install if
- Codex CLI 0.146.0 users who want evidence-bound person memory. You are the one fully verified host, with the complete flow (ingest, brief, commit, correct, review, install-as-skill) verified by the project.
- Agent-platform engineers studying fail-closed plugin design. The committed capacity fixtures, sha256 release manifest, lease-based briefing contract, and crash-recovery journal are a reference implementation worth reading even if you never install it.
- Bilingual (CN/EN) users on legacy hosts. The
dot-skillbranch keeps the original workflow alive across Claude Code, OpenClaw, Hermes, Codex, DSH, Pi, and Grok Build, provided you accept its documented security-boundary caveats.
skip if
- Anyone not running one of the three exact recorded host versions. That is most people: current Hermes, Claude Code, Codex, and OpenCode installs are all refused by the Preview gate today.
- Users wanting a turnkey install. No npm package, no tagged Preview release, build-from-source only; if
git clone && pnpm buildis not in your comfort zone, wait for a release. - Privacy-sensitive users who need the Feishu/Slack/DingTalk/email collectors. Those live in the legacy branch, which the project itself excludes from its reviewed security boundary because collectors write credential configuration into
~/.distilly/.
What It Does
Distilly (formerly Colleague Skill, in Chinese "εεδΊ Skill") turns a person's source material, working habits, judgment, and voice into a versioned Person Profile that an agent can recall mid-run or install as a long-lived host skill. The default branch (distilly-plugin, an unreleased 0.1.0-preview.1 Developer Preview) is a nine-package TypeScript monorepo: a CLI, a SQLite-backed engine, a five-tool MCP server, a local review Panel, and plugin bindings for Codex, Claude Code, OpenClaw, and Hermes. The agent-facing contract is a 174-line SKILL.md that routes every operation through exactly five tools (distilly_get, distilly_ingest, distilly_pending, distilly_commit, distilly_correct) with leases, evidence quotes, and candidate review. A separate dot-skill branch preserves the original 1,518-line bilingual skill that accumulated the repo's 24,337 stars. The target user is a developer who wants reusable, evidence-bound person memory on a coding agent host.
The Good
The test discipline is exceptional for a preview. On a fresh clone, vitest run passes 997 tests across 91 files in 438 seconds, the Python suites pass 39 tests, the package-boundary suite passes 49, and the build-artifact suite passes 34, for 1,119 passing tests with zero failures. The suite includes crash-recovery tests that terminate the process mid-journal at four distinct points (after the operation, after the first event, after the current profile, after the terminal journal) and assert exact target recovery afterward; each of those runs takes about 7.6 seconds of real crash-and-recover work, not a mocked shortcut.
The fail-closed host gate fails closed for real. The README claims that any unrecorded host version or changed release tuple returns a refusal before writing an integration, and the claim held in testing: setup --host codex on a host without Codex exits 1 with "Could not find the codex executable on PATH", setup --host hermes against a Hermes newer than the recorded v0.9.0 fixture exits 1 with "This host session does not provide a verified Distilly briefing capacity", and doctor emits honest ok: false JSON with exit 1 when nothing is installed. The capacity evidence itself is committed as three JSON fixture files (for example hermes-agent-v0.9.0-cli-distilly-0.1.0-preview.1-v2.json) recording exact host versions, byte budgets (65,536 for Codex and OpenClaw, 49,752 for Hermes), and sha256 transcript digests.
Skill distribution is byte-disciplined end to end. The three SKILL.md copies under plugins/shared, plugins/claude-code, and plugins/codex are byte-identical (verified with cmp), plugins/release-manifest.json pins per-file and manifest sha256 digests, and the repo's own verifier (python3 scripts/assemble_plugins.py --check) validates the working tree against that manifest. Installing through npx skills add titanwings/distilly --skill distilly --agent hermes-agent --copy --yes lands a SKILL.md in ./.hermes/skills/distilly that cmp confirms byte-identical to the repo copy, alongside references/source-materials.md and a skills-lock.json.
The local-first claims hold in code. A grep for fetch(, axios, node-fetch, and XMLHttpRequest across the non-test source of the engine and runtime packages returns zero hits, and storage runs on Node's built-in node:sqlite (DatabaseSync), so the "no additional model API key" and "storage authority stays local" statements are supported by the code, not just the README.
Documentation is unusually honest and multilingual. The README ships in eight languages (English plus ZH, DE, ES, JA, KO, PT, RU) with seven translated ROADMAPs, a 5,442-line design document (docs/design/system-v3.md), a host-status table that explicitly marks Claude Code as "binding included; exact host fixture still needed", and a UPDATES.md that names the current bottleneck as host evidence rather than features. INSTALL.md separates the Preview path from the legacy branch and warns that legacy collectors can write credential configuration into ~/.distilly/ outside the reviewed security boundary.
The Bad
Setup is a wall for most of the repo's own audience. There is no npm package (the npm name distilly belongs to an unrelated project by a different maintainer), no tagged Preview release (the only git tag is an old v0.01), and installation means cloning a branch, satisfying Node 22.19+ or 24 plus pnpm 10.32+, and building from source with a 203MB node_modules tree. Setup then only succeeds on three exact host versions. A Hermes install newer than v0.9.0 is refused, which means the large majority of current Hermes, Claude Code, Codex, and OpenCode users cannot run the Preview path at all today.
The 24K stars and the Preview are two different products sharing one repo. The stars were earned by the original dot-skill skill (a 1,518-line bilingual SKILL.md plus 6,016 lines of Python collectors for Feishu, Slack, DingTalk, and email), which the project itself now documents as a separate maintenance line outside the Preview's security boundary. Demand-side data reflects the split: the skills.sh registry still lists the legacy names dot-skill (435 installs) and create-colleague (274 installs), but the default branch ships only the distilly skill, so installing by registry name fails with "No matching skills found for: dot-skill". Total lifetime installs (709) sit about 34 times below the star count, and every one of them points at the legacy names.
A standalone evaluator cannot exercise the happy path. The MCP fixture server (packages/mcp/scripts/stdio-fixture.mjs) completes the handshake and enumerates the exact five tools, but a positive distilly_get call against its fake engine returns internal_error because the fixture scripts only the flows vitest drives. Demonstrating a real ingest-to-profile round-trip requires a host matching a recorded fixture version, which is precisely what a reviewer without those pinned hosts lacks. The input-validation layer is verifiable standalone (a wireVersion: "2" call returns a structured invalid_input error with fieldPath: "input"), but the engine beyond it is not.
Small gaps add friction. The CLI has no --version flag and rejects the argument with exit 2 ("Unknown or unavailable Developer Preview command: --version"), so version discovery depends on README and manifest reading. The smoke:built gate did not finish inside a 300-second cap in this review. Panel browser tests require a Playwright Chromium download that this review declined. And pnpm 10's build-script allowlist silently skips the esbuild postinstall, requiring a manual pnpm rebuild esbuild before vitest runs.
Smoke Test Results
Host-based hands-on testing on macOS 26.5.2 aarch64 (Node 24.13.1, corepack pnpm 10.32.1, Python 3.12.13). All commands ran against a fresh shallow clone of the default distilly-plugin branch at commit 24acbe0.
Run A. Fresh sandbox, no deps preinstalled
$ git clone --branch distilly-plugin --depth 1 https://github.com/titanwings/distilly.git
β
PASS: 12MB clone, 9-package pnpm workspace detected
$ corepack pnpm install --frozen-lockfile
β
PASS: exit 0 in 8.4s, 203MB node_modules (esbuild postinstall skipped by pnpm 10 allowlist)
$ corepack pnpm run build
β
PASS: tsc -b --force exit 0, packages/cli/lib/bin.js emitted
$ node packages/cli/lib/bin.js --help
β
PASS: usage text rendered, fail-closed policy stated in help
$ node packages/cli/lib/bin.js doctor
β
PASS: honest {"ok": false, "installed": false} JSON, exit 1
$ HOME=/tmp/distilly-sbx-home-codex node packages/cli/lib/bin.js setup --host codex
β
PASS: refused, exit 1: "Could not find the codex executable on PATH."
Pass rate: 6 of 6. Fresh clone to working CLI is fast; the refusals are the correct behavior on an unpopulated host.
Run B. Sandbox with deps preinstalled (repo's own gates)
$ python3 -B scripts/assemble_plugins.py --check
β
PASS: plugin assembly: ok (release-manifest digests match working tree)
$ python3 -B scripts/verify_docs.py
β
PASS: docs: ok (documentation contracts hold)
$ python3 -B -m unittest tests.test_assemble_plugins tests.test_verify_docs tests.test_run_tests tests.test_sync_design_chapters
β
PASS: Ran 39 tests, OK (0.489s)
$ node --test tests/check_package_boundaries.test.mjs
β
PASS: 49 pass, 0 fail
$ node --test tests/build_artifacts.test.mjs
β
PASS: 34 pass, 0 fail
$ corepack pnpm run check:engine-pack
β
PASS: engine pack: ok (338 files)
$ corepack pnpm exec vitest run
β
PASS: 91 files, 997 tests passed, 0 failed (438s, incl. 7.6s-per-case SQLite crash-recovery)
$ corepack pnpm run smoke:built
β FAIL: stopped at the 300s hard cap before completing (per-package smoke suite is long-running)
Pass rate: 7 of 8. The single failure is a review-side time cap, not a repo defect; every gate that completed passed clean.
Run C. Functional verification (does it do what it claims?)
$ python3 mcp-stdio-client.py node packages/mcp/scripts/stdio-fixture.mjs
β
PASS: serverInfo {"name": "distilly", "version": "0.1.0-preview.1"}, protocol 2024-11-05,
tool count: 5, names exactly [distilly_get, distilly_ingest, distilly_pending, distilly_commit, distilly_correct],
resources/prompts: Method not found (disabled as documented)
$ ... --call distilly_get --args '{"wireVersion":"2", ...}'
β
PASS: structured rejection {"code":"invalid_input","fieldPath":"input","retryable":false}
$ grep -rE "fetch\(|axios|node-fetch|XMLHttpRequest" packages/engine/src packages/runtime/src
β
PASS: 0 hits in non-test source (local-first claim holds in code)
$ cmp plugins/shared/.../SKILL.md plugins/claude-code/.../SKILL.md; cmp ... plugins/codex/.../SKILL.md
β
PASS: all three SKILL.md copies byte-identical (174 lines + 133-line reference)
$ npx skills add titanwings/distilly --skill dot-skill --agent hermes-agent --copy --yes
β FAIL: "No matching skills found for: dot-skill" (registry name absent from default branch; clean error, exit 1)
$ npx skills add titanwings/distilly --skill distilly --agent hermes-agent --copy --yes
β
PASS: landed ./.hermes/skills/distilly/SKILL.md + references/ + skills-lock.json, cmp byte-identical to repo
Functional pass rate: 5 of 6. The one failure is a real registry-drift finding, not a tooling problem.
Structural validation
$ ls LICENSE CITATION.cff CONTRIBUTING.md INSTALL.md ROADMAP.md UPDATES.md
β
PASS: all present; GitHub API reports license spdx MIT
$ cat plugins/release-manifest.json | python3 -m json.tool > /dev/null
β
PASS: valid JSON; canonical skill + 2 target manifests digest-pinned (schemaVersion 1, wire 3.x)
$ ls docs/lang
β
PASS: 8 README languages + 7 ROADMAP translations
$ wc -l .github/workflows/ci.yml
β
PASS: 130-line CI running full gates on Node 22.19/24 x ubuntu/macos + Python 3.9/3.11 matrix + Ruff
$ npm view distilly --json
β
PASS (documented): npm name held by an unrelated project; repo honestly states "not an npm package yet"
Structural pass rate: 5 of 5.
What the runs tell you
The engineering is real and reproducible: every completed gate passes on a fresh clone, the install refuses unverified hosts exactly as documented, and the wire contract validates input strictly. What cannot be verified without one of three pinned host versions is the actual person-distillation workflow, so the score reflects a product whose machinery is proven but whose headline flow most readers can only reach through the legacy branch or by waiting for broader host fixtures.
Setup Walkthrough
- Clone the Preview branch:
git clone --branch distilly-plugin https://github.com/titanwings/distilly.git(the repo default branch isdistilly-plugin, notmain). - Enter the directory and run
corepack enable(or usecorepack pnpmdirectly if the global symlink is not writable), thenpnpm install --frozen-lockfileandpnpm run build. Node 22.19+ or 24 is enforced byengines. - Check your host against the recorded fixtures: Codex CLI 0.146.0, OpenClaw 2026.3.24, or Hermes v0.9.0. Anything else fails closed by design.
- Run
node packages/cli/lib/bin.js setup --host codex(oropenclaw/hermes), thendoctor --hostto confirm, and restart the host. - To install an approved profile as a persistent skill:
node packages/cli/lib/bin.js install subject_<32 hex chars> --host codex. Uninstall withuninstall --host codex; person data under~/.distilly/survives removal. - On any other host, either copy the skill payload (
npx skills add titanwings/distilly --skill distilly --agent) knowing the runtime is not bound, or use the explicit legacydot-skillbranch documented in INSTALL.md.
Gotchas: pnpm 10 blocks the esbuild postinstall by default (pnpm rebuild esbuild if vitest complains), the CLI has no --version flag, and the legacy branch's collectors write credential configuration into the same ~/.distilly/ namespace the Preview uses, so run only one mode at a time.
Alternatives
- OpenViking - a full context database unifying memory, resource, and skill under one local store with native Hermes integration; prefer it when you want general agent memory rather than person distillation specifically.
- mem0 (open source) - the mainstream agent-memory layer with broad framework support; less rigorous provenance per fact, far easier to install.
- virgiliojr94/book-to-skill - distills books (not people) into portable skills with a simpler file-based pipeline; prefer it when your source is a document set rather than a person's working style.
Reviews stay honest because nobody pays us to publish them. If this one saved you time, throw a coin.
Tip the reviewer- reviewed by
- GearScope
- tested
- 2026-09-04 · macOS (Apple Silicon)
- last verified
- 2026-09-04
- depth
- HANDS-ON
- sponsorship
- none, ever
Don't install your next skill blind.
Every week: the shortlist of skills worth installing β and the ones to skip β from 100+ hands-on tests. No spam, no affiliate links.