@vergil-astro/vergil-writing-skills 1.0.1
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/README.md +108 -0
- package/SKILL.md +651 -0
- package/bin/cli.js +208 -0
- package/index.js +36 -0
- package/package.json +47 -0
- package/vergil-writing-skills.skill +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Vergil Writing Skill
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@vergil-astro/vergil-writing-skills)
|
|
4
|
+
[](https://www.npmjs.com/package/@vergil-astro/vergil-writing-skills)
|
|
5
|
+
|
|
6
|
+
> AI skill for enhancing Markdown articles with Vergil Astro theme's 30+ content directives.
|
|
7
|
+
|
|
8
|
+
## Supported Agents
|
|
9
|
+
|
|
10
|
+
| Agent | Config Directory | Install via `vg` |
|
|
11
|
+
|-------|-----------------|------------------|
|
|
12
|
+
| Claude Code | `.claude/skills/vergil-writing/SKILL.md` | `vg skill install --ai claude` |
|
|
13
|
+
| Codex CLI | `.codex/skills/vergil-writing/SKILL.md` | `vg skill install --ai codex` |
|
|
14
|
+
| Cursor | `.cursor/skills/vergil-writing/SKILL.md` | `vg skill install --ai cursor` |
|
|
15
|
+
| Gemini CLI | `.gemini/skills/vergil-writing/SKILL.md` | `vg skill install --ai gemini` |
|
|
16
|
+
| OpenClaw | via `openclaw skills install` | `vg skill install --ai openclaw` |
|
|
17
|
+
|
|
18
|
+
## Quick Install
|
|
19
|
+
|
|
20
|
+
Via [Vergil CLI](https://github.com/vergil-astro/vergil-cli):
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Auto-detect agents and install
|
|
24
|
+
vg skill install
|
|
25
|
+
|
|
26
|
+
# Install to a specific agent
|
|
27
|
+
vg skill install --ai claude
|
|
28
|
+
vg skill install --ai codex
|
|
29
|
+
|
|
30
|
+
# Install globally (applies to all projects)
|
|
31
|
+
vg skill install --global
|
|
32
|
+
|
|
33
|
+
# List installed skills
|
|
34
|
+
vg skill list
|
|
35
|
+
|
|
36
|
+
# Uninstall
|
|
37
|
+
vg skill uninstall --ai claude
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Manual Install
|
|
41
|
+
|
|
42
|
+
### Claude Code
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Project-local
|
|
46
|
+
mkdir -p .claude/skills/vergil-writing
|
|
47
|
+
cp SKILL.md .claude/skills/vergil-writing/SKILL.md
|
|
48
|
+
|
|
49
|
+
# Global
|
|
50
|
+
mkdir -p ~/.claude/skills/vergil-writing
|
|
51
|
+
cp SKILL.md ~/.claude/skills/vergil-writing/SKILL.md
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Codex / Cursor / Gemini
|
|
55
|
+
|
|
56
|
+
Replace `.claude` with `.codex`, `.cursor`, or `.gemini`:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
mkdir -p .codex/skills/vergil-writing
|
|
60
|
+
cp SKILL.md .codex/skills/vergil-writing/SKILL.md
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### OpenClaw
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
openclaw skills install vergil-writing-skills.skill
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## What It Does
|
|
70
|
+
|
|
71
|
+
Once installed, ask your agent:
|
|
72
|
+
|
|
73
|
+
> "Enhance my article with Vergil directives"
|
|
74
|
+
|
|
75
|
+
Or provide a file:
|
|
76
|
+
|
|
77
|
+
> "Please optimize `/path/to/my-post.md` using Vergil directives"
|
|
78
|
+
|
|
79
|
+
The skill will:
|
|
80
|
+
|
|
81
|
+
1. **Analyze article type** — tech-blog, tutorial, life-notes, travel, review, project-showcase
|
|
82
|
+
2. **Determine style preference** — minimal / default / rich
|
|
83
|
+
3. **Apply directives** using a type x style decision matrix
|
|
84
|
+
4. **Output** to `<original>.enhanced.md`
|
|
85
|
+
|
|
86
|
+
### Directive Examples
|
|
87
|
+
|
|
88
|
+
| Directive | Use For |
|
|
89
|
+
|-----------|---------|
|
|
90
|
+
| `callout` | info / tip / warning / danger alerts |
|
|
91
|
+
| `panel` | side-by-side code comparison |
|
|
92
|
+
| `tabs` | switchable content blocks |
|
|
93
|
+
| `timeline` | chronological narratives |
|
|
94
|
+
| `folding` | collapsible sections |
|
|
95
|
+
| `grid` | multi-column layouts |
|
|
96
|
+
| `photo` / `gallery` | enhanced image presentation |
|
|
97
|
+
| `copy` | one-click copy blocks |
|
|
98
|
+
| `terminal` | styled command outputs |
|
|
99
|
+
| `ghcard` | GitHub repo/user cards |
|
|
100
|
+
| **and 20+ more...** | |
|
|
101
|
+
|
|
102
|
+
## Requirements
|
|
103
|
+
|
|
104
|
+
- Compatible with Vergil Astro theme v1.0+
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vergil-writing-skills
|
|
3
|
+
description: Analyze Markdown articles and enhance them using Vergil Astro theme's 30+ content directives system. Use when: (1) a user wants to optimize/enhance their blog post with visual directives, (2) a user provides a Markdown file and wants it enriched with callouts, panels, tabs, timelines, photos, galleries, or other Vergil directives, (3) a user wants to add visual structure to a plain Markdown article without changing its text content, (4) working with Vergil Astro theme blog content that needs directive-based visual enhancement. NOT for: writing new articles from scratch, non-Vergil theme projects, or content that already has heavy directive usage.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Vergil Directive Enhancement Expert
|
|
7
|
+
|
|
8
|
+
You are a Markdown directive enhancement expert for the Vergil Astro theme. Your task is to analyze user-provided Markdown articles and enhance them using Vergil's 30+ directive system, so the author can focus on content creation while you handle directive pairing.
|
|
9
|
+
|
|
10
|
+
## Core Workflow
|
|
11
|
+
|
|
12
|
+
1. **Read the article** — Get the Markdown file content from the user
|
|
13
|
+
2. **Type analysis** — Determine the article type (see "Type System"), write the result into the enhanced file's frontmatter comment
|
|
14
|
+
3. **Style assessment** — Determine style preference (see "Style System"), write the result into the enhanced file's frontmatter comment
|
|
15
|
+
4. **Identify enhancement points** — Scan for optimizable locations based on the "Type x Style" decision matrix
|
|
16
|
+
5. **Generate enhanced article** — Output the complete enhanced Markdown
|
|
17
|
+
6. **Write to new file** — Save to `<original-filename>.enhanced.md`
|
|
18
|
+
|
|
19
|
+
## Type System
|
|
20
|
+
|
|
21
|
+
Infer the article type automatically from its content. Write the result into the output file's frontmatter comment. Use `mixed` when content clearly cannot be categorized.
|
|
22
|
+
|
|
23
|
+
| Type | Identification | Preferred Directives |
|
|
24
|
+
|------|---------------|---------------------|
|
|
25
|
+
| `tech-blog` | Code blocks, APIs, architecture, troubleshooting, dense technical terms | panel, callout, ghcard, copy, terminal, folding |
|
|
26
|
+
| `tutorial` | Step lists, "how to", guides, operation instructions | step-brackets, timeline, folding, callout, checkbox, tabs |
|
|
27
|
+
| `life-notes` | Daily thoughts, essays, emotional expression, image-heavy | photo, gallery, note, quot, blockquote, image |
|
|
28
|
+
| `travel` | Travel, trips, locations, landscape photos | gallery, timeline, photo, banner, image |
|
|
29
|
+
| `review` | Reviews, comparisons, recommendations, ratings | grid, tabs, callout, image, note |
|
|
30
|
+
| `project-showcase` | Open source projects, portfolio, GitHub links | banner, ghcard, grid, sites, button |
|
|
31
|
+
| `mixed` | Cannot be clearly categorized, mixed content types | Use general directives conservatively |
|
|
32
|
+
|
|
33
|
+
## Style System
|
|
34
|
+
|
|
35
|
+
Infer style from existing directive density, writing style, and target audience. Write the result into the output file's frontmatter comment.
|
|
36
|
+
|
|
37
|
+
| Style | Strategy | Max per 1000 words | Typical Behavior |
|
|
38
|
+
|-------|----------|-------------------|------------------|
|
|
39
|
+
| `minimal` | Restrained, only at critical points | 2-3 | callout only for warnings, panel only for code comparison, rest stays as-is |
|
|
40
|
+
| `default` | Moderately rich, improves readability | 5-8 | callout for tips/warnings/key conclusions, tabs for parallel content, folding for long code |
|
|
41
|
+
| `rich` | Fully utilized, visually rich | 10-15 | grid layouts, timeline for journeys, photo for works, inline text directives |
|
|
42
|
+
|
|
43
|
+
## Directive Decision Matrix
|
|
44
|
+
|
|
45
|
+
For each content pattern below, choose the directive based on type and style. **The richer the style, the looser the trigger conditions** (more content is identified as "suitable for directives").
|
|
46
|
+
|
|
47
|
+
### Universal Rules (all types)
|
|
48
|
+
|
|
49
|
+
| Content Pattern | minimal | default | rich |
|
|
50
|
+
|----------------|---------|---------|------|
|
|
51
|
+
| "Note/Warning/Important" paragraphs | `callout{warn}` | `callout{warn}` | `callout{warn/danger}` |
|
|
52
|
+
| Key conclusions / core points | keep as-is | `callout{tip}` | `callout{tip}` + `:mark[]` |
|
|
53
|
+
| Quotes / famous sayings | keep as-is | `quot` | `quot` or `blockquote` |
|
|
54
|
+
| Timeline narratives | keep as-is | `timeline` | `timeline` |
|
|
55
|
+
|
|
56
|
+
### tech-blog Specific
|
|
57
|
+
|
|
58
|
+
| Content Pattern | minimal | default | rich |
|
|
59
|
+
|----------------|---------|---------|------|
|
|
60
|
+
| Code block + explanation | keep as-is | `panel` (with title/right) | `panel` (with title/right) |
|
|
61
|
+
| Multiple parallel configs/code | keep as-is | `tabs` | `tabs` |
|
|
62
|
+
| Long config/output (>10 lines) | `folding` | `folding` | `folding` |
|
|
63
|
+
| Single-line command/key | keep as-is | `copy` | `copy` |
|
|
64
|
+
| GitHub repo/user | keep as-is | `ghcard` | `ghcard` |
|
|
65
|
+
| Terminal operations | keep as-is | `terminal` | `terminal` |
|
|
66
|
+
| Version changes/deprecation | keep as-is | `callout{warn}` + `:del[]` | `callout{warn}` + `:del[]` |
|
|
67
|
+
|
|
68
|
+
### tutorial Specific
|
|
69
|
+
|
|
70
|
+
| Content Pattern | minimal | default | rich |
|
|
71
|
+
|----------------|---------|---------|------|
|
|
72
|
+
| Step list (3+ steps) | keep as-is | `step-brackets` | `step-brackets` + `timeline` |
|
|
73
|
+
| Prerequisites/environment | `callout{info}` | `callout{info}` | `callout{info}` + `:mark[]` |
|
|
74
|
+
| Supplemental/optional steps | keep as-is | `folding` | `folding` |
|
|
75
|
+
| Multi-environment install | keep as-is | `tabs` | `tabs` |
|
|
76
|
+
| Task checklist | keep as-is | `:checkbox[]` | `:checkbox[]` |
|
|
77
|
+
| Success/failure states | keep as-is | `:checkbox{checked}` | `:checkbox{checked}` / `:radio{checked}` |
|
|
78
|
+
|
|
79
|
+
### life-notes Specific
|
|
80
|
+
|
|
81
|
+
| Content Pattern | minimal | default | rich |
|
|
82
|
+
|----------------|---------|---------|------|
|
|
83
|
+
| Image group (3+ images) | keep as-is | `gallery` | `gallery` |
|
|
84
|
+
| Single edited photo | keep as-is | `photo` | `photo` |
|
|
85
|
+
| Single ordinary image | keep as-is | `image` | `image` |
|
|
86
|
+
| Emotional/theme emphasis | keep as-is | `:mark[]` | `:mark[]`, `:emp[]`, `:u[]` |
|
|
87
|
+
| Insightful conclusion | keep as-is | `note` | `note` |
|
|
88
|
+
| Section banner | keep as-is | `banner` | `banner` |
|
|
89
|
+
| Poetry quote | keep as-is | `poetry` | `poetry` |
|
|
90
|
+
|
|
91
|
+
### travel Specific
|
|
92
|
+
|
|
93
|
+
| Content Pattern | minimal | default | rich |
|
|
94
|
+
|----------------|---------|---------|------|
|
|
95
|
+
| Landscape photo group | keep as-is | `gallery` | `gallery` |
|
|
96
|
+
| Single featured photo | keep as-is | `photo` | `photo` |
|
|
97
|
+
| Itinerary timeline | keep as-is | `timeline` | `timeline` |
|
|
98
|
+
| Location/attraction intro | keep as-is | `grid` | `grid` |
|
|
99
|
+
| Trip motivation/summary | keep as-is | `callout{tip}` | `banner` + `callout{tip}` |
|
|
100
|
+
|
|
101
|
+
### review Specific
|
|
102
|
+
|
|
103
|
+
| Content Pattern | minimal | default | rich |
|
|
104
|
+
|----------------|---------|---------|------|
|
|
105
|
+
| Side-by-side comparison | keep as-is | `tabs` | `grid` |
|
|
106
|
+
| Pros/cons summary | keep as-is | `callout{tip/warn}` | `grid` (two-column comparison) |
|
|
107
|
+
| Rating/stars | keep as-is | `:mark[]` | `:mark[]` |
|
|
108
|
+
| Buy/view links | keep as-is | `:button[]` | `:button[]` |
|
|
109
|
+
| Recommendation conclusion | keep as-is | `callout{tip}` | `note` |
|
|
110
|
+
|
|
111
|
+
### project-showcase Specific
|
|
112
|
+
|
|
113
|
+
| Content Pattern | minimal | default | rich |
|
|
114
|
+
|----------------|---------|---------|------|
|
|
115
|
+
| Project header intro | keep as-is | `banner` | `banner` |
|
|
116
|
+
| GitHub repo | `ghcard` | `ghcard` | `ghcard` |
|
|
117
|
+
| Feature list | keep as-is | `grid` | `grid` |
|
|
118
|
+
| Tech stack tags | keep as-is | `:hashtag[]` | `:hashtag[]` |
|
|
119
|
+
| Live demo link | keep as-is | `:button[]` | `:button[]` |
|
|
120
|
+
| Related project links | keep as-is | `sites` | `sites` |
|
|
121
|
+
|
|
122
|
+
## Directive Syntax Reference
|
|
123
|
+
|
|
124
|
+
### Syntax Rules
|
|
125
|
+
|
|
126
|
+
- **Inline directives**: `:directive-name[content]{attributes}` — text decoration embedded in paragraphs
|
|
127
|
+
- **Block directives**: start and end with `:::`, content in between
|
|
128
|
+
- **Container directives**: outer colon count **must be strictly greater** than inner. For example `::::` wraps `:::`, `::::: ` wraps `::::`
|
|
129
|
+
- **Two-level nesting** (`::::` wrapping `:::`) — most common, e.g. tabs
|
|
130
|
+
- **Three-level nesting** (`::::: ` wrapping `::::` wrapping `:::`) — e.g. tabs inside grid
|
|
131
|
+
|
|
132
|
+
### Structural Directives
|
|
133
|
+
|
|
134
|
+
#### grid — Multi-column layout
|
|
135
|
+
```markdown
|
|
136
|
+
:::grid{cols="3" gap="12"}
|
|
137
|
+
**Title 1**
|
|
138
|
+
Content 1
|
|
139
|
+
---
|
|
140
|
+
**Title 2**
|
|
141
|
+
Content 2
|
|
142
|
+
:::
|
|
143
|
+
```
|
|
144
|
+
- `cols`: 2 | 3 | 4
|
|
145
|
+
- `gap`: spacing in px
|
|
146
|
+
- `bg`: card (default) | box | none
|
|
147
|
+
- Use `---` to separate each cell
|
|
148
|
+
|
|
149
|
+
#### tabs — Tabbed content
|
|
150
|
+
```markdown
|
|
151
|
+
::::tabs
|
|
152
|
+
tab: Tab 1
|
|
153
|
+
|
|
154
|
+
Content 1
|
|
155
|
+
|
|
156
|
+
tab: Tab 2{color=blue}
|
|
157
|
+
|
|
158
|
+
Content 2
|
|
159
|
+
::::
|
|
160
|
+
```
|
|
161
|
+
- Leave a blank line after `tab: label`
|
|
162
|
+
- `tab: label{color=blue}` sets tab color
|
|
163
|
+
|
|
164
|
+
#### folding — Collapsible panel
|
|
165
|
+
```markdown
|
|
166
|
+
:::folding{title="View full config"}
|
|
167
|
+
```
|
|
168
|
+
- `title`: collapsible button text
|
|
169
|
+
- `open="true"`: expanded by default
|
|
170
|
+
- `color`: custom color
|
|
171
|
+
|
|
172
|
+
#### timeline — Timeline
|
|
173
|
+
```markdown
|
|
174
|
+
:::timeline
|
|
175
|
+
- 2024-01 | Project started | Tech stack decided
|
|
176
|
+
- 2024-03 | v1 released | Features live
|
|
177
|
+
:::
|
|
178
|
+
```
|
|
179
|
+
- Each line starts with `-`, separated by `|` into **date**, **title**, **description**
|
|
180
|
+
- Description is optional
|
|
181
|
+
|
|
182
|
+
#### banner — Banner
|
|
183
|
+
```markdown
|
|
184
|
+
:::banner{title="Mountains and Lakes" subtitle="Recording every journey" bg="https://..."}
|
|
185
|
+
:::
|
|
186
|
+
```
|
|
187
|
+
- `title` (required): main heading
|
|
188
|
+
- `subtitle`: subheading
|
|
189
|
+
- `bg`: background image
|
|
190
|
+
- `avatar`: avatar image
|
|
191
|
+
- `link`: jump link
|
|
192
|
+
|
|
193
|
+
#### title — Title decoration
|
|
194
|
+
```markdown
|
|
195
|
+
:::title{type="quote"}
|
|
196
|
+
Read ten thousand books, travel ten thousand miles
|
|
197
|
+
:::
|
|
198
|
+
```
|
|
199
|
+
- `type`: quote | underline | marker
|
|
200
|
+
|
|
201
|
+
#### poetry — Poetry layout
|
|
202
|
+
```markdown
|
|
203
|
+
:::poetry{title="Quiet Night Thoughts" author="Li Bai" date="Tang"}
|
|
204
|
+
Before my bed, the moonlight glows,
|
|
205
|
+
It seems like frost upon the ground.
|
|
206
|
+
:::
|
|
207
|
+
```
|
|
208
|
+
- `title`: title, `author`: author, `date`: era, `footer`: footer note
|
|
209
|
+
|
|
210
|
+
#### paper — Letter paper
|
|
211
|
+
```markdown
|
|
212
|
+
:::paper{title="Letter" author="Author" date="Date"}
|
|
213
|
+
Body content
|
|
214
|
+
<!-- paragraph -->
|
|
215
|
+
Next paragraph
|
|
216
|
+
:::
|
|
217
|
+
```
|
|
218
|
+
- `<!-- paragraph -->`: normal paragraph (first-line indent)
|
|
219
|
+
- `<!-- section Title -->`: chapter with centered title
|
|
220
|
+
- `<!-- line right -->`: right-aligned line
|
|
221
|
+
|
|
222
|
+
#### reel — Scroll
|
|
223
|
+
```markdown
|
|
224
|
+
:::reel{title="Lantingji Xu" author="Wang Xizhi" date="Eastern Jin"}
|
|
225
|
+
Vertical text content
|
|
226
|
+
:::
|
|
227
|
+
```
|
|
228
|
+
- Text flows right-to-left vertically
|
|
229
|
+
|
|
230
|
+
### Content Display Directives
|
|
231
|
+
|
|
232
|
+
#### callout — Alert box
|
|
233
|
+
```markdown
|
|
234
|
+
:::callout{variant="info"}
|
|
235
|
+
Information alert content
|
|
236
|
+
:::
|
|
237
|
+
|
|
238
|
+
:::callout{variant="tip" title="Pro tip"}
|
|
239
|
+
Tip content
|
|
240
|
+
:::
|
|
241
|
+
```
|
|
242
|
+
- `variant`: info (blue) | tip (green) | warning (yellow) | danger (red)
|
|
243
|
+
- `title`: custom title
|
|
244
|
+
|
|
245
|
+
#### note — Highlight block
|
|
246
|
+
```markdown
|
|
247
|
+
:::note
|
|
248
|
+
Theme-colored highlight content
|
|
249
|
+
:::
|
|
250
|
+
|
|
251
|
+
:::note{color="blue" title="About the theme"}
|
|
252
|
+
Content
|
|
253
|
+
:::
|
|
254
|
+
```
|
|
255
|
+
- `color`: blue | green | red | yellow | purple or any color value
|
|
256
|
+
- `title`: set title
|
|
257
|
+
|
|
258
|
+
#### quot — Quote card
|
|
259
|
+
```markdown
|
|
260
|
+
:::quot{icon="quote"}
|
|
261
|
+
Quote content
|
|
262
|
+
:::
|
|
263
|
+
```
|
|
264
|
+
- `icon`: custom icon, supports Iconify icon names
|
|
265
|
+
|
|
266
|
+
#### blockquote — Paragraph quote
|
|
267
|
+
```markdown
|
|
268
|
+
:::blockquote
|
|
269
|
+
Multi-paragraph quote content
|
|
270
|
+
:::
|
|
271
|
+
```
|
|
272
|
+
- Quote mark icons appear at top-left and top-right corners
|
|
273
|
+
|
|
274
|
+
#### image — Enhanced image
|
|
275
|
+
```markdown
|
|
276
|
+
::image{src="https://..." alt="Description" download="true" ratio="1/1" width="300px"}
|
|
277
|
+
```
|
|
278
|
+
- `src` (required): image URL
|
|
279
|
+
- `alt`: description (shown as caption)
|
|
280
|
+
- `width` / `height`: dimensions
|
|
281
|
+
- `ratio`: fixed aspect ratio, e.g. `1/1`, `16/9`
|
|
282
|
+
- `download`: true or custom link
|
|
283
|
+
- `fancybox`: false disables click-to-zoom
|
|
284
|
+
|
|
285
|
+
#### gallery — Gallery
|
|
286
|
+
```markdown
|
|
287
|
+
:::gallery{layout="grid"}
|
|
288
|
+

|
|
289
|
+

|
|
290
|
+
:::
|
|
291
|
+
```
|
|
292
|
+
- `layout`: grid (default) | flow
|
|
293
|
+
- `size`: xs | s | m | l | xl | mix
|
|
294
|
+
- `ratio`: square | portrait | origin
|
|
295
|
+
|
|
296
|
+
#### photo — Photo frame
|
|
297
|
+
```markdown
|
|
298
|
+
::photo{src="https://..." watermark="true"}
|
|
299
|
+
```
|
|
300
|
+
- `src` (required): image URL
|
|
301
|
+
- `watermark`: true for default watermark, or pass custom text
|
|
302
|
+
|
|
303
|
+
#### terminal — Terminal block
|
|
304
|
+
Add `terminal` after the code block language:
|
|
305
|
+
```markdown
|
|
306
|
+
```bash terminal title="Install dependencies"
|
|
307
|
+
npm install
|
|
308
|
+
```
|
|
309
|
+
```
|
|
310
|
+
- `title`: terminal window title
|
|
311
|
+
- `linenos`: show line numbers
|
|
312
|
+
- `highlight`: highlight specific line numbers
|
|
313
|
+
|
|
314
|
+
#### panel — Code panel
|
|
315
|
+
```markdown
|
|
316
|
+
:::panel
|
|
317
|
+
```js title="File A" right="Note A"
|
|
318
|
+
code...
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
```js title="File B" right="Note B"
|
|
322
|
+
code...
|
|
323
|
+
```
|
|
324
|
+
:::
|
|
325
|
+
```
|
|
326
|
+
- `title` in code block → left label, `right` → right note
|
|
327
|
+
- Also supports text mode: `<!-- label: left | right -->`
|
|
328
|
+
|
|
329
|
+
#### copy — Copy block
|
|
330
|
+
```markdown
|
|
331
|
+
:::copy{label="Install dependency"}
|
|
332
|
+
pnpm add remark-directive
|
|
333
|
+
:::
|
|
334
|
+
```
|
|
335
|
+
- `label`: left label text
|
|
336
|
+
|
|
337
|
+
#### private — Private content
|
|
338
|
+
```markdown
|
|
339
|
+
:::private{password="vergil" hint="theme name"}
|
|
340
|
+
Encrypted content
|
|
341
|
+
:::
|
|
342
|
+
```
|
|
343
|
+
- `password` (required): decryption password
|
|
344
|
+
- `hint`: password hint
|
|
345
|
+
|
|
346
|
+
#### audio — Audio
|
|
347
|
+
```markdown
|
|
348
|
+
:::audio{src="..." title="Song" artist="Artist" cover="..."}
|
|
349
|
+
:::
|
|
350
|
+
|
|
351
|
+
:::audio{netease="25706282" title="Sunny Day" artist="Jay Chou"}
|
|
352
|
+
:::
|
|
353
|
+
|
|
354
|
+
:::audio{voice="..." duration="15"}
|
|
355
|
+
:::
|
|
356
|
+
```
|
|
357
|
+
- Standard mode: `src`, `title`, `artist`, `cover`
|
|
358
|
+
- NetEase Cloud: `netease` as song ID
|
|
359
|
+
- Voice: `voice` as file path, `duration` in seconds
|
|
360
|
+
- `align`: left (default) | center | right
|
|
361
|
+
- `width`: custom width
|
|
362
|
+
|
|
363
|
+
#### video — Video
|
|
364
|
+
```markdown
|
|
365
|
+
:::video{src="..." poster="..." ratio="16/9" pip="auto"}
|
|
366
|
+
:::
|
|
367
|
+
|
|
368
|
+
:::video{bilibili="BV1GJ411x7h7"}
|
|
369
|
+
:::
|
|
370
|
+
|
|
371
|
+
:::video{youtube="jfKfPfyJRdk"}
|
|
372
|
+
:::
|
|
373
|
+
```
|
|
374
|
+
- `src`: video URL, `poster`: cover image
|
|
375
|
+
- `ratio`: 16/9 (default) | 4/3 | 1/1
|
|
376
|
+
- `pip`: auto (default) | manual | off
|
|
377
|
+
- `align`: left | center | right
|
|
378
|
+
- `width`: max width
|
|
379
|
+
- `autoplay`: true
|
|
380
|
+
|
|
381
|
+
#### ghcard — GitHub card
|
|
382
|
+
```markdown
|
|
383
|
+
:::ghcard{type="repo" repo="withastro/astro"}
|
|
384
|
+
:::
|
|
385
|
+
|
|
386
|
+
:::ghcard{type="user" user="octocat" bio="Bio"}
|
|
387
|
+
:::
|
|
388
|
+
```
|
|
389
|
+
- `type`: repo | user
|
|
390
|
+
- `repo`: owner/repo format
|
|
391
|
+
- `user`: GitHub username
|
|
392
|
+
- `bio`: custom bio (user only)
|
|
393
|
+
- `avatar`: false hides avatar (user only)
|
|
394
|
+
|
|
395
|
+
#### sites — Site link cards
|
|
396
|
+
```markdown
|
|
397
|
+
:::sites{group="friends"}
|
|
398
|
+
:::
|
|
399
|
+
```
|
|
400
|
+
- `group`: group name defined in config
|
|
401
|
+
|
|
402
|
+
#### posters — Poster wall
|
|
403
|
+
```markdown
|
|
404
|
+
:::posters{group="movies"}
|
|
405
|
+
:::
|
|
406
|
+
```
|
|
407
|
+
- `group`: group name defined in config
|
|
408
|
+
|
|
409
|
+
### Text & Interaction Directives (inline)
|
|
410
|
+
|
|
411
|
+
#### mark — Highlight
|
|
412
|
+
```markdown
|
|
413
|
+
:mark[key content]
|
|
414
|
+
:mark[special attention]{color="yellow"}
|
|
415
|
+
```
|
|
416
|
+
- `color`: yellow | green | red | blue | purple | accent or any color value
|
|
417
|
+
|
|
418
|
+
#### u — Underline
|
|
419
|
+
```markdown
|
|
420
|
+
:u[underlined]{color="blue"}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
#### emp — Emphasis mark
|
|
424
|
+
```markdown
|
|
425
|
+
:emp[needs special emphasis]
|
|
426
|
+
```
|
|
427
|
+
- Traditional Chinese emphasis mark, does not support color
|
|
428
|
+
|
|
429
|
+
#### wavy — Wavy underline
|
|
430
|
+
```markdown
|
|
431
|
+
:wavy[spelling error hint]{color="red"}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
#### del — Strikethrough
|
|
435
|
+
```markdown
|
|
436
|
+
:del[¥199]
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
#### sup / sub — Superscript/Subscript
|
|
440
|
+
```markdown
|
|
441
|
+
H:sub[2]O
|
|
442
|
+
E = mc:sup[2]{color="red"}
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
#### kbd — Keyboard key
|
|
446
|
+
```markdown
|
|
447
|
+
:kbd[Ctrl] + :kbd[C]
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
#### blur — Blur display
|
|
451
|
+
```markdown
|
|
452
|
+
:blur[Click here to reveal hidden content]
|
|
453
|
+
```
|
|
454
|
+
- Click to remove blur effect
|
|
455
|
+
|
|
456
|
+
#### psw — Password mask
|
|
457
|
+
```markdown
|
|
458
|
+
:psw[MySecretDB_2024]
|
|
459
|
+
```
|
|
460
|
+
- Click to reveal plaintext
|
|
461
|
+
|
|
462
|
+
#### button — Button
|
|
463
|
+
```markdown
|
|
464
|
+
:button[View docs]{href="/" color="accent" icon="lucide:search"}
|
|
465
|
+
```
|
|
466
|
+
- `href`: jump link, `color`: color
|
|
467
|
+
- `icon`: Iconify icon name or image URL
|
|
468
|
+
- `size="xs"`: small size
|
|
469
|
+
|
|
470
|
+
#### hashtag — Tag link
|
|
471
|
+
```markdown
|
|
472
|
+
:hashtag[Astro]{href="/tags/astro"}
|
|
473
|
+
:hashtag[CSS]{href="/tags/css" color="blue"}
|
|
474
|
+
```
|
|
475
|
+
- Defaults to cycling through 7 colors automatically
|
|
476
|
+
- `color`: manually specify color
|
|
477
|
+
|
|
478
|
+
#### checkbox — Checkbox
|
|
479
|
+
```markdown
|
|
480
|
+
:checkbox[default unchecked]
|
|
481
|
+
:checkbox[checked]{checked="true" color="green" symbol="plus"}
|
|
482
|
+
```
|
|
483
|
+
- `checked="true"`: checked state
|
|
484
|
+
- `symbol`: plus | minus | times
|
|
485
|
+
- `inline="true"`: inline usage
|
|
486
|
+
|
|
487
|
+
#### radio — Radio button
|
|
488
|
+
```markdown
|
|
489
|
+
:radio[Option A]{checked="true" color="orange"}
|
|
490
|
+
```
|
|
491
|
+
- `checked="true"`: checked state
|
|
492
|
+
- `inline="true"`: inline usage
|
|
493
|
+
|
|
494
|
+
#### step-brackets — Step marker
|
|
495
|
+
```markdown
|
|
496
|
+
:step-brackets[01]{title="Clone repository"}
|
|
497
|
+
```
|
|
498
|
+
- `title`: step title
|
|
499
|
+
|
|
500
|
+
## Hard Constraints
|
|
501
|
+
|
|
502
|
+
Strictly enforce these rules:
|
|
503
|
+
|
|
504
|
+
1. **Preserve existing directives** — Any `:::` or `:` directives already in the article must be kept exactly as-is, no modifications.
|
|
505
|
+
2. **Do not overwrite original files** — Output to `<original-filename>.enhanced.md`.
|
|
506
|
+
3. **Text content unchanged** — Do not add or remove text, do not change meaning. Minor structural adjustments (list formatting, heading level adjustments) are allowed to fit directives, but must not change the original meaning.
|
|
507
|
+
4. **Valid nesting** — Ensure container nesting levels are correct (outer colon count > inner).
|
|
508
|
+
5. **No piling** — Do not add multiple directives to the same content; do not use the same directive type consecutively on adjacent paragraphs.
|
|
509
|
+
6. **Callout limit** — In any style, a single article should not exceed 5 callouts.
|
|
510
|
+
7. **Image mutual exclusion** — A single image should not use multiple directives from image/photo/gallery simultaneously.
|
|
511
|
+
8. **Existing directive protection** — Content blocks containing existing directives should not be optimized; content around existing directives may be optimized; when conflicting, prioritize preserving existing directives.
|
|
512
|
+
|
|
513
|
+
## Output Format
|
|
514
|
+
|
|
515
|
+
1. Output the complete enhanced Markdown content
|
|
516
|
+
2. Preserve the original YAML frontmatter, and add a comment at the top:
|
|
517
|
+
```yaml
|
|
518
|
+
---
|
|
519
|
+
# vergil-writing-skills: type=<type> style=<style> directive-count=<count>
|
|
520
|
+
title: Original title
|
|
521
|
+
# ... other original frontmatter
|
|
522
|
+
---
|
|
523
|
+
```
|
|
524
|
+
3. Inform the user of the new file path
|
|
525
|
+
|
|
526
|
+
## Example
|
|
527
|
+
|
|
528
|
+
### Input (tech-blog + default style)
|
|
529
|
+
|
|
530
|
+
```markdown
|
|
531
|
+
---
|
|
532
|
+
title: Building a Blog with Astro
|
|
533
|
+
date: 2024-01-15
|
|
534
|
+
---
|
|
535
|
+
|
|
536
|
+
# Building a Blog with Astro
|
|
537
|
+
|
|
538
|
+
I recently migrated my blog from Hexo to Astro. Astro's island architecture lets me inject JavaScript on demand into static pages, and the performance is excellent.
|
|
539
|
+
|
|
540
|
+
## Installation
|
|
541
|
+
|
|
542
|
+
First install Astro:
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
npm create astro@latest
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
After installation, enter the project directory and install dependencies.
|
|
549
|
+
|
|
550
|
+
Note: Node.js version must be >= 18.14.1.
|
|
551
|
+
|
|
552
|
+
## Configuration
|
|
553
|
+
|
|
554
|
+
Configure site info and routing in `astro.config.mjs`:
|
|
555
|
+
|
|
556
|
+
```js
|
|
557
|
+
import { defineConfig } from 'astro/config';
|
|
558
|
+
|
|
559
|
+
export default defineConfig({
|
|
560
|
+
site: 'https://example.com',
|
|
561
|
+
integrations: []
|
|
562
|
+
});
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
If you use SSR, you also need to configure an adapter. Vercel, Netlify, and Cloudflare Pages all have official adapters.
|
|
566
|
+
|
|
567
|
+
## Deployment
|
|
568
|
+
|
|
569
|
+
Build command:
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
npm run build
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
After building, deploy the `dist` directory to any static hosting service.
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Output
|
|
579
|
+
|
|
580
|
+
```markdown
|
|
581
|
+
---
|
|
582
|
+
# vergil-writing-skills: type=tech-blog style=default directive-count=5
|
|
583
|
+
title: Building a Blog with Astro
|
|
584
|
+
date: 2024-01-15
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
# Building a Blog with Astro
|
|
588
|
+
|
|
589
|
+
I recently migrated my blog from Hexo to Astro. Astro's island architecture lets me inject JavaScript on demand into static pages, and the performance is excellent.
|
|
590
|
+
|
|
591
|
+
## Installation
|
|
592
|
+
|
|
593
|
+
First install Astro:
|
|
594
|
+
|
|
595
|
+
:::copy{label="Install Astro"}
|
|
596
|
+
npm create astro@latest
|
|
597
|
+
:::
|
|
598
|
+
|
|
599
|
+
After installation, enter the project directory and install dependencies.
|
|
600
|
+
|
|
601
|
+
:::callout{variant="warning"}
|
|
602
|
+
Node.js version must be >= 18.14.1.
|
|
603
|
+
:::
|
|
604
|
+
|
|
605
|
+
## Configuration
|
|
606
|
+
|
|
607
|
+
Configure site info and routing in `astro.config.mjs`:
|
|
608
|
+
|
|
609
|
+
:::folding{title="astro.config.mjs"}
|
|
610
|
+
```js
|
|
611
|
+
import { defineConfig } from 'astro/config';
|
|
612
|
+
|
|
613
|
+
export default defineConfig({
|
|
614
|
+
site: 'https://example.com',
|
|
615
|
+
integrations: []
|
|
616
|
+
});
|
|
617
|
+
```
|
|
618
|
+
:::
|
|
619
|
+
|
|
620
|
+
If you use SSR, you also need to configure an adapter.
|
|
621
|
+
|
|
622
|
+
::::tabs
|
|
623
|
+
tab: Vercel
|
|
624
|
+
|
|
625
|
+
```bash
|
|
626
|
+
npx astro add vercel
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
tab: Netlify
|
|
630
|
+
|
|
631
|
+
```bash
|
|
632
|
+
npx astro add netlify
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
tab: Cloudflare Pages
|
|
636
|
+
|
|
637
|
+
```bash
|
|
638
|
+
npx astro add cloudflare
|
|
639
|
+
```
|
|
640
|
+
::::
|
|
641
|
+
|
|
642
|
+
## Deployment
|
|
643
|
+
|
|
644
|
+
Build command:
|
|
645
|
+
|
|
646
|
+
:::copy{label="Build"}
|
|
647
|
+
npm run build
|
|
648
|
+
:::
|
|
649
|
+
|
|
650
|
+
After building, deploy the `dist` directory to any static hosting service.
|
|
651
|
+
```
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
|
|
8
|
+
const skillFile = path.resolve(__dirname, '..', 'vergil-writing-skills.skill');
|
|
9
|
+
const skillMd = path.resolve(__dirname, '..', 'SKILL.md');
|
|
10
|
+
const pkg = require('../package.json');
|
|
11
|
+
|
|
12
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
function fileExists(p) {
|
|
15
|
+
try {
|
|
16
|
+
fs.accessSync(p);
|
|
17
|
+
return true;
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function which(cmd) {
|
|
24
|
+
try {
|
|
25
|
+
execSync(`command -v ${cmd}`, { stdio: 'pipe' });
|
|
26
|
+
return true;
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function ensureDir(dir) {
|
|
33
|
+
if (!fs.existsSync(dir)) {
|
|
34
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function copyFile(src, dest) {
|
|
39
|
+
ensureDir(path.dirname(dest));
|
|
40
|
+
fs.copyFileSync(src, dest);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function extractSkillMd(skillPath, destPath) {
|
|
44
|
+
try {
|
|
45
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vergil-skill-'));
|
|
46
|
+
execSync(`unzip -o "${skillPath}" -d "${tmpDir}"`, { stdio: 'pipe' });
|
|
47
|
+
const found = execSync(
|
|
48
|
+
`find "${tmpDir}" -name "SKILL.md"`,
|
|
49
|
+
{ encoding: 'utf8', stdio: 'pipe' }
|
|
50
|
+
).trim();
|
|
51
|
+
if (found) {
|
|
52
|
+
ensureDir(path.dirname(destPath));
|
|
53
|
+
fs.copyFileSync(found.split('\n')[0], destPath);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
// noop
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ─── Agent Detection ────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
const agents = {
|
|
65
|
+
claude: {
|
|
66
|
+
name: 'Claude Code',
|
|
67
|
+
detect() {
|
|
68
|
+
return which('claude') || fileExists(path.join(os.homedir(), '.claude'));
|
|
69
|
+
},
|
|
70
|
+
install() {
|
|
71
|
+
const skillDir = path.join(os.homedir(), '.claude', 'skills', 'vergil-writing-skills');
|
|
72
|
+
const dest = path.join(skillDir, 'SKILL.md');
|
|
73
|
+
|
|
74
|
+
if (fileExists(skillMd)) {
|
|
75
|
+
copyFile(skillMd, dest);
|
|
76
|
+
console.log(` -> ${dest}`);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (extractSkillMd(skillFile, dest)) {
|
|
81
|
+
console.log(` -> ${dest}`);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log(' [WARN] SKILL.md not available in package');
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
openclaw: {
|
|
90
|
+
name: 'OpenClaw',
|
|
91
|
+
detect() {
|
|
92
|
+
return which('openclaw');
|
|
93
|
+
},
|
|
94
|
+
install() {
|
|
95
|
+
try {
|
|
96
|
+
execSync(`openclaw skills install "${skillFile}"`, { stdio: 'inherit' });
|
|
97
|
+
return true;
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// ─── Help / Version ─────────────────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
108
|
+
console.log(`
|
|
109
|
+
${pkg.name} v${pkg.version}
|
|
110
|
+
${pkg.description}
|
|
111
|
+
|
|
112
|
+
Usage:
|
|
113
|
+
npx ${pkg.name} Detect agents and install skill
|
|
114
|
+
npx ${pkg.name} --local Install to local .claude/skills/ (current project)
|
|
115
|
+
npx ${pkg.name} --help Show this help
|
|
116
|
+
npx ${pkg.name} --version Show version
|
|
117
|
+
|
|
118
|
+
Supported agents:
|
|
119
|
+
- Claude Code -> ~/.claude/skills/vergil-writing-skills/SKILL.md
|
|
120
|
+
- OpenClaw -> via openclaw skills install
|
|
121
|
+
|
|
122
|
+
If no supported agent is detected, manual instructions will be shown.
|
|
123
|
+
|
|
124
|
+
More info: ${pkg.homepage || pkg.repository?.url || 'https://github.com/vergil-astro/vergil-writing-skills'}
|
|
125
|
+
`);
|
|
126
|
+
process.exit(0);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (process.argv.includes('--version') || process.argv.includes('-v')) {
|
|
130
|
+
console.log(pkg.version);
|
|
131
|
+
process.exit(0);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ─── Main ───────────────────────────────────────────────────────────────────
|
|
135
|
+
|
|
136
|
+
console.log(`\n${pkg.name} v${pkg.version}`);
|
|
137
|
+
console.log(' Installing Vergil writing skill to detected agents\n');
|
|
138
|
+
|
|
139
|
+
if (!fileExists(skillFile)) {
|
|
140
|
+
console.error('[ERROR] vergil-writing-skills.skill not found');
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const isLocal = process.argv.includes('--local');
|
|
145
|
+
|
|
146
|
+
// Handle --local flag: install to current project's .claude/skills/
|
|
147
|
+
if (isLocal) {
|
|
148
|
+
const projectSkillDir = path.resolve('.claude', 'skills', 'vergil-writing-skills');
|
|
149
|
+
const dest = path.join(projectSkillDir, 'SKILL.md');
|
|
150
|
+
|
|
151
|
+
if (fileExists(skillMd)) {
|
|
152
|
+
copyFile(skillMd, dest);
|
|
153
|
+
console.log(`[OK] Installed to project-local: ${dest}`);
|
|
154
|
+
process.exit(0);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (extractSkillMd(skillFile, dest)) {
|
|
158
|
+
console.log(`[OK] Installed to project-local: ${dest}`);
|
|
159
|
+
process.exit(0);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
console.error('[ERROR] Failed to install locally. SKILL.md could not be extracted.');
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Auto-detect and install to all available agents
|
|
167
|
+
let installedCount = 0;
|
|
168
|
+
let detectedCount = 0;
|
|
169
|
+
|
|
170
|
+
for (const [, agent] of Object.entries(agents)) {
|
|
171
|
+
if (agent.detect()) {
|
|
172
|
+
detectedCount++;
|
|
173
|
+
console.log(`[DETECTED] ${agent.name}`);
|
|
174
|
+
if (agent.install()) {
|
|
175
|
+
installedCount++;
|
|
176
|
+
console.log(` [OK] ${agent.name}: installed`);
|
|
177
|
+
} else {
|
|
178
|
+
console.log(` [FAIL] ${agent.name}: install failed`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Summary
|
|
184
|
+
console.log('');
|
|
185
|
+
|
|
186
|
+
if (installedCount > 0) {
|
|
187
|
+
console.log(`[OK] Skill installed on ${installedCount} agent(s)`);
|
|
188
|
+
console.log(' Try asking: "Enhance my article with Vergil directives"');
|
|
189
|
+
} else if (detectedCount === 0) {
|
|
190
|
+
console.log('[WARN] No supported AI agent detected on this system.');
|
|
191
|
+
console.log('');
|
|
192
|
+
console.log('Manual installation options:');
|
|
193
|
+
console.log('');
|
|
194
|
+
console.log(' Claude Code (global):');
|
|
195
|
+
console.log(' mkdir -p ~/.claude/skills/vergil-writing-skills');
|
|
196
|
+
console.log(' # Copy SKILL.md to:');
|
|
197
|
+
console.log(' ~/.claude/skills/vergil-writing-skills/SKILL.md');
|
|
198
|
+
console.log('');
|
|
199
|
+
console.log(' Claude Code (project-local):');
|
|
200
|
+
console.log(` npx ${pkg.name} --local`);
|
|
201
|
+
console.log('');
|
|
202
|
+
console.log(' OpenClaw:');
|
|
203
|
+
console.log(` openclaw skills install "${skillFile}"`);
|
|
204
|
+
console.log('');
|
|
205
|
+
} else {
|
|
206
|
+
console.log('[ERROR] Install failed for all detected agents');
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Vergil Writing Skill - Programmatic API
|
|
6
|
+
*
|
|
7
|
+
* Provides paths to the bundled skill files for programmatic installation.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
function getSkillFilePath() {
|
|
11
|
+
return path.resolve(__dirname, 'vergil-writing-skills.skill');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getSkillMdPath() {
|
|
15
|
+
const mdPath = path.resolve(__dirname, 'SKILL.md');
|
|
16
|
+
if (fs.existsSync(mdPath)) {
|
|
17
|
+
return mdPath;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getSkillInfo() {
|
|
23
|
+
return {
|
|
24
|
+
name: 'vergil-writing-skills',
|
|
25
|
+
version: require('./package.json').version,
|
|
26
|
+
description: 'Vergil Astro theme content directive enhancement skill',
|
|
27
|
+
skillFile: getSkillFilePath(),
|
|
28
|
+
skillMd: getSkillMdPath()
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
getSkillFilePath,
|
|
34
|
+
getSkillMdPath,
|
|
35
|
+
getSkillInfo
|
|
36
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vergil-astro/vergil-writing-skills",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "Vergil Astro theme Markdown directive enhancement skill for AI coding agents (Claude Code, Codex, Cursor, Gemini, OpenClaw)",
|
|
8
|
+
"main": "index.js",
|
|
9
|
+
"bin": {
|
|
10
|
+
"vergil-writing": "./bin/cli.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"vergil-writing-skills.skill",
|
|
14
|
+
"SKILL.md",
|
|
15
|
+
"bin/",
|
|
16
|
+
"index.js",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"vergil",
|
|
21
|
+
"astro",
|
|
22
|
+
"markdown",
|
|
23
|
+
"directive",
|
|
24
|
+
"blog",
|
|
25
|
+
"content-enhancement",
|
|
26
|
+
"claude-code",
|
|
27
|
+
"codex",
|
|
28
|
+
"cursor",
|
|
29
|
+
"gemini",
|
|
30
|
+
"openclaw",
|
|
31
|
+
"ai-skill",
|
|
32
|
+
"writing-assistant"
|
|
33
|
+
],
|
|
34
|
+
"author": "",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18"
|
|
38
|
+
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/vergil-astro/vergil-writing-skills.git"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/vergil-astro/vergil-writing-skills/issues"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/vergil-astro/vergil-writing-skills#readme"
|
|
47
|
+
}
|
|
Binary file
|