- #4127: PostToolUseFailure registered for Bash and Write|Edit|MultiEdit and forwarded with -s false and the real exit code (builds on #4170 by @rudycelekli; payload shape verified against Claude Code 2.1.289)
- #4176: the hook shim starts the CLI from CLAUDE_PROJECT_DIR; the CLI only adopts a proven config in a directory that carries ruflo init's markers, not a bare .claude/ that Claude Code created
- #4128: the shim starts the CLI detached and returns at once (about 25 ms instead of 0.2-4 s per hook), bounded to 4 concurrent telemetry CLIs per project, Stop never dropped, RUFLO_HOOK_SYNC=1 for the old path
- ruflo-core 0.2.9
Co-Authored-By: RuFlo <ruv@ruv.net>
On Claude Code Desktop every picture was missing: no banner, no title
art, no topology, map, gauge or chart, and not even the text lines meant
to stand in for them. The host completes every resolved table with every
element name, and on the desktop its Raster draws an empty fragment, so
`kit.Raster !== undefined` always held and the console drew empty boxes.
- kitForSurface(): the terminal gets its Raster and no Svg; every other
surface (desktop, vscode, mobile) gets Svg and no Raster. Applied to the
Pane and the band. On the terminal nothing changes: the same Rasters,
keys, text and fallbacks.
- gfx/svg.ts: the same Grid as one SVG document. Every Block Elements
glyph (U+2580 to U+259F) and every braille glyph is drawn as
rectangles; other glyphs are placed cell by cell (a control character,
a value past Unicode or a character XML cannot hold is a blank cell);
colours are kept, the default background stays transparent, text is
escaped. A picture that would pass the host's 131,072-character Svg
limit is not sent, so one large picture cannot invalidate the whole
tree; it then falls back as on a surface with no pictures (its text line
where it has one).
- A surface that draws Svg gets still frames, since nothing blits an Svg:
nothing strikes in and the motion stops, as with fps 0, and the
decorative light (the header's sweep, the title's shimmer, the palette's
sweep) is off instead of caught mid-way. The boot keeps its real time so
its progress shows, and a picture of data is drawn as of the render. The
terminal keeps its moving light, with fps 0 too.
- art(): one helper for every picture site (header, title art, boot,
Orbital art, picture(), learning, memmap, palette). An Svg's alt is the
picture's fallback line without "needs a terminal".
- The frame loop runs while the view has pictures, as before, so the
menu entry and the Learning pulse still move on the desktop; it only
rebuilds and blits when a Raster is mounted, so the desktop no longer
rebuilds every picture per frame and blits keys that were never mounted.
The band's mark animates on the terminal only.
- tests: svg-pictures.spec.ts (vitest) for the writer, the kit, the still
frames (on every page in every look: header, title and palette the same
at any moment, every other picture equal to fps 0's) and the frame loop
by surface; surface-pictures.test.ts mounts the 33 main views and the
agent drill-down of a fixture agent in the bbs, plain and orbital looks
on terminal and desktop (7 tests, all fail on the parent commit). It
imports claude-code/testing, so it is listed in
scripts/ci-test-excluded.txt with the console's other kit tests. The old desktop test only asserted "no Raster",
which held while every picture was gone; it now asserts the Svgs arrive.
Fixes#4111
Co-Authored-By: Ruflo & AQE
README gets a short optional pointer (npx ruflo tui, --plain) and one small animated SVG. docs/USERGUIDE.md gets a
Terminal UI (optional) section: requirements, commands, keys, exit codes, what each page shows, the AI page's ask-first
card and its Codex/OpenRouter rules, the honest limits and a pointer to the Orbital theme. Both SVGs are built from real
frames of ruflo-tui 3.56.7 in a throwaway sample project; scripts/render-tui-svg.mjs rebuilds them (CSS animation only,
no scripts or external references, prefers-reduced-motion shows the first frame).
Co-Authored-By: RuFlo <ruv@ruv.net>
Carries #4031 (rudycelekli) and #4091 (proffesor-for-testing); oversized-tail and permission-safe
recovery per rUv's review and martinvlad's fresh-consumer finding. Adds scripts/smoke-shared-fresh-consumer.mjs
(packed tarball, plain Node) and a CI step for it.
Co-Authored-By: RuFlo <ruv@ruv.net>
Page 6. Reuses harness.send and the conversation bridge's sendTo, not a second harness. Host.spawn runs only the pinned Codex 0.162.0
release (never current or PATH), read-only, from a fixed argument allow-list; Host.httpSend sends only https POST to openrouter.ai or a
convoTargets host, never follows a redirect, and a key is read by variable name and never drawn. Enter shows a card of exactly what would be
sent; a lone y answers it only while it was drawn in full (#3983); spend cap from the provider-reported cost. e2e host matrix gets a tui leg
(keyless in CI, live gated). Not in this PR: the workspace-write toggle.
Co-Authored-By: RuFlo <ruv@ruv.net>
ADR-490 (loop), ADR-491 (mods host integration, Proposed). The loop's first run found two defects, fixed test-first:
- ruflo mcp start advertised resources but answered resources/* with -32601 (3 stdio servers).
- init --dual's marketplace clone ran under a 20 s budget (17.5 s measured), swallowing the real error.
Co-Authored-By: RuFlo <ruv@ruv.net>
Checked every CLI command, flag and MCP tool the skills tell the model to use
against ruflo 3.56.5 and the tool registry. Fixed what was false:
- workflows 0.6.6: MCP tool names with underscores that do not exist; gaia-bench
has no --dry-run/--task-id (unknown flags are ignored, so the documented cost
estimate started a billed run); opt-in guard for native workflows; stale smoke
- security-audit 0.3.4: non-existent `security report`, wrong `audit` usage,
scan depth table that described phases the scanner lacks; --fix gated
- swarm 0.3.7: `swarm watch/health/shutdown` do not exist; swarm-watch.mjs poller
- rag-memory 0.3.5: `ruflo recall`/`memory bridge` do not exist; shell-quoting
of user text in /recall
- testgen 0.3.2: tdd-repair now enforces that the test is not edited; shell
quoting; invalid --limit
- rvf 0.3.6: export went through the public IPFS marketplace; now memory export
- ruvllm 0.3.4: provider claims and persistence claims corrected
- observability 0.3.4: no invented traces when nothing wrote spans
- plugin-creator 0.4.3: required plugin.json fields and tool existence check
Co-Authored-By: RuFlo <ruv@ruv.net>
Under Git Bash MSYS rewrote the /c of the generated cmd /c IF EXIST hook, so cmd
started interactively, executed the hook's stdin JSON and created zero-byte files
from text after a >. The Windows hook is now a single node -e with no cmd, no
%VAR%, and none of < > | & $ or inner double quotes. It keeps the project-first
then user-profile fallback (#1943), user scope never reads the project, and the
helper runs as a child with inherited stdio so stdin and the exit status pass
through. pinToUserHelpers recognises the new form (exact match only) as well as
the old ones.
Co-Authored-By: RuFlo <ruv@ruv.net>
The statusline now builds shell command lines from HELPER_ROOT (the checkout's
directory, chosen by whoever made it). A directory named p$(...) was expanded
inside the double-quoted command; shell-active paths are now skipped.
The statusline-generator delegation smoke ran the generated helper from tmpdir,
so with CLI resolution moved to the helper root it fell through to the registry's
published CLI (intelligencePct null). It now writes the helper into a throwaway
helper root whose v3/@claude-flow/cli is the repo's built CLI.
Co-Authored-By: RuFlo <ruv@ruv.net>
Settings written to ~/.claude/settings.json apply to every project the user
opens. The #1943 probe ran `$CLAUDE_PROJECT_DIR/.claude/helpers/<script>`
whenever that file existed, so in user-level settings the opened project
decided which helper code ran.
helper-commands.ts now owns the hook/statusline command forms:
- project-level settings keep the #1943 project-first probe, unchanged;
- user-level settings (init target is the home directory) get commands
pinned to $HOME/.claude/helpers with no project lookup;
- `init --upgrade --settings` on the home directory re-pins the probe and
git-root forms ruflo generated earlier and leaves user-authored commands.
The #1943/#1948 fix invariants now point at helper-commands.ts.
Test: settings-user-level-helpers.test.ts (8 cases).
- smoke-plugin-registry-signature.mjs: follow the verifier rename to
registrySignatureFailure and require the fail-closed call site
`if (failure) return this.fallbackToBuiltIn(`, keeping full #1922 coverage.
- verifyEd25519Signature verifies in RFC 8032 strict mode, and
isPlaceholderSigningKey rejects every small-order or off-curve key, not
only the all-zero one.
- An unverified registry claims no official plugins and no verified
authors; MCP transfer_plugin-* results carry the registry status.
- Tests no longer assume the shipped trust anchor stays a placeholder.
- Document the strict-mode asymmetry for unlisted packages in --help.
Console 0.42.0: Overview "Grounding" line (on / not installed / installed, disabled / unknown), a default-on nudge setting that adds one fixed line pointing at search_ruvnet to the mission context when the brain is on and the mission names the ruvnet stack (through modelLine, nothing interpolated), and a default-off, dismissible once-per-session install hint. Mods 0.5.0: option `grounding` (default off) adds a read-only /ruflo-mods row.
Detect-only: never calls, installs, gates, blocks or copies anything of the third-party plugin; ruflo behaves identically without it (smoke steps console 20, mods 15).
Co-Authored-By: RuFlo <ruv@ruv.net>