uniweb 0.8.31 → 0.8.33
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 +4 -4
- package/partials/agents.md +21 -4
- package/src/commands/doctor.js +25 -0
- package/src/commands/update.js +55 -0
- package/src/index.js +8 -0
- package/src/utils/agents-stamp.js +41 -0
- package/src/utils/scaffold.js +4 -1
- package/src/versions.js +9 -0
- package/templates/workspace/AGENTS.md.hbs +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.33",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
43
|
"tar": "^7.0.0",
|
|
44
44
|
"@uniweb/core": "0.5.18",
|
|
45
|
-
"@uniweb/kit": "0.7.
|
|
46
|
-
"@uniweb/runtime": "0.6.
|
|
45
|
+
"@uniweb/kit": "0.7.21",
|
|
46
|
+
"@uniweb/runtime": "0.6.28"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@uniweb/build": "0.8.
|
|
49
|
+
"@uniweb/build": "0.8.32",
|
|
50
50
|
"@uniweb/content-reader": "1.1.4",
|
|
51
51
|
"@uniweb/semantic-parser": "1.1.8"
|
|
52
52
|
},
|
package/partials/agents.md
CHANGED
|
@@ -398,7 +398,7 @@ function Hello() {
|
|
|
398
398
|
|
|
399
399
|
Access: `content.snippets[0]` → `{ language: 'jsx', code: 'function Hello() {...}' }`. The `language` attribute is a display hint for syntax highlighting, not a parsing format. Filter by language: `content.snippets.filter(s => s.language === 'css')`.
|
|
400
400
|
|
|
401
|
-
Both appear in `content.sequence` for document-order rendering. The difference: tagged data blocks are parsed and extracted to `content.data`; code snippets are preserved and collected in `content.snippets`.
|
|
401
|
+
Both appear in `content.sequence` for document-order rendering. The difference: tagged data blocks are parsed and extracted to `content.data`; code snippets are preserved and collected in `content.snippets`. `<Prose>` handles this automatically — it renders code snippets with syntax highlighting and skips tagged data blocks, which components access separately via `content.data`.
|
|
402
402
|
|
|
403
403
|
### Composition: Nesting and Embedding
|
|
404
404
|
|
|
@@ -875,12 +875,29 @@ Kit provides `H1` through `H6` — use the appropriate level for semantic hierar
|
|
|
875
875
|
**Full content rendering** (article/docs sections where the author controls the flow):
|
|
876
876
|
|
|
877
877
|
```jsx
|
|
878
|
-
import { Section,
|
|
878
|
+
import { Section, Prose } from '@uniweb/kit'
|
|
879
879
|
|
|
880
880
|
<Section block={block} width="lg" padding="md" />
|
|
881
|
-
<
|
|
881
|
+
<Prose content={content} block={block} />
|
|
882
882
|
```
|
|
883
883
|
|
|
884
|
+
`Prose` renders from the parsed content sequence — headings, paragraphs, images, code snippets, lists, etc. — with prose typography. Tagged data blocks are **skipped** (they're structured data, not prose). Access them via `content.data` for custom rendering:
|
|
885
|
+
|
|
886
|
+
```jsx
|
|
887
|
+
function Lesson({ content, block }) {
|
|
888
|
+
return (
|
|
889
|
+
<div>
|
|
890
|
+
<Prose content={content} block={block} />
|
|
891
|
+
{content.data.quiz && <Quiz data={content.data.quiz} />}
|
|
892
|
+
</div>
|
|
893
|
+
)
|
|
894
|
+
}
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
Pass `content` (the parsed content object — has `.sequence`). Pass `block` too if the content uses insets. Also works as a pure typography wrapper: `<Prose>{children}</Prose>`.
|
|
898
|
+
|
|
899
|
+
`Article` is an older alternative that renders from `block.rawContent` (raw ProseMirror nodes) — it renders everything including data blocks. Prefer `Prose` for new components.
|
|
900
|
+
|
|
884
901
|
**Visuals:**
|
|
885
902
|
|
|
886
903
|
```jsx
|
|
@@ -893,7 +910,7 @@ import { Visual } from '@uniweb/kit'
|
|
|
893
910
|
|
|
894
911
|
**Rendering text:** `H1`–`H6`, `P`, `Span`, `Div`, `Text` (with `as` prop)
|
|
895
912
|
|
|
896
|
-
**Rendering content:** `Section` (full section with prose + layout), `
|
|
913
|
+
**Rendering content:** `Section` (full section with prose + layout), `Prose` (prose from parsed content sequence, skips data blocks), `Article` (raw ProseMirror rendering), `Render` (ProseMirror nodes → React), `ChildBlocks` (render child sections)
|
|
897
914
|
|
|
898
915
|
**Rendering media:** `Visual` (first non-empty: inset/video/image), `Image`, `Media`, `Icon`
|
|
899
916
|
|
package/src/commands/doctor.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import { existsSync, readFileSync, readdirSync } from 'node:fs'
|
|
6
6
|
import { join, resolve, basename, dirname, relative } from 'node:path'
|
|
7
7
|
import yaml from 'js-yaml'
|
|
8
|
+
import { getCliVersion } from '../versions.js'
|
|
9
|
+
import { readAgentsVersion } from '../utils/agents-stamp.js'
|
|
8
10
|
|
|
9
11
|
// ANSI colors
|
|
10
12
|
const colors = {
|
|
@@ -484,6 +486,29 @@ export async function doctor(args = []) {
|
|
|
484
486
|
}
|
|
485
487
|
}
|
|
486
488
|
|
|
489
|
+
// Check AGENTS.md freshness
|
|
490
|
+
log('')
|
|
491
|
+
const agentsPath = join(workspaceDir, 'AGENTS.md')
|
|
492
|
+
const agentsVersion = readAgentsVersion(agentsPath)
|
|
493
|
+
const cliVersion = getCliVersion()
|
|
494
|
+
|
|
495
|
+
if (!existsSync(agentsPath)) {
|
|
496
|
+
warn('AGENTS.md not found')
|
|
497
|
+
info(`Run: uniweb update`)
|
|
498
|
+
issues.push({ type: 'warn', message: 'AGENTS.md not found' })
|
|
499
|
+
} else if (!agentsVersion) {
|
|
500
|
+
// No stamp — manually created or pre-stamp version
|
|
501
|
+
warn('AGENTS.md has no version stamp (may be outdated)')
|
|
502
|
+
info(`Run: uniweb update`)
|
|
503
|
+
issues.push({ type: 'warn', message: 'AGENTS.md has no version stamp' })
|
|
504
|
+
} else if (agentsVersion !== cliVersion) {
|
|
505
|
+
warn(`AGENTS.md is outdated (v${agentsVersion} → v${cliVersion})`)
|
|
506
|
+
info(`Run: uniweb update`)
|
|
507
|
+
issues.push({ type: 'warn', message: `AGENTS.md outdated (v${agentsVersion} → v${cliVersion})` })
|
|
508
|
+
} else {
|
|
509
|
+
success(`AGENTS.md is up to date (v${cliVersion})`)
|
|
510
|
+
}
|
|
511
|
+
|
|
487
512
|
// Summary
|
|
488
513
|
log('')
|
|
489
514
|
log('─'.repeat(50))
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uniweb update - Update generated project files
|
|
3
|
+
*
|
|
4
|
+
* Regenerates AGENTS.md from the installed CLI version.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { existsSync, writeFileSync } from 'node:fs'
|
|
8
|
+
import { join, resolve } from 'node:path'
|
|
9
|
+
import { findWorkspaceRoot } from '../utils/workspace.js'
|
|
10
|
+
import { readAgentsVersion, generateAgentsContent } from '../utils/agents-stamp.js'
|
|
11
|
+
import { getCliVersion } from '../versions.js'
|
|
12
|
+
|
|
13
|
+
// ANSI colors
|
|
14
|
+
const colors = {
|
|
15
|
+
reset: '\x1b[0m',
|
|
16
|
+
bright: '\x1b[1m',
|
|
17
|
+
dim: '\x1b[2m',
|
|
18
|
+
red: '\x1b[31m',
|
|
19
|
+
green: '\x1b[32m',
|
|
20
|
+
yellow: '\x1b[33m',
|
|
21
|
+
blue: '\x1b[36m'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const success = (msg) => console.log(`${colors.green}✓${colors.reset} ${msg}`)
|
|
25
|
+
const warn = (msg) => console.log(`${colors.yellow}⚠${colors.reset} ${msg}`)
|
|
26
|
+
const error = (msg) => console.log(`${colors.red}✗${colors.reset} ${msg}`)
|
|
27
|
+
const log = console.log
|
|
28
|
+
|
|
29
|
+
export async function update(args = []) {
|
|
30
|
+
const workspaceDir = findWorkspaceRoot(process.cwd())
|
|
31
|
+
|
|
32
|
+
if (!workspaceDir) {
|
|
33
|
+
error('Not in a Uniweb workspace')
|
|
34
|
+
log(`${colors.dim}Run this command from your project root or a package directory.${colors.reset}`)
|
|
35
|
+
process.exit(1)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const cliVersion = getCliVersion()
|
|
39
|
+
const agentsPath = join(workspaceDir, 'AGENTS.md')
|
|
40
|
+
const currentVersion = readAgentsVersion(agentsPath)
|
|
41
|
+
|
|
42
|
+
if (currentVersion === cliVersion) {
|
|
43
|
+
success(`AGENTS.md is already up to date (v${cliVersion})`)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const content = generateAgentsContent()
|
|
48
|
+
writeFileSync(agentsPath, content)
|
|
49
|
+
|
|
50
|
+
if (currentVersion) {
|
|
51
|
+
success(`Updated AGENTS.md (v${currentVersion} → v${cliVersion})`)
|
|
52
|
+
} else {
|
|
53
|
+
success(`Created AGENTS.md (v${cliVersion})`)
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/index.js
CHANGED
|
@@ -35,6 +35,7 @@ import { publish } from './commands/publish.js'
|
|
|
35
35
|
import { deploy } from './commands/deploy.js'
|
|
36
36
|
import { invite } from './commands/invite.js'
|
|
37
37
|
import { handoff } from './commands/handoff.js'
|
|
38
|
+
import { update } from './commands/update.js'
|
|
38
39
|
import { template } from './commands/template.js'
|
|
39
40
|
import {
|
|
40
41
|
resolveTemplate,
|
|
@@ -479,6 +480,12 @@ async function main() {
|
|
|
479
480
|
return
|
|
480
481
|
}
|
|
481
482
|
|
|
483
|
+
// Handle update command
|
|
484
|
+
if (command === 'update') {
|
|
485
|
+
await update(args.slice(1))
|
|
486
|
+
return
|
|
487
|
+
}
|
|
488
|
+
|
|
482
489
|
// Handle inspect command
|
|
483
490
|
if (command === 'inspect') {
|
|
484
491
|
await inspect(args.slice(1))
|
|
@@ -794,6 +801,7 @@ ${colors.bright}Commands:${colors.reset}
|
|
|
794
801
|
inspect <path> Inspect parsed content shape of a markdown file or folder
|
|
795
802
|
docs Generate component documentation
|
|
796
803
|
doctor Diagnose project configuration issues
|
|
804
|
+
update Update AGENTS.md to match installed CLI version
|
|
797
805
|
i18n <cmd> Internationalization (extract, sync, status)
|
|
798
806
|
template publish Publish a site as a cloud template
|
|
799
807
|
login Log in to your Uniweb account
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AGENTS.md version stamp utilities
|
|
3
|
+
*
|
|
4
|
+
* The stamp is an HTML comment on the first line: <!-- uniweb-agents v0.8.32 -->
|
|
5
|
+
* Used by `doctor` (freshness check) and `update` (regeneration).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
9
|
+
import { join, dirname } from 'node:path'
|
|
10
|
+
import { fileURLToPath } from 'node:url'
|
|
11
|
+
import { getCliVersion } from '../versions.js'
|
|
12
|
+
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
14
|
+
|
|
15
|
+
const STAMP_PATTERN = /^<!-- uniweb-agents v([\d.]+) -->/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Read the version stamp from an AGENTS.md file
|
|
19
|
+
* @param {string} filePath - Absolute path to AGENTS.md
|
|
20
|
+
* @returns {string|null} Version string or null if no stamp
|
|
21
|
+
*/
|
|
22
|
+
export function readAgentsVersion(filePath) {
|
|
23
|
+
if (!existsSync(filePath)) return null
|
|
24
|
+
try {
|
|
25
|
+
const firstLine = readFileSync(filePath, 'utf8').split('\n')[0]
|
|
26
|
+
const match = firstLine.match(STAMP_PATTERN)
|
|
27
|
+
return match ? match[1] : null
|
|
28
|
+
} catch {
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Generate AGENTS.md content with version stamp
|
|
35
|
+
* @returns {string} Full AGENTS.md content with stamp
|
|
36
|
+
*/
|
|
37
|
+
export function generateAgentsContent() {
|
|
38
|
+
const partialsDir = join(__dirname, '..', '..', 'partials')
|
|
39
|
+
const agentsContent = readFileSync(join(partialsDir, 'agents.md'), 'utf8')
|
|
40
|
+
return `<!-- uniweb-agents v${getCliVersion()} -->\n${agentsContent}\n`
|
|
41
|
+
}
|
package/src/utils/scaffold.js
CHANGED
|
@@ -11,7 +11,7 @@ import { join, dirname } from 'node:path'
|
|
|
11
11
|
import { fileURLToPath } from 'node:url'
|
|
12
12
|
import yaml from 'js-yaml'
|
|
13
13
|
import { copyTemplateDirectory, registerVersions } from '../templates/processor.js'
|
|
14
|
-
import { getVersionsForTemplates } from '../versions.js'
|
|
14
|
+
import { getVersionsForTemplates, getCliVersion } from '../versions.js'
|
|
15
15
|
|
|
16
16
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
17
17
|
const TEMPLATES_DIR = join(__dirname, '..', '..', 'templates')
|
|
@@ -36,6 +36,9 @@ export async function scaffoldWorkspace(targetDir, context, options = {}) {
|
|
|
36
36
|
// because an empty packages: [] makes pnpm search parent directories.
|
|
37
37
|
const skip = context.workspaceGlobs?.length ? [] : ['pnpm-workspace.yaml']
|
|
38
38
|
|
|
39
|
+
// Inject CLI version for AGENTS.md stamp
|
|
40
|
+
context = { ...context, cliVersion: getCliVersion() }
|
|
41
|
+
|
|
39
42
|
const templatePath = join(TEMPLATES_DIR, 'workspace')
|
|
40
43
|
await copyTemplateDirectory(templatePath, targetDir, context, {
|
|
41
44
|
onProgress: options.onProgress,
|
package/src/versions.js
CHANGED
|
@@ -22,6 +22,15 @@ function getCliPackageJson() {
|
|
|
22
22
|
return JSON.parse(readFileSync(packagePath, 'utf8'))
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Get the CLI's own version
|
|
27
|
+
*
|
|
28
|
+
* @returns {string} CLI version (e.g., "0.8.32")
|
|
29
|
+
*/
|
|
30
|
+
export function getCliVersion() {
|
|
31
|
+
return getCliPackageJson().version
|
|
32
|
+
}
|
|
33
|
+
|
|
25
34
|
/**
|
|
26
35
|
* Extract version number from version spec (e.g., "^0.1.4" -> "0.1.4")
|
|
27
36
|
*/
|