Releases: ruvnet/ruflo
Release list
v3.38.19 — supersedes broken v3.38.17/v3.38.18 (Windows CI, dead agentdb exports, memory driver doctor check, MCP HTTP transport)
Supersedes v3.38.17 and v3.38.18, both of which shipped with a corrupted dependency graph due to a publish race between two concurrent sessions working this checkout simultaneously (see the postmortem note below). v3.38.17/3.38.18 are now deprecated on npm for all three packages.
What's actually fixed (same content as v3.38.18 intended, now correctly published)
- #2992 — Windows CI
Build V3matrix job pinned towindows-2022(waswindows-latest, which moved to VS2026 — node-gyp can't detect it, breaking native builds forhnswlib-node/better-sqlite3). - #2977 —
@claude-flow/memory'scontroller-registry.tsno longer attempts deadimport('agentdb')calls for 8 exports no installable agentdb range provides.hierarchicalMemory/memoryConsolidationnow go straight to their working fallback implementations; the other 6 controllers with no fallback returnnulldirectly.agentdb_consolidate's stub response now says explicitly that it didn't run. Published as@claude-flow/memory@3.0.0-alpha.23. - #2968 — new read-only
doctorcheck (checkMemoryPersistenceDriver) reports whether the active SQLite driver is nativebetter-sqlite3(durable) or the sql.js fallback (silently drops writes), using the ~47-vs-~10 table-count signal from the issue. - #2990 — MCP HTTP transport
protocolVersion/tools-list/dual-stack-bind fixes were already onmain; this release actually ships them (previous releases pinned an unpublished@claude-flow/mcp@3.0.0-alpha.10, now corrected to^3.0.0-alpha.9). - #3002 (ruvocal hidden-tab stream freeze) — confirmed already fixed on
main, no change needed this release.
Postmortem: why 3.38.17 and 3.38.18 were broken
A subagent spawned mid-session to relay a status message went out of scope and independently ran its own fix/verify/publish cycle in parallel, racing the primary session's edits on the same checkout. Combined with stale-cached claude-flow daemon background processes self-healing package.json mid-write (tracked in #3005), @claude-flow/cli got published twice (3.38.17, 3.38.18) with a broken @claude-flow/mcp pin, and 3.38.18 additionally shipped with @claude-flow/memory missing from dependencies entirely. claude-flow and ruflo inherited the defect at 3.38.18. All three are now deprecated at those versions; 3.38.19 is the verified-correct cut.
v3.38.18 — Windows CI, dead agentdb exports, memory driver doctor check, MCP HTTP transport
⚠️ BROKEN — superseded by v3.38.19
This version (and 3.38.17) shipped with a corrupted dependency graph due to a publish race — see v3.38.19 for the postmortem. @claude-flow/cli, claude-flow, and ruflo are all deprecated on npm at this version. Install 3.38.19 or later instead.
Fixes
- #2992 — Windows CI (
Build V3job) was fully broken:windows-latestmoved to VS2026, which node-gyp's VS detector can't identify, breaking native builds forhnswlib-nodeandbetter-sqlite3. Pinned the matrix towindows-2022. - #2977 —
@claude-flow/memory's controller registry attempted to import 8agentdbexports that no installableagentdbrange actually provides, silently degrading every fresh install. Removed the dead import attempts and promoted the existing, verified-working fallback implementations (tieredMemoryFallback, the consolidation stub) to first-class forhierarchicalMemory/memoryConsolidation; the 6 controllers with no fallback now returnnulldirectly.agentdb_consolidate's stub response now says explicitly that it's a no-op rather than reading as "nothing to consolidate." - #2968 — Added a read-only
doctorcheck (checkMemoryPersistenceDriver) that reports whether the active SQLite driver is nativebetter-sqlite3(durable, WAL-capable) or the silently-lossysql.jsfallback, using the table-count signal from the issue (~47 native vs ~10 fallback tables). Warns, never fails; does not change install behavior. - #2990 — MCP HTTP transport spec violations (non-string
protocolVersion, HTTPtools/listonly exposing 4 system tools, IPv6-only bind) were already fixed in source but had never shipped in a release; this release ships them. - Fixed a stale
@claude-flow/mcpdependency pin (3.0.0-alpha.10, never published) that broke a plainnpm installof the monorepo; repinned to the real published range. @claude-flow/memorybumped to3.0.0-alpha.23(carries the #2977 fix) and republished, since it's resolved via the npm registry rather than bundled with@claude-flow/cli.
Verified: @claude-flow/memory full test suite (459/459), @claude-flow/cli doctor/commands/mcp-tools suites (541/541), clean tsc --noEmit on both packages, clean production builds. #3002 (ruvocal hidden-tab stream freeze) was checked and found already fixed on main — no change needed.
v3.38.16 — 3 dream cycles: MessageBus retry bound, hybridSearch opt-in, discounted Thompson bandit
Release train off three dream-cycle landings.
Dream Cycles
- #3062 → #3061 — dream(swarm): MessageBus retry-attempts silently reset to 0 on every re-queue, unbounded redelivery, `message.failed` unreachable. Bounded retry counter now persists across re-queues; `message.failed` fires at the cap. 220/220 tests. ACCEPT. Details in docs/dream-cycle/dream-gist-2026-08-19.md.
- #3057 → #3056 — dream(memory): `hybridSearch` controller was built but unreachable — explicit opt-in flag silently null-returned. Fixed via controller-registry wiring + graceful-retrieval test. Overall recall@10 +0.267 (category B pure-paraphrase regresses -0.133, disclosed). ACCEPT-scoped. Details in docs/dream-cycle/dream-gist-2026-08-18.md.
- #3049 → #3048 — dream(intelligence): discounted Thompson-sampling prior decay for the model-router bandit (opt-in). Recovers ~17.6% faster after workload shift in the low-cost bucket (t=7.00, held); med-bucket null (no generalization, disclosed). ACCEPT-scoped. Details in docs/dream-cycle/dream-gist-2026-08-17.md.
Install
- `npx ruflo@latest` (or `@alpha` / `@v3alpha` — all three tags aligned)
Merged PRs
🤖 Generated with RuFlo
v3.38.15 — session-end state, Windows Claude launch, MCP tool filter, settings-risk scanner
Bug-fix + security-hardening train: four PRs merged from external contributors and one dream cycle.
Fixes
- #3060 → #3055 — `mcp tools` now honors `CLAUDE_FLOW_MCP_TOOLS` when listing (previously the env var was accepted but ignored on the list path). Thanks @dajiaohuang.
- #3076 → #3071 — Claude Code launches now resolve correctly on Windows npm installs. Replaces the brittle `which claude` execSync with a platform-aware `resolveClaudeLaunchCommand` that follows the npm shim to the native `claude.exe` (or falls back to `node <cli.js>` for older JS installs). Thanks @dajiaohuang.
- #3077 → #3063 — `hooks session-end` now persists the real session state (session id, duration, task/edit/command/error metrics from the actual run) instead of a hardcoded summary + fabricated session id. Thanks @dajiaohuang.
Security (Dream Cycle 2026-08-16)
- #3044 → #3043 — Advisory scanner for untrusted `.claude/settings.json` `hooks` and `permissions.allow` entries that `ruflo init` / `ruflo init --upgrade` previously carried forward unexamined. Same trust shape as CVE-2025-59536 (settings.json hook payload achieving command execution with no review step), reached via ruflo's own merge logic. Advisory-only — the merge/write behavior itself is unchanged, findings surface as CLI warnings. Hardened after an independent adversarial-critic pass found 6 concrete bypasses (intermediate-pipe-stage downloads, two-step download+exec, eval-wrapped base64, interpreter-mediated dangerous commands, absolute-path-prefixed commands, whitespace-evasive allow rules) — all fixed and pinned as a held-out regression set. Also self-identified an ANSI/control-character injection risk in the warning output and stripped it.
Install
- `npx ruflo@latest` (or `@alpha` / `@v3alpha` — all three tags aligned)
Merged PRs
Closes #3055, #3063, #3071, #3043.
🤖 Generated with RuFlo
v3.38.14 — memory_store tags cache-loss fix (#3051)
Follow-up patch to v3.38.13 — fixes the last of the recently-reported issues.
Fix
#3051 — memory_store accepted a tags array and returned success: true, but the very next memory_retrieve (or memory_list) came back with tags: [].
Root cause was in bridgeStoreEntry: after the DB insert (which serialized tags correctly to the tags column), the write-through cache set stored only a partial entry — { id, key, namespace, content, embedding } — with no tags. The next bridgeGetEntry hit that cache and returned tags: cached.tags || [] = [].
Fix: replace the partial write-through with cache invalidation. Next read re-fetches the authoritative row (which correctly parses the tags JSON column) and repopulates the cache with the full shape. Side benefit: same defect had also caused access_count, createdAt, and updatedAt to be stale from the cache — invalidation fixes those too.
Proven regression test in __tests__/memory-store-tags-cache-3051.test.ts: pre-fix returns tags: [], post-fix returns the real tags.
Install
npx ruflo@latest(or@alpha/@v3alpha— all three tags aligned)
Merged PR
🤖 Generated with RuFlo
v3.38.13 — statusline cache, colon-agent routing, YAML fix + new deepseek harness plugin
Bug-fix train + one new plugin. All three npm packages published as 3.38.13 (latest + alpha + v3alpha).
Bug fixes
- #3045 —
.claude/helpers/statusline.cjsgetGitInfo()ran the 5-command git chain uncached on every render, queuing subprocesses faster than they finished on large repos with concurrent Claude Code sessions. Now wrapped in a per-cwd tmp-file cache with 5s TTL — dirty status still feels live, pileup is bounded. - #3064 —
hooks post-tasksilently dropped every colon-namespaced plugin agent (ruflo-core:reviewer,feature-dev:code-explorer, …). Removed the narrow ad-hoc regex; the canonicalvalidateIdentifier()upstream already allows:and.. Regression test locks in 4 shape variants and is proven to catch the bug (2/4 fail on revert; 4/4 with the fix). - #3065 —
plugins/ruflo-metaharness/skills/harness-gepa/SKILL.mdhad an unquoted colon indescriptionthat brokenpx skills add. Quoted the field and rephrased the bare(default:to avoid the leading colon.
New plugin
plugins/ruflo-deepseek-harness/— sibling toruflo-metaharness(ADR-150 shape). Two skills —deepseek-chat(non-reasoning) anddeepseek-reason(surfacesreasoning_contentseparately from the final answer). ReadsDEEPSEEK_API_KEY; degrades gracefully ({status: 'degraded', reason, hint}with exit 0) when the key is missing or the API is unreachable.--alert-on-erroropts into hard exit 1 for CI gates.
Not fixed
- #3051 (
memory_storetags dropped) — current source's handler passestagsstraight through tostoreEntry; a maintainer already verified round-trip works onfa13ee4ad. Waiting on the reporter'sruflo/@claude-flow/cliversion to identify the affected release path before patching.
Install
npx ruflo@latest(or@alpha/@v3alphafor the legacy tags, all aligned)npx @claude-flow/cli@latest/npx claude-flow@latest
Merged PR
Closes #3045, #3064, #3065 — #3078
🤖 Generated with RuFlo
v3.38.9 — path-validator symlinked-prefix fix
Fixes
#3010 — PathValidator rejected everything under a symlinked prefix, breaking ruflo proxy install on macOS. validate() canonicalized the candidate path through fs.realpath but the constructor only ever path.resolve()d the allowed prefixes — so on macOS, where os.tmpdir() is reached through a symlink (/var → /private/var), the realpath'd candidate could never match the non-realpath'd prefix, and every path under it — including the prefix's own contents — was rejected as "outside allowed directories." Download and Ed25519 signature verification both succeeded during proxy install; it then failed on this defense-in-depth path check. Fixed by realpath-ing prefixes at construction time too, with the same ENOENT-tolerant fallback validate() already uses for candidates.
Links
v3.38.8 — provider/model config propagation fix (#2962)
Highlights
providers configure and agent spawn --provider/--model previously persisted user intent but the execution path (callAnthropicMessages, executeAgentTask, determineAgentModel) only ever consulted env vars and a fixed 5-alias model list — silently discarding both. A user who configured local Ollama or OpenRouter would see two successful CLI commands, then execution would either fail closed or silently use a different provider/model than requested.
determineAgentModel()now treats any non-aliasconfig.modelstring (e.g. an Ollama tag) as an explicit selection via the existingmodelIdfast-path, instead of falling through to task-based routing / agent-type defaults.agent_spawnforwardsconfig.providerinto the stored (and returned) agent record when it's an unambiguous explicit choice (ollama/openrouter;anthropicis excluded since the CLI silently defaults to it when--providerisn't passed).callAnthropicMessages()now consults the persistedagents.providersconfig forbaseUrl/apiKey/modelwhen env vars are absent. A self-hosted, unauthenticated Ollama endpoint no longer requires the undocumentedOLLAMA_API_KEY=localsentinel.executeAgentTask()forwards the agent's explicit provider into the first dispatch call.
Precedence (resolving the open design question from the issue thread, credit @pacphi): explicit per-agent flag → env vars → persisted agents.providers config → key-presence inference (unchanged, last resort).
Regression coverage: v3/@claude-flow/cli/__tests__/agent-provider-model-propagation.test.ts (3 tests, each verified to fail against the pre-fix code and pass against the fix).
Verification
- TypeScript clean (
tsc --noEmit) - 202/209 existing tests green for touched files (7 pre-existing unrelated failures confirmed present on unpatched
maintoo — stalefsmock inmcp-tools-deep.test.ts) - CI: 107 checks passed, 3 skipped (conditional), 0 failed
- Tarball-verified: fix present in the published
@claude-flow/cli@3.38.8package
v3.38.7 — HNSW status honesty fix, cache-fingerprint follow-up
Fixes
#2920 (follow-up) — consolidate()'s graph write was missing the contentFingerprint stamp that init()'s cache-hit gate checks. The v3.38.6 fix made consolidate() (the session-end path) rebuild graph-state.json unconditionally, but that write never included contentFingerprint — only init()'s own write did. So every init() immediately following a consolidate() saw nodeCount match but contentFingerprint undefined !== <real hash>, missed the cache, and did a full rebuild even with zero content changes. Fail direction was safe (extra rebuilds, never stale data), so it didn't block v3.38.6 — but it meant the 60s graph cache never actually fired across a consolidate/restart boundary.
#2922 — the memory bridge's brute-force cosine search was misreported as HNSW-accelerated. getHNSWStatus() returned available: true whenever the AgentDB v3 bridge was loaded, regardless of whether an HNSW index was actually in the request path — the bridge's default search is a full-table SELECT + brute-force cosine similarity loop that never touches @ruvector/core. Same issue in bridgeGetHNSWStatus (unconditional available: true) and in three misleadingly-named functions that do no HNSW work: bridgeSearchHNSW, bridgeAddToHNSW, bridgeGetHNSWStatus — renamed to bridgeSearchBruteForceCosine, bridgeAddEmbedding, bridgeGetVectorSearchStatus. Both status functions now expose an algorithm: 'hnsw' | 'brute-force-cosine' field. The memory_stats MCP tool response (and 6 others) previously hardcoded backend: 'sql.js + HNSW' regardless of which path ran — now reports the real algorithm.
Note: this changes the values returned in the backend field of 7 MCP memory tool responses (memory_store, memory_retrieve, memory_search, etc.) from the previous hardcoded 'sql.js + HNSW' to an accurate value — an observable but non-breaking change (the field's type and presence are unchanged).
Actually wiring AgentDBBackend's real HNSW implementation into the bridge's default search path is a larger architectural question, tracked as the remaining open scope on #2922.
Links
v3.38.6 — Codex stdin fix, intelligence cache staleness fix, daemon config restore fix
Fixes
#2947 — DualModeOrchestrator left every Codex worker's stdin open, causing codex exec to hang waiting for EOF. Both Claude and Codex workers receive their prompt positionally/via a flag — never over stdin — but the pipe was never written to or closed. claude -p ignores the unused pipe, but codex exec blocks in resolve_root_prompt waiting for stdin EOF that never arrives, hanging every real Codex worker until the orchestrator's own multi-minute timeout kills it. Now closes stdin immediately after spawn for both platforms.
#2920 — Editing a MEMORY.md section's body (same ID, same entry count) served stale cached content instead of refreshing it. Two related bugs in the intelligence helper's graph/store caching, both keyed on entry count instead of content: init()'s graph-cache-hit gate compared only node count, so a same-ID content edit was invisible to it and ranked-context.json never refreshed; consolidate()'s persist gate only fired on insight creation or a dedup-driven shrink, so an in-memory content change (e.g. assigning an id to a previously id-less entry) was silently never written back to disk. Added a storeFingerprint() helper folding every entry's content into one aggregate value, used to gate the cache hit and to make consolidate() always persist.
#2935 — .claude-flow/config.json resourceThresholds overrides were silently lost to a stale daemon-state.json. The daemon's stale-state restoration guard only checked the constructor arg (originalConfig), not a value set via config.json — so an explicit override (e.g. minFreeMemoryPercent: 0, a workaround for Darwin's os.freemem() undercounting reclaimable memory) kept losing to whatever a daemon-state.json from before the override existed had persisted, on every restart. Same bug class as #2661 (aiWorkersEnabled), fixed the same way, per-field. Also fixed a secondary diagnostic bug: readDaemonConfigFromFile() logged "Daemon config loaded from ..." from inside the constructor before this.config existed, so the log call threw inside its own try/catch and never reached daemon.log — made "is the config file even being read?" impossible to answer from the log. Does not address this issue's primary Darwin os.freemem() memory-gate report — that needs vm_stat/memory_pressure-based measurement, left for a follow-up.
CI infrastructure
Fixed a recurring sharp/libvips "socket hang up" / 503 flake in npm ci across CI workflows (confirmed on 8+ unrelated PRs this session) by adding a retry-with-backoff composite action and wiring it into every npm ci call site, including the two OS-conditional fallback blocks initially missed.