@uniweb/build 0.20.1 → 0.22.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 +7 -7
- package/src/site/index.js +4 -0
- package/src/site/plugin.js +56 -3
- package/src/uwx/site-project.js +2 -1
- package/src/uwx/site.js +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/build",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Build tooling for the Uniweb Component Web Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -59,16 +59,16 @@
|
|
|
59
59
|
"js-yaml": "^4.1.0",
|
|
60
60
|
"sharp": "^0.35.3",
|
|
61
61
|
"yaml": "^2.5.0",
|
|
62
|
-
"@uniweb/
|
|
63
|
-
"@uniweb/theming": "^0.1.15",
|
|
62
|
+
"@uniweb/projections": "^0.3.1",
|
|
64
63
|
"@uniweb/content-writer": "^0.3.3",
|
|
65
|
-
"@uniweb/
|
|
64
|
+
"@uniweb/theming": "^0.1.15",
|
|
65
|
+
"@uniweb/schemas": "^0.2.10"
|
|
66
66
|
},
|
|
67
67
|
"optionalDependencies": {
|
|
68
|
-
"@uniweb/
|
|
68
|
+
"@uniweb/content-reader": "^1.2.2",
|
|
69
69
|
"@uniweb/schemas": "^0.2.10",
|
|
70
|
-
"@uniweb/
|
|
71
|
-
"@uniweb/
|
|
70
|
+
"@uniweb/runtime": "^0.11.7",
|
|
71
|
+
"@uniweb/semantic-parser": "^1.2.2"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
package/src/site/index.js
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
export { siteContentPlugin } from './plugin.js'
|
|
10
10
|
export { defineSiteConfig, readSiteConfig, default } from './config.js'
|
|
11
11
|
export { collectSiteContent } from './content-collector.js'
|
|
12
|
+
// The `agents:` vocabulary lives in @uniweb/projections (which owns the block);
|
|
13
|
+
// re-exported so the CLI can validate an author's spelling without taking a
|
|
14
|
+
// direct dependency on it. Same shape as the search re-exports.
|
|
15
|
+
export { AGENTS_KEYS } from '@uniweb/projections'
|
|
12
16
|
export { buildSiteData } from './build-site-data.js'
|
|
13
17
|
export { shouldSplitContent } from './split-content.js'
|
|
14
18
|
export {
|
package/src/site/plugin.js
CHANGED
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
pageMarkdownFilename,
|
|
44
44
|
branchIndexFilename,
|
|
45
45
|
applyRouteTranslation,
|
|
46
|
+
partitionKnowledgePages,
|
|
46
47
|
INDEX_FILENAME
|
|
47
48
|
} from '@uniweb/projections'
|
|
48
49
|
import { collectSiteContent, mountEntriesOf } from './content-collector.js'
|
|
@@ -505,6 +506,58 @@ export function siteContentPlugin(options = {}) {
|
|
|
505
506
|
robots: seo.robots || {}
|
|
506
507
|
}
|
|
507
508
|
|
|
509
|
+
// Warn once per build, not once per collection — the dev server re-collects
|
|
510
|
+
// on every content change and would otherwise repeat this on every keystroke.
|
|
511
|
+
let warnedAboutKnowledge = false
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Collect the site, then drop `knowledge:` pages.
|
|
515
|
+
*
|
|
516
|
+
* ⛔ **This is the bundle lane, and the bundle lane has no agent.**
|
|
517
|
+
* `uniweb export` and `uniweb deploy --host <adapter>` both run this pipeline
|
|
518
|
+
* (`cli/src/commands/export.js`, `deploy.js`), and their destinations are
|
|
519
|
+
* static hosts — files served as files, with no service running over the
|
|
520
|
+
* content. A `knowledge:` page is source material for such a service: prose
|
|
521
|
+
* written for it to reason with, addressed to it rather than to a person.
|
|
522
|
+
* Here there is no service to give it to, so publishing it would turn prose
|
|
523
|
+
* written for a machine reader into pages for visitors — the only readers
|
|
524
|
+
* this host has.
|
|
525
|
+
*
|
|
526
|
+
* ⚠️ **Not a confidentiality argument.** [Diego, 2026-08-13] *"It is not the
|
|
527
|
+
* case that it's private in the sense of sensitive."* The service quotes this
|
|
528
|
+
* material back to whoever prompts it, by design. The reason to drop it here
|
|
529
|
+
* is that it has no reader on this lane, not that it must be kept from one.
|
|
530
|
+
*
|
|
531
|
+
* Measured 2026-08-13, before this existed: a knowledge page became
|
|
532
|
+
* `dist/kb/index.html` — a public route — and its body rode in the
|
|
533
|
+
* `__SITE_CONTENT__` of *every* prerendered page including `404.html`,
|
|
534
|
+
* because that script carries the whole site.
|
|
535
|
+
*
|
|
536
|
+
* ⚠️ **Deliberately NOT inside `collectSiteContent`.** The link lane
|
|
537
|
+
* (`build-site-data.js`) calls that same collector and **must keep** these
|
|
538
|
+
* pages: it hands `site-content.json` to a backend that derives an agent
|
|
539
|
+
* corpus from it and gates access to that corpus. Same flag, two correct
|
|
540
|
+
* answers, decided by what is behind the destination — so the subtraction
|
|
541
|
+
* belongs to the pipeline, not to the collector.
|
|
542
|
+
*/
|
|
543
|
+
async function collectForBundle(path, options) {
|
|
544
|
+
const collected = await collectSiteContent(path, options)
|
|
545
|
+
const { knowledgePages, renderedPages } = partitionKnowledgePages(collected.pages || [])
|
|
546
|
+
if (!knowledgePages.length) return collected
|
|
547
|
+
|
|
548
|
+
if (!warnedAboutKnowledge) {
|
|
549
|
+
warnedAboutKnowledge = true
|
|
550
|
+
const routes = knowledgePages.map(page => page.route).join(', ')
|
|
551
|
+
console.warn(
|
|
552
|
+
`[site-content] Dropped ${knowledgePages.length} knowledge page(s) from this build: ${routes}\n` +
|
|
553
|
+
` This build targets a host that serves files only, so nothing here reads them — their prose is ` +
|
|
554
|
+
`written for a site assistant, not for visitors. Use \`uniweb deploy\` to make them agent-readable.`
|
|
555
|
+
)
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return { ...collected, pages: renderedPages }
|
|
559
|
+
}
|
|
560
|
+
|
|
508
561
|
let siteContent = null
|
|
509
562
|
let resolvedSitePath = null
|
|
510
563
|
let resolvedPublicDir = null
|
|
@@ -738,7 +791,7 @@ export function siteContentPlugin(options = {}) {
|
|
|
738
791
|
if (!isProduction) {
|
|
739
792
|
try {
|
|
740
793
|
// Do an early content collection to get the collections config
|
|
741
|
-
const earlyContent = await
|
|
794
|
+
const earlyContent = await collectForBundle(resolvedSitePath, { foundationPath })
|
|
742
795
|
collectionsConfig = earlyContent.config?.collections
|
|
743
796
|
|
|
744
797
|
// Resolve content directory paths from site.yml paths: group
|
|
@@ -788,7 +841,7 @@ export function siteContentPlugin(options = {}) {
|
|
|
788
841
|
// pages stay in the graph so in-progress drafts remain previewable.
|
|
789
842
|
// strict on a production build: a mount that contributes no pages is a
|
|
790
843
|
// warning while you author and a broken deploy once you ship.
|
|
791
|
-
siteContent = await
|
|
844
|
+
siteContent = await collectForBundle(resolvedSitePath, { foundationPath, dropUnpublished: isProduction, base: basePath, strict: isProduction })
|
|
792
845
|
headHtml = await loadHeadHtml()
|
|
793
846
|
console.log(`[site-content] Collected ${siteContent.pages?.length || 0} pages`)
|
|
794
847
|
|
|
@@ -841,7 +894,7 @@ export function siteContentPlugin(options = {}) {
|
|
|
841
894
|
rebuildTimeout = setTimeout(async () => {
|
|
842
895
|
console.log('[site-content] Content changed, rebuilding...')
|
|
843
896
|
try {
|
|
844
|
-
siteContent = await
|
|
897
|
+
siteContent = await collectForBundle(resolvedSitePath, { foundationPath, base: basePath })
|
|
845
898
|
headHtml = await loadHeadHtml()
|
|
846
899
|
// Execute fetches for the updated content
|
|
847
900
|
await executeDevFetches(siteContent, resolvedSitePath)
|
package/src/uwx/site-project.js
CHANGED
|
@@ -358,7 +358,7 @@ export function pageSectionsToFiles({ pageDir, pageSections, ctx, pageContext })
|
|
|
358
358
|
// and preserved. Keep in sync with pageRecordToYml below.
|
|
359
359
|
const PAGE_YML_MANAGED_KEYS = new Set([
|
|
360
360
|
'id', 'title', 'description', 'label', 'keywords', 'index', 'hidden',
|
|
361
|
-
'hideIn', 'redirect', 'rewrite', 'layout', 'seo',
|
|
361
|
+
'hideIn', 'knowledge', 'redirect', 'rewrite', 'layout', 'seo',
|
|
362
362
|
'fetch', 'sections',
|
|
363
363
|
])
|
|
364
364
|
|
|
@@ -380,6 +380,7 @@ function pageRecordToYml(record, sectionsArray, sourceLocale) {
|
|
|
380
380
|
if (record.is_index) y.index = true
|
|
381
381
|
if (record.hidden !== undefined) y.hidden = record.hidden
|
|
382
382
|
if (record.hide_in !== undefined) y.hideIn = record.hide_in
|
|
383
|
+
if (record.knowledge !== undefined) y.knowledge = record.knowledge
|
|
383
384
|
if (record.redirect !== undefined) y.redirect = record.redirect
|
|
384
385
|
if (record.rewrite !== undefined) y.rewrite = record.rewrite
|
|
385
386
|
if (record.layout !== undefined) y.layout = record.layout
|
package/src/uwx/site.js
CHANGED
|
@@ -201,6 +201,11 @@ function buildPageData(config, ctx) {
|
|
|
201
201
|
setIf(data, 'hidden', config.hidden)
|
|
202
202
|
const hideIn = normalizeHideIn(config)
|
|
203
203
|
if (hideIn.length) data.hide_in = hideIn
|
|
204
|
+
// Agent-only content. Sent as authored — only the marked page carries it, and
|
|
205
|
+
// the cascade to descendants is the CONSUMER's to compute (by route prefix, or
|
|
206
|
+
// equivalently by walking the page tree). A reader that tests this field alone
|
|
207
|
+
// honours the branch root and silently misses every child.
|
|
208
|
+
setIf(data, 'knowledge', config.knowledge)
|
|
204
209
|
setIf(data, 'redirect', config.redirect)
|
|
205
210
|
setIf(data, 'rewrite', config.rewrite)
|
|
206
211
|
setIf(data, 'layout', config.layout)
|