Skip to content

Tech stack

LayerChoiceWhy
LanguageNode.js (ESM, .mjs)Claude Code’s native ecosystem. Hooks are shell commands — node is universally present.
Runtime depsZeroStdlib only: node:fs, node:child_process, node:path, node:readline, node:os. Optional @anthropic-ai/sdk for SDK-fallback mode. No bundler.
AI — preferredclaude -p headlessRides user’s existing Claude Code auth. Zero additional billing.
AI — Tier 0 (filter)Local weighted scoringFree. Kills ~70% of triggers before any API call. Runs in Node, no subprocess.
AI — Tier 1 (routine)Claude Haiku 4.5Cheap (~$0.003/call cached). Handles all automated distillation.
AI — Tier 2 (deep cleanup)Claude Sonnet 4.6Available via --model flag; no automatic trigger yet. Planned for Haiku drift correction.
SyncGit (scoped to .wyren/)Zero infra. LAN + WAN. Free history. Pluggable behind WyrenSync.
StorageFilesystem markdownHuman-readable, git-diffable, native Claude context format.
SessionStart hookadditionalContext injectionOnly Claude Code surface that injects hidden system context at session init.
Stop hookWatermark + detached spawnTracks turn count; spawns distiller detached after threshold (5 turns or 2 min idle). Never blocks.
UserPromptSubmit hookLive sync delta injectionPulls remote on every user turn; injects only sections added since last injection. 3 s budget.
Distributioninstall.sh / install.ps1 one-linersClone to ~/.claude/wyren/, wire hooks in settings.json, register wyren CLI via npm install -g.
CLIbin/wyren.mjsinit, status, distill, broadcast-skill, install, update, uninstall, doctor, log. Pure Node.
Docs siteAstro Starlight → GitHub PagesMarkdown-native, search, dark mode, Mermaid, Node-aligned.
  • External services: Anthropic API (only if claude -p unavailable), git remote.
  • No database. No server. No auth. No frontend.

Non-choices (what we explicitly do NOT use)

Section titled “Non-choices (what we explicitly do NOT use)”
ThingWhy not
TypeScriptZero build step. Node runs .mjs directly; stdlib types are sufficient.
Bundler (webpack, esbuild)Nothing to bundle.
DatabaseFilesystem markdown fits. No query surface needed.
Custom serverGit is the sync layer.
AuthTrust model = same team. Git remote access is the permission boundary.
DockerNothing to containerize.
Observability stack.wyren/log + wyren status CLI.
Test framework beyond node:testStdlib is sufficient.
React / Vue / SvelteDocs site uses Starlight; plugin has no UI.

MCP servers are tool-invocable only — Claude calls them as tools during a conversation. They cannot inject system context at session initialization.

Wyren’s core value is automatic context at start, which only hooks can deliver. An MCP server is a viable post-ship addition — on-demand query of teammate transcripts via a wyren_search(query) tool — but is intentionally deferred. See Future.

Two reasons:

  1. Claude Code is Node. Hooks are shell commands; Node is guaranteed present on any machine running Claude Code.
  2. Zero deps possible. A Python distiller would need anthropic package + pip + venv. The Node distiller shells out to claude -p via built-in child_process — zero install steps on teammate machines.