@contentrain/skills 0.1.1 → 0.2.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.
Files changed (45) hide show
  1. package/README.md +65 -60
  2. package/dist/index.cjs +65 -1
  3. package/dist/index.d.cts +50 -2
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.mts +50 -2
  6. package/dist/index.d.mts.map +1 -1
  7. package/dist/index.mjs +65 -2
  8. package/dist/index.mjs.map +1 -1
  9. package/frameworks/nuxt.md +26 -1
  10. package/package.json +3 -1
  11. package/skills/contentrain/SKILL.md +149 -0
  12. package/skills/contentrain/references/architecture.md +212 -0
  13. package/skills/contentrain/references/content-formats.md +279 -0
  14. package/skills/contentrain/references/i18n.md +298 -0
  15. package/skills/contentrain/references/mcp-pipelines.md +192 -0
  16. package/skills/contentrain/references/mcp-tools.md +308 -0
  17. package/skills/contentrain/references/model-kinds.md +330 -0
  18. package/skills/contentrain/references/schema-types.md +177 -0
  19. package/skills/contentrain/references/security.md +146 -0
  20. package/skills/contentrain/references/workflow.md +267 -0
  21. package/skills/contentrain-bulk/SKILL.md +99 -0
  22. package/skills/contentrain-content/SKILL.md +162 -0
  23. package/skills/contentrain-diff/SKILL.md +62 -0
  24. package/skills/contentrain-doctor/SKILL.md +62 -0
  25. package/skills/contentrain-generate/SKILL.md +183 -0
  26. package/skills/contentrain-generate/references/generated-client.md +198 -0
  27. package/skills/contentrain-init/SKILL.md +99 -0
  28. package/skills/contentrain-model/SKILL.md +141 -0
  29. package/skills/contentrain-normalize/SKILL.md +185 -0
  30. package/skills/contentrain-normalize/references/extraction.md +164 -0
  31. package/skills/contentrain-normalize/references/reuse.md +146 -0
  32. package/skills/contentrain-normalize/references/what-is-content.md +115 -0
  33. package/skills/contentrain-quality/SKILL.md +180 -0
  34. package/skills/contentrain-quality/references/accessibility.md +160 -0
  35. package/skills/contentrain-quality/references/content-quality.md +299 -0
  36. package/skills/contentrain-quality/references/media.md +170 -0
  37. package/skills/contentrain-quality/references/seo.md +229 -0
  38. package/skills/contentrain-review/SKILL.md +170 -0
  39. package/skills/contentrain-sdk/SKILL.md +145 -0
  40. package/skills/contentrain-sdk/references/bundler-config.md +135 -0
  41. package/skills/contentrain-serve/SKILL.md +96 -0
  42. package/skills/contentrain-translate/SKILL.md +180 -0
  43. package/skills/contentrain-validate-fix/SKILL.md +92 -0
  44. package/workflows/contentrain-content.md +1 -1
  45. package/workflows/contentrain-generate.md +5 -5
@@ -0,0 +1,170 @@
1
+ ---
2
+ name: contentrain-review
3
+ description: "Review content changes for quality, accuracy, and compliance before publishing. Use when reviewing content, checking quality, or approving changes."
4
+ metadata:
5
+ author: Contentrain
6
+ version: "1.0.0"
7
+ ---
8
+
9
+ # Skill: Review Pending Content Changes
10
+
11
+ > Review content changes on Contentrain branches, apply quality checks, and recommend approval or rejection.
12
+
13
+ ---
14
+
15
+ ## When to Use
16
+
17
+ The user wants to review content quality, audit existing entries, check pending changes, or run a pre-publish checklist. Triggers: "review content", "check pending changes", "review the contentrain branch", "content QA", "audit content", "pre-publish check".
18
+
19
+ ---
20
+
21
+ ## Steps
22
+
23
+ ### 1. Check Project State
24
+
25
+ Call `contentrain_status` to understand the current project:
26
+
27
+ - All models, their kinds, domains, and entry counts.
28
+ - Configured locales and source locale.
29
+ - Pending branches or unsubmitted changes.
30
+ - Workflow mode (auto-merge or review).
31
+
32
+ ### 2. List Content for Review
33
+
34
+ For each model (or the user-specified scope), call `contentrain_content_list(model: "<modelId>", locale: "<locale>")`:
35
+
36
+ - Retrieve entries for the source locale first.
37
+ - For i18n models, also retrieve entries for each target locale.
38
+ - Note entry counts per locale to identify i18n coverage gaps.
39
+
40
+ If reviewing a specific branch, list the `contentrain/*` branches and show:
41
+
42
+ - Branch name (indicates operation type: extract, reuse, content-save, model-save).
43
+ - Number of changed files.
44
+ - Last commit date.
45
+
46
+ ### 3. Run Automated Validation
47
+
48
+ Call `contentrain_validate` to get the automated validation report:
49
+
50
+ - Schema compliance errors (missing required fields, type mismatches).
51
+ - Referential integrity issues (broken relation references).
52
+ - i18n completeness gaps (missing locale entries).
53
+ - Content policy violations.
54
+
55
+ ### 4. Apply Quality Checklist
56
+
57
+ Go through each category and report findings:
58
+
59
+ #### 4.1 Content Quality (from content-quality.md)
60
+
61
+ - [ ] All required fields are populated with real, non-placeholder values.
62
+ - [ ] Text fields respect `min`/`max` constraints.
63
+ - [ ] No placeholder text (lorem ipsum, TODO, TBD, [insert here]).
64
+ - [ ] Tone is consistent with `context.json` → `conventions.tone`.
65
+ - [ ] Vocabulary terms from `vocabulary.json` are used consistently.
66
+ - [ ] Collection entries have no duplicate `unique` field values.
67
+ - [ ] Content follows the correct content type pattern (blog post, landing page, docs, etc.).
68
+ - [ ] No duplicate content across entries.
69
+
70
+ #### 4.2 SEO (from seo-rules.md)
71
+
72
+ - [ ] Page titles: 50-60 characters (max 70), primary keyword in first 30 characters.
73
+ - [ ] Meta descriptions: 120-160 characters, complete sentences.
74
+ - [ ] Slugs: kebab-case, descriptive, 3-5 words, no stop words.
75
+ - [ ] Heading hierarchy in markdown/richtext: h1 → h2 → h3 (no skips).
76
+ - [ ] Image alt text is present and descriptive (under 125 characters).
77
+ - [ ] No orphan pages (content exists but is not linked/referenced).
78
+
79
+ #### 4.3 Accessibility (from accessibility-rules.md)
80
+
81
+ - [ ] Image fields have corresponding alt text fields (or the alt is embedded).
82
+ - [ ] Color contrast: text color values meet WCAG AA ratio if paired colors are in the model.
83
+ - [ ] Link text is descriptive (no raw URLs, "click here", or "read more" without context).
84
+ - [ ] Media content has text alternatives where applicable.
85
+ - [ ] Heading hierarchy is sequential (no skipped levels).
86
+ - [ ] Color is not used as the sole means of conveying information.
87
+
88
+ #### 4.4 Security (from security-rules.md)
89
+
90
+ - [ ] No hardcoded secrets, API keys, or credentials in content fields.
91
+ - [ ] No internal URLs or staging domains in production content.
92
+ - [ ] User-generated or external URLs use HTTPS.
93
+ - [ ] No inline JavaScript or script injection vectors in richtext/markdown fields.
94
+ - [ ] No user-supplied HTML that could enable XSS.
95
+ - [ ] Email fields contain valid, non-internal addresses (unless intended).
96
+
97
+ #### 4.5 i18n Completeness (from i18n-quality.md)
98
+
99
+ - [ ] All models with `i18n: true` have entries for every supported locale.
100
+ - [ ] Entry counts match across locales (no missing translations).
101
+ - [ ] Required fields are populated in every locale.
102
+ - [ ] Dictionary keys are identical across all locale files.
103
+ - [ ] Vocabulary terms are translated in all locales.
104
+ - [ ] Translations are idiomatic (not word-for-word).
105
+ - [ ] Translated text fits within field `max` constraints.
106
+ - [ ] No source-locale text left untranslated in target locales.
107
+
108
+ #### 4.6 Referential Integrity
109
+
110
+ - [ ] All `relation` fields point to existing entries.
111
+ - [ ] All `relations` arrays contain valid references.
112
+ - [ ] No circular relations that could cause infinite loops.
113
+ - [ ] Referenced entries are in a publishable state.
114
+
115
+ ### 5. Generate Review Report
116
+
117
+ Present a structured report:
118
+
119
+ ```
120
+ ## Content Review Report
121
+
122
+ ### Summary
123
+ - Models reviewed: X
124
+ - Total entries: X
125
+ - Locales checked: X
126
+
127
+ ### Issues Found
128
+
129
+ #### Critical (must fix before publish)
130
+ - [list of blocking issues with field references]
131
+
132
+ #### Warning (should fix)
133
+ - [list of non-blocking issues]
134
+
135
+ #### Info (suggestions)
136
+ - [list of improvements]
137
+
138
+ ### Per-Model Breakdown
139
+ | Model | Kind | Entries | Issues | Status |
140
+ |---|---|---|---|---|
141
+
142
+ ### i18n Coverage
143
+ | Locale | Coverage | Missing Entries |
144
+ |---|---|---|
145
+ ```
146
+
147
+ ### 6. Make a Recommendation
148
+
149
+ Based on the findings:
150
+
151
+ - **Approve:** No errors, few or no warnings. Changes are ready to merge.
152
+ - **Request changes:** Errors or significant warnings found. List the specific changes needed.
153
+ - **Reject:** Fundamental issues (wrong model structure, placeholder-only content, security violations). Explain why and suggest starting over.
154
+
155
+ ### 7. Offer Fixes
156
+
157
+ For each fixable issue, offer to resolve it:
158
+
159
+ - Missing translations: offer to run `/contentrain-translate`.
160
+ - Schema violations: offer to update entries with `contentrain_content_save`.
161
+ - Missing required fields: draft content for empty fields.
162
+ - SEO issues: suggest improved titles, descriptions, slugs.
163
+
164
+ Only make changes after user approval.
165
+
166
+ ### 8. Re-validate
167
+
168
+ If fixes were applied, call `contentrain_validate` again to confirm all issues are resolved.
169
+
170
+ Report the final status: "All checks passed" or list remaining issues that require manual attention.
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: contentrain-sdk
3
+ description: "Use the @contentrain/query SDK to query Contentrain content with type safety. Use when importing from #contentrain, using QueryBuilder, SingletonAccessor, DictionaryAccessor, or DocumentQuery."
4
+ metadata:
5
+ author: Contentrain
6
+ version: "1.0.0"
7
+ ---
8
+
9
+ # Contentrain Query SDK
10
+
11
+ ## Overview
12
+
13
+ `@contentrain/query` is a Prisma-pattern generated client that provides type-safe access to Contentrain content. Generated output lives in `.contentrain/client/` — never edit it manually.
14
+
15
+ ## Quick Start
16
+
17
+ ```bash
18
+ npx contentrain generate # Generate client from models
19
+ ```
20
+
21
+ ```typescript
22
+ import { query, singleton, dictionary, document } from '#contentrain'
23
+
24
+ // Collection
25
+ const posts = query('blog-post').where('category', 'eq', 'engineering').sort('published_at', 'desc').limit(10).all()
26
+
27
+ // Singleton
28
+ const hero = singleton('hero').get()
29
+
30
+ // Dictionary
31
+ const t = dictionary('ui-texts').get()
32
+ const loginLabel = t['auth.login.button']
33
+
34
+ // Document
35
+ const doc = document('blog-post').bySlug('getting-started')
36
+ ```
37
+
38
+ ## Runtime API
39
+
40
+ ### QueryBuilder (collections)
41
+
42
+ | Method | Description |
43
+ |--------|-------------|
44
+ | `.all()` | Get all entries |
45
+ | `.first()` | Get first entry |
46
+ | `.where(field, op, value)` | Filter (`eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `contains`) |
47
+ | `.sort(field, direction?)` | Sort (`asc`/`desc`, default `asc`) |
48
+ | `.limit(n)` | Limit results |
49
+ | `.offset(n)` | Skip results |
50
+ | `.include(relation)` | Resolve relation (1 level deep) |
51
+
52
+ ### SingletonAccessor
53
+
54
+ | Method | Description |
55
+ |--------|-------------|
56
+ | `.get()` | Get the singleton data |
57
+ | `.include(relation)` | Resolve relation fields |
58
+
59
+ ### DictionaryAccessor
60
+
61
+ | Method | Description |
62
+ |--------|-------------|
63
+ | `.get()` | Get all key-value pairs |
64
+ | `.get(key)` | Get single value by key |
65
+ | `.get(key, params)` | Get with interpolation: `{placeholder}` → value |
66
+
67
+ ### DocumentQuery
68
+
69
+ | Method | Description |
70
+ |--------|-------------|
71
+ | `.all()` | Get all documents |
72
+ | `.bySlug(slug)` | Get document by slug |
73
+ | `.first()` | Get first document |
74
+ | `.where(field, op, value)` | Filter by frontmatter field |
75
+ | `.include(relation)` | Resolve relation fields |
76
+
77
+ ## CDN Mode (Remote Data)
78
+
79
+ For server-side or client-side apps that fetch content from Contentrain Studio CDN:
80
+
81
+ ```typescript
82
+ import { createContentrain } from '@contentrain/query/cdn'
83
+
84
+ const client = createContentrain({
85
+ projectId: '350696e8-...',
86
+ apiKey: 'crn_live_xxx',
87
+ // baseUrl: 'https://studio.contentrain.io/api/cdn/v1' (default)
88
+ })
89
+
90
+ // All CDN queries are async (return Promise)
91
+ const posts = await client.collection('faq').locale('en').all()
92
+ const hero = await client.singleton('hero').locale('en').get()
93
+ const t = await client.dictionary('ui').locale('en').get()
94
+ const doc = await client.document('docs').locale('en').bySlug('intro')
95
+ ```
96
+
97
+ ### CDN Collection Query Operators
98
+
99
+ | Operator | Example | Description |
100
+ |----------|---------|-------------|
101
+ | `eq` | `.where('status', 'eq', 'published')` | Equals |
102
+ | `ne` | `.where('status', 'ne', 'draft')` | Not equals |
103
+ | `gt` | `.where('order', 'gt', 5)` | Greater than |
104
+ | `gte` | `.where('order', 'gte', 5)` | Greater than or equal |
105
+ | `lt` | `.where('price', 'lt', 100)` | Less than |
106
+ | `lte` | `.where('price', 'lte', 100)` | Less than or equal |
107
+ | `in` | `.where('category', 'in', ['a','b'])` | In array |
108
+ | `contains` | `.where('tags', 'contains', 'vue')` | String/array contains |
109
+
110
+ ### CDN vs Local
111
+
112
+ | Aspect | Local (`#contentrain`) | CDN (`createContentrain()`) |
113
+ |--------|----------------------|---------------------------|
114
+ | Data source | Bundled `.mjs` files | HTTP fetch from CDN |
115
+ | Return type | Sync (`T[]`) | Async (`Promise<T[]>`) |
116
+ | Auth | None | API key required |
117
+ | Caching | In-memory (embedded) | ETag-based HTTP cache |
118
+ | Use case | SSG, build-time | SSR, client-side, serverless |
119
+
120
+ ## Key Rules
121
+
122
+ - **Local mode** queries are **synchronous** — no `await` needed
123
+ - **CDN mode** queries are **async** — always `await`
124
+ - Relation resolution is **1 level deep** — no recursive resolution
125
+ - Locale fallback chain: explicit → config default → first available
126
+ - Generated files in `.contentrain/client/` are **immutable** — always regenerate, never edit
127
+ - Run `contentrain generate` after any model change
128
+
129
+ ## Framework Integration
130
+
131
+ | Framework | Import | Notes |
132
+ |-----------|--------|-------|
133
+ | Nuxt 3 | `import { query } from '#contentrain'` | Server-only (server routes, plugins) |
134
+ | Next.js | `import { query } from '#contentrain'` | Works in RSC and API routes |
135
+ | Astro | `import { query } from '#contentrain'` | Works in `.astro` frontmatter |
136
+ | SvelteKit | `import { query } from '#contentrain'` | Works in `+page.server.ts` |
137
+ | Vue + Vite | `import { query } from '#contentrain'` | Requires Vite alias config |
138
+ | React + Vite | `import { query } from '#contentrain'` | Requires Vite alias config |
139
+ | Node.js | `import { query } from '#contentrain'` | ESM with subpath imports |
140
+
141
+ ## References
142
+
143
+ | Reference | Description |
144
+ |-----------|-------------|
145
+ | [Bundler Configuration](references/bundler-config.md) | Vite, Next.js, Nuxt, SvelteKit, Metro alias setup |
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: bundler-config
3
+ description: "Framework-specific bundler configuration for #contentrain subpath imports"
4
+ ---
5
+
6
+ # Bundler Configuration for #contentrain
7
+
8
+ The `#contentrain` import requires subpath imports configuration in `package.json` and bundler-specific aliases.
9
+
10
+ ## package.json (all frameworks)
11
+
12
+ ```json
13
+ {
14
+ "imports": {
15
+ "#contentrain": "./.contentrain/client/index.mjs"
16
+ }
17
+ }
18
+ ```
19
+
20
+ ## Vite (Vue, React, Svelte)
21
+
22
+ ```typescript
23
+ // vite.config.ts
24
+ import { resolve } from 'node:path'
25
+ import { defineConfig } from 'vite'
26
+
27
+ export default defineConfig({
28
+ resolve: {
29
+ alias: {
30
+ '#contentrain': resolve(__dirname, '.contentrain/client/index.mjs')
31
+ }
32
+ }
33
+ })
34
+ ```
35
+
36
+ ## Next.js
37
+
38
+ ```javascript
39
+ // next.config.mjs
40
+ import { resolve } from 'node:path'
41
+
42
+ export default {
43
+ webpack(config) {
44
+ config.resolve.alias['#contentrain'] = resolve(process.cwd(), '.contentrain/client/index.mjs')
45
+ return config
46
+ }
47
+ }
48
+ ```
49
+
50
+ ## Nuxt 3
51
+
52
+ ```typescript
53
+ // nuxt.config.ts
54
+ import { resolve } from 'node:path'
55
+
56
+ export default defineNuxtConfig({
57
+ alias: {
58
+ '#contentrain': resolve(__dirname, '.contentrain/client/index.mjs')
59
+ }
60
+ })
61
+ ```
62
+
63
+ **Important:** Treat `#contentrain` as **server-only** in Nuxt. Use in server routes, server plugins, and `useAsyncData` callbacks only.
64
+
65
+ ## SvelteKit
66
+
67
+ ```javascript
68
+ // svelte.config.js
69
+ import { resolve } from 'node:path'
70
+
71
+ export default {
72
+ kit: {
73
+ alias: {
74
+ '#contentrain': resolve('.contentrain/client/index.mjs')
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ## Expo / React Native (Metro)
81
+
82
+ ```javascript
83
+ // metro.config.js
84
+ const { getDefaultConfig } = require('expo/metro-config')
85
+ const path = require('path')
86
+
87
+ const config = getDefaultConfig(__dirname)
88
+ config.resolver.extraNodeModules = {
89
+ '#contentrain': path.resolve(__dirname, '.contentrain/client/index.cjs')
90
+ }
91
+ module.exports = config
92
+ ```
93
+
94
+ **Bootstrap required:**
95
+ ```javascript
96
+ // App.js (before any #contentrain import)
97
+ require('#contentrain').init()
98
+ ```
99
+
100
+ ## Node.js (pure ESM)
101
+
102
+ No alias needed — Node.js natively supports `#imports` in `package.json`:
103
+
104
+ ```json
105
+ {
106
+ "type": "module",
107
+ "imports": {
108
+ "#contentrain": "./.contentrain/client/index.mjs"
109
+ }
110
+ }
111
+ ```
112
+
113
+ ## Node.js (CJS)
114
+
115
+ ```json
116
+ {
117
+ "imports": {
118
+ "#contentrain": "./.contentrain/client/index.cjs"
119
+ }
120
+ }
121
+ ```
122
+
123
+ Bootstrap required:
124
+ ```javascript
125
+ const contentrain = require('#contentrain')
126
+ await contentrain.init()
127
+ ```
128
+
129
+ ## Watch Mode
130
+
131
+ For development, run the generator in watch mode to auto-regenerate on model/content changes:
132
+
133
+ ```bash
134
+ npx contentrain generate --watch
135
+ ```
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: contentrain-serve
3
+ description: "Start the local Contentrain review and normalize UI. Use when launching the serve interface, reviewing changes visually, or managing normalize plans."
4
+ metadata:
5
+ author: Contentrain
6
+ version: "1.0.0"
7
+ ---
8
+
9
+ # Skill: Review the Project with `contentrain serve`
10
+
11
+ > Start the local review UI as a bridge between agent and developer.
12
+
13
+ ---
14
+
15
+ ## When to Use
16
+
17
+ Use this when:
18
+
19
+ - a normalize plan, branch, or validation result needs developer review
20
+ - the developer wants to browse models, content, or history visually
21
+ - another skill needs to hand off to the UI for approval (normalize, review)
22
+
23
+ ---
24
+
25
+ ## Steps
26
+
27
+ ### 1. Check if Serve is Already Running
28
+
29
+ Before starting a new instance, check if port 3333 is already in use:
30
+
31
+ ```bash
32
+ lsof -ti:3333
33
+ ```
34
+
35
+ If a process is running, serve is already up — skip to Step 3.
36
+
37
+ ### 2. Start Serve
38
+
39
+ Run from the project root (where `.contentrain/` lives):
40
+
41
+ ```bash
42
+ contentrain serve
43
+ ```
44
+
45
+ Optional flags:
46
+
47
+ - `--port` (default: 3333)
48
+ - `--host` (default: localhost)
49
+ - `--open=false` (prevent auto-opening browser)
50
+ - `--stdio` (MCP stdio transport for IDE integration — no web UI)
51
+
52
+ Wait for the "Contentrain Serve" banner confirming the server is ready.
53
+
54
+ ### 3. Direct the Developer to the Right Page
55
+
56
+ Based on the current context, tell the developer exactly where to go:
57
+
58
+ | Context | URL | What to do |
59
+ |---|---|---|
60
+ | Normalize plan ready | `http://localhost:3333/normalize` | Review extractions, approve or reject |
61
+ | Pending branches | `http://localhost:3333/branches` | Review and merge branches |
62
+ | Validation issues | `http://localhost:3333/validate` | Inspect errors and warnings |
63
+ | Content browsing | `http://localhost:3333/content` | Browse entries and models |
64
+ | General overview | `http://localhost:3333` | Dashboard with project stats |
65
+
66
+ ### 4. Wait for Developer Action
67
+
68
+ After directing the developer to the UI:
69
+
70
+ - **Normalize flow:** Check `.contentrain/normalize-plan.json` — if deleted, check for new branches to determine approve vs reject
71
+ - **Branch flow:** Check branch list — if branch was merged or deleted, proceed accordingly
72
+ - **Validation flow:** Re-read validation results after developer reviews
73
+
74
+ The UI communicates back through filesystem changes (plan files, branches, context.json). Poll these to detect the developer's decision.
75
+
76
+ ### 5. Resume the Workflow
77
+
78
+ After the developer acts in the UI:
79
+
80
+ - If **approved**: continue with the next step in the calling skill (validate, submit, Phase 2)
81
+ - If **rejected**: ask the developer what to change and iterate
82
+ - If **merged**: confirm and report the final state
83
+
84
+ Do NOT leave the developer hanging — always follow up after UI interaction.
85
+
86
+ ---
87
+
88
+ ## UI Philosophy
89
+
90
+ The serve UI is a **monitoring + approval surface**, not an action trigger:
91
+
92
+ - **Monitoring**: models, content, validation, history, branches — read-only browsing
93
+ - **Approval**: approve/reject normalize plans, merge/delete branches — human decisions
94
+ - **Prompts**: every page shows copyable agent prompts that developers paste into their AI agent
95
+
96
+ All mutations (create, edit, delete, scan, fix, normalize) are **agent-driven via MCP tools**. The UI never triggers these directly.