uniweb 0.2.41 → 0.2.42
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 +28 -0
- package/package.json +2 -2
- package/partials/{claude-md.hbs → agents-md.hbs} +1 -1
- package/partials/ai-assistance.hbs +1 -1
- package/partials/components-docs.hbs +6 -8
- package/src/commands/docs.js +74 -13
- package/src/templates/resolver.js +1 -1
- package/templates/_shared/AGENTS.md.hbs +1 -0
- package/templates/multi/AGENTS.md.hbs +1 -0
- package/templates/multi/README.md.hbs +1 -1
- package/templates/multi/foundations/default/package.json.hbs +1 -2
- package/templates/single/README.md.hbs +1 -1
- package/templates/single/foundation/package.json.hbs +1 -2
- package/templates/single/template.json +1 -1
- package/templates/template/template/{CLAUDE.md.hbs → AGENTS.md.hbs} +1 -1
- package/templates/_shared/CLAUDE.md.hbs +0 -1
- package/templates/multi/CLAUDE.md.hbs +0 -1
package/README.md
CHANGED
|
@@ -18,6 +18,9 @@ The `marketing` template includes real components (Hero, Features, Pricing, Test
|
|
|
18
18
|
**Other templates:**
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
+
# Multilingual business site (English, Spanish, French)
|
|
22
|
+
npx uniweb@latest create my-site --template international
|
|
23
|
+
|
|
21
24
|
# Academic site (researcher portfolios, lab pages)
|
|
22
25
|
npx uniweb@latest create my-site --template academic
|
|
23
26
|
|
|
@@ -371,6 +374,31 @@ uniweb create my-site --template docs
|
|
|
371
374
|
|
|
372
375
|
Perfect for technical documentation, guides, and API references.
|
|
373
376
|
|
|
377
|
+
### International
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
uniweb create my-site --template international
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Includes:** Hero, Features, Team, CTA, Header (with language switcher), Footer (with language links)
|
|
384
|
+
|
|
385
|
+
**Languages:** English (default), Spanish, French
|
|
386
|
+
|
|
387
|
+
A multilingual business site demonstrating Uniweb's i18n capabilities. Includes pre-configured translation files and a complete localization workflow:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
# Extract translatable strings
|
|
391
|
+
uniweb i18n extract
|
|
392
|
+
|
|
393
|
+
# Check translation coverage
|
|
394
|
+
uniweb i18n status
|
|
395
|
+
|
|
396
|
+
# Build generates locale-specific output (dist/es/, dist/fr/)
|
|
397
|
+
uniweb build
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Perfect for international businesses and learning the i18n workflow.
|
|
401
|
+
|
|
374
402
|
## External Templates
|
|
375
403
|
|
|
376
404
|
Use templates from npm or GitHub:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.42",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"js-yaml": "^4.1.0",
|
|
38
38
|
"prompts": "^2.4.2",
|
|
39
39
|
"tar": "^7.0.0",
|
|
40
|
-
"@uniweb/build": "0.1.
|
|
40
|
+
"@uniweb/build": "0.1.23",
|
|
41
41
|
"@uniweb/core": "0.1.10",
|
|
42
42
|
"@uniweb/kit": "0.1.5",
|
|
43
43
|
"@uniweb/runtime": "0.2.11"
|
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
Generate up-to-date documentation for all foundation components:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
# From
|
|
7
|
-
pnpm docs
|
|
8
|
-
```
|
|
6
|
+
# From foundation directory
|
|
7
|
+
pnpm uniweb docs
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- Presets (pre-configured parameter combinations)
|
|
9
|
+
# Or from site directory (auto-detects linked foundation)
|
|
10
|
+
cd site && pnpm uniweb docs
|
|
11
|
+
```
|
|
14
12
|
|
|
15
|
-
The documentation is generated from component `meta.js` files, so it's always current.
|
|
13
|
+
This creates `COMPONENTS.md` with details on each component's parameters, presets, and content elements. The documentation is generated from component `meta.js` files, so it's always current.
|
package/src/commands/docs.js
CHANGED
|
@@ -7,10 +7,14 @@
|
|
|
7
7
|
* uniweb docs # Generate docs for current directory
|
|
8
8
|
* uniweb docs --output README.md # Custom output filename
|
|
9
9
|
* uniweb docs --from-source # Build schema from source (no build required)
|
|
10
|
+
*
|
|
11
|
+
* When run from a site directory, automatically finds and documents the
|
|
12
|
+
* linked foundation, placing COMPONENTS.md in the site folder.
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
import { existsSync } from 'node:fs'
|
|
13
|
-
import {
|
|
16
|
+
import { readFile } from 'node:fs/promises'
|
|
17
|
+
import { resolve, join, dirname } from 'node:path'
|
|
14
18
|
import { generateDocs } from '@uniweb/build'
|
|
15
19
|
|
|
16
20
|
// Colors for terminal output
|
|
@@ -72,7 +76,7 @@ function showHelp() {
|
|
|
72
76
|
${colors.bright}uniweb docs${colors.reset} - Generate component documentation
|
|
73
77
|
|
|
74
78
|
${colors.dim}Usage:${colors.reset}
|
|
75
|
-
uniweb docs Generate COMPONENTS.md
|
|
79
|
+
uniweb docs Generate COMPONENTS.md
|
|
76
80
|
uniweb docs --output DOCS.md Custom output filename
|
|
77
81
|
uniweb docs --from-source Build schema from source (no build required)
|
|
78
82
|
|
|
@@ -82,8 +86,9 @@ ${colors.dim}Options:${colors.reset}
|
|
|
82
86
|
-h, --help Show this help message
|
|
83
87
|
|
|
84
88
|
${colors.dim}Notes:${colors.reset}
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
Run from a foundation directory to generate docs there.
|
|
90
|
+
Run from a site directory to auto-detect the linked foundation
|
|
91
|
+
and generate docs in the site folder for convenience.
|
|
87
92
|
`)
|
|
88
93
|
}
|
|
89
94
|
|
|
@@ -96,6 +101,47 @@ function isFoundation(dir) {
|
|
|
96
101
|
return existsSync(componentsDir)
|
|
97
102
|
}
|
|
98
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Detect if current directory is a site
|
|
106
|
+
*/
|
|
107
|
+
function isSite(dir) {
|
|
108
|
+
return existsSync(join(dir, 'site.yml')) || existsSync(join(dir, 'site.yaml'))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Resolve foundation path from a site directory
|
|
113
|
+
* Reads package.json to find foundation dependency with file: protocol
|
|
114
|
+
*/
|
|
115
|
+
async function resolveFoundationFromSite(siteDir) {
|
|
116
|
+
const pkgPath = join(siteDir, 'package.json')
|
|
117
|
+
if (!existsSync(pkgPath)) {
|
|
118
|
+
return null
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'))
|
|
123
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
124
|
+
|
|
125
|
+
// Look for foundation dependency with file: protocol
|
|
126
|
+
// Common names: "foundation", or the foundation name from site.yml
|
|
127
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
128
|
+
if (typeof version === 'string' && version.startsWith('file:')) {
|
|
129
|
+
const relativePath = version.slice(5) // Remove 'file:' prefix
|
|
130
|
+
const absolutePath = resolve(siteDir, relativePath)
|
|
131
|
+
|
|
132
|
+
// Check if this is actually a foundation
|
|
133
|
+
if (isFoundation(absolutePath)) {
|
|
134
|
+
return { name, path: absolutePath }
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch {
|
|
139
|
+
// Ignore parse errors
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return null
|
|
143
|
+
}
|
|
144
|
+
|
|
99
145
|
/**
|
|
100
146
|
* Main docs command
|
|
101
147
|
*/
|
|
@@ -108,19 +154,34 @@ export async function docs(args) {
|
|
|
108
154
|
}
|
|
109
155
|
|
|
110
156
|
const projectDir = resolve(process.cwd())
|
|
157
|
+
let foundationDir = projectDir
|
|
158
|
+
let outputDir = projectDir
|
|
159
|
+
|
|
160
|
+
// Check if we're in a site directory
|
|
161
|
+
if (isSite(projectDir)) {
|
|
162
|
+
const foundation = await resolveFoundationFromSite(projectDir)
|
|
163
|
+
if (!foundation) {
|
|
164
|
+
error('Could not find a linked foundation in this site.')
|
|
165
|
+
log(`${colors.dim}Make sure package.json has a foundation dependency like:${colors.reset}`)
|
|
166
|
+
log(`${colors.dim} "foundation": "file:../foundation"${colors.reset}`)
|
|
167
|
+
process.exit(1)
|
|
168
|
+
}
|
|
111
169
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
170
|
+
foundationDir = foundation.path
|
|
171
|
+
outputDir = projectDir
|
|
172
|
+
info(`Found foundation: ${foundation.name} (${foundation.path})`)
|
|
173
|
+
} else if (!isFoundation(projectDir)) {
|
|
174
|
+
error('This directory does not appear to be a foundation or site.')
|
|
175
|
+
log(`${colors.dim}Foundations have a src/components/ directory.${colors.reset}`)
|
|
176
|
+
log(`${colors.dim}Sites have a site.yml file.${colors.reset}`)
|
|
116
177
|
process.exit(1)
|
|
117
178
|
}
|
|
118
179
|
|
|
119
180
|
// Check if schema.json exists (if not using --from-source)
|
|
120
|
-
const schemaPath = join(
|
|
181
|
+
const schemaPath = join(foundationDir, 'dist', 'schema.json')
|
|
121
182
|
if (!options.fromSource && !existsSync(schemaPath)) {
|
|
122
|
-
log(`${colors.yellow}⚠${colors.reset} No dist/schema.json found.`)
|
|
123
|
-
log(`${colors.dim}Run 'uniweb build' first, or use '--from-source'
|
|
183
|
+
log(`${colors.yellow}⚠${colors.reset} No dist/schema.json found in foundation.`)
|
|
184
|
+
log(`${colors.dim}Run 'uniweb build' in the foundation first, or use '--from-source'.${colors.reset}`)
|
|
124
185
|
log('')
|
|
125
186
|
info('Falling back to --from-source mode')
|
|
126
187
|
options.fromSource = true
|
|
@@ -129,8 +190,8 @@ export async function docs(args) {
|
|
|
129
190
|
try {
|
|
130
191
|
info('Generating documentation...')
|
|
131
192
|
|
|
132
|
-
const result = await generateDocs(
|
|
133
|
-
output: options.output,
|
|
193
|
+
const result = await generateDocs(foundationDir, {
|
|
194
|
+
output: join(outputDir, options.output),
|
|
134
195
|
fromSource: options.fromSource,
|
|
135
196
|
})
|
|
136
197
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export const BUILTIN_TEMPLATES = ['single', 'multi', 'template']
|
|
7
7
|
|
|
8
8
|
// Official templates from @uniweb/templates package (downloaded from GitHub releases)
|
|
9
|
-
export const OFFICIAL_TEMPLATES = ['marketing', 'academic', 'docs']
|
|
9
|
+
export const OFFICIAL_TEMPLATES = ['marketing', 'academic', 'docs', 'international']
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Parse a template identifier and determine its source type
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{> agents-md}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{> agents-md}}
|
|
@@ -22,7 +22,7 @@ A website built with [Uniweb](https://github.com/uniweb/cli) — a component web
|
|
|
22
22
|
│ ├── site.yml # Site configuration
|
|
23
23
|
│ └── vite.config.js # defineSiteConfig()
|
|
24
24
|
│
|
|
25
|
-
└──
|
|
25
|
+
└── AGENTS.md # AI assistant instructions
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Content Authoring
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "A minimal Uniweb project with one foundation and one site. The canonical starting point for any Uniweb project.",
|
|
4
4
|
"base": "_shared",
|
|
5
5
|
"structure": {
|
|
6
|
-
"root": ["package.json.hbs", "pnpm-workspace.yaml", ".gitignore", "
|
|
6
|
+
"root": ["package.json.hbs", "pnpm-workspace.yaml", ".gitignore", "AGENTS.md.hbs"],
|
|
7
7
|
"foundation": ["package.json.hbs", "vite.config.js", ".gitignore", "src/"],
|
|
8
8
|
"site": ["package.json.hbs", "vite.config.js", "index.html.hbs", "site.yml.hbs", "src/", "pages/"]
|
|
9
9
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{{> claude-md}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{{> claude-md}}
|