v0.7.4 — plugin-root paths, Summer-only X-Userinfo, token: none
Three dogfooding bugs, all found running spec-flow against an external Node/Express project (claude-code-provider / tenant-usage-monitoring). None are in the target project's code — all three are spec-flow defects that cost real debugging time.
bin/task-masterwas invoked cwd-relative in the skill instructions.commands/{phase,ingest,init,change,resync}.mdandagents/hybrid-executor.mdtold the agent to runnode bin/task-master …, but those commands execute in the user's project, which has nobin/task-master— the binary lives in the plugin. Result:MODULE_NOT_FOUND, and the agent had to hand-resolve the plugin's absolute path to continue. Nownode ${CLAUDE_PLUGIN_ROOT}/bin/task-master …, matching how everyflow-tools.cjsinvocation was already written. Root cause:scripts/cutover.cjs'sNATIVE_CLI_PREFIX(v0.7.0) rewrote the oldnpxinvocations to a relative path. The cutover/rollback script pair is left as-is — it is one-shot historical migration tooling and the legacy dependency it targets is already removed.docs/invocations are unchanged: those are run from the spec-flow repo root, where the relative path is correct.detect-auth.shmissed customAuthorization: Bearerschemes, andchecklist-gendefaulted the wrong way. Two compounding bugs. (1) The detector classifies by dependency fingerprint (jsonwebtoken,jjwt,pyjwt, …), so a service that reads theAuthorizationheader itself and validates an opaque API key — no JWT library anywhere — fell through tounknown. It now also greps the source for header-read +Bearerprefix, across every stack, and reportsjwt-basic(same wire form; only how you mint the token differs). (2)checklist-gentreated the Summer/APISIXpayload:/X-Userinfoform as the default andbearer:as the special case — exactly backwards.X-Userinfois a Summer/APISIX-specific convention that is only trusted behind a real gateway upstream; an unclassified project got a scaffold that 401s every generated test with a failure that reads like an app bug. Now inverted: only an explicitly-detectedsummerproject getspayload:;jwt-basic,session,no-auth, andunknownall scaffoldbearer: "${TOKEN}"with an advisory comment naming the detected type. (Hit twice in one session, on two different projects.)token: nonefailed instead of sending an unauthenticated request. The natural way to write a 401 / public-endpoint test —token: none— was looked up as a token named"none"in thetokens:map, missed, and failed the test withunknown token 'none'. The working spelling (omit thetoken:line entirely) was documented nowhere.checklist_lib/runner.pynow treatsnone/null/no-auth/noauth/anonymous/false/-as "send no auth header", while a token genuinely declared under that name still wins (backward-compatible). The error for a real typo now lists the declared token names and points at the no-auth spelling. Documented inreferences/checklist.md,templates/CHECKLIST.yaml,commands/checklist.md, and the generated scaffold's own header comment..mcp.jsonmade plugin-root-absolute too (same root cause as the first item): the bundled MCP server entry was["bin/mcp-server.js"], now["${CLAUDE_PLUGIN_ROOT}/bin/mcp-server.js"]. Caveat:${CLAUDE_PLUGIN_ROOT}is only defined when the file is loaded as a plugin manifest — opening the spec-flow repo directly as a project no longer resolves it. Plugin distribution is the primary path, so that is the right trade; revert this one line if you need the repo-as-project case back.- 778 Node tests green (assertions updated for the flipped auth default), 48 Python tests green (5 new).