aeon-ui-engine 1.3.0 → 1.3.5

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/package.json +7 -2
  3. package/packages/react/src/combobox/index.tsx +13 -8
  4. package/packages/react/src/tooltip/index.tsx +48 -22
  5. package/packages/schemas/dist/index.d.ts +69 -24
  6. package/packages/schemas/dist/index.js +447 -49
  7. package/packages/schemas/json/appNav.json +146 -0
  8. package/packages/schemas/json/appShell.json +151 -0
  9. package/packages/schemas/json/avatar.json +130 -0
  10. package/packages/schemas/json/bar.json +126 -0
  11. package/packages/schemas/json/catalog.json +3163 -15
  12. package/packages/schemas/json/combobox.json +19 -7
  13. package/packages/schemas/json/composer.json +125 -0
  14. package/packages/schemas/json/content.json +167 -0
  15. package/packages/schemas/json/conversation.json +166 -0
  16. package/packages/schemas/json/entry.json +182 -0
  17. package/packages/schemas/json/identity.json +147 -0
  18. package/packages/schemas/json/listRow.json +131 -0
  19. package/packages/schemas/json/metricStrip.json +132 -0
  20. package/packages/schemas/json/nav.json +136 -0
  21. package/packages/schemas/json/panel.json +143 -0
  22. package/packages/schemas/json/pinInput.json +112 -0
  23. package/packages/schemas/json/profileHeader.json +138 -0
  24. package/packages/schemas/json/prompt.json +155 -0
  25. package/packages/schemas/json/radioGroup.json +130 -0
  26. package/packages/schemas/json/separator.json +105 -0
  27. package/packages/schemas/json/slider.json +147 -0
  28. package/packages/schemas/json/statusBanner.json +149 -0
  29. package/packages/schemas/json/stickyBar.json +153 -0
  30. package/packages/schemas/json/thread.json +129 -0
  31. package/packages/schemas/json/tooltip.json +21 -7
  32. package/packages/schemas/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  33. package/packages/schemas/prompts/cursorrules.md +6 -4
  34. package/packages/schemas/prompts/statecharts.md +23 -2
  35. package/packages/schemas/prompts/system.md +2 -2
  36. package/packages/schemas/registry/catalog.json +295 -4
  37. package/packages/schemas/registry/components/appNav.json +146 -0
  38. package/packages/schemas/registry/components/appShell.json +151 -0
  39. package/packages/schemas/registry/components/avatar.json +130 -0
  40. package/packages/schemas/registry/components/bar.json +126 -0
  41. package/packages/schemas/registry/components/combobox.json +19 -7
  42. package/packages/schemas/registry/components/composer.json +125 -0
  43. package/packages/schemas/registry/components/content.json +167 -0
  44. package/packages/schemas/registry/components/conversation.json +166 -0
  45. package/packages/schemas/registry/components/entry.json +182 -0
  46. package/packages/schemas/registry/components/identity.json +147 -0
  47. package/packages/schemas/registry/components/listRow.json +131 -0
  48. package/packages/schemas/registry/components/metricStrip.json +132 -0
  49. package/packages/schemas/registry/components/nav.json +136 -0
  50. package/packages/schemas/registry/components/panel.json +143 -0
  51. package/packages/schemas/registry/components/pinInput.json +112 -0
  52. package/packages/schemas/registry/components/profileHeader.json +138 -0
  53. package/packages/schemas/registry/components/prompt.json +155 -0
  54. package/packages/schemas/registry/components/radioGroup.json +130 -0
  55. package/packages/schemas/registry/components/separator.json +105 -0
  56. package/packages/schemas/registry/components/slider.json +147 -0
  57. package/packages/schemas/registry/components/statusBanner.json +149 -0
  58. package/packages/schemas/registry/components/stickyBar.json +153 -0
  59. package/packages/schemas/registry/components/thread.json +129 -0
  60. package/packages/schemas/registry/components/tooltip.json +21 -7
  61. package/packages/schemas/registry/machines/accordion.json +58 -0
  62. package/packages/schemas/registry/machines/appNav.json +108 -0
  63. package/packages/schemas/registry/machines/appShell.json +128 -0
  64. package/packages/schemas/registry/machines/contentRegion.json +314 -0
  65. package/packages/schemas/registry/machines/panel.json +131 -0
  66. package/packages/schemas/registry/machines/popover.json +143 -0
  67. package/packages/schemas/registry/machines/slider.json +151 -0
  68. package/packages/schemas/registry/machines/stickyBar.json +261 -0
  69. package/packages/schemas/registry/machines/tabs.json +58 -0
  70. package/packages/schemas/registry/machines/toast.json +89 -0
  71. package/packages/schemas/registry/machines/toggle.json +134 -0
  72. package/packages/schemas/scripts/emit.ts +23 -0
  73. package/packages/schemas/src/components.ts +429 -6
  74. package/packages/schemas/src/index.test.ts +83 -0
  75. package/packages/schemas/src/index.ts +1 -0
  76. package/packages/schemas/src/machine-id.ts +7 -0
  77. package/packages/schemas/src/prompts.ts +25 -4
  78. package/packages/schemas/src/registry.ts +28 -39
  79. package/scripts/bump-version.mjs +93 -0
  80. package/scripts/require-version-bump.mjs +70 -0
@@ -1,8 +1,14 @@
1
+ import { componentSchemas } from './components.js'
2
+ import { machineRegistryId } from './machine-id.js'
3
+ import type { JsonSchema } from './schema-builder.js'
4
+
1
5
  /**
2
6
  * Aeon UI agent registry — machine-legible component contracts for Generative UI.
3
7
  * Fetch at runtime: GET https://aeon-ui.com/registry/catalog.json
4
8
  * Per component: GET https://aeon-ui.com/registry/components/{id}.json
5
9
  * Machines: GET https://aeon-ui.com/registry/machines/{id}.json
10
+ *
11
+ * Components are derived from `componentSchemas` — do not hand-maintain a parallel list.
6
12
  */
7
13
  export type RegistryEntry = {
8
14
  id: string
@@ -16,6 +22,24 @@ export type RegistryEntry = {
16
22
 
17
23
  export const REGISTRY_BASE = 'https://aeon-ui.com/registry' as const
18
24
 
25
+ function entryFromSchema(id: string, schema: JsonSchema): RegistryEntry {
26
+ const x = schema['x-aeon'] as {
27
+ scope: string
28
+ machine: string | null
29
+ runtime: string
30
+ }
31
+ const mid = machineRegistryId(x.machine)
32
+ return {
33
+ id,
34
+ title: String(schema.title ?? id),
35
+ scope: x.scope,
36
+ schemaUrl: `${REGISTRY_BASE}/components/${id}.json`,
37
+ ...(mid ? { machineUrl: `${REGISTRY_BASE}/machines/${mid}.json` } : {}),
38
+ runtime: x.runtime,
39
+ description: String(schema.description ?? ''),
40
+ }
41
+ }
42
+
19
43
  export const registryCatalog = {
20
44
  $id: `${REGISTRY_BASE}/catalog.json`,
21
45
  version: '0.1.0',
@@ -27,47 +51,12 @@ export const registryCatalog = {
27
51
  component: `${REGISTRY_BASE}/components/{id}.json`,
28
52
  machine: `${REGISTRY_BASE}/machines/{id}.json`,
29
53
  },
30
- components: [
31
- {
32
- id: 'button',
33
- title: 'Button',
34
- scope: 'button',
35
- schemaUrl: `${REGISTRY_BASE}/components/button.json`,
36
- machineUrl: `${REGISTRY_BASE}/machines/buttonLifecycle.json`,
37
- runtime: 'status prop',
38
- description: 'Action control with idle|pending|success|failure|disabled',
39
- },
40
- {
41
- id: 'async',
42
- title: 'Async',
43
- scope: 'async',
44
- schemaUrl: `${REGISTRY_BASE}/components/async.json`,
45
- machineUrl: `${REGISTRY_BASE}/machines/async.json`,
46
- runtime: 'useAeonMachine',
47
- description: 'Fetch lifecycle region with full totality',
48
- },
49
- {
50
- id: 'field',
51
- title: 'Field',
52
- scope: 'field',
53
- schemaUrl: `${REGISTRY_BASE}/components/field.json`,
54
- machineUrl: `${REGISTRY_BASE}/machines/field.json`,
55
- runtime: 'useAeonMachine',
56
- description: 'Parallel interaction × validation × submission',
57
- },
58
- {
59
- id: 'dialog',
60
- title: 'Dialog',
61
- scope: 'dialog',
62
- schemaUrl: `${REGISTRY_BASE}/components/dialog.json`,
63
- machineUrl: `${REGISTRY_BASE}/machines/dialog.json`,
64
- runtime: 'useAeonMachine',
65
- description: 'Modal open/closed',
66
- },
67
- ] satisfies RegistryEntry[],
54
+ components: Object.entries(componentSchemas).map(([id, schema]) =>
55
+ entryFromSchema(id, schema),
56
+ ) satisfies RegistryEntry[],
68
57
  client: {
69
58
  fetchCatalog: `fetch('${REGISTRY_BASE}/catalog.json').then(r => r.json())`,
70
59
  fetchComponent: `id => fetch(\`${REGISTRY_BASE}/components/\${id}.json\`).then(r => r.json())`,
71
60
  fetchMachine: `id => fetch(\`${REGISTRY_BASE}/machines/\${id}.json\`).then(r => r.json())`,
72
61
  },
73
- } as const
62
+ }
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Bump aeon-ui-engine semver, changelog, tag, optionally push + npm publish.
4
+ *
5
+ * node scripts/bump-version.mjs patch|minor|major [--push] [--publish] [--no-commit]
6
+ */
7
+ import { execSync } from 'node:child_process'
8
+ import fs from 'node:fs'
9
+ import path from 'node:path'
10
+ import { fileURLToPath } from 'node:url'
11
+
12
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
13
+ const pkgPath = path.join(root, 'package.json')
14
+ const changelogPath = path.join(root, 'CHANGELOG.md')
15
+
16
+ const args = process.argv.slice(2)
17
+ const bump = args.find((a) => a === 'patch' || a === 'minor' || a === 'major')
18
+ const noCommit = args.includes('--no-commit')
19
+ const doPush = args.includes('--push')
20
+ const doPublish = args.includes('--publish')
21
+
22
+ if (!bump) {
23
+ console.error('Usage: bump-version.mjs patch|minor|major [--push] [--publish] [--no-commit]')
24
+ process.exit(1)
25
+ }
26
+
27
+ function parseSemver(v) {
28
+ const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v.trim())
29
+ if (!m) throw new Error(`Invalid semver: ${v}`)
30
+ return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]) }
31
+ }
32
+
33
+ function format({ major, minor, patch }) {
34
+ return `${major}.${minor}.${patch}`
35
+ }
36
+
37
+ function bumpSemver(v, kind) {
38
+ const s = parseSemver(v)
39
+ if (kind === 'major') return format({ major: s.major + 1, minor: 0, patch: 0 })
40
+ if (kind === 'minor') return format({ major: s.major, minor: s.minor + 1, patch: 0 })
41
+ return format({ major: s.major, minor: s.minor, patch: s.patch + 1 })
42
+ }
43
+
44
+ function today() {
45
+ return new Date().toISOString().slice(0, 10)
46
+ }
47
+
48
+ function prependChangelog(version) {
49
+ const entry = `## [${version}] - ${today()}\n\n### Changed\n\n- Describe this release.\n\n`
50
+ if (!fs.existsSync(changelogPath)) {
51
+ fs.writeFileSync(changelogPath, `# Changelog\n\n${entry}`)
52
+ return
53
+ }
54
+ const existing = fs.readFileSync(changelogPath, 'utf8')
55
+ if (existing.includes(`## [${version}]`)) return
56
+ if (existing.startsWith('# Changelog')) {
57
+ fs.writeFileSync(changelogPath, existing.replace('# Changelog\n\n', `# Changelog\n\n${entry}`))
58
+ } else {
59
+ fs.writeFileSync(changelogPath, `# Changelog\n\n${entry}${existing}`)
60
+ }
61
+ }
62
+
63
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
64
+ const prev = pkg.version
65
+ const next = bumpSemver(prev, bump)
66
+ pkg.version = next
67
+ fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`)
68
+ prependChangelog(next)
69
+ console.log(`aeon-ui-engine ${prev} → ${next}`)
70
+
71
+ if (!noCommit) {
72
+ execSync('git add package.json CHANGELOG.md', { cwd: root, stdio: 'inherit' })
73
+ execSync(`git commit -m "Release aeon-ui-engine v${next}"`, { cwd: root, stdio: 'inherit' })
74
+ try {
75
+ execSync(`git tag v${next}`, { cwd: root, stdio: 'inherit' })
76
+ } catch {
77
+ console.warn(`Tag v${next} already exists`)
78
+ }
79
+ }
80
+
81
+ if (doPush) {
82
+ execSync('git push origin HEAD', { cwd: root, stdio: 'inherit' })
83
+ execSync(`git push origin v${next}`, { cwd: root, stdio: 'inherit' })
84
+ }
85
+
86
+ if (doPublish) {
87
+ execSync('npm publish --access public', { cwd: root, stdio: 'inherit' })
88
+ }
89
+
90
+ if (!doPush) {
91
+ console.log(`Tagged v${next}. Push: git push && git push origin v${next}`)
92
+ console.log('Or: npm run version:push')
93
+ }
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Fail if package.json version is not strictly newer than the latest remote tag (v*).
4
+ */
5
+ import { execSync } from 'node:child_process'
6
+ import fs from 'node:fs'
7
+ import path from 'node:path'
8
+ import { fileURLToPath } from 'node:url'
9
+
10
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
11
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'))
12
+ const local = pkg.version
13
+
14
+ function parse(v) {
15
+ const m = /^(\d+)\.(\d+)\.(\d+)/.exec(String(v).replace(/^v/, ''))
16
+ if (!m) return null
17
+ return [Number(m[1]), Number(m[2]), Number(m[3])]
18
+ }
19
+
20
+ function gt(a, b) {
21
+ for (let i = 0; i < 3; i++) {
22
+ if (a[i] > b[i]) return true
23
+ if (a[i] < b[i]) return false
24
+ }
25
+ return false
26
+ }
27
+
28
+ try {
29
+ execSync('git fetch --tags --quiet', { cwd: root, stdio: 'ignore' })
30
+ } catch {
31
+ /* offline */
32
+ }
33
+
34
+ let remoteTag = ''
35
+ try {
36
+ remoteTag = execSync(
37
+ 'git describe --tags --abbrev=0 origin/main 2>/dev/null || git describe --tags --abbrev=0',
38
+ { cwd: root, encoding: 'utf8' },
39
+ ).trim()
40
+ } catch {
41
+ remoteTag = ''
42
+ }
43
+
44
+ const localP = parse(local)
45
+ if (!localP) {
46
+ console.error(`Invalid package.json version: ${local}`)
47
+ process.exit(1)
48
+ }
49
+
50
+ if (!remoteTag) {
51
+ console.log(`No remote tag yet — allowing push of v${local}`)
52
+ process.exit(0)
53
+ }
54
+
55
+ const remoteP = parse(remoteTag)
56
+ if (!remoteP) {
57
+ console.log(`Unparsed remote tag ${remoteTag} — allowing push`)
58
+ process.exit(0)
59
+ }
60
+
61
+ if (!gt(localP, remoteP)) {
62
+ console.error(`
63
+ Refusing push: aeon-ui-engine ${local} is not newer than remote tag ${remoteTag}.
64
+
65
+ npm run version:push
66
+ `)
67
+ process.exit(1)
68
+ }
69
+
70
+ console.log(`Version OK: ${local} > ${remoteTag.replace(/^v/, '')}`)