Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,37 @@ concurrency:
cancel-in-progress: true

jobs:
# tools/hooks/commit-msg only protects a machine that has run
# `git config core.hooksPath tools/hooks`. Nothing protected the pull
# request itself, so `Release 0.0.2-beta.2` reached main and printed itself
# beside a dozen files, permanently — the subject of a merged commit cannot
# be reworded once a tag points at it. The hook is the same file either way;
# this runs it where it cannot be skipped.
subjects:
name: Commit subjects
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
with:
# Every commit the pull request adds, not just its tip.
fetch-depth: 0
- name: Check each subject against tools/hooks/commit-msg
run: |
set -e
base="${{ github.event.pull_request.base.sha }}"
head="${{ github.event.pull_request.head.sha }}"
failed=0
for sha in $(git rev-list --no-merges "$base..$head"); do
git log -1 --format=%B "$sha" > /tmp/msg
if ! sh tools/hooks/commit-msg /tmp/msg; then
echo " ^ $(git log -1 --format='%h %s' "$sha")"
failed=1
fi
done
[ "$failed" = "0" ] || exit 1

test:
name: Test on Node ${{ matrix.node }}
runs-on: ubuntu-latest
Expand Down
31 changes: 30 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,35 @@ versioning follows [SemVer](https://semver.org/).

## [Unreleased]

## [0.0.2-beta.3] — 2026-09-06

Documentation and the guards around it. No runtime change: `dist/` differs from
beta.2 only in the version string it reports.

### Fixed
- **The Code of Conduct says where to report.** Its enforcement section invited
reports "to the community leaders responsible for enforcement" and named no
address, which is the same as having no channel. It now names
`support@jsray.org`, the address SECURITY.md already used.
- **A release subject that is a version and one word is rejected.**
`tools/hooks/commit-msg` already refused a bare `0.0.1-beta.3`, with a
comment about how a version number lands on every file the release touched.
`Release 0.0.2-beta.2` walked past that pattern and did exactly what it
describes, on twelve files. The pattern now covers a leading
release/bump/publish/tag word.
- **The subject check runs on pull requests.** The hook only protects a
machine that has configured `core.hooksPath`; CI now runs the same file
against every commit a pull request adds, where it cannot be skipped.
- **The roadmap entry for jsray-vscode and jsray-terminal.** It described both
as unpublished, bundling Core `0.0.1-beta.5`, with READMEs pointing at
`0.0.1-beta.1`. Both are public, both bundle `0.0.2-beta.1`, and both now
derive and check the badges it said they needed first.

### Changed
- **Availability is stated, not contrasted.** The integrations table and
`docs/projects.md` paired each channel with the one it is not on yet. They
now say where each integration is installed from.

## [0.0.2-beta.2] — 2026-09-05

Ships the portable renderer, and corrects what the registry and the site were
Expand All @@ -30,7 +59,7 @@ saying about this project.

- **The palette fallback chain has one implementation.** `applyThemeToRoot` carried the only copy of it; `resolveToken` is now shared with the portable renderer, because two renderers resolving the same palette by two implementations is how they come to disagree about a palette that predates a token key.
- The site build ships `themes/` and the new page. The paste page fetches every palette at runtime for the same reason the Studio does — a second copy of the colours is a second thing to drift.
- **The README says what the integrations are, because npm shows this file.** The published page for `@jsray/core@0.0.2-beta.1` still lists all three as "Coming soon"; all three are public with releases, and the table now links each one and says where it can actually be installed from — which is GitHub rather than its host's directory in every case. npm freezes a package page per version, so a correction only reaches the registry by publishing.
- **The README says what the integrations are, because npm shows this file.** The published page for `@jsray/core@0.0.2-beta.1` still lists all three as "Coming soon"; all three are public with releases, and the table now links each one and says where each can be installed from. npm freezes a package page per version, so a correction only reaches the registry by publishing.
- **`repository` and `bugs` point at the organisation's current name.** They were published as `github.com/JSRayCore/JSRay`, which still redirects — but the frozen metadata is what every tool reads, and the org name it names no longer exists.
- **The versioning doc says why Core counts its betas.** It justified the counter mechanically — `check:versions` wants it, `version_compare()` orders it — which is true and is not the reason. Core is the kernel every integration renders through, so it earns more revision rounds before `0.1.0` than anything built on it, and those land inside one patch. The integrations bump the patch each time, so a counter would say nothing.

Expand Down
8 changes: 6 additions & 2 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ Examples of unacceptable behavior:
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement. All complaints
will be reviewed and investigated promptly and fairly.
reported to <support@jsray.org>. All complaints will be reviewed and
investigated promptly and fairly, and the reporter's identity is not shared
outside the people handling the report.

Saying complaints "may be reported" without saying where is the same as having
no channel: this document named none until 0.0.2-beta.3.

## Attribution

Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

[![npm](https://img.shields.io/npm/v/@jsray/core/beta?label=npm)](https://www.npmjs.com/package/@jsray/core)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-0.0.2--beta.2-lightgrey)](CHANGELOG.md)
[![Version](https://img.shields.io/badge/version-0.0.2--beta.3-lightgrey)](CHANGELOG.md)
[![Channel](https://img.shields.io/badge/channel-beta-blue)](docs/versioning.md)
[![Zero deps](https://img.shields.io/badge/dependencies-0-success)](package.json)
[![Size](https://img.shields.io/badge/dist-core%20js%20%2B%20css-lightgrey)](dist/)
Expand Down Expand Up @@ -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
<script src="https://jsray.org/v/0.0.2-beta.2/jsray.js"></script>
<script src="https://jsray.org/v/0.0.2-beta.3/jsray.js"></script>
```

### Verifying what you loaded
Expand All @@ -56,15 +56,15 @@ 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
<script src="https://jsray.org/v/0.0.2-beta.2/jsray.js"
<script src="https://jsray.org/v/0.0.2-beta.3/jsray.js"
integrity="sha256-…"
crossorigin="anonymous"></script>
```

The hashes live next to the files they describe, in the same format SRI uses:

```
https://jsray.org/v/0.0.2-beta.2/integrity.json
https://jsray.org/v/0.0.2-beta.3/integrity.json
```

`crossorigin="anonymous"` is required, not optional — SRI on a cross-origin
Expand Down Expand Up @@ -111,12 +111,12 @@ Official integrations live in their own repositories, use JSRay Core by default,

| Integration | Repository | Status |
|---|---|---|
| WordPress plugin | [`jsray-wp`](https://github.com/jsrayorg/jsray-wp) | Public beta · not on WordPress.org yet |
| VS Code extension | [`jsray-vscode`](https://github.com/jsrayorg/jsray-vscode) | Public beta · not on the Marketplace yet |
| Terminal CLI | [`jsray-terminal`](https://github.com/jsrayorg/jsray-terminal) | Public beta · not on npm yet |
| WordPress plugin | [`jsray-wp`](https://github.com/jsrayorg/jsray-wp) | Public beta |
| VS Code extension | [`jsray-vscode`](https://github.com/jsrayorg/jsray-vscode) | Public beta |
| Terminal CLI | [`jsray-terminal`](https://github.com/jsrayorg/jsray-terminal) | Public beta |
| …and more | — | Community & official adapters welcome |

Each is installable today, from GitHub rather than from its host's directory:
Install any of them today:

```sh
# Terminal CLI
Expand Down
16 changes: 8 additions & 8 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

[![npm](https://img.shields.io/npm/v/@jsray/core/beta?label=npm)](https://www.npmjs.com/package/@jsray/core)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-0.0.2--beta.2-lightgrey)](CHANGELOG.md)
[![Version](https://img.shields.io/badge/version-0.0.2--beta.3-lightgrey)](CHANGELOG.md)
[![Channel](https://img.shields.io/badge/channel-beta-blue)](docs/versioning.md)
[![Zero deps](https://img.shields.io/badge/dependencies-0-success)](package.json)
[![Size](https://img.shields.io/badge/dist-core%20js%20%2B%20css-lightgrey)](dist/)
Expand Down Expand Up @@ -45,7 +45,7 @@ JSRay.highlight('const x = 42;', 'js');
`jsray.org/dist/` 始终提供当前发布版本。**线上站点如果你不会持续盯着,请改用锁定版本的地址** —— 每个发布版本都固化在自己的路径下,永不变动:

```html
<script src="https://jsray.org/v/0.0.2-beta.2/jsray.js"></script>
<script src="https://jsray.org/v/0.0.2-beta.3/jsray.js"></script>
```

### 校验你加载到的东西
Expand All @@ -55,15 +55,15 @@ JSRay.highlight('const x = 42;', 'js');
哈希,浏览器在文件与发布内容不符时会直接拒绝执行:

```html
<script src="https://jsray.org/v/0.0.2-beta.2/jsray.js"
<script src="https://jsray.org/v/0.0.2-beta.3/jsray.js"
integrity="sha256-…"
crossorigin="anonymous"></script>
```

哈希就放在它所描述的文件旁边,格式与 SRI 完全一致:

```
https://jsray.org/v/0.0.2-beta.2/integrity.json
https://jsray.org/v/0.0.2-beta.3/integrity.json
```

`crossorigin="anonymous"` 是必需的,不是可选:跨源脚本的 SRI 只有在加载走
Expand All @@ -90,12 +90,12 @@ JSRay 的目标是成为完整开源的代码渲染生态:一个轻量 Core

| 集成 | 仓库 | 状态 |
|---|---|---|
| WordPress 插件 | [`jsray-wp`](https://github.com/jsrayorg/jsray-wp) | 公开测试版 · 尚未上架 WordPress.org |
| VS Code 扩展 | [`jsray-vscode`](https://github.com/jsrayorg/jsray-vscode) | 公开测试版 · 尚未上架 Marketplace |
| 终端 CLI | [`jsray-terminal`](https://github.com/jsrayorg/jsray-terminal) | 公开测试版 · 尚未发布到 npm |
| WordPress 插件 | [`jsray-wp`](https://github.com/jsrayorg/jsray-wp) | 公开测试版 |
| VS Code 扩展 | [`jsray-vscode`](https://github.com/jsrayorg/jsray-vscode) | 公开测试版 |
| 终端 CLI | [`jsray-terminal`](https://github.com/jsrayorg/jsray-terminal) | 公开测试版 |
| …以及更多 | — | 欢迎官方与社区适配器 |

三个集成现在都能装,只是要从 GitHub 拿,而不是各自平台的市场:
三个集成现在都能装:

```sh
# 终端 CLI
Expand Down
3 changes: 2 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ one.

| Version | Security updates |
|---|---|
| 0.0.2-beta.2 | ✅ Current public beta |
| 0.0.2-beta.3 | ✅ Current public beta |
| 0.0.2-beta.1 – beta.2 | ❌ 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 |
2 changes: 1 addition & 1 deletion demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ <h3>Project</h3>
</div>

<div class="site-footer__base">
<p>© 2026 JSRay · MIT · <code data-jsray-version>0.0.2-beta.2</code></p>
<p>© 2026 JSRay · MIT · <code data-jsray-version>0.0.2-beta.3</code></p>
<p>Made by Jie</p>
</div>
</footer>
Expand Down
2 changes: 1 addition & 1 deletion demo/studio.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ <h3>Project</h3>
</div>

<div class="site-footer__base">
<p>© 2026 JSRay · MIT · <code data-jsray-version>0.0.2-beta.2</code></p>
<p>© 2026 JSRay · MIT · <code data-jsray-version>0.0.2-beta.3</code></p>
<p>Made by Jie</p>
</div>
</footer>
Expand Down
2 changes: 1 addition & 1 deletion dist/jsray.js
Original file line number Diff line number Diff line change
Expand Up @@ -1865,7 +1865,7 @@
* Runtime version, for shell/core compatibility negotiation.
* Must match version.json — tools/check-versions.mjs asserts it.
*/
version: '0.0.2-beta.2',
version: '0.0.2-beta.3',
languages: G,
normalizeLanguage,
detectLanguage,
Expand Down
11 changes: 6 additions & 5 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,16 +402,17 @@ deliberately deferred).
contribution paths). Hard rule: a locked core must surface an explicit
warning when a security-grade Core update ships — security fixes are
never silently pinnable.
- **jsray-vscode / jsray-terminal**: not published, and deliberately behind
while their features settle. Before either one goes public it needs what
`jsray-wp` gained on 2026-08-26/27, because all three drift the same way:
- **jsray-vscode / jsray-terminal**: both public since 2026-09-03 and
2026-09-05, each with a release carrying an installable build. They now
carry what `jsray-wp` gained on 2026-08-26/27, because all three drift the
same way:
`tools/sync-core-version.mjs` deriving the README Core badge instead of
leaving it to whoever runs the sync; `check:versions` asserting the badges
and the phase wording *in both directions* — the wrong phrase sitting beside
the right one is what let "Internal test build · no public beta yet" survive
the whole public beta; and the plugin version ladder (`0.0.1-beta →
0.0.2-beta`, no counter) rather than Core's. Both still carry Core
`0.0.1-beta.5` and READMEs pointing at `0.0.1-beta.1`.
0.0.2-beta`, no counter) rather than Core's. Both bundle Core
`0.0.2-beta.1`; syncing them to `0.0.2-beta.2` is the next step.

- **Core**: minification is deliberately absent (zero-build); revisit at
public beta.
Expand Down
10 changes: 5 additions & 5 deletions docs/development.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,14 @@ CI:每个仓库都有 GitHub Actions(Node 18/20/22 矩阵;Core 另验 `dist/`
管线)跑 32 条断言。
- **终端**:`--bg`(整底色绘制)、分页器集成与 `--core <path>` 覆盖在路线图上。
- **用户侧 Core 锁定**(路线图):平台原生的更新控制已允许用户拒绝某班列车(WP 手动更新、VS Code 按扩展关自动更新 + 装历史版本、npm 版本锁定)。插件内的"Core 更新策略"(跟随/锁定/自定义文件)对 WP 与终端可行,对 VS Code 预览不可行(贡献点路径静态)。硬规则:锁定状态下遇到安全级 Core 更新必须显式警告——安全修复不允许被静默锁死。
- **jsray-vscode / jsray-terminal**:未发布,且在功能定型之前刻意落后。这两个
中任何一个要公开之前,都需要补上 `jsray-wp` 在 2026-08-26/27 得到的那套机制 ——
三个集成的失效方式是同一种:`tools/sync-core-version.mjs` 自己推导 README 的
- **jsray-vscode / jsray-terminal**:分别于 2026-09-03 和 2026-09-05 公开,各自
的 Release 里都挂着可直接安装的构建。两者现已补齐 `jsray-wp` 在 2026-08-26/27
得到的那套机制 —— 三个集成的失效方式是同一种:`tools/sync-core-version.mjs` 自己推导 README 的
Core 徽章,而不是留给"跑同步的那个人";`check:versions` **双向**校验徽章与阶段
措辞 —— 正是"该出现的词在、不该出现的词也在"这一点,让「内部测试版 · 尚未发布
公开测试版」在整个公开 beta 期间活了下来;以及插件的版本阶梯(`0.0.1-beta →
0.0.2-beta`,无计数器)而非 Core 的记法。两者目前仍内置 Core `0.0.1-beta.5`,
README 指向 `0.0.1-beta.1`。
0.0.2-beta`,无计数器)而非 Core 的记法。两者均内置 Core `0.0.2-beta.1`,
同步到 `0.0.2-beta.2` 是下一步。

- **Core**:minify 刻意缺席(零构建);公开 beta 时再议。
- **完全没有规则的字面量形式**(beta.5 审查时发现,因属"缺功能"而非"抢错范围"而推迟):
Expand Down
14 changes: 7 additions & 7 deletions docs/projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ Core changes flow into plugin repositories by copying or packaging `dist/` asset

| Repository | Intended channel | Licence | Available from today |
|---|---|---|---|
| `jsray` | npm `@jsray/core` | MIT | npm — `@jsray/core@0.0.2-beta.2` |
| `jsray-wp` | WordPress.org plugin | GPLv2 or later | GitHub release zip · not on WordPress.org yet |
| `jsray-terminal` | npm CLI | MIT | GitHub — `npm i -g github:jsrayorg/jsray-terminal` · not on npm yet |
| `jsray-vscode` | VS Code Marketplace | MIT | GitHub release `.vsix` · not on the Marketplace yet |
| `jsray` | npm `@jsray/core` | MIT | npm — `@jsray/core@0.0.2-beta.3` |
| `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` |

A public repository is not a listing. The last column is where a user can
actually get the thing today; the second is where it is headed.
The last column is where a user gets the thing today; the second is the channel
each is headed for at `0.1.0`.

Future platform repositories such as `jsray-react`, `jsray-astro`, or
`jsray-mdx` if needed.
Expand All @@ -94,7 +94,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/<version>/`: the same files frozen per release
(`jsray.org/v/0.0.2-beta.2/jsray.js`). A page that pins here keeps rendering
(`jsray.org/v/0.0.2-beta.3/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
Expand Down
10 changes: 5 additions & 5 deletions docs/projects.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ Core 的变更通过拷贝或打包 `dist/` 资产流向插件仓库。插件的
| 仓库 | 交付形态 | 许可 | 状态 |
|---|---|---|---|
| `jsray` | npm `@jsray/core` | MIT | 已公开 |
| `jsray-wp` | WordPress.org 插件 | GPLv2 or later | GitHub Release 的 zip · 尚未上架 WordPress.org |
| `jsray-terminal` | npm CLI | MIT | GitHub —— `npm i -g github:jsrayorg/jsray-terminal` · 尚未发布到 npm |
| `jsray-vscode` | VS Code Marketplace | MIT | GitHub Release 的 `.vsix` · 尚未上架 Marketplace |
| `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` |

仓库公开不等于已上架。最后一列是**今天用户实际能从哪里拿到**,第二列是它将来要去的地方。
最后一列是**今天用户从哪里拿到**,第二列是各自在 `0.1.0` 要去的渠道。

未来按需增加的平台仓库,例如 `jsray-react`、`jsray-astro`、`jsray-mdx`。

Expand All @@ -89,7 +89,7 @@ GPLv2 or later,因为 WordPress.org 的第一条指南接受任何 GPL 兼容许
(`jsray.org/dist/jsray.js`、`jsray.org/dist/themes/<name>.css`)。这个路径每次
发版都会变 —— 对演示页是对的,对没人盯着的站点是错的。
- `https://jsray.org/v/<version>/`:同样的文件按版本固化
(`jsray.org/v/0.0.2-beta.2/jsray.js`)。锁定到这里的页面,今天怎么渲染,
(`jsray.org/v/0.0.2-beta.3/jsray.js`)。锁定到这里的页面,今天怎么渲染,
以后还怎么渲染。

`tools/build-site.sh` 两者都生成。Cloudflare 每次部署都会整体替换资产包,因此
Expand Down
4 changes: 2 additions & 2 deletions docs/versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.2`
Current version: `0.0.2-beta.3`
Current channel: `beta`
Public beta released: yes

Expand Down Expand Up @@ -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.2 → 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.3 → 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,
Expand Down
Loading
Loading