Skip to content

Releases: ruvnet/ruflo

v3.38.19 — supersedes broken v3.38.17/v3.38.18 (Windows CI, dead agentdb exports, memory driver doctor check, MCP HTTP transport)

Choose a tag to compare

@ruvnet ruvnet released this 22 Aug 16:39

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 V3 matrix job pinned to windows-2022 (was windows-latest, which moved to VS2026 — node-gyp can't detect it, breaking native builds for hnswlib-node/better-sqlite3).
  • #2977@claude-flow/memory's controller-registry.ts no longer attempts dead import('agentdb') calls for 8 exports no installable agentdb range provides. hierarchicalMemory/memoryConsolidation now go straight to their working fallback implementations; the other 6 controllers with no fallback return null directly. 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 doctor check (checkMemoryPersistenceDriver) reports whether the active SQLite driver is native better-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 on main; 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

Choose a tag to compare

@ruvnet ruvnet released this 22 Aug 16:30

⚠️ 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 V3 job) was fully broken: windows-latest moved to VS2026, which node-gyp's VS detector can't identify, breaking native builds for hnswlib-node and better-sqlite3. Pinned the matrix to windows-2022.
  • #2977@claude-flow/memory's controller registry attempted to import 8 agentdb exports that no installable agentdb range 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 for hierarchicalMemory/memoryConsolidation; the 6 controllers with no fallback now return null directly. 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 doctor check (checkMemoryPersistenceDriver) that reports whether the active SQLite driver is native better-sqlite3 (durable, WAL-capable) or the silently-lossy sql.js fallback, 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, HTTP tools/list only 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/mcp dependency pin (3.0.0-alpha.10, never published) that broke a plain npm install of the monorepo; repinned to the real published range.
  • @claude-flow/memory bumped to 3.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

Choose a tag to compare

@ruvnet ruvnet released this 21 Aug 15:23
5234333

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

Closes #3061, #3056, #3048.

🤖 Generated with RuFlo

https://claude.ai/code/session_0118jMsYhwHD5dx2vStENsEB

v3.38.15 — session-end state, Windows Claude launch, MCP tool filter, settings-risk scanner

Choose a tag to compare

@ruvnet ruvnet released this 21 Aug 14:42
87bacd5

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

https://claude.ai/code/session_0118jMsYhwHD5dx2vStENsEB

v3.38.14 — memory_store tags cache-loss fix (#3051)

Choose a tag to compare

@ruvnet ruvnet released this 21 Aug 14:31
703e774

Follow-up patch to v3.38.13 — fixes the last of the recently-reported issues.

Fix

#3051memory_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

Closes #3051#3079

🤖 Generated with RuFlo

https://claude.ai/code/session_0118jMsYhwHD5dx2vStENsEB

v3.38.13 — statusline cache, colon-agent routing, YAML fix + new deepseek harness plugin

Choose a tag to compare

@ruvnet ruvnet released this 21 Aug 14:20
0f3c451

Bug-fix train + one new plugin. All three npm packages published as 3.38.13 (latest + alpha + v3alpha).

Bug fixes

  • #3045.claude/helpers/statusline.cjs getGitInfo() 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.
  • #3064hooks post-task silently dropped every colon-namespaced plugin agent (ruflo-core:reviewer, feature-dev:code-explorer, …). Removed the narrow ad-hoc regex; the canonical validateIdentifier() 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).
  • #3065plugins/ruflo-metaharness/skills/harness-gepa/SKILL.md had an unquoted colon in description that broke npx skills add. Quoted the field and rephrased the bare (default: to avoid the leading colon.

New plugin

  • plugins/ruflo-deepseek-harness/ — sibling to ruflo-metaharness (ADR-150 shape). Two skills — deepseek-chat (non-reasoning) and deepseek-reason (surfaces reasoning_content separately from the final answer). Reads DEEPSEEK_API_KEY; degrades gracefully ({status: 'degraded', reason, hint} with exit 0) when the key is missing or the API is unreachable. --alert-on-error opts into hard exit 1 for CI gates.

Not fixed

  • #3051 (memory_store tags dropped) — current source's handler passes tags straight through to storeEntry; a maintainer already verified round-trip works on fa13ee4ad. Waiting on the reporter's ruflo/@claude-flow/cli version to identify the affected release path before patching.

Install

  • npx ruflo@latest (or @alpha / @v3alpha for the legacy tags, all aligned)
  • npx @claude-flow/cli@latest / npx claude-flow@latest

Merged PR

Closes #3045, #3064, #3065#3078

🤖 Generated with RuFlo

https://claude.ai/code/session_0118jMsYhwHD5dx2vStENsEB

v3.38.9 — path-validator symlinked-prefix fix

Choose a tag to compare

@ruvnet ruvnet released this 13 Aug 12:41

Fixes

#3010PathValidator 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)

Choose a tag to compare

@ruvnet ruvnet released this 12 Aug 22:33

Highlights

  • fix(agent): explicit provider/model config now propagates into agent execution (#2962, PR #3007)

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-alias config.model string (e.g. an Ollama tag) as an explicit selection via the existing modelId fast-path, instead of falling through to task-based routing / agent-type defaults.
  • agent_spawn forwards config.provider into the stored (and returned) agent record when it's an unambiguous explicit choice (ollama/openrouter; anthropic is excluded since the CLI silently defaults to it when --provider isn't passed).
  • callAnthropicMessages() now consults the persisted agents.providers config for baseUrl/apiKey/model when env vars are absent. A self-hosted, unauthenticated Ollama endpoint no longer requires the undocumented OLLAMA_API_KEY=local sentinel.
  • 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 main too — stale fs mock in mcp-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.8 package

v3.38.7 — HNSW status honesty fix, cache-fingerprint follow-up

Choose a tag to compare

@ruvnet ruvnet released this 12 Aug 21:48

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

  • PR: #3003 (#2920 follow-up)
  • PR: #3006 (#2922, re-opened after #3004 was auto-closed by a base-branch deletion)
  • Filed: #3005 — a suspected root-cause bug in helper-refresh.ts's self-heal path, discovered while working this release
  • Previous release: v3.38.6

v3.38.6 — Codex stdin fix, intelligence cache staleness fix, daemon config restore fix

Choose a tag to compare

@ruvnet ruvnet released this 12 Aug 20:49

Fixes

#2947DualModeOrchestrator 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.

Links