ship-onboarding — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited ship-onboarding (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 project's user guide and screenshots into a real first-run experience: an ordered docs/onboarding.json (the spec) and an embeddable, on-brand coachmark tour component that spotlights elements, walks a new user to their first win, and fires once per release.
This is the in-app sibling of the guide: user-guide-builder explains every feature on a docs page; this skill picks the shortest activation path out of those features and shows it inside the running app. It does not invent product behavior — it derives steps from the guide and you write honest, specific copy.
docs/VERSION ← shared semver anchor (stamps the tour's version + storageKey)
docs/brand.json ← brand-as-data (colors + fonts) → themes the component, never purple
│
├─ user-guide-builder → the guide whose workflows seed the tour's steps
├─ screenshot-capture → the shot ids a step can show before its element exists
├─ shipping-log → the release that bumps VERSION (re-show the tour once)
└─ ship-onboarding → docs/onboarding.json + an embeddable tour component ← you are here1. node scripts/onboarding.mjs scaffold → DRAFT docs/onboarding.json from the guide workflows
2. Trim to the activation path + write real copy and real selectors (references/authoring…md)
3. node scripts/onboarding.mjs validate → lint shape, ids, version, leftover drafts
4. node scripts/render-tour.mjs → onboarding-tour.js + onboarding-preview.html
5. Open the preview, click through, refine the JSON, re-render
6. Embed <onboarding-tour> in the app shell; add data-tour hooks to the target elementsScripts are run, never inlined. Both are dependency-free Node (.mjs) — nothing to install.
Before generating anything, look. Never overwrite real work or pretend inputs exist.
| Look for | Why it matters |
|---|---|
docs/onboarding.json | Already there → UPDATE it, don't overwrite. Re-run validate/gaps, refine. |
docs/user-guide/*.md (or docs/user-guide.md) | Source of workflow steps. No guide → run user-guide-builder first, or hand-author steps. |
docs/screenshots.config.json | Shot ids a step can display. Lets a tour exist before every element is wired. |
docs/brand.json | Themes the component (colors + fonts). Absent → safe non-purple defaults, and say so. |
docs/VERSION | Stamps the spec's version + storageKey. Absent → falls back to 0.1.0. |
Existing tour code (onboarding, coachmark, intro.js, driver.js, shepherd) | Don't duplicate. Adapt the spec to what's there, or replace intentionally. |
Run the read-only gap report to see exactly what's missing — no files written:
node scripts/onboarding.mjs gaps # TODO selectors · draft copy · uncovered workflows · missing screenshotsnode scripts/onboarding.mjs scaffold \
--guide docs/user-guide/<Guide>.md \
--shots docs/screenshots.config.json \
--out docs/onboarding.jsonThis reads the guide's ##/### workflow headings, drops meta sections (TOC, glossary, appendices, FAQ), and proposes welcome + up to 7 coachmarks + finish, each marked draft:true with a TODO: selector and a REPLACE … body. It matches a step to a screenshot id when the workflow slug equals a shot id. Nothing pretends to be wired up. --force to overwrite a previous draft.
If there's no guide, the scaffold emits a starter step and warns — hand-author the steps from the routes/nav instead, or build the guide first.
The scaffold is a candidate list, not the answer. A first-run tour is the shortest path to one real win, not a tour of every feature. Cut to 4–8 steps:
invite crew). Drop settings, admin, glossary.
Copy must be specific and honest: name the real screen/button, give one action to try, say what they'll get. No "simply/just," no feature lists, no claims the guide can't back. Full copy rules, selector strategy, and a complete input → output worked example are in [references/authoring-and-embedding.md](references/authoring-and-embedding.md). The spec field reference is [references/spec-schema.md](references/spec-schema.md).
Wire each step to a stable hook — prefer data-tour="<id>" attributes over brittle CSS selectors — then drop the TODO: and draft flags.
node scripts/onboarding.mjs validate # exits non-zero on structural errorsChecks: array shape, unique step ids, semver version and whether it matches docs/VERSION, duplicate selectors, screenshot ids with no matching shot, and any leftover draft:true / TODO / REPLACE. Fix everything it flags before rendering.
node scripts/render-tour.mjs \
--in docs/onboarding.json --out-dir docs/onboarding --brand docs/brand.jsonWrites two self-contained, brand-themed artifacts:
<onboarding-tour> Web Component(spotlight + coachmark, Next/Back/Skip, dots, localStorage "fire once," graceful fallback when a selector isn't on the page). Drops into React/Vue/Svelte/plain HTML unchanged.
mock app so you can click through the real copy before wiring it in. No server needed.
Themed entirely from docs/brand.json via :root --ob-* variables. Never purple by default (blue/amber defaults). No backdrop-filter, no SVG feTurbulence — the spotlight is a plain box-shadow ring, so it never hangs a renderer. Embedded, the component inherits your app's CSS variables if you define the same names.
Copy onboarding-tour.js + onboarding.json into the app's public dir, add data-tour hooks to the target elements, and mount <onboarding-tour src="/onboarding.json"> once in the authenticated shell (not the marketing site). It self-fires for users who haven't seen storageKey. Give users a restart() control for "show me around again." Full React/Next.js snippet and route handling: references/authoring-and-embedding.md.
On each release, re-stamp `version` + `storageKey` (so returning users see a materially new path once), re-run gaps, and re-render. Edit the JSON and re-render — never hand-edit the generated .js.
Nothing here is app-specific. The guide, brand, routes, and selectors all come from the target repo's docs/. The same scripts serve MyFieldTime, LogNog, Directors Palette, or any web app — only the inputs change. The component is a plain Web Component, so it works regardless of the app's framework. External tour libraries (driver.js, Shepherd, intro.js) are adapters you can target, not dependencies — the default output assumes none of them are installed.
The tour isn't done until:
no generic "manage your X here," no claim the guide can't back.
data-tour), not a TODO: placeholder;validate reports zero drafts and zero errors.
backdrop-filter / feTurbulence.
version + storageKey match docs/VERSION, so the tour re-shows once after a real release.onboarding-preview.html) and clicked through — it reads like a calmproduct trainer, not a feature dump.
If any of these fail, keep going.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.