@iamdangavin/claude-skill-vitepress-docs 1.9.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{skill/SKILL.md → commands/vitedocs/init.md} +328 -21
- package/install.js +10 -6
- package/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: VitePress documentation suite —
|
|
4
|
-
argument-hint: [
|
|
2
|
+
name: vitedocs:init
|
|
3
|
+
description: VitePress documentation suite — prompts for which mode to run and proceeds directly.
|
|
4
|
+
argument-hint: [setup|generate|screenshot|sync|brand|update] or omit to be prompted
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Write
|
|
@@ -12,17 +12,21 @@ allowed-tools:
|
|
|
12
12
|
- AskUserQuestion
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
#
|
|
15
|
+
# vitedocs:init
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
If a mode was passed as an argument, proceed directly to that mode's instructions below. Otherwise use AskUserQuestion:
|
|
18
18
|
|
|
19
|
-
- header: "
|
|
19
|
+
- header: "vitedocs"
|
|
20
20
|
- question: "Which mode do you need?"
|
|
21
21
|
- options:
|
|
22
22
|
- "setup — Wire up VitePress + GitHub Actions for Pages deployment"
|
|
23
23
|
- "generate — Analyze the codebase and write documentation pages"
|
|
24
24
|
- "screenshot — Capture real screenshots and replace placeholders"
|
|
25
25
|
- "sync — Detect code drift and update docs that are out of date"
|
|
26
|
+
- "brand — Configure colors, fonts, logo, and visual identity"
|
|
27
|
+
- "update — Retrofit an existing docs setup with the latest components"
|
|
28
|
+
|
|
29
|
+
Once a mode is selected, execute that mode's full instructions inline — do not ask the user to run a different command. The complete instructions for every mode follow below.
|
|
26
30
|
|
|
27
31
|
---
|
|
28
32
|
|
|
@@ -159,7 +163,7 @@ Present the relevant checklist as plain text, then use AskUserQuestion to confir
|
|
|
159
163
|
- "Not yet — I need more time"
|
|
160
164
|
- "I have a question"
|
|
161
165
|
|
|
162
|
-
If "Not yet": tell the user to run `/
|
|
166
|
+
If "Not yet": tell the user to run `/vitedocs:setup` again when ready and exit.
|
|
163
167
|
If "I have a question": answer it, then re-ask this question.
|
|
164
168
|
|
|
165
169
|
The checklist to present (tailor to their answers):
|
|
@@ -588,13 +592,13 @@ If `apiBase` was collected in Q1b, write the following files before updating the
|
|
|
588
592
|
@click="activeTab = tab"
|
|
589
593
|
>{{ tab }}</button>
|
|
590
594
|
</div>
|
|
591
|
-
<pre class="api-ep__code"><code
|
|
595
|
+
<pre class="api-ep__code"><code v-html="highlightedSample"></code></pre>
|
|
592
596
|
<p v-if="activeTab === 'Fetch'" class="api-ep__note">
|
|
593
597
|
Must be called from an authenticated browser session — cookies are sent automatically.
|
|
594
598
|
</p>
|
|
595
599
|
<template v-if="response">
|
|
596
600
|
<div class="api-ep__section-label">Sample Response</div>
|
|
597
|
-
<pre class="api-ep__code"><code
|
|
601
|
+
<pre class="api-ep__code"><code v-html="highlightedResponse"></code></pre>
|
|
598
602
|
</template>
|
|
599
603
|
</div>
|
|
600
604
|
</div>
|
|
@@ -603,6 +607,19 @@ If `apiBase` was collected in Q1b, write the following files before updating the
|
|
|
603
607
|
<script setup>
|
|
604
608
|
import { ref, computed } from 'vue'
|
|
605
609
|
import { useData } from 'vitepress'
|
|
610
|
+
import hljs from 'highlight.js/lib/core'
|
|
611
|
+
import javascript from 'highlight.js/lib/languages/javascript'
|
|
612
|
+
import bash from 'highlight.js/lib/languages/bash'
|
|
613
|
+
import json from 'highlight.js/lib/languages/json'
|
|
614
|
+
// ADD THESE ONLY IF THE CORRESPONDING TAB WAS SELECTED IN Q1b:
|
|
615
|
+
// import php from 'highlight.js/lib/languages/php'
|
|
616
|
+
// import python from 'highlight.js/lib/languages/python'
|
|
617
|
+
|
|
618
|
+
hljs.registerLanguage('javascript', javascript) // Fetch + Axios
|
|
619
|
+
hljs.registerLanguage('bash', bash) // cURL
|
|
620
|
+
hljs.registerLanguage('json', json) // response bodies
|
|
621
|
+
// hljs.registerLanguage('php', php)
|
|
622
|
+
// hljs.registerLanguage('python', python)
|
|
606
623
|
|
|
607
624
|
const props = defineProps({
|
|
608
625
|
method: { type: String, required: true },
|
|
@@ -658,9 +675,32 @@ const currentSample = computed(() => {
|
|
|
658
675
|
return ''
|
|
659
676
|
})
|
|
660
677
|
|
|
678
|
+
const tabLang = {
|
|
679
|
+
'Fetch': 'javascript',
|
|
680
|
+
'Axios': 'javascript',
|
|
681
|
+
'cURL': 'bash',
|
|
682
|
+
'PHP': 'php',
|
|
683
|
+
'Python': 'python',
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const highlight = (code, lang) => {
|
|
687
|
+
const registered = hljs.getLanguage(lang)
|
|
688
|
+
return registered
|
|
689
|
+
? hljs.highlight(code, { language: lang }).value
|
|
690
|
+
: hljs.highlightAuto(code).value
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
const highlightedSample = computed(() =>
|
|
694
|
+
highlight(currentSample.value, tabLang[activeTab.value] ?? 'bash')
|
|
695
|
+
)
|
|
696
|
+
|
|
661
697
|
const formattedResponse = computed(() =>
|
|
662
698
|
props.response ? JSON.stringify(props.response, null, 2) : ''
|
|
663
699
|
)
|
|
700
|
+
|
|
701
|
+
const highlightedResponse = computed(() =>
|
|
702
|
+
formattedResponse.value ? highlight(formattedResponse.value, 'json') : ''
|
|
703
|
+
)
|
|
664
704
|
</script>
|
|
665
705
|
|
|
666
706
|
<style scoped>
|
|
@@ -686,10 +726,10 @@ const formattedResponse = computed(() =>
|
|
|
686
726
|
</style>
|
|
687
727
|
```
|
|
688
728
|
|
|
689
|
-
**Install
|
|
729
|
+
**Install dependencies** in the docs folder:
|
|
690
730
|
|
|
691
731
|
```bash
|
|
692
|
-
cd DOCS_FOLDER && npm install medium-zoom
|
|
732
|
+
cd DOCS_FOLDER && npm install medium-zoom highlight.js
|
|
693
733
|
```
|
|
694
734
|
|
|
695
735
|
**`.vitepress/theme/index.css`** — create if it doesn't exist, otherwise append:
|
|
@@ -753,7 +793,7 @@ Add `docs-manifest.json` to `.vitepress/` entry in `.gitignore`.
|
|
|
753
793
|
|
|
754
794
|
```
|
|
755
795
|
Generated X pages (Y user-facing, Z developer).
|
|
756
|
-
Created N placeholder screenshots — run /
|
|
796
|
+
Created N placeholder screenshots — run /vitedocs:screenshot when ready to capture real images.
|
|
757
797
|
Filled M of P gaps — X remaining gap comments left in files for manual review.
|
|
758
798
|
```
|
|
759
799
|
|
|
@@ -785,8 +825,8 @@ const OUTPUT = 'FILL_IN_OUTPUT_PATH';
|
|
|
785
825
|
const scanlines = [];
|
|
786
826
|
for (let y = 0; y < H; y++) {
|
|
787
827
|
const row = Buffer.alloc(1 + W * 3);
|
|
788
|
-
row[0] = 0;
|
|
789
|
-
row.fill(0x88, 1);
|
|
828
|
+
row[0] = 0;
|
|
829
|
+
row.fill(0x88, 1);
|
|
790
830
|
scanlines.push(row);
|
|
791
831
|
}
|
|
792
832
|
const raw = Buffer.concat(scanlines);
|
|
@@ -813,7 +853,7 @@ function makeChunk(type, data) {
|
|
|
813
853
|
const sig = Buffer.from([137,80,78,71,13,10,26,10]);
|
|
814
854
|
const ihdr = Buffer.alloc(13);
|
|
815
855
|
ihdr.writeUInt32BE(W, 0); ihdr.writeUInt32BE(H, 4);
|
|
816
|
-
ihdr[8] = 8; ihdr[9] = 2;
|
|
856
|
+
ihdr[8] = 8; ihdr[9] = 2;
|
|
817
857
|
|
|
818
858
|
mkdirSync(dirname(OUTPUT), { recursive: true });
|
|
819
859
|
writeFileSync(OUTPUT, Buffer.concat([
|
|
@@ -896,7 +936,7 @@ import { chromium } from '/opt/homebrew/lib/node_modules/playwright/index.mjs';
|
|
|
896
936
|
|
|
897
937
|
**⛔ Credential rule — NEVER write credentials to any file.** Do not write them to a script file, `.env`, the manifest, or anywhere on disk. All Playwright scripts run as inline bash heredocs — credentials are passed directly as inline values to `page.fill()` calls within the heredoc and exist only in memory for the duration of the command. If Playwright needs credentials in a reusable way, use a saved storage state file — but prompt the user for credentials fresh each time rather than caching them.
|
|
898
938
|
|
|
899
|
-
**For pages requiring auth:** if credentials were provided, drive a login flow before navigating to the target URL. If no credentials were given, skip auth-gated pages and list them in the final summary so the user can run screenshot
|
|
939
|
+
**For pages requiring auth:** if credentials were provided, drive a login flow before navigating to the target URL. If no credentials were given, skip auth-gated pages and list them in the final summary so the user can run `/vitedocs:screenshot` again with credentials.
|
|
900
940
|
|
|
901
941
|
**Standard capture script template:**
|
|
902
942
|
|
|
@@ -916,9 +956,7 @@ SCRIPT
|
|
|
916
956
|
|
|
917
957
|
Adjust `SETTLE_MS` based on stack type: WordPress/non-SPA → `500`, Next.js/SPA → `2000`–`4000`.
|
|
918
958
|
|
|
919
|
-
Never write the script to a file — always use the heredoc form above.
|
|
920
|
-
|
|
921
|
-
After each capture, display the image inline with the Read tool so the user can verify it before moving on.
|
|
959
|
+
Never write the script to a file — always use the heredoc form above.
|
|
922
960
|
|
|
923
961
|
### Step 4 — Rewrite prose around captured images
|
|
924
962
|
|
|
@@ -938,7 +976,7 @@ Captured X of Y screenshots.
|
|
|
938
976
|
|
|
939
977
|
Rewrote prose in X doc pages.
|
|
940
978
|
|
|
941
|
-
Run /
|
|
979
|
+
Run /vitedocs:sync after future code changes to keep docs current.
|
|
942
980
|
```
|
|
943
981
|
|
|
944
982
|
---
|
|
@@ -1021,7 +1059,276 @@ Update `lastSynced` and `syncHash` for all updated pages. Update the top-level `
|
|
|
1021
1059
|
```
|
|
1022
1060
|
Updated X of N drifted pages.
|
|
1023
1061
|
X gap comments added for manual review.
|
|
1024
|
-
Y screenshots flagged for recapture — run /
|
|
1062
|
+
Y screenshots flagged for recapture — run /vitedocs:screenshot when ready.
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
---
|
|
1066
|
+
|
|
1067
|
+
## Mode: brand
|
|
1068
|
+
|
|
1069
|
+
### Step 1 — Locate docs paths
|
|
1070
|
+
|
|
1071
|
+
Check the manifest(s) to find all configured docs folders. If no manifest exists, scan for `.vitepress/config.mjs` files across the known focus paths. Present what was found so the user can confirm before proceeding.
|
|
1072
|
+
|
|
1073
|
+
### Step 2 — Shared or per-path branding
|
|
1074
|
+
|
|
1075
|
+
If more than one docs path is found, ask:
|
|
1076
|
+
|
|
1077
|
+
- header: "Branding scope"
|
|
1078
|
+
- question: "How should branding be applied across your docs?"
|
|
1079
|
+
- options:
|
|
1080
|
+
- "Same brand across all docs"
|
|
1081
|
+
- "Different brand per path — I'll configure each one separately"
|
|
1082
|
+
|
|
1083
|
+
If per-path: complete all brand questions for path 1 before moving to path 2 — never ask about two paths simultaneously.
|
|
1084
|
+
|
|
1085
|
+
### Step 3 — Brand questions
|
|
1086
|
+
|
|
1087
|
+
Ask these once (shared) or once per path (per-path). Always label the header with the path name when in per-path mode so the user knows which repo they're configuring.
|
|
1088
|
+
|
|
1089
|
+
**B-Q1 — Primary brand color** (plain text): Ask — "What is the primary brand color? (hex, e.g. `#E63946`). This becomes the link, button, and accent color throughout the docs."
|
|
1090
|
+
|
|
1091
|
+
From this single hex value, derive the full VitePress brand palette automatically:
|
|
1092
|
+
- `--vp-c-brand-1`: the base hex
|
|
1093
|
+
- `--vp-c-brand-2`: 15% lighter
|
|
1094
|
+
- `--vp-c-brand-3`: 30% lighter
|
|
1095
|
+
- `--vp-c-brand-soft`: the hex at 12% opacity (for backgrounds)
|
|
1096
|
+
|
|
1097
|
+
Also derive dark mode variants — slightly brighter versions of each to account for dark backgrounds. Present the derived palette to the user before writing anything.
|
|
1098
|
+
|
|
1099
|
+
**B-Q2 — Logo:**
|
|
1100
|
+
- header: "Logo"
|
|
1101
|
+
- question: "Do you have a logo to use in the docs nav?"
|
|
1102
|
+
- options:
|
|
1103
|
+
- "Yes — I'll provide the path to the file"
|
|
1104
|
+
- "Text only — use the site title"
|
|
1105
|
+
- "Skip for now"
|
|
1106
|
+
|
|
1107
|
+
If yes: ask as plain text — "What is the path to the logo file? (SVG or PNG recommended, e.g. `public/logo.svg`)"
|
|
1108
|
+
|
|
1109
|
+
**B-Q3 — Favicon:**
|
|
1110
|
+
- header: "Favicon"
|
|
1111
|
+
- question: "Do you have a favicon?"
|
|
1112
|
+
- options:
|
|
1113
|
+
- "Yes — I'll provide the path"
|
|
1114
|
+
- "Use the logo as favicon"
|
|
1115
|
+
- "Skip for now"
|
|
1116
|
+
|
|
1117
|
+
If yes: ask as plain text — "Path to favicon? (e.g. `public/favicon.ico` or `public/favicon.svg`)"
|
|
1118
|
+
|
|
1119
|
+
**B-Q4 — Font:**
|
|
1120
|
+
- header: "Font"
|
|
1121
|
+
- question: "What font should the docs use?"
|
|
1122
|
+
- options:
|
|
1123
|
+
- "VitePress default (Inter)"
|
|
1124
|
+
- "System font stack (no external load)"
|
|
1125
|
+
- "Google Font — I'll tell you which"
|
|
1126
|
+
- "Custom — I'll provide the CSS import"
|
|
1127
|
+
|
|
1128
|
+
If Google Font: ask as plain text — "Which Google Font family? (e.g. `Outfit`, `DM Sans`)"
|
|
1129
|
+
If custom: ask as plain text — "Paste your @import or @font-face CSS."
|
|
1130
|
+
|
|
1131
|
+
**B-Q5 — Dark mode:**
|
|
1132
|
+
- header: "Dark mode"
|
|
1133
|
+
- question: "How should dark mode colors work?"
|
|
1134
|
+
- options:
|
|
1135
|
+
- "Auto-derive from brand color (recommended)"
|
|
1136
|
+
- "I want to set a custom dark mode accent color"
|
|
1137
|
+
- "Use VitePress default dark mode"
|
|
1138
|
+
|
|
1139
|
+
If custom: ask as plain text — "What hex color for dark mode accent?"
|
|
1140
|
+
|
|
1141
|
+
### Step 4 — Preview palette
|
|
1142
|
+
|
|
1143
|
+
Before writing any files, present the full derived palette as a table:
|
|
1144
|
+
|
|
1145
|
+
```
|
|
1146
|
+
Light mode
|
|
1147
|
+
--vp-c-brand-1: #E63946
|
|
1148
|
+
--vp-c-brand-2: #EB5E6A
|
|
1149
|
+
--vp-c-brand-3: #F28B93
|
|
1150
|
+
--vp-c-brand-soft: #E6394620
|
|
1151
|
+
|
|
1152
|
+
Dark mode
|
|
1153
|
+
--vp-c-brand-1: #F05A64
|
|
1154
|
+
--vp-c-brand-2: #F47980
|
|
1155
|
+
--vp-c-brand-3: #F7A0A5
|
|
1156
|
+
--vp-c-brand-soft: #F05A6420
|
|
1157
|
+
```
|
|
1158
|
+
|
|
1159
|
+
Then ask:
|
|
1160
|
+
|
|
1161
|
+
- header: "Palette"
|
|
1162
|
+
- question: "Does this palette look right?"
|
|
1163
|
+
- options:
|
|
1164
|
+
- "Yes — apply it"
|
|
1165
|
+
- "Adjust the base color — I'll give you a new hex"
|
|
1166
|
+
- "Manually tweak individual values"
|
|
1167
|
+
|
|
1168
|
+
If adjust: take the new hex and re-derive. If manual: ask as plain text for each value to change.
|
|
1169
|
+
|
|
1170
|
+
### Step 5 — Write brand files
|
|
1171
|
+
|
|
1172
|
+
For each docs path being branded:
|
|
1173
|
+
|
|
1174
|
+
**`.vitepress/theme/index.css`** — append the brand variables block. Do not remove existing entries — only add or update the brand vars:
|
|
1175
|
+
|
|
1176
|
+
```css
|
|
1177
|
+
:root {
|
|
1178
|
+
--vp-c-brand-1: HEX1;
|
|
1179
|
+
--vp-c-brand-2: HEX2;
|
|
1180
|
+
--vp-c-brand-3: HEX3;
|
|
1181
|
+
--vp-c-brand-soft: HEXSOFT;
|
|
1182
|
+
/* FONT_VARS if custom font selected */
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
.dark {
|
|
1186
|
+
--vp-c-brand-1: DARK_HEX1;
|
|
1187
|
+
--vp-c-brand-2: DARK_HEX2;
|
|
1188
|
+
--vp-c-brand-3: DARK_HEX3;
|
|
1189
|
+
--vp-c-brand-soft: DARK_HEXSOFT;
|
|
1190
|
+
}
|
|
1191
|
+
```
|
|
1192
|
+
|
|
1193
|
+
If a Google Font was selected, add the `@import` at the top of the CSS file and set `--vp-font-family-base`.
|
|
1194
|
+
|
|
1195
|
+
**`.vitepress/config.mjs`** — add to `themeConfig`:
|
|
1196
|
+
- `logo` field if a logo was provided
|
|
1197
|
+
- `favicon` via `head` entry if a favicon was provided
|
|
1198
|
+
|
|
1199
|
+
Read the existing config before editing. Make only targeted additions — do not rewrite unrelated sections.
|
|
1200
|
+
|
|
1201
|
+
### Step 6 — Summary
|
|
1202
|
+
|
|
1203
|
+
```
|
|
1204
|
+
Branded X docs path(s).
|
|
1205
|
+
|
|
1206
|
+
Files updated:
|
|
1207
|
+
PATH/.vitepress/theme/index.css — brand palette + font
|
|
1208
|
+
PATH/.vitepress/config.mjs — logo, favicon
|
|
1209
|
+
|
|
1210
|
+
Run the local dev server to preview: npm run dev
|
|
1211
|
+
```
|
|
1212
|
+
|
|
1213
|
+
---
|
|
1214
|
+
|
|
1215
|
+
## Mode: update
|
|
1216
|
+
|
|
1217
|
+
Retrofits an existing VitePress docs setup with the latest components, dependencies, and theme wiring. Does not re-run setup or regenerate pages.
|
|
1218
|
+
|
|
1219
|
+
### Step 1 — Locate docs paths
|
|
1220
|
+
|
|
1221
|
+
Scan the current working directory and any known focus paths for `.vitepress/config.mjs` (or `.ts`) files. List what was found and ask the user to confirm which paths to update.
|
|
1222
|
+
|
|
1223
|
+
### Step 2 — Inventory current state
|
|
1224
|
+
|
|
1225
|
+
For each confirmed docs path, check what is already present:
|
|
1226
|
+
|
|
1227
|
+
- `.vitepress/components/ApiEndpoint.vue` — exists?
|
|
1228
|
+
- `.vitepress/theme/index.js` — exists? includes `medium-zoom`? includes `ApiEndpoint`?
|
|
1229
|
+
- `.vitepress/theme/index.css` — exists? includes `.medium-zoom-overlay` z-index rules?
|
|
1230
|
+
- `package.json` — are `medium-zoom` and `highlight.js` listed in dependencies?
|
|
1231
|
+
|
|
1232
|
+
Report findings as a checklist:
|
|
1233
|
+
```
|
|
1234
|
+
Path: docs/
|
|
1235
|
+
[x] ApiEndpoint.vue — found (needs update)
|
|
1236
|
+
[ ] medium-zoom installed
|
|
1237
|
+
[x] highlight.js installed
|
|
1238
|
+
[x] theme/index.js — found (missing medium-zoom wiring)
|
|
1239
|
+
[x] theme/index.css — found (missing z-index rules)
|
|
1240
|
+
```
|
|
1241
|
+
|
|
1242
|
+
Then ask:
|
|
1243
|
+
|
|
1244
|
+
- header: "Update"
|
|
1245
|
+
- question: "What would you like to update?"
|
|
1246
|
+
- options:
|
|
1247
|
+
- "Everything that's missing or outdated"
|
|
1248
|
+
- "Let me choose item by item"
|
|
1249
|
+
|
|
1250
|
+
### Step 3 — Gather inputs (only if needed)
|
|
1251
|
+
|
|
1252
|
+
If `ApiEndpoint.vue` is being written or updated and no existing `apiBase` is in the VitePress config, ask:
|
|
1253
|
+
|
|
1254
|
+
**U-Q1 — API base URL** (plain text): "What is the API base URL? (e.g. `https://api.example.com/wp-json/my-plugin/v1`)"
|
|
1255
|
+
|
|
1256
|
+
**U-Q2 — Code sample tabs:**
|
|
1257
|
+
- header: "Code tabs"
|
|
1258
|
+
- question: "Which code sample tabs should the ApiEndpoint component show?"
|
|
1259
|
+
- options:
|
|
1260
|
+
- "Fetch + cURL (default)"
|
|
1261
|
+
- "Fetch + cURL + PHP"
|
|
1262
|
+
- "Fetch + cURL + Python"
|
|
1263
|
+
- "Fetch + cURL + Axios"
|
|
1264
|
+
- "All of the above"
|
|
1265
|
+
- "Custom — I'll list them"
|
|
1266
|
+
|
|
1267
|
+
Skip U-Q1 and U-Q2 if `apiBase` already exists in `.vitepress/config.mjs` `themeConfig` — infer `apiBase` and existing tabs from the config and the current `ApiEndpoint.vue`.
|
|
1268
|
+
|
|
1269
|
+
### Step 4 — Apply updates
|
|
1270
|
+
|
|
1271
|
+
Apply only the items selected (or all missing/outdated items if "Everything" was chosen). Always read existing files before editing — never overwrite unrelated content.
|
|
1272
|
+
|
|
1273
|
+
**`ApiEndpoint.vue`** — write the full component from the template in generate Step 6, substituting the correct tab list. If the file already exists, replace it entirely (it is a generated component, not hand-edited).
|
|
1274
|
+
|
|
1275
|
+
**`medium-zoom` + `highlight.js`** — if either is missing from `package.json` dependencies, run:
|
|
1276
|
+
```bash
|
|
1277
|
+
cd DOCS_FOLDER && npm install medium-zoom highlight.js
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
**`.vitepress/theme/index.css`** — if `.medium-zoom-overlay` z-index block is missing, append:
|
|
1281
|
+
```css
|
|
1282
|
+
.medium-zoom-overlay {
|
|
1283
|
+
z-index: 100;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
.medium-zoom-image--opened {
|
|
1287
|
+
z-index: 101;
|
|
1288
|
+
}
|
|
1289
|
+
```
|
|
1290
|
+
Do not remove or overwrite existing entries.
|
|
1291
|
+
|
|
1292
|
+
**`.vitepress/theme/index.js`** — merge only what is missing:
|
|
1293
|
+
- If `medium-zoom` wiring is absent, add the `onMounted`/`watch` setup block
|
|
1294
|
+
- If `ApiEndpoint` registration is absent (and `apiBase` is configured), add the import and `app.component()` call
|
|
1295
|
+
- Never remove existing registrations or setup logic
|
|
1296
|
+
|
|
1297
|
+
Reference template for the full correct state:
|
|
1298
|
+
```js
|
|
1299
|
+
import DefaultTheme from 'vitepress/theme'
|
|
1300
|
+
import { onMounted, watch, nextTick } from 'vue'
|
|
1301
|
+
import { useRoute } from 'vitepress'
|
|
1302
|
+
import mediumZoom from 'medium-zoom'
|
|
1303
|
+
import './index.css'
|
|
1304
|
+
import ApiEndpoint from '../components/ApiEndpoint.vue'
|
|
1305
|
+
|
|
1306
|
+
export default {
|
|
1307
|
+
extends: DefaultTheme,
|
|
1308
|
+
setup() {
|
|
1309
|
+
const route = useRoute()
|
|
1310
|
+
const initZoom = () => mediumZoom('.main img', { background: 'var(--vp-c-bg)' })
|
|
1311
|
+
onMounted(initZoom)
|
|
1312
|
+
watch(() => route.path, () => nextTick(initZoom))
|
|
1313
|
+
},
|
|
1314
|
+
enhanceApp({ app }) {
|
|
1315
|
+
app.component('ApiEndpoint', ApiEndpoint)
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
```
|
|
1319
|
+
|
|
1320
|
+
**`.vitepress/config.mjs`** — if `apiBase` was collected and is not already in `themeConfig`, add it.
|
|
1321
|
+
|
|
1322
|
+
### Step 5 — Summary
|
|
1323
|
+
|
|
1324
|
+
```
|
|
1325
|
+
Updated X of Y docs path(s).
|
|
1326
|
+
|
|
1327
|
+
Changes applied:
|
|
1328
|
+
PATH/.vitepress/components/ApiEndpoint.vue — written
|
|
1329
|
+
PATH/.vitepress/theme/index.js — merged medium-zoom + ApiEndpoint
|
|
1330
|
+
PATH/.vitepress/theme/index.css — added z-index rules
|
|
1331
|
+
PATH/package.json — installed medium-zoom, highlight.js
|
|
1025
1332
|
```
|
|
1026
1333
|
|
|
1027
1334
|
---
|
package/install.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { mkdirSync, copyFileSync } from 'fs';
|
|
2
|
+
import { mkdirSync, copyFileSync, readdirSync } from 'fs';
|
|
3
3
|
import { join, dirname } from 'path';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
const dest = join(homedir(), '.claude', '
|
|
9
|
+
const src = join(__dirname, 'commands', 'vitedocs');
|
|
10
|
+
const dest = join(homedir(), '.claude', 'commands', 'vitedocs');
|
|
11
11
|
|
|
12
12
|
mkdirSync(dest, { recursive: true });
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
const files = readdirSync(src).filter(f => f.endsWith('.md'));
|
|
15
|
+
for (const file of files) {
|
|
16
|
+
copyFileSync(join(src, file), join(dest, file));
|
|
17
|
+
}
|
|
14
18
|
|
|
15
19
|
console.log(`✓ Installed @iamdangavin/claude-skill-vitepress-docs`);
|
|
16
|
-
console.log(` → ${dest}
|
|
17
|
-
console.log(` Invoke with: /
|
|
20
|
+
console.log(` → ${dest}/`);
|
|
21
|
+
console.log(` Invoke with: /vitedocs:init in Claude Code`);
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iamdangavin/claude-skill-vitepress-docs",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Installs the
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Installs the vitedocs: Claude Code skill suite — VitePress docs setup, generate, screenshot, sync, brand, and update.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"claude-skill-vitepress-docs": "./install.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"install.js",
|
|
11
|
-
"
|
|
11
|
+
"commands/"
|
|
12
12
|
],
|
|
13
13
|
"keywords": [
|
|
14
14
|
"claude",
|