diff --git a/CHANGELOG.md b/CHANGELOG.md
index 205cbcb..4dc4862 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,12 @@ versioning follows [SemVer](https://semver.org/).
## [Unreleased]
+## [0.0.2-beta.4] — 2026-09-09
+
+Five languages gain the literals they never had, by way of the one thing the
+rule format could not express: an end that is only knowable once the opening
+has been read.
+
### Added
- **Literals whose end is decided at runtime.** A grammar rule may now carry
@@ -47,6 +53,12 @@ versioning follows [SemVer](https://semver.org/).
the sentence under it explained the English one; and the versioning doc
dropped the npm account the package publishes from.
+- **The per-language reference did not mention the new literals.** Nothing in
+ `docs/languages.md` was wrong; it understated, which on a page whose whole
+ job is "what does this handle" comes to the same thing. It is also the gap
+ `check:docs-parity` cannot see, because both translations were equally
+ silent.
+
- **The roadmap described jsray-terminal as having a release.** It has none —
the only way in is the GitHub install line. It also carried "syncing them to
0.0.2-beta.2 is the next step", written when Core was on beta.2 and wrong in
diff --git a/README.md b/README.md
index b9ccb3d..3f41083 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[](https://www.npmjs.com/package/@jsray/core)
[](LICENSE)
-[](CHANGELOG.md)
+[](CHANGELOG.md)
[](docs/versioning.md)
[](package.json)
[](dist/)
@@ -46,7 +46,7 @@ Or drop it into a page with no build step at all:
watching, pin the version instead** — every release is frozen at its own path:
```html
-
+
```
### Verifying what you loaded
@@ -56,7 +56,7 @@ A pinned URL says which release you asked for, not which bytes you got. Add a
hash and the browser refuses to run the file if it is not the one published:
```html
-
```
@@ -64,7 +64,7 @@ hash and the browser refuses to run the file if it is not the one published:
The hashes live next to the files they describe, in the same format SRI uses:
```
-https://jsray.org/v/0.0.2-beta.3/integrity.json
+https://jsray.org/v/0.0.2-beta.4/integrity.json
```
`crossorigin="anonymous"` is required, not optional — SRI on a cross-origin
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 4f41658..38ddf9f 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -9,7 +9,7 @@
[](https://www.npmjs.com/package/@jsray/core)
[](LICENSE)
-[](CHANGELOG.md)
+[](CHANGELOG.md)
[](docs/versioning.md)
[](package.json)
[](dist/)
@@ -45,7 +45,7 @@ JSRay.highlight('const x = 42;', 'js');
`jsray.org/dist/` 始终提供当前发布版本。**线上站点如果你不会持续盯着,请改用锁定版本的地址** —— 每个发布版本都固化在自己的路径下,永不变动:
```html
-
+
```
### 校验你加载到的东西
@@ -55,7 +55,7 @@ JSRay.highlight('const x = 42;', 'js');
哈希,浏览器在文件与发布内容不符时会直接拒绝执行:
```html
-
```
@@ -63,7 +63,7 @@ JSRay.highlight('const x = 42;', 'js');
哈希就放在它所描述的文件旁边,格式与 SRI 完全一致:
```
-https://jsray.org/v/0.0.2-beta.3/integrity.json
+https://jsray.org/v/0.0.2-beta.4/integrity.json
```
`crossorigin="anonymous"` 是必需的,不是可选:跨源脚本的 SRI 只有在加载走
diff --git a/SECURITY.md b/SECURITY.md
index fa08a27..7515710 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -43,8 +43,8 @@ one.
| Version | Security updates |
|---|---|
-| 0.0.2-beta.3 | ✅ Current public beta |
-| 0.0.2-beta.1 – beta.2 | ❌ Superseded — upgrade to the current beta |
+| 0.0.2-beta.4 | ✅ Current public beta |
+| 0.0.2-beta.1 – beta.3 | ❌ Superseded — upgrade to the current beta |
| Earlier betas | ❌ Superseded — upgrade to the current beta |
| 0.0.1-internal.∗ | ❌ Superseded by the public beta |
| Stable | Not yet released |
diff --git a/demo/index.html b/demo/index.html
index 01ebd0b..d383e8b 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -357,7 +357,7 @@
Project
diff --git a/demo/studio.html b/demo/studio.html
index 5a0faf0..78af21e 100644
--- a/demo/studio.html
+++ b/demo/studio.html
@@ -112,7 +112,7 @@ Project
diff --git a/dist/jsray.js b/dist/jsray.js
index 51d6cff..d9edea5 100644
--- a/dist/jsray.js
+++ b/dist/jsray.js
@@ -1990,7 +1990,7 @@
* Runtime version, for shell/core compatibility negotiation.
* Must match version.json — tools/check-versions.mjs asserts it.
*/
- version: '0.0.2-beta.3',
+ version: '0.0.2-beta.4',
languages: G,
normalizeLanguage,
detectLanguage,
diff --git a/docs/projects.md b/docs/projects.md
index b244817..1a5353d 100644
--- a/docs/projects.md
+++ b/docs/projects.md
@@ -76,7 +76,7 @@ wait for the next feature release — cut the integration release for it.
| Repository | Intended channel | Licence | Available from today |
|---|---|---|---|
-| `jsray` | npm `@jsray/core` | MIT | npm — `@jsray/core@0.0.2-beta.3` |
+| `jsray` | npm `@jsray/core` | MIT | npm — `@jsray/core@0.0.2-beta.4` |
| `jsray-wp` | WordPress.org plugin | GPLv2 or later | GitHub release zip |
| `jsray-terminal` | npm CLI | MIT | GitHub — `npm i -g github:jsrayorg/jsray-terminal` |
| `jsray-vscode` | VS Code Marketplace | MIT | GitHub release `.vsix` |
@@ -107,7 +107,7 @@ The public website keeps the brand concentrated under `jsray.org`:
moves on every release, which is right for the demo and wrong for a site
nobody is watching.
- `https://jsray.org/v//`: the same files frozen per release
- (`jsray.org/v/0.0.2-beta.3/jsray.js`). A page that pins here keeps rendering
+ (`jsray.org/v/0.0.2-beta.4/jsray.js`). A page that pins here keeps rendering
the way it did the day it was written.
`tools/build-site.sh` emits both. Cloudflare replaces the whole asset bundle on
diff --git a/docs/projects.zh-CN.md b/docs/projects.zh-CN.md
index 8bf5897..9f0b644 100644
--- a/docs/projects.zh-CN.md
+++ b/docs/projects.zh-CN.md
@@ -72,7 +72,7 @@ tag 附带的源码包,一概如此 —— 所以一个在 Core 发布当下
| 仓库 | 交付形态 | 许可 | 今天从哪里拿到 |
|---|---|---|---|
-| `jsray` | npm `@jsray/core` | MIT | npm —— `@jsray/core@0.0.2-beta.3` |
+| `jsray` | npm `@jsray/core` | MIT | npm —— `@jsray/core@0.0.2-beta.4` |
| `jsray-wp` | WordPress.org 插件 | GPLv2 or later | GitHub Release 的 zip |
| `jsray-terminal` | npm CLI | MIT | GitHub —— `npm i -g github:jsrayorg/jsray-terminal` |
| `jsray-vscode` | VS Code Marketplace | MIT | GitHub Release 的 `.vsix` |
@@ -98,7 +98,7 @@ GPLv2 or later,因为 WordPress.org 的第一条指南接受任何 GPL 兼容许
(`jsray.org/dist/jsray.js`、`jsray.org/dist/themes/.css`)。这个路径每次
发版都会变 —— 对演示页是对的,对没人盯着的站点是错的。
- `https://jsray.org/v//`:同样的文件按版本固化
- (`jsray.org/v/0.0.2-beta.3/jsray.js`)。锁定到这里的页面,今天怎么渲染,
+ (`jsray.org/v/0.0.2-beta.4/jsray.js`)。锁定到这里的页面,今天怎么渲染,
以后还怎么渲染。
`tools/build-site.sh` 两者都生成。Cloudflare 每次部署都会整体替换资产包,因此
diff --git a/docs/versioning.md b/docs/versioning.md
index 8c6123c..c720bd2 100644
--- a/docs/versioning.md
+++ b/docs/versioning.md
@@ -4,7 +4,7 @@
JSRay Core uses single-project versioning. Platform plugins keep their own version files in their own repositories.
-Current version: `0.0.2-beta.3`
+Current version: `0.0.2-beta.4`
Current channel: `beta`
Public beta released: yes
@@ -33,7 +33,7 @@ The mechanics follow from that: `check:versions` requires the counter here, and
`0.0.2`.
```
-0.0.1-beta.1 … 0.0.1-beta.5 → 0.0.2-beta.1 … 0.0.2-beta.3 → 0.0.3-beta.1 → … → 0.1.0
+0.0.1-beta.1 … 0.0.1-beta.5 → 0.0.2-beta.1 … 0.0.2-beta.4 → 0.0.3-beta.1 → … → 0.1.0
```
The `0.0.1` line closed at beta.5. `0.1.0` is where the beta label comes off,
diff --git a/docs/versioning.zh-CN.md b/docs/versioning.zh-CN.md
index 6e9d22e..34ad37f 100644
--- a/docs/versioning.zh-CN.md
+++ b/docs/versioning.zh-CN.md
@@ -4,7 +4,7 @@
JSRay Core 采用单项目版本号。平台插件在各自仓库里维护自己的版本文件。
-当前版本:`0.0.2-beta.3`
+当前版本:`0.0.2-beta.4`
当前通道:`beta`
公开测试版已发布:是
@@ -30,7 +30,7 @@ JSRay Core 是独立的 JavaScript 原生代码渲染内核。平台插件(包
`version_compare()` —— 字符串排序会把 `0.0.10` 排在 `0.0.2` 前面。
```
-0.0.1-beta.1 … 0.0.1-beta.5 → 0.0.2-beta.1 … 0.0.2-beta.3 → 0.0.3-beta.1 → …… → 0.1.0
+0.0.1-beta.1 … 0.0.1-beta.5 → 0.0.2-beta.1 … 0.0.2-beta.4 → 0.0.3-beta.1 → …… → 0.1.0
```
`0.0.1` 这条线在 beta.5 结束。`0.1.0` 才是脱掉 beta 标签的地方,因此 `0.0.1`
diff --git a/integrity.json b/integrity.json
index cdd5837..69b7a31 100644
--- a/integrity.json
+++ b/integrity.json
@@ -1,10 +1,10 @@
{
"project": "jsray",
- "version": "0.0.2-beta.3",
+ "version": "0.0.2-beta.4",
"algorithm": "sha256",
"note": "Base64 SHA-256 digests of the released Core assets. Integrations copy the relevant digest at sync time and verify their bundled snapshot against it.",
"files": {
- "dist/jsray.js": "sha256-BIsbeOmZ00Y8FqAaKyrPOUL1b5Q36LC4b52CVYcX2xQ=",
+ "dist/jsray.js": "sha256-ZU8tfz1KrOvaewDqhJC9D5rzbItkXfreHJF+zkQ7EUU=",
"dist/jsray.css": "sha256-6Fuva+aZwCcmltNi2oN+1yWIJoKE+1rLpUxZvD9iutc=",
"dist/themes/aurora.css": "sha256-S8X+R8XZNC8WRdHOen839zMkPxVFol6PPTrpZibbeJA=",
"dist/themes/default.css": "sha256-vENOigRjwn1hW6wPjdM4tbZ58Ja44FMsa+akavPiMSI=",
diff --git a/package.json b/package.json
index bf33bce..bd6c118 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@jsray/core",
- "version": "0.0.2-beta.3",
+ "version": "0.0.2-beta.4",
"description": "JavaScript-native code rendering kernel with 23-class token semantics and pluggable themes.",
"author": "Jie ",
"license": "MIT",
diff --git a/src/jsray.js b/src/jsray.js
index 51d6cff..d9edea5 100644
--- a/src/jsray.js
+++ b/src/jsray.js
@@ -1990,7 +1990,7 @@
* Runtime version, for shell/core compatibility negotiation.
* Must match version.json — tools/check-versions.mjs asserts it.
*/
- version: '0.0.2-beta.3',
+ version: '0.0.2-beta.4',
languages: G,
normalizeLanguage,
detectLanguage,
diff --git a/tokens.json b/tokens.json
index e01a12a..d8c4f3e 100644
--- a/tokens.json
+++ b/tokens.json
@@ -1,7 +1,7 @@
{
"name": "JSRay",
"author": "Jie",
- "version": "0.0.2-beta.3",
+ "version": "0.0.2-beta.4",
"description": "Default palette · 23 token classes · 6 identifier families visually separated",
"philosophy": {
"identifier-families": {
diff --git a/types/jsray.d.ts b/types/jsray.d.ts
index 3dce653..d5bb3fa 100644
--- a/types/jsray.d.ts
+++ b/types/jsray.d.ts
@@ -32,7 +32,7 @@ declare namespace JSRay {
/** A renderer-agnostic stream produced by `tokenize`. */
type TokenStream = Array;
- /** Runtime version string, matches version.json (e.g. "0.0.2-beta.3"). */
+ /** Runtime version string, matches version.json (e.g. "0.0.2-beta.4"). */
const version: string;
/** Grammars for every registered language, keyed by name and by alias. */
diff --git a/version.json b/version.json
index d3d62bb..aa68e70 100644
--- a/version.json
+++ b/version.json
@@ -1,7 +1,7 @@
{
"project": "jsray",
"name": "JSRay Core",
- "version": "0.0.2-beta.3",
+ "version": "0.0.2-beta.4",
"channel": "beta",
"publicBetaReleased": true,
"notes": "Standalone JavaScript-native code rendering kernel. JSRay is planned as a fully open-source ecosystem with Core, official integrations, and community integrations."
diff --git a/vocabulary.json b/vocabulary.json
index e7c3976..5a16537 100644
--- a/vocabulary.json
+++ b/vocabulary.json
@@ -1,6 +1,6 @@
{
"project": "jsray",
- "version": "0.0.2-beta.3",
+ "version": "0.0.2-beta.4",
"description": "Machine-readable token vocabulary: the three-name lock-step every JSRay surface shares. A palette key maps to one CSS custom property (--jr-) and one runtime class (tk-).",
"tokens": {
"keyword": "keyword",