export declare const HELPERS_STAMP_FILE = ".helpers-version"; export declare const HELPERS_REFRESH_LOCK_FILE = ".helpers-refresh.lock"; interface RefreshOptions { sourceDirOverride?: string; pubkeyPemOverride?: string; versionOverride?: string; alsoRefreshGlobal?: boolean; beforeWriteOverride?: () => void | Promise; lockWaitMsOverride?: number; lockRetryMsOverride?: number; malformedLockStaleMsOverride?: number; } /** * ruflo-owned helpers that carry hook logic (or the render surface for the * funnel disclosure row) and must track the package version. Adding to this * list REQUIRES re-signing `helpers.manifest.json` at publish time — the * integrity gate below refuses any file it doesn't have a signed hash for. */ export declare const CRITICAL_HELPERS: string[]; /** Installed @claude-flow/cli version — the value the helpers are stamped with. */ export declare function getInstalledCliVersion(): string; /** * On CLI startup, refresh critical helpers if their stamp is older than the * installed CLI version. Two passes: * * 1. **Project pass** — `/.claude/helpers/`. Always attempted. The * original behavior; project statuslines pin to a stamp per repo. * * 2. **Global pass** — `~/.claude/helpers/`. Opt-in via `alsoRefreshGlobal`. * Fixes the "promo row missing on remote installs" bug: `ruflo init` * writes helpers to `~/.claude/helpers/` too so Claude Code's global * settings.json statusLine can fall back to them (executor.ts:460-462), * but nothing ever REFRESHED that global copy — so any install predating * a helpers change (e.g. the 2026-07-13 funnel/promo Line-3 addition) * stayed frozen at the pre-feature statusline forever, even after `npm * i -g @claude-flow/cli@latest`. The global pass fixes that on the next * `ruflo ` invocation. Same forward-only `semver.gte` guard * protects against downgrade by a stale cached CLI. * * `alsoRefreshGlobal` defaults FALSE so tests don't touch the developer's * real `~/.claude/helpers/`. The real CLI entry (src/index.ts) passes * `true` to activate the global pass in production. * * Best-effort, never throws. No-op for a helpers dir that doesn't already * contain a `hook-handler.cjs` — never creates files in an unrelated dir. * * FORWARD-ONLY (never downgrades): refreshing on any mere INEQUALITY, rather * than only when the installed version is semver-NEWER, is a real corruption * vector — confirmed live: a stray/older installed binary (a stale `npx` * cache, a marketplace install lagging behind an unpublished dev-tree fix) * running `daemon start` (or any command) would see its own older version != * the project's newer stamp and silently overwrite hand-fixed * `hook-handler.cjs`/`intelligence.cjs` with its own older, already-superseded * bundled copies. The semver guard is therefore re-evaluated while holding a * per-directory cross-process lock; otherwise an older process can pass the * guard first but finish writing last. * * `opts` exists for tests ONLY (mirrors daemon-autostart.ts's injectable * `SpawnDaemonFn` pattern): the real signed-copy path is otherwise coupled * to THIS repo's actual current `.claude/helpers` + its real Ed25519 * signature — fine for production (that coupling to the real source IS the * point), but it means a test exercising that path for real would only pass * when this repo's manifest happens to be currently re-signed, which is a * separately-gated, occasionally-stale publish-time step. `sourceDirOverride` * + `pubkeyPemOverride` let a test build its own tiny, throwaway-keypair- * signed fixture and get real, deterministic coverage of the verify → hash * → copy logic without depending on that. * * Return shape: the project-pass result is the top-level object (backwards- * compat with pre-3.31.3 callers). If the global pass ran, its own result is * carried in the optional `global` field. */ export declare function autoRefreshHelpersIfStale(cwd: string, opts?: RefreshOptions): Promise<{ refreshed: boolean; from?: string; to?: string; blocked?: string; global?: { refreshed: boolean; from?: string; to?: string; blocked?: string; }; }>; export {}; //# sourceMappingURL=helper-refresh.d.ts.map