ship-helpbot — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited ship-helpbot (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Turn the user guide you already have into an in-app assistant users can ask in plain language — and that answers only from the guide, with citations that deep-link to the exact section. Two drop-in pieces do this in any app:
launcher + chat panel). Plain HTML, React/Next, Vue, Svelte, Astro — anywhere.
an LLM to answer using only those, returning { answer, citations }.
A small script chunks the guide markdown into docs/guide-index.json (the retrieval corpus). The retrieval ranking is dependency-free and runnable on the CLI, so you can verify answer quality before any API key is involved. The LLM is pluggable behind an adapter (Claude / Vercel AI Gateway / local Ollama), so the same code runs on any stack.
This is grounded retrieval over your own docs — not a general chatbot. If the guide doesn't cover something, the bot says so instead of inventing steps.
This skill consumes the output of user-guide-builder and shares the same docs/VERSION anchor and docs/brand.json theming as the rest of the pack:
docs/VERSION ← single source of truth (semver)
├─ user-guide-builder → writes docs/user-guide/<Guide>.md + renders <Guide>.html (anchors = heading slugs)
├─ ship-helpbot → chunks that .md into guide-index.json; answers cite the SAME anchors (this skill)
├─ shipping-log → "what changed" (the bot can point users to what's new)
└─ screenshot-capture → the images the guide referencesBecause the index reuses the guide renderer's anchor slugs, a citation like ▸ Change Orders links straight to /help#change-orders in the rendered guide. Re-run the chunker on each release. Also relevant: logo-pack for the launcher mark if you want one.
Before building anything, run this discovery so you don't clobber or duplicate work:
node "<skill-dir>/scripts/version.mjs" get 2>/dev/null # current docs version (or init it)
ls docs/brand.json docs/guide-index.json 2>/dev/null # brand tokens? a prior index?
ls docs/user-guide/*.md docs/user-guide.md USER_GUIDE.md 2>/dev/null # the guide to chunk
ls public/ship-helpbot.js public/guide-index.json 2>/dev/null # widget already deployed?
ls app/api/ask-docs/route.* pages/api/ask-docs.* 2>/dev/null # route already wired?Interpret the results:
user-guide-builder first (/ship-guide). The helpbot isonly as good as the guide; there is nothing to chunk without it. Say so plainly.
Offer to create brand.json (see logo-pack / the pack) so the launcher matches the app, but don't block on it.
node "<skill-dir>/scripts/version.mjs" init 0.1.0 and say so.<skill-dir> is this skill's folder. Use the absolute path the slash command passes, or ${CLAUDE_PLUGIN_ROOT}/skills/ship-helpbot.
node "<skill-dir>/scripts/build-index.mjs" \
--in docs/user-guide/<Guide>.md --out docs/guide-index.json \
--version docs/VERSION --brand docs/brand.json--in to auto-discover the guide (docs/user-guide/*.md, then docs/user-guide.md, …).##/### heading becomes one section: { id, title, level, anchor, breadcrumb, text, tokens }.Anchors are the same slugs the guide's HTML renderer emits, so citations deep-link.
[SCREENSHOT:] markersare stripped. Tune granularity with --min-level/--max-level (default h2–h3).
fix the guide (run user-guide-builder), not the chunker.
node "<skill-dir>/scripts/retrieve.mjs" --index docs/guide-index.json --q "how do I add a change order"This runs the exact ranking the route uses (BM25-lite + title boost) and prints the top sections with scores. If the right section isn't on top, the bug is in chunking or the guide — catch it here, cheaply. Try 3–5 real user questions. This step is the quality gate.
node "<skill-dir>/scripts/build-widget.mjs" \
--out public/ship-helpbot.js --brand docs/brand.json \
--endpoint /api/ask-docs --src /guide-index.jsonWrites one self-contained custom-element file. Colors/fonts come from brand.json (baked in, also overridable at runtime via --shb-* host CSS). No purple default, no `backdrop-filter`, no SVG `feTurbulence` — per the pack's HTML rules; Shadow DOM isolates it from host CSS; honors prefers-reduced-motion. Also copy guide-index.json to where it's served (e.g. public/).
/api/ask-docs routeRead [references/api-route.md](references/api-route.md) and create the route for the app's stack (Next.js route shown in full; Express/SvelteKit/Remix/edge notes included). Copy scripts/retrieve.mjs into the app (e.g. lib/ship-helpbot/retrieve.mjs) and import { rank } — do not re-implement ranking. Pick the model adapter via HELPBOT_PROVIDER env var.
Read [references/embedding.md](references/embedding.md) and add the two lines (script + tag) to the app's root layout. Set guide="/help" (or wherever the rendered guide is served) so citations deep-link. Verify the launcher appears, ask a real question, confirm an answer + a working citation.
Tell the user: index path + section count + version stamped, the widget/route files written, which model provider is wired (and the env vars it needs), and any gaps (e.g. "guide is thin on billing — the bot will say it can't answer billing questions"). Do not paste the whole index into chat.
Pick at runtime with HELPBOT_PROVIDER. Full code in references/api-route.md.
| Provider | HELPBOT_PROVIDER | Needs | Use when |
|---|---|---|---|
| Anthropic Claude (direct) | claude | ANTHROPIC_API_KEY | best answer quality; check claude-api skill for model ids |
| Vercel AI Gateway | gateway | AI_GATEWAY_API_KEY | one key, many models, failover; app already on Vercel |
| Local Ollama (LAN/offline) | ollama | OLLAMA_URL (e.g. http://localhost:11434) | private/offline; no per-token cost |
Adapters are referenced via env, not assumed installed — if a provider isn't configured the route fails soft (502 + friendly message) and the widget still links to the guide. If the repo already uses the Vercel AI SDK, prefer generateText (see the vercel:ai-sdk skill) over raw fetch.
The helpbot isn't done until all of these hold:
an honest "I couldn't find that in the guide," never a fabricated feature, price, or step.
anchor opens the matching section in the rendered guide. Click one and verify it lands.
retrieve.mjs on real questions and the rightsections ranked first. (If retrieval is wrong, the LLM can't save it.)
brand.json; no purple default; nobackdrop-filter/feTurbulence; Shadow-DOM isolated; respects reduced motion; one file, no deps.
nothing hardcoded to one project. Index, widget, and route all read brand/version where relevant.
src neverused as a filesystem path. See the hardening checklist in references/api-route.md.
A bot that confidently invents steps is worse than no bot. Grounding + citations are non-negotiable.
A full input→output trace (guide slice → guide-index.json → ranked retrieval → grounded, cited answer, including the honest-failure case) is in [references/worked-example.md](references/worked-example.md).
scripts/build-index.mjs — chunk the guide markdown into docs/guide-index.json (run it).scripts/retrieve.mjs — dependency-free BM25-lite ranking; CLI verifier and the rank()the route imports. Don't reinvent retrieval; import this.
scripts/build-widget.mjs — emit the themed, self-contained <ship-helpbot> web component.scripts/version.mjs — the shared semver anchor manager (byte-identical across the pack).references/api-route.md — the /api/ask-docs route, system prompt, the three model adapters,full Next.js code, and the hardening checklist.
references/embedding.md — how to embed <ship-helpbot> in HTML/Next/Vue/Svelte/Astro; attributes; theming.references/worked-example.md — one concrete input→output trace.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.