uniweb 0.87.3 → 0.88.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/README.md CHANGED
@@ -268,7 +268,7 @@ _Foundation-first_ — You're building a component system. The site is a test ha
268
268
 
269
269
  ## Growing Your Project
270
270
 
271
- > **Install the CLI globally** with `npm i -g uniweb` for the best experience. You can also use `npx uniweb` or `pnpm uniweb` without a global install.
271
+ > **Install the CLI globally** with `npm i -g uniweb` for the best experience — inside a project it runs the project's own copy. Keep it current: `create` and `clone` start a project on the CLI that runs them, so a global install stops them when a newer release is out. Without a global install, use `npx uniweb@latest create` to start a project and `pnpm uniweb` inside one.
272
272
 
273
273
  Start simple. Add what you need, when you need it:
274
274
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniweb",
3
- "version": "0.87.3",
3
+ "version": "0.88.0",
4
4
  "description": "Create structured Vite + React sites with content/code separation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,16 +42,16 @@
42
42
  "prompts": "^2.4.2",
43
43
  "tar": "^7.0.0",
44
44
  "@uniweb/core": "^0.38.0",
45
- "@uniweb/kit": "^0.20.0",
46
- "@uniweb/runtime": "^0.29.4",
45
+ "@uniweb/content-writer": "^0.3.4",
47
46
  "@uniweb/schemas": "^0.13.0",
48
- "@uniweb/semantic-parser": "^1.5.1",
49
- "@uniweb/content-writer": "^0.3.4"
47
+ "@uniweb/runtime": "^0.29.5",
48
+ "@uniweb/kit": "^0.20.0",
49
+ "@uniweb/semantic-parser": "^1.5.1"
50
50
  },
51
51
  "peerDependencies": {
52
- "@uniweb/build": "^0.80.3",
53
52
  "@uniweb/content-reader": "^1.2.8",
54
- "@uniweb/semantic-parser": "^1.5.1"
53
+ "@uniweb/semantic-parser": "^1.5.1",
54
+ "@uniweb/build": "^0.80.3"
55
55
  },
56
56
  "peerDependenciesMeta": {
57
57
  "@uniweb/build": {
@@ -109,11 +109,13 @@ For anything not in that table, start at the index. For CLI flags, prefer `uniwe
109
109
  **Always use the CLI to scaffold — never hand-write `package.json`, `vite.config.js`, `entry.js`, or `index.html`.** The CLI resolves correct versions and structure; hand-written config is the most common way to end up with a project that can't build.
110
110
 
111
111
  ```bash
112
- npx uniweb create my-project --template marketing
112
+ npx uniweb@latest create my-project --template marketing
113
113
  cd my-project && pnpm install
114
114
  uniweb dev
115
115
  ```
116
116
 
117
+ `@latest` matters: a project starts on the packages and templates of the CLI that creates it, and a bare `npx uniweb` runs a globally installed `uniweb` when there is one, however old.
118
+
117
119
  **Choosing a template.** `--template <name>` gives you a working site plus a foundation you can study and edit. `--template none` gives you the same two packages with no content — the right choice when you're building a foundation from scratch or porting a design. `--blank` gives you an empty workspace and assumes you'll add packages with `uniweb add`; use it only if you already know the framework.
118
120
 
119
121
  Official templates include `marketing` (tokens, insets, grids, multi-line headings), `docs` (sidebar nav, code highlighting), `blog` (records of the standard `@std/article` schema, a query, a parametric `[slug]` page), `dynamic` (live API data, loading states), `international` (i18n, records, multi-locale routing), `store` (product grids, e-commerce), `academic` (publications, timeline, math), `extensions` (multi-foundation, runtime loading). `uniweb template list` shows them all.
@@ -1066,7 +1066,7 @@ async function applyFromTemplate(
1066
1066
  })
1067
1067
 
1068
1068
  try {
1069
- const metadata = await validateTemplate(resolved.path, {})
1069
+ const metadata = await validateTemplate(resolved.path)
1070
1070
 
1071
1071
  // Look in contentDirs for matching package type
1072
1072
  const match =
@@ -1083,10 +1083,7 @@ async function applyFromTemplate(
1083
1083
  projectName,
1084
1084
  versions: getVersionsForTemplates()
1085
1085
  },
1086
- {
1087
- onProgress: (msg) => info(` ${msg}`),
1088
- renames: match.renames
1089
- }
1086
+ { onProgress: (msg) => info(` ${msg}`) }
1090
1087
  )
1091
1088
 
1092
1089
  // Merge template dependencies
@@ -1,29 +1,25 @@
1
1
  /**
2
- * template — `list` is live; `register` is RESERVED (not on the new backend yet).
3
- *
4
- * `uniweb template publish` submitted a site as a cloud template to the legacy
5
- * registry (the PHP backend + Cloudflare Worker) the CLI no longer talks to. A
6
- * new-backend equivalent isn't built; when it is, a template is REGISTERED (like
7
- * a foundation or a schemas package) — the verb will be `register`, not `publish`
8
- * (`publish` is for SITES only). The command name is kept reserved.
9
- *
10
- * (Unrelated: scaffolding FROM a template — `uniweb create --template <name>` —
11
- * is a separate path and is unaffected.)
2
+ * template — lists the official templates.
12
3
  *
13
4
  * ⭐ `list` exists so a SCRIPT can enumerate the official templates. The
14
- * interactive picker in `create` has always shown this list; `--json` is the
15
- * same data, second rendering, for tooling that scaffolds several templates in
16
- * a row and needs their names first.
5
+ * interactive picker in `create` shows the same list; `--json` is the same
6
+ * data, second rendering, for tooling that scaffolds several templates in a
7
+ * row and needs their names first. A bare `uniweb template` lists too.
8
+ *
9
+ * ⚠️ IT REPORTS THIS CLI'S SNAPSHOT, NOT A LIVE FETCH — the roster is baked into
10
+ * the CLI at publish time (`src/framework-index.json`), and `create` downloads
11
+ * these templates from the release that same snapshot names. So it answers
12
+ * "which official templates does THIS CLI scaffold", which is the right
13
+ * question when the next step is resolving one of those names with the same
14
+ * CLI. `cliVersion` is in the JSON for exactly that reason. A newer template
15
+ * than your CLI will not appear — and an unknown name is not fatal either way,
16
+ * since `create` falls through to npm `@uniweb/template-<name>`, so this is the
17
+ * OFFICIAL roster rather than the set of resolvable names.
17
18
  *
18
- * ⚠️ IT REPORTS A BUNDLED SNAPSHOT, NOT A LIVE FETCH — the roster is baked into
19
- * the CLI at publish time (`src/framework-index.json`, rewritten from
20
- * `templates/manifest.json` by the pre-publish hook). So it answers "which
21
- * official templates does THIS CLI know", which is the right question when the
22
- * next step is resolving one of those names with the same CLI. `cliVersion` is
23
- * in the JSON for exactly that reason. A newer template than your CLI will not
24
- * appear — and an unknown name is not fatal either way, since `create` falls
25
- * through to npm `@uniweb/template-<name>`, so this is the OFFICIAL roster
26
- * rather than the set of resolvable names.
19
+ * ⛔ There is no `template register` [Diego, 2026-10-08]: a site is offered as a
20
+ * template by the backend it is pushed to when its `site.yml` says
21
+ * `template: true`, so there is nothing for a verb to do. It was a reserved
22
+ * refusal until then, and never worked on the current backend.
27
23
  */
28
24
 
29
25
  import { OFFICIAL_TEMPLATE_MAP } from '../templates/resolver.js'
@@ -37,24 +33,6 @@ const colors = {
37
33
  red: '\x1b[31m'
38
34
  }
39
35
 
40
- function reserved() {
41
- console.error(
42
- "\x1b[31m✗\x1b[0m `uniweb template register` isn't available on the new backend yet."
43
- )
44
- console.error(
45
- ' Submitting a site as a cloud template was retired with the PHP backend.'
46
- )
47
- console.error(
48
- ' A template is REGISTERED, like a foundation — `publish` is for sites only.'
49
- )
50
- console.error(
51
- ' (Scaffolding FROM a template still works: `uniweb create --template <name>`.)'
52
- )
53
- console.error('')
54
- console.error(' To list the official templates: `uniweb template list`.')
55
- process.exit(1)
56
- }
57
-
58
36
  function listTemplates(args) {
59
37
  const entries = Object.entries(OFFICIAL_TEMPLATE_MAP).map(([id, info]) => ({
60
38
  id,
@@ -73,19 +51,19 @@ function listTemplates(args) {
73
51
  2
74
52
  ) + '\n'
75
53
  )
76
- return
54
+ return { exitCode: 0 }
77
55
  }
78
56
 
79
57
  if (entries.length === 0) {
80
- // Not a crash: a CLI whose snapshot failed to load falls back to an empty
81
- // map, and `create` then routes every name to npm. Say which happened.
58
+ // Not a crash: a CLI whose snapshot failed to load has an empty map, and
59
+ // `create` then routes every name to npm. Say which happened.
82
60
  console.error(
83
61
  `${colors.red}✗${colors.reset} No official templates found in this CLI's bundled index.`
84
62
  )
85
63
  console.error(
86
64
  ` ${colors.dim}A template name will still resolve through npm as @uniweb/template-<name>.${colors.reset}`
87
65
  )
88
- process.exit(1)
66
+ return { exitCode: 1 }
89
67
  }
90
68
 
91
69
  const width = Math.max(...entries.map((e) => e.id.length))
@@ -107,12 +85,23 @@ function listTemplates(args) {
107
85
  ` ${colors.dim}--json for scripts. This is the roster THIS CLI ships with, not a live fetch.${colors.reset}`
108
86
  )
109
87
  console.log('')
88
+ return { exitCode: 0 }
110
89
  }
111
90
 
91
+ /**
92
+ * @param {string[]} args - what follows `uniweb template`
93
+ * @returns {{ exitCode: number }}
94
+ */
112
95
  export async function template(args = []) {
113
96
  const sub = args.find((a) => !a.startsWith('-'))
114
- if (sub === 'list') return listTemplates(args)
115
- return reserved()
97
+ if (sub === undefined || sub === 'list') return listTemplates(args)
98
+ console.error(
99
+ `${colors.red}✗${colors.reset} Unknown subcommand: uniweb template ${sub}`
100
+ )
101
+ console.error(
102
+ ` ${colors.dim}uniweb template list lists the official templates${colors.reset}`
103
+ )
104
+ return { exitCode: 2 }
116
105
  }
117
106
 
118
107
  export default template
@@ -1,141 +1,66 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-10-08T17:12:48.725Z",
3
+ "generatedAt": "2026-10-09T02:27:27.906Z",
4
4
  "packages": {
5
5
  "@uniweb/api": {
6
- "version": "0.7.0",
7
- "path": "framework/api",
8
- "deps": [
9
- "@uniweb/core"
10
- ]
6
+ "version": "0.7.0"
11
7
  },
12
8
  "@uniweb/build": {
13
- "version": "0.80.3",
14
- "path": "framework/build",
15
- "deps": [
16
- "@uniweb/content-reader",
17
- "@uniweb/content-writer",
18
- "@uniweb/core",
19
- "@uniweb/projections",
20
- "@uniweb/runtime",
21
- "@uniweb/runtime",
22
- "@uniweb/schemas",
23
- "@uniweb/semantic-parser",
24
- "@uniweb/theming"
25
- ]
9
+ "version": "0.80.3"
26
10
  },
27
11
  "@uniweb/content-reader": {
28
- "version": "1.2.8",
29
- "path": "framework/content-reader",
30
- "deps": []
12
+ "version": "1.2.8"
31
13
  },
32
14
  "@uniweb/content-writer": {
33
- "version": "0.3.4",
34
- "path": "framework/content-writer",
35
- "deps": []
15
+ "version": "0.3.4"
36
16
  },
37
17
  "@uniweb/core": {
38
- "version": "0.38.0",
39
- "path": "framework/core",
40
- "deps": [
41
- "@uniweb/semantic-parser",
42
- "@uniweb/theming"
43
- ]
18
+ "version": "0.38.0"
44
19
  },
45
20
  "@uniweb/frame-bridge": {
46
- "version": "0.3.2",
47
- "path": "framework/frame-bridge",
48
- "deps": []
21
+ "version": "0.3.2"
49
22
  },
50
23
  "@uniweb/icons": {
51
- "version": "0.4.29",
52
- "path": "framework/icons",
53
- "deps": [
54
- "@uniweb/core"
55
- ]
24
+ "version": "0.4.29"
56
25
  },
57
26
  "@uniweb/kit": {
58
- "version": "0.20.0",
59
- "path": "framework/kit",
60
- "deps": [
61
- "@uniweb/core",
62
- "@uniweb/projections",
63
- "@uniweb/scene",
64
- "@uniweb/schemas",
65
- "@uniweb/semantic-parser"
66
- ]
27
+ "version": "0.20.0"
67
28
  },
68
29
  "@uniweb/loom": {
69
- "version": "0.2.5",
70
- "path": "framework/loom",
71
- "deps": []
30
+ "version": "0.2.5"
72
31
  },
73
32
  "@uniweb/press": {
74
- "version": "0.4.18",
75
- "path": "framework/press",
76
- "deps": []
33
+ "version": "0.4.18"
77
34
  },
78
35
  "@uniweb/projections": {
79
- "version": "0.7.15",
80
- "path": "framework/projections",
81
- "deps": [
82
- "@uniweb/content-writer",
83
- "@uniweb/core"
84
- ]
36
+ "version": "0.7.15"
85
37
  },
86
38
  "@uniweb/runtime": {
87
- "version": "0.29.4",
88
- "path": "framework/runtime",
89
- "deps": [
90
- "@uniweb/core",
91
- "@uniweb/theming"
92
- ]
39
+ "version": "0.29.5"
93
40
  },
94
41
  "@uniweb/scene": {
95
- "version": "0.1.3",
96
- "path": "framework/scene",
97
- "deps": []
42
+ "version": "0.1.3"
98
43
  },
99
44
  "@uniweb/schemas": {
100
- "version": "0.13.0",
101
- "path": "framework/schemas",
102
- "deps": []
45
+ "version": "0.13.0"
103
46
  },
104
47
  "@uniweb/scholar": {
105
- "version": "0.2.3",
106
- "path": "framework/scholar",
107
- "deps": []
48
+ "version": "0.2.3"
108
49
  },
109
50
  "@uniweb/semantic-parser": {
110
- "version": "1.5.1",
111
- "path": "framework/semantic-parser",
112
- "deps": []
51
+ "version": "1.5.1"
113
52
  },
114
53
  "@uniweb/snapshot": {
115
- "version": "0.1.2",
116
- "path": "framework/snapshot",
117
- "deps": []
54
+ "version": "0.1.2"
118
55
  },
119
56
  "@uniweb/templates": {
120
- "version": "0.18.4",
121
- "path": "framework/templates",
122
- "deps": []
57
+ "version": "0.18.5"
123
58
  },
124
59
  "@uniweb/theming": {
125
- "version": "0.2.0",
126
- "path": "framework/theming",
127
- "deps": []
60
+ "version": "0.2.0"
128
61
  },
129
62
  "@uniweb/unipress": {
130
- "version": "0.10.24",
131
- "path": "framework/unipress",
132
- "deps": [
133
- "@uniweb/build",
134
- "@uniweb/content-reader",
135
- "@uniweb/core",
136
- "@uniweb/runtime",
137
- "@uniweb/semantic-parser"
138
- ]
63
+ "version": "0.10.24"
139
64
  }
140
65
  },
141
66
  "templates": {
@@ -233,8 +158,8 @@
233
158
  ]
234
159
  },
235
160
  "cv-loom": {
236
- "name": "CV (Loom)",
237
- "description": "A single-page narrative CV whose prose is written with {placeholder} expressions and instantiated at render time via the foundation content handler and @uniweb/loom. Reference implementation of the handler hook.",
161
+ "name": "CV (Loom + Press)",
162
+ "description": "An academic CV whose sections are written with Loom {placeholder} expressions, filled in from a single profile at render time by the foundation's content handler, and downloadable as a branded Word document through Press. Ships with Charles Darwin's CV as sample data.",
238
163
  "tags": [
239
164
  "cv",
240
165
  "loom",