Releases: PDgit12/knit
v0.9.0
The "tackle the honest limits" release. v0.8 closed the retrieval story
(BM25 + graph fusion). v0.9 closes the enforcement story — every limit
in the v0.8 architecture got a structural fix:
| Limit (pre-v0.9) | Structural fix shipped |
|---|---|
| Verifier exists but model has to call it | knit_verify_claim + citation requirement in instructions + auto-search in knit_classify_task |
| No background fact checker | PostToolUse import-validation hook + Stop-hook budget watch |
| Hooks remind but don't intervene mid-call | PreToolUse content inspection + mandatory-search gate for standard/complex |
| Model has its own context limits | knit_get_learning for hierarchical retrieval + knit_consolidate_learnings for KB compaction |
| Relies on agent calling search before re-investigating | Auto-search in classify_task + PreToolUse search-gate |
| Doesn't decide what content to read | suggested_reads from knit_build_context |
| Doesn't grade context relevance in real time | Stop-hook budget watch (closes the loop) |
Added — handler/tool surface (Round 1)
-
knit_verify_claim(Tier 1, knowledge-graph). Single-call fact-check
against the knowledge graph. Parses patterns ("A imports B", "X exports Y",
"A is tested by B", "X exists") and returns verdict (verified /
contradicted / unparseable) with evidence. The on-demand companion to the
knit_query_*family — they answer "what?"; this answers "is the agent's
claim about it true?". -
knit_get_learning(Tier 1, memory). Fetch one full learning by id.
Pair withknit_search_learnings(which returns headlines) for
hierarchical retrieval — expand only what turned out to be relevant.
Sets up the v0.9 path where summaries are the default and detail is on demand. -
knit_consolidate_learnings(Tier 1, memory). Detects clusters of
similar learnings via tag-Jaccard ≥ 0.5, proposes a single pattern entry
per cluster, optionally commits withcommit=true. Dry-run by default.
Keeps the KB working set lean as it grows — old similar learnings
collapse into patterns; originals are tagged#consolidated(preserved
but deprioritized in retrieval).
Added — auto-injection inside existing handlers
-
Auto-search in
knit_classify_task. Forstandard/complextier,
classify_task automatically runs BM25 over (description + affected
domains) and embeds top-3 hits aspre_emptive_learningsin the response.
Closes the "agent skipped search before re-investigation" gap without
requiring a new tool call. -
suggested_readsinknit_build_context. Returns a curated list of
files the agent should consider reading before editing the files-to-touch.
Three signals: graph-importers (blast radius), graph-imports (likely
needed for the edit), memory-mentions (files referenced by past learnings
in these domains). Caps at 8 entries; each carries{ path, reason, via }
for diagnostic transparency.
Added — system prompt directive
- Citation rule in
KNIT_INSTRUCTIONS_BASE. Tells the agent: "when you
state a fact about this codebase, cite the Knit tool result that verified
it — e.g. '(per knit_query_imports)'. If you can't cite, mark the claim
as 'unverified' explicitly." Norm-setting at the system-prompt level.
Makes hallucinations visible at the claim level instead of letting them
ship as confident-sounding prose.
Added — hook-level enforcement (Round 2)
HOOKS_VERSION bumped 6 → 7. Existing installs auto-refresh on next
brain load.
-
.searched-currentmarker (searchMarkerPath). Written by
knit_search_learningsandknit_search_global_learnings. Cleared on
UserPromptSubmit(turn boundary). -
PreToolUse search-gate. Extends the existing classification gate.
Whenmarker.tier ∈ {standard, complex}and the search-marker is
absent, the gate fires:warn(default): stderr nudge "call knit_search_learnings before Edit"block: hard-fail with exit 2
-
PreToolUse content inspection on Write/Edit/MultiEdit. Reads the
proposed content fromtool_input(or assembled fromtool_input.edits),
extracts relativeimportstatements, validates each path resolves on
disk. Warns about unresolved relative imports — likely hallucinated paths.
Never blocks on its own; the existing classification gate is the block
vehicle. -
PostToolUse import-validation on Write/Edit/MultiEdit. After the file
lands on disk, re-parses imports and warns about any unresolved relative
paths. Catches anything that slipped past the pre-write check (e.g.
MultiEdit combinations). -
Stop-hook budget watch. Reads CLAUDE.md size at session end. Emits
a warning to stderr if it crosses the 12.5KB over-budget threshold (25%
above the 6.5KB target). Drift becomes visible even if the agent never
callsknit_brain_status.
Tool registry now 43 entries (Tier 1 = 31)
Added: knit_verify_claim (knowledge-graph), knit_get_learning (memory),
knit_consolidate_learnings (memory). Knowledge-graph cluster grows
5 → 6. Memory cluster grows 8 → 10.
Tests — 467 → 492 (+25 new)
tests/verify-claim.test.ts(NEW, 14 tests) — claim parsing per
pattern (import/export/test/exists), true + false cases, unparseable
free-form, pre_emptive_learnings not firing on trivial/inquiry,
suggested_reads graph-importer + graph-import, knit_get_learning
fetch + error paths, citation rule presence.tests/consolidate-learnings.test.ts(NEW, 7 tests) — no-op
conditions (size, threshold), clustering with high overlap, dry-run
preserves KB, commit=true persists, custom min_cluster_size,
skip-already-consolidated.- Updated count assertions across
features.test.tsand
mcp-tools.test.ts(38 → 43 across the three v0.9 rounds).
Gates
typecheck ✓ · lint 0 errors ✓ · 492/492 tests pass ✓ · build ✓ ·
dist/cli.js --version → 0.9.0.
Upgrade path
After npx knit-mcp@latest setup (or just letting npx auto-fetch), restart
Claude Code. The HOOKS_VERSION 6 → 7 bump triggers automatic regeneration
of .claude/settings.local.json with the new hooks on the next brain
load — no manual knit refresh needed.
v0.8.0
Vectorless RAG ships. All three search tools (knit_search_learnings,
knit_search_global_learnings, knit_search_sessions) now use BM25 with
proper IDF + term-frequency saturation + length normalization. Session
search adds branch-diversification so one verbose feature branch doesn't
flood the response. RRF (Reciprocal Rank Fusion) plumbing is in place
for the v0.8.1+ graph-traversal retriever to layer on without changing
the handler shape.
This is the v0.7-plan's step 9 — the biggest piece. Zero new
dependencies, ~700 LOC across three modules, fully deterministic.
Added
-
src/engine/retrieval/bm25.ts— standalone BM25 index. Tokenizes
with a conservative English stopword set + min-length filter (drops
noise like "a", "I", "to"). Identifier-safe split preserves
underscores soknit_classify_taskstays one token. Standard k1=1.5,
b=0.75. ~250 LOC. 27 unit tests pin IDF behavior, length
normalization, corpus mutation, and Knit-shaped corpus retrieval. -
src/engine/retrieval/rrf.ts— Reciprocal Rank Fusion utility.
Combines independent rankers (BM25 lexical, future graph traversal,
future vector layers) viascore = Σ 1 / (k + rank)from Cormack et
al. 2009. k=60 default. No score calibration needed across rankers.
Per-retriever rank breakdown exposed in results for diagnostics. -
src/engine/retrieval/index.ts— barrel + builders that turn
Knit's domain types into BM25 corpora:buildLearningsIndex(entries)— concatenates summary + lesson +
approach + tags + domains so a tag query like "auth" finds entries
tagged #auth even without the # prefix.buildGlobalLearningsIndex(entries)— same shape over the
cross-project pool, includes project name in the indexed text.buildSessionsIndex(sessions)— includes branch + commits + tags
so "auth migration" finds sessions onfeature/auth-migration
even if the summary was sparse.diversifyByBranch(results, maxPerBranch=2)— the v0.7-plan's
step 9.5: cap session results per branch in the final ranking.
-
loadAllGlobalLearnings()insrc/engine/global-learnings.ts
andloadAllSessions(rootPath)insrc/engine/sessions.ts—
the iterator helpers the retrieval layer needs to build indices.
Changed
-
knit_search_learnings— new behavior. Two parameters drive search:query(NEW, optional): BM25 free-text over
summary/lesson/approach/tags/domains.domains(existing, optional): comma-separated tag filter.- Both: BM25 results filtered to those with ≥1 matching tag.
- Neither: error with helpful instruction.
- Response gains
retrieverfield (bm25/tag-filter) so callers
know which path produced the results. - Old domains-only path is fully preserved for back-compat.
-
knit_search_global_learnings— BM25-backed. Same single-query
parameter shape as before. Falls back to substring scan on tiny pools
or partial-word queries that don't survive tokenization. -
knit_search_sessions— BM25 + branch diversification. Over-fetches
candidates, then caps results-per-branch to 2 viadiversifyByBranch.
One feature branch can't flood the result set anymore. Same fallback
pattern as global learnings.
Tests — 413 → 446 (+33 new)
tests/bm25.test.ts(NEW, 27 tests) — tokenizer edge cases, IDF
rare-vs-common, length normalization, corpus mutation, Knit-shaped
corpus smoke (Stripe webhook, atomic writes, Node strict mode).tests/mcp-tools.test.tsadds 6 BM25 integration tests covering
free-text path, error path, BM25 + domains intersection, back-compat
tag-filter path, limit honoring, empty-result instruction text.
Performance
- BM25 index build: ~10ms per 100 entries (typical Knit corpus is <100).
- Search: <5ms for queries against a 100-entry corpus.
- Rebuild-per-search is acceptable at Knit scale; an incremental-index
cached inBrainCacheis a v0.9 optimization if corpora grow. - Hot path stays fully local — zero network, zero new dependencies.
What's still ahead
- v0.8.1 — graph-traversal retriever fused via RRF (the second
ranker the infrastructure is plumbed for). - v0.8.x — per-project instruction tailoring driven by
integrations.json(the v0.7.2 scanner's output). - v0.8.x — compounding-memory benchmarks measuring session N+1
cost vs. session N to validate the "Knit gets cheaper over time"
claim quantitatively. - v0.8.x — honest "Knit vs Ruflo" docs section now that the
positioning is clear and the technical differentiators are real.
v0.7.2
Token discipline becomes measurable, updates become visible, and Knit
learns who else is on the host. Three small but compounding pieces:
a budget guardrail in knit_brain_status, an in-band update
notification, and an integration scanner that detects other workflow
frameworks (Ruflo, gstack, CodeTour) for v0.8's per-project instruction
tailoring.
Added
-
Token-budget guardrail in
knit_brain_status. Four per-session
surfaces (claude_md,tool_registry,instructions,
per_session_overhead) report actual vs. target bytes with
healthy / warn / over-budgetverdicts. Budgets calibrated to v0.7
reality: 6.5KB CLAUDE.md, 8.5KB tool registry, 2.5KB instructions,
17.5KB total. Verdict flips immediately on drift — no more vibes
reviews. Acompoundingsub-block shows session count + learnings
hit rate so the value side of the ledger sits next to the cost.
Back-compat: the flattoken_accountingshape from pre-v0.7.2 is
preserved for callers that hard-coded those field names. -
In-band update notification via
knit_brain_status. New module
src/mcp/update-check.tsfires a fire-and-forget HTTP GET to
https://registry.npmjs.org/-/package/knit-mcp/dist-tagsat brain
load (best-effort, 2-second timeout, 1-hour TTL, errors silently
swallowed).knit_brain_statusreads the cached value
synchronously and adds anupdate_availablefield iff the registry
latestis strictly newer than the installedVERSION. Includes
achangelogURL and explicit "Restart Claude Code; if pinned,
switch to@latest" upgrade hint. Air-gapped CI and offline users
see nothing — never a failure. -
Integration scanner — new
src/engine/integration-scanner.ts.
Detects existing workflow frameworks installed alongside Knit:- Ruflo / claude-flow — via
~/.ruflo/,~/.claude-flow/,
project.claude-flow/, MCP-server registration, npm dependency - gstack — via
~/.gstack/,~/.claude/skills/gstack*,
project.gstack/ - CodeTour — via
.tours/*.tourfiles - Conductor — via
~/.conductor/ - Other MCP servers — all non-knit-brain entries in
~/.claude.json - Custom workflow sections in CLAUDE.md (
## Engineering Workflow,
## Methodology, etc.) outside the knit-managed block
Persists to~/.knit/projects/<hash>/integrations.jsonvia atomic
temp-then-rename write. Auto-runs atautoInitialize; manual
re-trigger via the newknit_scan_integrationstool (Tier 1).
knit_brain_statussurfaces the latest scan result under a new
integrationsfield. v0.7.2 surfaces; v0.8 will tailor the MCP
server-levelinstructionsfield per-project to defer routing
decisions to detected frameworks where they overlap (memory +
classification stay Knit's domain).
- Ruflo / claude-flow — via
Changed
- README gains a Quiet mode + Uninstall section. After
weighing it against the Ruflo-inspired lite-install path, we chose
documentation over a forked install flow. Quiet mode is one MCP
call (knit_set_protocol_strictness({level: "off"})); uninstall is
3 steps (~30 seconds). No new code path to maintain, no doc surface
doubling, no support burden of "lite or full?" diagnostics.
Tool count
TOOL_REGISTRY is now 39 entries — Tier 1 = 27 (added
knit_scan_integrations), Tier 2 = 10, Tier 3 = 2. tools/list
filter logic, knit_list_features discovery, and the registry
recoverability invariant for Tier-1 control tools all pinned by
updated tests.
Tests — 374 → 413 (+39 over v0.7.1)
tests/token-budget.test.ts(NEW, 7 tests) — budget surface
invariants, verdicts at boundary conditions, back-compat shape.tests/update-check.test.ts(NEW, 14 tests) — semver comparator
edge cases, sync read of cached value, brain-status integration
with theupdate_availablefield.tests/integration-scanner.test.ts(NEW, 14 tests) — detection
per framework, custom-workflow-section parsing that strips knit- legacy engram markers, atomic persistence round-trip,
malformed JSON graceful fallback,knit_scan_integrations
handler smoke test.
- legacy engram markers, atomic persistence round-trip,
- Updated tool-count assertions across
features.test.tsand
mcp-tools.test.tsto reflect the 38→39 transition.
Network discipline
The update check is the only network call Knit makes during normal
operation (subagent fetch is the other, fired once per agent then
cached forever). Per session, the update check is at most one HTTP
GET of ~200 bytes — far less than the token cost of the upgrade
prompt it surfaces.
What's still ahead in v0.8
- BM25 + import-graph vectorless retrieval (replaces substring search
acrossknit_search_*). - Per-project instruction tailoring driven by
integrations.json. - Compounding memory benchmarks comparing session N+1 cost vs. session N.
- Honest "Knit vs Ruflo" docs section.
v0.7.1
Hot-reload for tier-gated tools. knit_enable_feature and
knit_disable_feature now emit the MCP notifications/tools/list_changed
notification when they successfully change persisted state. The client
(Claude Code, Cursor, Codex) re-fetches tools/list immediately and
newly-active tools appear in the same session — no Claude Code restart
needed for these operations.
This was the realistic partial win from the v0.7.0 "auto-update on
MCP code change" question. Handler code changes still require restart
(MCP transport limitation, not Knit), but the visible tool surface
update is restart-free starting in v0.7.1.
Added
-
src/mcp/notifier.ts— late-bound dispatcher that bridges the
handler layer (no Server reference) to the transport layer.
registerToolsListChangedNotifier(fn)is called once byserver.ts
andcli.tsafter constructing the Server.notifyToolsListChanged()
is called by handlers after a state change; fire-and-forget, never
throws, swallows both sync exceptions and async rejections so a
notification failure can't tear down the handler. -
Server capability advertisement.
tools: { listChanged: true }
now appears incapabilitieson bothsrc/mcp/server.tsand
src/cli.tsrunMCP-mode constructors, telling clients we may emit
the notification.
Changed
-
handleEnableFeaturefiresnotifyToolsListChanged()after a
successful enable (NOT on already-enabled — re-enable is a no-op
notification too). Responseinstructionupdated to reflect the new
live behavior: "Tools list updated for this session. The newly-
enabled tools should be available immediately — call
knit_list_features to confirm." -
handleDisableFeaturesymmetric: fires on successful disable
(real state transition), no-ops on already-disabled.
Tests
366 → 374. New tests/notifier.test.ts covers:
- Notifier registration + invocation.
- No-op when no notifier registered (handlers running outside MCP).
- Sync exceptions and async rejections from the notifier are swallowed.
handleEnableFeaturefires exactly on real flag-flip-on; idempotent
re-enable does NOT fire.handleDisableFeaturefires exactly on real flag-flip-off.- Invalid feature names hit the error path and do NOT fire.
What still requires a Claude Code restart (honest scope)
- Handler code bug fixes (the v0.6.4 Stop-hook fix would still need
restart even after v0.7.1). - Server
instructionsfield changes — sent at handshake only. - Upgrading the npm package version itself (process is already running
the prior version's code).
For these, the answer is and will remain "restart Claude Code." It's
a property of the MCP stdio transport, not a Knit limitation.
v0.7.0
The "connective tissue" release. Knit becomes the universal MCP layer
for any project shape: tier-gated tool surface, dynamic per-project
protocol injection at session start, ~60% per-turn token reduction
across the board. No breaking changes for v0.6.5 users — every new
behavior is additive or opt-in, with back-compat for legacy markers
and persistence files.
Important upgrade note: after upgrading, restart Claude Code
(or your MCP client) so the running MCP server picks up the new
instructions field and tier-gated tools/list. The new server
instructions only flow into the system prompt at handshake time —
the cached MCP process from before the upgrade keeps the v0.6.5
behavior until restart.
Added
-
MCP server-level
instructionsfield. The Server constructor now
emits a ~2KB universal-baseline protocol string that every MCP client
(Claude Code, Cursor, Codex) injects into the session system prompt
BEFORE tool descriptions are read. Closes the "agent doesn't know
Knit's flow at session start" gap that CLAUDE.md alone could never
close — CLAUDE.md is harness-wrapped with "may or may not be
relevant" caveats; instructions surface unconditionally. New file
src/mcp/instructions.tsexportsKNIT_INSTRUCTIONS; both
src/mcp/server.tsandsrc/cli.tsrunMCP-mode wire it in. -
Inquiry tier in the classifier.
knit_classify_tasknow detects
read-only "what / where / audit / explain / status / how" intent in
the task description and returnstier: 'inquiry'with empty phases
andauto_plan_mode: false— Inquiry-class tasks (e.g., "audit the
codebase") no longer hijack plan mode the way they did pre-v0.7.
Action directives ("fix this", "implement X") override even if an
inquiry word appears, so write-bearing commands stay correctly
routed. The workflow protocol always documented an Inquiry tier;
the classifier implementation just shipped late. -
Tier-gated tool registry — 38 tools, three tiers.
- Tier 1 (26 tools, always active): memory + retrieval (8),
knowledge graph (5), workflow + classification (4), false positives- reflection (3), Protocol Guard config (2), diagnostics + meta (4).
- Tier 2 (10 tools, auto-exposed when project shape matches):
team worktrees (9) auto-active when ≥3 domains detected OR
knit_enable_feature("teams"); subagents (1) auto-active when
.claude/agents/exists ORknit_enable_feature("subagents"). - Tier 3 (2 tools, strictly opt-in):
knit_prune_sessionsand
knit_setup_project, both reachable viaknit_enable_feature("admin").
tools/listMCP responses are now filtered per project shape — the
agent never sees tools it can't usefully call. Solo-domain projects
drop 9 team-worktree tools from their decision space.
- Tier 1 (26 tools, always active): memory + retrieval (8),
-
knit_list_features— the discoverability escape hatch. Always
Tier 1. Returns{ active, available, totals, by_category, project_shape }. Theavailableentries carry the rationale and
enable_viahint so the agent can tell the user how to switch a
hidden tool on. -
knit_enable_feature/knit_disable_feature— flip Tier-2/3
flags on/off. Both Tier 1 (must always be reachable — otherwise a
user who disables "admin" by accident could lock themselves out of
the recovery path). Persisted to~/.knit/projects/<hash>/features.json
via atomic temp-then-rename write so a mid-write crash can't corrupt
the flag state. Unknown feature names in a persisted file are
silently dropped, not crashed on. -
Response payload caps.
knit_load_sessionis now lazy by default. The core response
(session_context, top 3 learnings, top 5 false positives, knowledge
counts) is always returned. Optional sections — patterns, teams,
metrics, recent_sessions, full_learnings, full_knowledge — gate
behindinclude=<comma-list>.include=allopts into everything.knit_classify_taskminimal-mode by default. Returns{ tier, affected_domains, phases, auto_plan_mode, instruction }. The
diagnostic fields (reasoning,cross_domain_ripple,files_count)
move behindverbose=truefor ad-hoc debugging.
Changed
-
CLAUDE.md generator trimmed ~88% on a typical project (16.7KB →
~2KB). The previously-injected system-reminder override paragraph,
verbose Protocol Guard prose, and Phase Status placeholder are gone
— covered by server instructions or pure ceremony. Project Map caps
high-fanout 15→5, untested 10→3. Tier vocabulary collapsed from a
prose-heavy section to a 4-row table. Workflow pointer collapsed
from a 10-phase code block to a one-liner. Project-specific value
(header, session-start pointer, project map, domain architecture,
build gates, false positives if curated) is fully preserved. -
Tool descriptions in
src/mcp/tools.tscompressed across the
board. Pre: average ~150 chars per tool. Post: average ~52 chars.
Action-verb-first one-liners. Behavior markers ("Call first on
every task.", "Opt-in.") retained because they affect agent
routing; elaborations and examples cut.
Fixed
spliceKnitBlocknow recognizes the legacy v0.5.x markers
(<!-- engram:start --> ... <!-- engram:end -->) in addition to the
current<!-- knit:start --> ... <!-- knit:end -->. Pre-fix, users
upgrading from v0.5.x would have ended up with a 16KB orphan block
stranded in CLAUDE.md while Knit wrote a separate.claude/KNIT.md
sidecar — confusing and wasteful. The legacy block now gets cleanly
replaced; the file converges to the current markers over time.
Token-budget table (per-session fixed cost)
| Surface | v0.6.5 | v0.7.0 | Cut |
|---|---|---|---|
| CLAUDE.md per-turn | ~16.7 KB | ~2 KB | 88% |
| Tool registry (typical project) | ~6-8 KB | ~3-4 KB | ~50% |
knit_classify_task response |
~500 tok | ~150 tok | 70% |
knit_load_session response (default) |
~3-5 KB | ~1.5 KB | ~60% |
Server instructions |
0 | ~500 tok | (new context) |
Net per-session fixed cost roughly halves on a typical project.
Deferred to v0.7.1 (close-successor)
- BM25 + import-graph retrieval (vectorless RAG) — replaces substring
search acrossknit_search_*. Designed inV0.7-PLAN.mdstep 9. - Session-diversified retrieval — trivial follow-on once BM25 lands.
- Integration scanner (
integrations.json) — detects gstack /
CodeTour / custom CLAUDE.md frameworks and tailors instructions
per-project. - Token budget guardrail in
knit_brain_status. - Knowledge-graph entity extraction.
- 4-tier memory consolidation.
/plugin installpackaging.- Secret-redaction pattern expansion based on real-user reports.
Tests
312 → 366. New coverage for: Inquiry-tier detection, KNIT_INSTRUCTIONS
budget + content invariants, tool registry shape + gating rules,
computeFeatureListing, isToolActive, getActiveToolDefinitions
filtering (including the Tier-1 recoverability invariant), feature-flag
persistence round-trip, malformed features.json graceful fallback,
unknown feature-name skip, atomic-write artifact check, multi-include
parsing on knit_load_session, minimal/verbose modes on
knit_classify_task, legacy <!-- engram:start --> marker migration
in spliceKnitBlock.
v0.6.5
Polish pass before public link. Final sweep through user-visible
strings that escaped the v0.6.0 rename, plus an honest README note on
Windows shell support.
Fixed
engram/Engramcleaned out of every user-visible string the
product writes to disk or returns to the agent:src/generators/workflow-protocol.ts— overview + tier-classification
headings ("Knit workflow — overview", "you decide, Knit informs").
This is what the agent sees when it callsknit_get_workflow.src/generators/claude-md.ts— the generated CLAUDE.md block now
reads "Knit-powered workflow", "Knit protocol", "Knit MCP tools
reference", "Knit-generated", and "Knit will configure domains".src/mcp/cache.ts— the.claude/KNIT.mdsidecar template (written
when a user-curated CLAUDE.md exists without Knit markers) now says
"Knit's per-project workflow".src/commands/export.ts— Obsidian export writesKnit Index.md
with heading# Knit Knowledge Index(wasEngram Index.md/# Engram Knowledge Index). Existing exports keep their filenames; a
re-export creates the new file.src/generators/learnings.ts— the bootstrap entry now reads
"Project initialized with Knit workflow".src/engine/worktrees.ts— new team worktrees use branch names
knit/team-<slug>-<ts>instead ofengram/team-…. Existing
worktrees keep their branch names; only new spawns are affected.
- Agent-md markers renamed with back-compat.
src/generators/agent-md.tswrites<!-- knit:context:start -->/
<!-- knit:context:end -->going forward. The legacy
<!-- engram:context:* -->markers are still recognized so v0.5.x
personalized agent files (in.claude/agents/knit-<name>.md) regenerate
cleanly without leaving an orphan block.src/engine/install-agents.ts
also checks both marker forms before treating a file as user-curated.
Added
- README: explicit Windows shell support boundary. Knit's hooks use
POSIX-stylenode -e '…'quoting which works under bash, zsh, Git
Bash, WSL, and Windows PowerShell — but not Windowscmd.exe
(single quotes are literal characters there, not delimiters). Documented
alongside setup instructions. Issue template for hook errors invites
users to report shell context.
Internal (not user-visible — left for a later sweep)
engramreferences inside source comments and internal variable names
(ENGRAM_GRADIENTinsrc/cli.ts,ENGRAM_DIRin
src/generators/settings.ts, doc comments insrc/mcp/cache.ts/
src/mcp/handlers.ts/src/generators/agent-md.tsetc.). These don't
appear in any output the user sees — chore commit any time.
v0.6.4
Hotfix for Node 22+/25+ hook execution. Closes a second, distinct
hook-runtime bug that v0.6.3 didn't catch.
Fixed
node -etop-levelreturnrejected on Node 22+ / 25+. Several
generated hook scripts (LEARN-compliance, KB-metrics, session-tuple
recorder, etc.) usedreturn;as an early-exit from a top-level
try { ... }. Older Node versions tolerated this in-e-evaluated
scripts; Node 22 and especially Node 25 reject it with
SyntaxError: Illegal return statement. Every Stop hook fired this
on session end.
Fix:nodeHookinsrc/generators/settings.tsnow wraps the script
body in an IIFE —(() => { … })()— soreturnis legal.- Regression test extended to actually execute generated hooks.
tests/generators.test.tspreviously usedbash -nto syntax-check
commands without running them; that caught the v0.6.3 quoting bug but
not this one (valid shell, valid JS — just illegal under Node's
evaluator). The new test runs every generatednode -ecommand under
the current Node, with empty stdin to prevent stdin-reading hooks from
hanging. Would have caught both v0.6.3 and v0.6.4 regressions. HOOKS_VERSIONbumped 5 → 6 so users who installed any v0.6.0–0.6.3
build get a clean hook regeneration on next brain load.
v0.6.2
v0.6.1
v0.6.0
Headline: project renamed from engram to Knit. This is a breaking change.
Why
The npm registry already had two prior-art packages in the same product
space — engram-mcp (engram-ai / danielwhyte.com, "MCP server for Engram:
persistent memory for AI") and engram-ai (mareo.ai, "small explicit memory
layer for AI agents"). Launching publicly under the engram name invited
trademark questions and positioned this project as a clone. With zero
external users today, the cost of renaming is at its lowest.
Knit is the new brand — it suggests the actual product mechanic:
sessions knitting together into compounding intelligence.
Migration for existing v0.5.x users
- New install command:
npx knit-mcp@latest setup(wasnpx @piyushdua/engram-dev@latest setup). - Data directory: moved from
~/.engram/to~/.knit/. Existing data is preserved at the old path — the new code reads from~/.knit/and falls back toENGRAM_HOMEenv var so the migration path works. - MCP tool names: all
engram_*tools renamed toknit_*(e.g.engram_classify_task→knit_classify_task). 35 tools, all renamed. - Settings file:
_engramHooksand_engramOwnedmarkers renamed to_knitHooks/_knitOwned. HOOKS_VERSION bumped 3 → 4; the auto-refresh path from v0.5.1 detects any settings.local.json with the old marker and regenerates cleanly via hybrid merge, preserving user-owned hooks and permissions. - Subagent files:
<project>/.claude/agents/engram-<name>.md→<project>/.claude/agents/knit-<name>.md. Path-resolution accepts both prefixes for back-compat reads. - Old package on npm:
@piyushdua/engram-devwill receive anpm deprecatenotice pointing toknit-mcp.
Changed
- Package name:
@piyushdua/engram-dev→knit-mcp. - CLI binary:
engram-dev→knit. - Repository:
github.com/PDgit12/engram→github.com/PDgit12/knit. - All 35 MCP tools renamed
engram_*→knit_*. - Env vars:
ENGRAM_HOME→KNIT_HOME(legacyENGRAM_HOMEstill honored). - Settings markers:
_engramHooks/_engramOwned→_knitHooks/_knitOwned. - Generated CLAUDE.md markers:
<!-- engram:start -->→<!-- knit:start -->. - Sidecar filename:
.claude/ENGRAM.md→.claude/KNIT.md. - Internal types:
EngramConfig→KnitConfig;ENGRAM_MARKER_*→KNIT_MARKER_*. - Internal functions:
writeEngramHooks→writeKnitHooks;spliceEngramBlock→spliceKnitBlock;engramRoot→knitRoot. - Worktree slug prefix:
<repo>-engram-<team>-<ts>→<repo>-knit-<team>-<ts>.
Internal
- 299 tests still pass after the rename — no behavior change, only identifier rename.
- Sed-driven mechanical refactor across 50 source/test files; targeted Edits for back-compat regexes that accept both
knit-andengram-prefixes.