Skip to main content

snippet-automation

Generate and sync Bluehawk snippets across MongoDB docsets. Use when the user asks to "run snip", "generate snippets", "sync snippets", "add snippet", "list snippets", "setup snippet for a docset", "set up a snippet source", or wants to extract and distribute content from a source docset to target docsets.

معلومات المصدر

المستودع
mongodb/docs
آخر نشاط في المصدر
١٧ سبتمبر ٢٠٢٦ في ٢٢:٥٥
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٧٧٧
التفرعات
١٬٦٩٩

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
4 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
snippet-automation
description
Generate and sync Bluehawk snippets across MongoDB docsets. Use when the user asks to "run snip", "generate snippets", "sync snippets", "add snippet", "list snippets", "setup snippet for a docset", "set up a snippet source", or wants to extract and distribute content from a source docset to target docsets.
# Snippet Automation: Cross-Docset Content Sharing Generate Bluehawk snippets from source files and distribute them to target docsets using the `snip.js` tooling with manifest-based change tracking. ## Scope **ALWAYS use when:** - User asks to "run snip", "generate snippets", "sync snippets", "add snippet", or "list snippets" - User wants to share content from one docset to others (atlas → search, vector-search, etc.) - User needs to register, remove, or check monitored snippet files - User wants to set up a new snippet source docset — add `snip.js`, `package.json`, and CI registration (also the version-flip setup for a versioned docset) **NEVER use when:** - Files are in `code-examples/tested/` → STOP, tell user to use Grove skill instead - User wants Grove test suite snippets → STOP, wrong skill - User wants to edit RST content directly → STOP, no skill needed ## Prerequisites **CI automation (recommended):** No local setup required. GitHub Action handles everything. **Local runs require:** - Node.js v18+ (MUST have) - npm (MUST have) - Bluehawk CLI: `npm install -g bluehawk` (MUST install first — installed globally, not as a docset dependency) ## Required Markers (Proprietary Syntax) Source files MUST contain these exact RST comments: ```rst .. :snippet-start: snippet-name .. :snippet-output: content/<target>/source/includes/path/filename.rst (content here) .. :snippet-end: ``` **Validation rules (enforce strictly):** - `:snippet-output:` is REQUIRED — STOP if missing, tell user to add it - Multi-snippet files MUST use explicit filenames, not directories — STOP if directory-only - Snippet names MUST be unique within a file — STOP on duplicate `:snippet-start:` names - Each block MUST have exactly one `:snippet-output:` — use comma-separated paths for multiple destinations, not repeated tags - Output filename gets `-snippet-from-<source>` suffix automatically (do NOT add manually) - Files in `code-examples/tested/` are FORBIDDEN — STOP immediately if detected. `snip.js` also enforces this: it skips these paths during directory traversal and rejects an explicit `--add` with `Excluded path, not added: <file>` **References:** - `references/bluehawk-syntax.md` — full syntax and validation rules - `references/snip-js-config.md` — configured docsets and error messages - `references/manifest-schema.md` — manifest structure for change tracking ## Versioned Docsets Only ONE version per versioned docset can be a snippet source, because output filenames carry the docset name but not the version. For `self-managed-search` that version is `current`. - Treat `:snippet-start:` markers in any other version (`upcoming`, `vX.Y`) as inert. They generate nothing. Do NOT add `:snippet-output:` tags to them to "fix" the invalid-marker report — that creates colliding output paths. - If the user asks to sync a non-`current` version, STOP and explain that its markers activate only at version flip. See `references/snip-js-config.md` for the flip checklist. ## Commands | Command | What It Does | Success Output | |---------|--------------|----------------| | `sync snippets` | Regenerate changed snippets across all docsets | `Sync complete: N file(s) changed, M snippet(s) written, X orphaned output(s) deleted.` | | `sync snippets for <docset>` | Sync one docset only | Same as above, scoped to that docset's manifest | | `add snippet <file>` | Register file for tracking | `Added to manifest: <path>` then ` Snippets: <names>` | | `register snippets <dir>` | Bulk-register directory | `Registered N file(s) from <dir>` | | `remove snippet <file>` | Stop tracking and delete output files | `Removed from manifest: <path> (N snippets, M output files deleted)` | | `list snippets` | Show tracked files | `Monitored files (N):` then each file with its snippets and output paths | | `setup snippet for <docset>` | Set up a new snippet source docset: copy `snip.js`, add `package.json`, register in CI, then init the manifest | drift check passes and `✓ Created empty manifest: <path>` | | `init manifest` | Create empty manifest (aborts if exists) | `✓ Created empty manifest: <path>` | | `reset manifest` | Clear all tracked files | `✓ Reset manifest: <path>` | | `validate manifest` | Check markers, files, and hashes | `N valid, M out of sync, X missing or invalid` | | `run snip` | One-off generation (no tracking) | Interactive prompt | **CLI equivalent**: `cd <source-dir> && npm run snip -- --<flag>`, where `<source-dir>` is the docset's snippet root: | Docset | `<source-dir>` | |--------|----------------| | atlas | `content/atlas/source` | | self-managed-search | `content/self-managed-search/current/source` | Only these two docsets have a `snip.js`. Destination docsets such as `search` and `vector-search` do not — they only receive generated output. Versioned docsets keep `snip.js` in one version only, so do NOT assume `content/<docset>/source`. **Example**: `/snippet-automation add snippet includes/nav/list-data-explorer.rst` ## Automation A GitHub Action (`.github/workflows/snippet-sync.yml`) automatically: 1. **Triggers** on PRs touching a configured docset's `includes/**` or its `snippet-manifest.json`. The paths are listed explicitly per docset, not globbed — `self-managed-search` is registered as `current/source/includes/**`, so markers in other versions never trigger it 2. **Installs Bluehawk** in the CI runner 3. **Runs `--sync`** for affected docsets with manifests 4. **Commits regenerated snippets** back to the PR branch Writers don't need Bluehawk installed locally — CI handles regeneration. ## Manual Workflows Every workflow starts by resolving the docset's source directory from the file path. Two shapes exist: - `content/<docset>/source/...` → source dir is `content/<docset>/source` - `content/<docset>/<version>/source/...` → source dir is `content/<docset>/<version>/source`, and only ONE version has `snip.js` (see Versioned Docsets above) VERIFY the directory has a `snip.js` before running any command: `ls <source-dir>/snip.js`. If it is absent, that version is not a snippet source — STOP, UNLESS the user is setting one up (see "Set up a new snippet source docset" below, the one workflow that runs before `snip.js` exists). All other commands below run from `<source-dir>`. ### Set up a new snippet source docset Use when a destination docset needs to become a source, or when a versioned docset flips and the incoming version must take over sourcing (see Versioned Docsets above). `<source-dir>` is the new docset's snippet root — `content/<docset>/source` or, for a versioned docset, the single owning version's `content/<docset>/<version>/source`. 1. CONFIRM it is not already a source: `ls <source-dir>/snip.js` MUST be absent. If it exists, STOP — the docset is already set up; use the tracking workflows instead. 2. COPY an existing copy verbatim — do NOT hand-write one: `cp content/atlas/source/snip.js <source-dir>/snip.js`. The drift check (`.github/scripts/check-snip-drift.js`) requires every copy to be byte-identical apart from one line. 3. EDIT only `DEFAULT_START_DIRECTORY` in the new copy so it equals `<source-dir>` exactly (for example `content/foo/source`). The drift check FAILS if this value is anything other than the copy's own directory. Change nothing else. 4. ADD `package.json` in `<source-dir>` with `"type": "module"` (required for the ESM `import` syntax) and the `snip` script: ```json { "name": "<docset>", "private": true, "type": "module", "scripts": { "snip": "node snip.js" } } ``` No `npm install` is needed — no dependencies are declared. Bluehawk is installed globally. 5. REGISTER the docset in `.github/workflows/snippet-sync.yml` with THREE edits: - Under `on.pull_request.paths`, add `content/<docset-path>/includes/**` and `content/<docset-path>/snippet-manifest.json`, where `<docset-path>` is `<source-dir>` minus the repo prefix. - In the `Detect changed docsets` step, add a `grep`/`DOCSETS` block appending the docset name when a matching file changes. - Add a `Sync <docset> snippets` step that `cd`s into `<source-dir>` and runs `--sync` when its manifest exists. Its `contains()` guard MUST use the space-padded form (`' {0} '`, `' <docset> '`) — an unpadded `search` would also match `self-managed-search` and fire the wrong step. Do NOT touch `check-snip-drift`: it discovers copies by walking `content/`, so the new copy is covered automatically. 6. INIT the manifest: `cd <source-dir> && npm run snip -- --init`. 7. VERIFY: run `node .github/scripts/check-snip-drift.js` (MUST exit 0) and `cd <source-dir> && npm run snip -- --validate`. 8. REPORT the files created (`snip.js`, `package.json`, `snippet-manifest.json`), the workflow edits, and the drift-check result. **Version-flip variant:** these steps also cover a versioned docset's flip, where the incoming version takes over sourcing. One extra consideration applies — source files branched forward into the new version keep their `:snippet-start:` markers but LOSE their `:snippet-output:` tags. Restore the `:snippet-output:` tag on every such file before step 6, or `--validate`/`--sync` reports them as invalid and skips them. **Worked example — converting `search` (a destination) into a source.** `<source-dir>` = `content/search/source`; each command maps to the numbered step above: ```bash ls content/search/source/snip.js # 1. MUST print "No such file" cp content/atlas/source/snip.js content/search/source/snip.js # 2. copy verbatim # 3. edit copy: const DEFAULT_START_DIRECTORY = "content/search/source"; # 4. add content/search/source/package.json (block above, "name": "search") # 5. snippet-sync.yml: add the two paths + a DOCSETS grep + a --sync step # guarded by contains(..., ' search ') — space-padded, else it also # matches self-managed-search cd content/search/source && npm run snip -- --init # 6. node .github/scripts/check-snip-drift.js # 7. MUST exit 0 cd content/search/source && npm run snip -- --validate # 7. ``` ### Add a file to tracking 1. VERIFY markers exist and are well-formed. The minimum valid block is: ```rst .. :snippet-start: list-data-explorer .. :snippet-output: content/search/source/includes/nav/list-data-explorer.rst In |service|, go to the :guilabel:`Data Explorer` page. .. :snippet-end: ``` If markers are missing or malformed, STOP and tell the user what to add. `--add` rejects the file rather than registering it, so bad markers cannot be fixed later by syncing. 2. EXECUTE: `npm run snip -- --add <file>` 3. VERIFY output exists: `ls content/<target>/source/includes/path/*-snippet-from-*.rst` 4. REPORT exactly: "Added [file] to manifest, generated [output] at [path]" ### Sync changed snippets 1. EXECUTE: `npm run snip -- --sync` 2. CHECK the exit code. Non-zero means files were skipped for invalid markers or failed to generate — the `Sync complete:` line still prints, so do NOT treat it alone as success. 3. If any `✗ Invalid: <file>` appeared, STOP and report which files were skipped and why. Fix markers, then re-run. 4. REPORT the `Sync complete: N file(s) changed, M snippet(s) written, X orphaned output(s) deleted.` counts. ### Remove a file from tracking `--remove` DELETES generated output files. Confirm with the user before running it. 1. RUN `npm run snip -- --list` first and show the user which outputs will be deleted. 2. EXECUTE: `npm run snip -- --remove <file>` 3. VERIFY the deleted outputs are no longer referenced: `grep -rn "<basename>-snippet-from-" content/`. Any surviving `.. include::` will break the target docset's build — report these to the user. 4. REPORT the `Removed from manifest: <path> (N snippets, M output files deleted)` line. ## Error Handling (STOP conditions) | Condition | Action | |-----------|--------| | Missing `:snippet-output:` | STOP. Tell user: "Add `:snippet-output:` tag with target path" | | Directory path in multi-snippet file | STOP. Tell user: "Each snippet MUST have explicit filename" | | Duplicate `:snippet-start:` name in one file | STOP. Tell user: "Rename so every snippet name in the file is unique" | | Repeated `:snippet-output:` in one block | STOP. Tell user: "Use one tag with comma-separated paths" | | `:snippet-output:` path has no file extension | STOP. Tell user: "Add the file extension, for example `.rst`" | | `--sync` reports `✗ Invalid: <file>` | STOP. The file was skipped and `--sync` exited non-zero. Fix the markers, then re-run | | `--sync` or `--validate` reports untracked snippet | Run `--sync` to add it to the manifest and generate its output | | `--sync` or `--validate` reports output path changed | Run `--sync` to delete the stale output and regenerate at the new path | | Target directory missing | CREATE it: `mkdir -p content/<target>/source/includes/path/` | | Bluehawk not installed locally | RECOMMEND CI. If local needed: `npm install -g bluehawk` | | File in `code-examples/tested/` | ABORT. Tell user: "Use Grove skill, not snippet-automation" |
عرض على GitHub