uniweb 0.80.8 → 0.81.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.81.0",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,17 +41,17 @@
|
|
|
41
41
|
"js-yaml": "^4.1.0",
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
43
|
"tar": "^7.0.0",
|
|
44
|
-
"@uniweb/core": "^0.35.4",
|
|
45
|
-
"@uniweb/runtime": "^0.28.9",
|
|
46
44
|
"@uniweb/content-writer": "^0.3.4",
|
|
47
|
-
"@uniweb/
|
|
48
|
-
"@uniweb/
|
|
45
|
+
"@uniweb/core": "^0.36.0",
|
|
46
|
+
"@uniweb/runtime": "^0.28.10",
|
|
47
|
+
"@uniweb/kit": "^0.19.15",
|
|
48
|
+
"@uniweb/schemas": "^0.10.2",
|
|
49
49
|
"@uniweb/semantic-parser": "^1.5.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
+
"@uniweb/build": "^0.75.0",
|
|
52
53
|
"@uniweb/content-reader": "^1.2.8",
|
|
53
|
-
"@uniweb/semantic-parser": "^1.5.1"
|
|
54
|
-
"@uniweb/build": "^0.74.4"
|
|
54
|
+
"@uniweb/semantic-parser": "^1.5.1"
|
|
55
55
|
},
|
|
56
56
|
"peerDependenciesMeta": {
|
|
57
57
|
"@uniweb/build": {
|
package/partials/agents.md
CHANGED
|
@@ -1031,7 +1031,7 @@ import LessonHeader from '../../components/LessonHeader' // ❌ breaks if you re
|
|
|
1031
1031
|
|
|
1032
1032
|
Within the same directory, use normal relative imports (`./AIFeedbackCard`).
|
|
1033
1033
|
|
|
1034
|
-
**Foundation entry (`main.js`).** A single `export default { … }` whose top-level keys are the foundation's identity — `name` (what it registers as, `@org/<name>`) and `description` — and the capabilities it provides — `defaultLayout`, `defaultSection`, `viewTransitions`, `
|
|
1034
|
+
**Foundation entry (`main.js`).** A single `export default { … }` whose top-level keys are the foundation's identity — `name` (what it registers as, `@org/<name>`) and `description` — and the capabilities it provides — `defaultLayout`, `defaultSection`, `viewTransitions`, `defaultInsets`, `xref`, `outputs`, `handlers` — plus an optional named `vars` export. The capabilities are read at render; the one thing a foundation declares that *isn't* — which host services it supports — lives in `package.json` instead (see [Declaring what your foundation supports](#declaring-what-your-foundation-supports)). Section types and layouts are auto-discovered and merged in by `@uniweb/build`. The build carries into `default.capabilities` in `dist/entry.js` only what a published page reads of your default export — the code it calls (`handlers`, `defaultInsets`, `xref`, `transports`, `outputs`) and its data, lean (`defaultLayout`, `defaultSection`, `viewTransitions`, `scroll`, each var's `default`, `type` and `applyTo`, each `data:` key's schema ref). `name`, `description`, a var's label or description and any key the framework does not read stay out of the published bundle: they are for the editor, which reads them from the foundation's schema. You never write that wrapper. The file is `main.js` — never `main.jsx`, which the build refuses; `main.js` may hold JSX. The one place it matters: when you import your **own** `main.js` from a component (e.g. a download button calling `compileDocument(website, { foundation })`), you get the bare default object — pass it through directly, Press handles both shapes.
|
|
1035
1035
|
|
|
1036
1036
|
### Props interface
|
|
1037
1037
|
|
|
@@ -2726,8 +2726,8 @@ That freezes sites using your foundation on the recorded version. Only reach for
|
|
|
2726
2726
|
```yaml
|
|
2727
2727
|
# site.yml
|
|
2728
2728
|
defaultLanguage: en
|
|
2729
|
-
languages: [en, es, fr] #
|
|
2730
|
-
# auto-discover from the locales/ folder
|
|
2729
|
+
languages: [en, es, fr] # codes only — a language's name comes from its code;
|
|
2730
|
+
# or '*' to auto-discover from the locales/ folder
|
|
2731
2731
|
publishLanguages: [en, es] # optional — fr stays a dev-previewable draft,
|
|
2732
2732
|
# excluded from production output entirely
|
|
2733
2733
|
```
|
|
@@ -2742,6 +2742,8 @@ uniweb build # merges translations, emits dist/es/, dist/fr/
|
|
|
2742
2742
|
|
|
2743
2743
|
Running `extract` before a build is the usual first mistake — it reads the compiled content, so a stale build yields a stale manifest. After content changes, `uniweb i18n sync` updates the manifest and `init` refreshes the language files; `status` and `audit` report coverage and stale entries.
|
|
2744
2744
|
|
|
2745
|
+
**A value is inline Markdown.** A sentence's links and bold go into its translation — `"Voir [Rôles](page:docs/roles)."` — or it renders without them, and coverage still counts it; `uniweb i18n status` lists these under *Loses markup*. A **button** — a line that is only a link — is the exception: translate its label alone and it keeps its link and options (`{role=primary}`). Buttons on consecutive lines are one string; give one label per line (`"Créer un groupe\nEn savoir plus"`).
|
|
2746
|
+
|
|
2745
2747
|
**Two mechanisms.** *Hash-based strings* (the default) — `locales/{locale}.json` maps content hash → translation, so structure stays identical across languages. When one source string needs different translations depending on where it appears, the value takes an override form:
|
|
2746
2748
|
|
|
2747
2749
|
```json
|
|
@@ -2858,4 +2860,8 @@ Source repo (public, cloneable): **https://github.com/uniweb/docs** · any page
|
|
|
2858
2860
|
| `development/` | Foundations, component patterns, project structures, data, layouts, i18n, migration, schemas |
|
|
2859
2861
|
| `reference/` | site.yml, page.yml, content structure, meta.js, kit API, navigation, records, queries, data fetching, parametric pages, CLI, deployment |
|
|
2860
2862
|
|
|
2861
|
-
The by-task table is in Part 0. For CLI flags, prefer `uniweb <command> --help` over this file — it's always current.
|
|
2863
|
+
The by-task table is in Part 0. For CLI flags, prefer `uniweb <command> --help` over this file — it's always current.
|
|
2864
|
+
|
|
2865
|
+
## Notes about this project
|
|
2866
|
+
|
|
2867
|
+
Conventions, decisions, where things are — keep them in a file of your own (`NOTES.md`, say). `uniweb update` rewrites this file for each new version, and the one part it keeps is a block between `<!-- project-notes:start -->` and `<!-- project-notes:end -->`, each on a line of its own, which it moves to the end of the file. That block is the place for a line pointing to your notes, or for short notes themselves.
|
package/src/commands/update.js
CHANGED
|
@@ -47,7 +47,9 @@ import prompts from 'prompts'
|
|
|
47
47
|
import { findWorkspaceRoot } from '../utils/workspace.js'
|
|
48
48
|
import {
|
|
49
49
|
readAgentsVersion,
|
|
50
|
-
|
|
50
|
+
refreshAgentsContent,
|
|
51
|
+
PROJECT_NOTES_START,
|
|
52
|
+
PROJECT_NOTES_END
|
|
51
53
|
} from '../utils/agents-stamp.js'
|
|
52
54
|
import { getCliVersion } from '../versions.js'
|
|
53
55
|
import { isNonInteractive } from '../utils/interactive.js'
|
|
@@ -775,9 +777,27 @@ async function refreshAgents(ctx) {
|
|
|
775
777
|
return 'current'
|
|
776
778
|
}
|
|
777
779
|
|
|
780
|
+
// The project's notes travel to the new file (`refreshAgentsContent`). Markers that do not pair
|
|
781
|
+
// up leave AGENTS.md as it is: where a block ends would be a guess, and a wrong one loses notes.
|
|
782
|
+
const refreshed = refreshAgentsContent(
|
|
783
|
+
existsSync(agentsPath) ? readFileSync(agentsPath, 'utf8') : null
|
|
784
|
+
)
|
|
785
|
+
if (refreshed.error) {
|
|
786
|
+
warn(`AGENTS.md left as it is: ${refreshed.error}.`)
|
|
787
|
+
log(
|
|
788
|
+
`${colors.dim}Your project notes are kept between ${PROJECT_NOTES_START} and ${PROJECT_NOTES_END}, each on a line of its own. Fix the markers, then re-run${colors.reset} ${colors.cyan}uniweb update${colors.reset}${colors.dim}.${colors.reset}`
|
|
789
|
+
)
|
|
790
|
+
log('')
|
|
791
|
+
if (agentsOnly) process.exit(1)
|
|
792
|
+
return 'skipped'
|
|
793
|
+
}
|
|
794
|
+
const keeping = refreshed.kept
|
|
795
|
+
? `, keeping ${refreshed.kept === 1 ? 'its project notes' : `its ${refreshed.kept} project-notes blocks`}`
|
|
796
|
+
: ''
|
|
797
|
+
|
|
778
798
|
if (dryRun) {
|
|
779
799
|
info(
|
|
780
|
-
`Dry-run: would ${currentAgentsVersion ? `update AGENTS.md (v${currentAgentsVersion} → v${cliVersion})` : `create AGENTS.md (v${cliVersion})`}.`
|
|
800
|
+
`Dry-run: would ${currentAgentsVersion ? `update AGENTS.md (v${currentAgentsVersion} → v${cliVersion})` : `create AGENTS.md (v${cliVersion})`}${keeping}.`
|
|
781
801
|
)
|
|
782
802
|
return 'skipped'
|
|
783
803
|
}
|
|
@@ -798,9 +818,9 @@ async function refreshAgents(ctx) {
|
|
|
798
818
|
}
|
|
799
819
|
}
|
|
800
820
|
|
|
801
|
-
writeFileSync(agentsPath,
|
|
821
|
+
writeFileSync(agentsPath, refreshed.content)
|
|
802
822
|
if (currentAgentsVersion) {
|
|
803
|
-
success(`Updated AGENTS.md (v${currentAgentsVersion} → v${cliVersion}).`)
|
|
823
|
+
success(`Updated AGENTS.md (v${currentAgentsVersion} → v${cliVersion})${keeping}.`)
|
|
804
824
|
return 'updated'
|
|
805
825
|
}
|
|
806
826
|
success(`Created AGENTS.md (v${cliVersion}).`)
|
package/src/framework-index.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-10-
|
|
3
|
+
"generatedAt": "2026-10-02T01:45:25.043Z",
|
|
4
4
|
"packages": {
|
|
5
5
|
"@uniweb/api": {
|
|
6
|
-
"version": "0.6.
|
|
6
|
+
"version": "0.6.9",
|
|
7
7
|
"path": "framework/api",
|
|
8
8
|
"deps": [
|
|
9
9
|
"@uniweb/core"
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
"@uniweb/build": {
|
|
13
|
-
"version": "0.
|
|
13
|
+
"version": "0.75.0",
|
|
14
14
|
"path": "framework/build",
|
|
15
15
|
"deps": [
|
|
16
16
|
"@uniweb/content-reader",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"deps": []
|
|
36
36
|
},
|
|
37
37
|
"@uniweb/core": {
|
|
38
|
-
"version": "0.
|
|
38
|
+
"version": "0.36.0",
|
|
39
39
|
"path": "framework/core",
|
|
40
40
|
"deps": [
|
|
41
41
|
"@uniweb/semantic-parser",
|
|
@@ -48,14 +48,14 @@
|
|
|
48
48
|
"deps": []
|
|
49
49
|
},
|
|
50
50
|
"@uniweb/icons": {
|
|
51
|
-
"version": "0.4.
|
|
51
|
+
"version": "0.4.27",
|
|
52
52
|
"path": "framework/icons",
|
|
53
53
|
"deps": [
|
|
54
54
|
"@uniweb/core"
|
|
55
55
|
]
|
|
56
56
|
},
|
|
57
57
|
"@uniweb/kit": {
|
|
58
|
-
"version": "0.19.
|
|
58
|
+
"version": "0.19.15",
|
|
59
59
|
"path": "framework/kit",
|
|
60
60
|
"deps": [
|
|
61
61
|
"@uniweb/core",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"deps": []
|
|
77
77
|
},
|
|
78
78
|
"@uniweb/projections": {
|
|
79
|
-
"version": "0.7.
|
|
79
|
+
"version": "0.7.13",
|
|
80
80
|
"path": "framework/projections",
|
|
81
81
|
"deps": [
|
|
82
82
|
"@uniweb/content-writer",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
]
|
|
85
85
|
},
|
|
86
86
|
"@uniweb/runtime": {
|
|
87
|
-
"version": "0.28.
|
|
87
|
+
"version": "0.28.10",
|
|
88
88
|
"path": "framework/runtime",
|
|
89
89
|
"deps": [
|
|
90
90
|
"@uniweb/core",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"deps": []
|
|
98
98
|
},
|
|
99
99
|
"@uniweb/schemas": {
|
|
100
|
-
"version": "0.10.
|
|
100
|
+
"version": "0.10.2",
|
|
101
101
|
"path": "framework/schemas",
|
|
102
102
|
"deps": []
|
|
103
103
|
},
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
"deps": []
|
|
118
118
|
},
|
|
119
119
|
"@uniweb/templates": {
|
|
120
|
-
"version": "0.17.
|
|
120
|
+
"version": "0.17.11",
|
|
121
121
|
"path": "framework/templates",
|
|
122
122
|
"deps": []
|
|
123
123
|
},
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"deps": []
|
|
128
128
|
},
|
|
129
129
|
"@uniweb/unipress": {
|
|
130
|
-
"version": "0.10.
|
|
130
|
+
"version": "0.10.18",
|
|
131
131
|
"path": "framework/unipress",
|
|
132
132
|
"deps": [
|
|
133
133
|
"@uniweb/build",
|
|
@@ -39,3 +39,72 @@ export function generateAgentsContent() {
|
|
|
39
39
|
const agentsContent = readFileSync(join(partialsDir, 'agents.md'), 'utf8')
|
|
40
40
|
return `<!-- uniweb-agents v${getCliVersion()} -->\n${agentsContent}\n`
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* ⭐ THE ONE PART OF AGENTS.md A PROJECT KEEPS: its project-notes blocks. `update` rewrites the
|
|
45
|
+
* file from this CLI's partial, so a note written anywhere else in it is lost on the next version.
|
|
46
|
+
* A block runs from a `<!-- project-notes:start -->` line to a `<!-- project-notes:end -->` line,
|
|
47
|
+
* and is carried over verbatim, at the end of the new file. ⛔ Until 2026-10-01 nothing was kept.
|
|
48
|
+
*
|
|
49
|
+
* A marker is a line of its own, outside a code fence — so the partial can name the markers in a
|
|
50
|
+
* sentence without its own text being taken for a block.
|
|
51
|
+
*/
|
|
52
|
+
export const PROJECT_NOTES_START = '<!-- project-notes:start -->'
|
|
53
|
+
export const PROJECT_NOTES_END = '<!-- project-notes:end -->'
|
|
54
|
+
|
|
55
|
+
const MARKER_LINE = /^<!--\s*project-notes:(start|end)\s*-->$/
|
|
56
|
+
const FENCE_LINE = /^(`{3,}|~{3,})/
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The project-notes blocks of an AGENTS.md, in order, each from its start line to its end line.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} text
|
|
62
|
+
* @returns {{ blocks: string[] } | { error: string }} an error when the markers do not pair up —
|
|
63
|
+
* where a block ends would be a guess, and a wrong one loses notes
|
|
64
|
+
*/
|
|
65
|
+
export function readProjectNotes(text) {
|
|
66
|
+
const blocks = []
|
|
67
|
+
let block = null
|
|
68
|
+
let fence = null
|
|
69
|
+
let lineNumber = 0
|
|
70
|
+
for (const line of String(text ?? '').split(/(?<=\n)/)) {
|
|
71
|
+
lineNumber++
|
|
72
|
+
const trimmed = line.trim()
|
|
73
|
+
const fenceMark = trimmed.match(FENCE_LINE)?.[1]
|
|
74
|
+
if (fenceMark && (!fence || fenceMark.startsWith(fence))) fence = fence ? null : fenceMark
|
|
75
|
+
const marker = !fence && !fenceMark ? trimmed.match(MARKER_LINE)?.[1] : null
|
|
76
|
+
|
|
77
|
+
if (marker === 'start') {
|
|
78
|
+
if (block) return { error: `a second ${PROJECT_NOTES_START} on line ${lineNumber}, before the first one's ${PROJECT_NOTES_END}` }
|
|
79
|
+
block = [line]
|
|
80
|
+
} else if (marker === 'end') {
|
|
81
|
+
if (!block) return { error: `${PROJECT_NOTES_END} on line ${lineNumber} has no ${PROJECT_NOTES_START} before it` }
|
|
82
|
+
block.push(line)
|
|
83
|
+
blocks.push(block.join('').replace(/\s+$/, ''))
|
|
84
|
+
block = null
|
|
85
|
+
} else if (block) {
|
|
86
|
+
block.push(line)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (block) return { error: `${PROJECT_NOTES_START} has no ${PROJECT_NOTES_END} after it` }
|
|
90
|
+
return { blocks }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* AGENTS.md as `update` writes it: this CLI's partial, stamped, and the project-notes blocks of the
|
|
95
|
+
* file it replaces after it.
|
|
96
|
+
*
|
|
97
|
+
* @param {string|null} existing - the current AGENTS.md, or null when there is none
|
|
98
|
+
* @returns {{ content: string, kept: number } | { error: string }}
|
|
99
|
+
*/
|
|
100
|
+
export function refreshAgentsContent(existing) {
|
|
101
|
+
const fresh = generateAgentsContent()
|
|
102
|
+
if (existing == null) return { content: fresh, kept: 0 }
|
|
103
|
+
const notes = readProjectNotes(existing)
|
|
104
|
+
if (notes.error) return notes
|
|
105
|
+
if (!notes.blocks.length) return { content: fresh, kept: 0 }
|
|
106
|
+
return {
|
|
107
|
+
content: `${fresh.replace(/\s+$/, '')}\n\n${notes.blocks.join('\n\n')}\n`,
|
|
108
|
+
kept: notes.blocks.length,
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// Foundation Configuration
|
|
2
|
-
// Schema: schemas/foundation.schema.json
|
|
3
2
|
//
|
|
4
3
|
// ─── CSS Custom Properties ──────────────────────────────────────────────────────
|
|
5
4
|
// Export `vars` to declare CSS custom properties that sites can override in theme.yml:
|
|
@@ -30,9 +29,5 @@ export default {
|
|
|
30
29
|
// ─── Layout ─────────────────────────────────────────────────────────────────
|
|
31
30
|
// Create layouts in layouts/MyLayout/index.jsx (auto-discovered).
|
|
32
31
|
// defaultLayout: 'MyLayout',
|
|
33
|
-
|
|
34
|
-
// ─── Props ──────────────────────────────────────────────────────────────────
|
|
35
|
-
// Foundation-wide data accessible via website.foundationProps in components.
|
|
36
|
-
// props: {},
|
|
37
32
|
}
|
|
38
33
|
{{/if}}
|
|
@@ -11,7 +11,7 @@ A website built with [Uniweb](https://github.com/uniweb/cli) — a component web
|
|
|
11
11
|
├── src/ # Foundation package (the site's source code; pkg name: src)
|
|
12
12
|
│ ├── sections/ # Section types (selectable by content authors)
|
|
13
13
|
│ ├── styles.css # Tailwind CSS v4 theme
|
|
14
|
-
│ ├── main.js # Foundation declarations (vars, defaultLayout
|
|
14
|
+
│ ├── main.js # Foundation declarations (name, vars, defaultLayout)
|
|
15
15
|
│ └── vite.config.js # defineFoundationConfig()
|
|
16
16
|
│
|
|
17
17
|
├── site/ # Content (markdown)
|