Skip to content

release: sync develop to main#240

Merged
haowei2000 merged 54 commits into
mainfrom
develop
Jul 16, 2026
Merged

release: sync develop to main#240
haowei2000 merged 54 commits into
mainfrom
develop

Conversation

@haowei2000

Copy link
Copy Markdown
Collaborator

Brings main up to date with develop:

🤖 Generated with Claude Code

dependabot Bot and others added 30 commits July 14, 2026 06:41
Bumps [rand](https://github.com/rust-random/rand) from 0.8.6 to 0.10.2.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](rust-random/rand@0.8.6...0.10.2)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.10.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
New connector.html / connector.zh-CN.html walk a non-developer through
installing, getting a token, writing one config file, and — importantly —
keeping the ACP connector updated, with the "bot can't see attached files
→ update the connector" failure mode called out prominently (the exact
symptom from a real haowe_codex report). Linked from both homepages' Docs
grids; recorded in website/README.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The MCP post_message tool maps to the channel.messages.create resource,
which crosses MCP → loopback HTTP → connector WS → gateway. Four changes
cut latency on that path and make it measurable:

- loopback: HTTP keep-alive so the MCP↔connector socket is reused across
  resource calls instead of reconnecting per call (Connection: close →
  keep-alive, with carry-over buffering for pipelined requests, a clean-EOF
  signal, and a 120s idle timeout). Helps every tool, not just post_message.
- gateway: spawn the post-commit broadcast (Redis PUBLISH + chain
  resolution + bot@bot trigger) off the reply's critical path, so
  post_message returns as soon as the row commits. Ordering stays correct —
  the frontend re-sorts incoming message frames by channel_seq.
- gateway: resolve mention_names in one batched ANY() query instead of one
  round-trip per name (the lone N+1 in the create path), mirroring
  validate_mention_ids. Group-token expansion and error/order semantics
  preserved.
- instrumentation: debug-level timing spans on the connector WS round-trip
  and the gateway db-path, plus the off-path broadcast, so the dominant hop
  is a number rather than a guess.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New website/mcp.html: a GitHub Pages reference for the Cheers MCP server —
its 26 tools grouped by capability with read/write/destructive access tags,
the four-hop request path, and where post_message spends its time. Reuses
the site's existing chrome (nav, theme toggle, table/callout/docs-grid
recipes and amber palette) so it matches index.html and plugin-dev.html.

Wire it into the nav and developer docs of index.html and plugin-dev.html,
and list it in website/README.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`cargo fmt --check` (CI: Agent Package Check) rejected the `timeout(...)`
call in handle_connection. Formatting only — no behaviour change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…seam

`resource::dispatch` is db-only by design, so a successful write there is only
half the operation: creating a message must also broadcast the live frame and
trigger @mentioned bots, leaving a channel must re-broadcast presence, and an
fs.* write must nudge open Desk views. Those need AppState (fanout /
stream_registry / bot_locator), which dispatch doesn't have — so each effect was
patched in at the bot-bridge WS boundary.

That put the rule "creating a message ⇒ broadcast + trigger" at exactly one call
site. A second transport (the Streamable-HTTP MCP endpoint we're considering)
calling resource::dispatch directly would persist the row, return ok, and
silently skip the broadcast and the trigger — no error, just a channel that
never updates and an @mentioned bot that never wakes.

Introduce gateway::resource_effects::dispatch_with_effects(state, principal,
frame): dispatch plus the effects it can't perform, so every transport routes
through one seam and gets the complete semantics of each verb. Moves the four
effect blocks (messages.create, channel.leave, fs.*, bot.status.write) out of
agent_bridge, which shrinks by ~114 lines to a single call.

Behaviour-preserving: same effects, same ok-gating, same off-critical-path spawn
for the message broadcast. `workspace.read` stays intercepted at the bridge — it
is an alternate dispatch, not a post-dispatch effect, and fails loudly rather
than silently elsewhere.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rf-2c79e9

post_message: trim the hot path, add a transport-neutral effects seam, document the MCP
Dev loop for renderer plugins without admin install: drop a .html on the
drawer (or Load extension) and its renderers join the candidates for this
browser session only, marked ⏱ in pickers. A same-id session plugin shadows
the installed one so a deployed plugin can be iterated on live; reload
restores the installed version.

- PluginMeta gains inline bundle?/transient? (session-only; never on the wire);
  SandboxRenderer uses the inline bundle instead of fetching
- manifest shape validation extracted to dependency-free pluginManifest.ts
  (shared by admin upload + temp load), with vitest coverage; uploads now
  reject empty/renderer-less (legacy panels) manifests with a named reason
- 2 MiB bundle cap on the temp load path (server install cap follows in the
  protocol PR)
- delete retired panels/cheers:init protocol examples (notes-plugin,
  research-plugin); point RESEARCH_SCENARIO at a current-protocol example
- PLUGIN_DEVELOPMENT.md restructured as the normative reference (Quickstart
  dev loop, protocol reference incl. cheers:resource + lifecycle/conflict
  flows, cookbook, troubleshooting); RENDERER_PLUGIN.md marked design
  original deferring to it; WORKBENCH/examples/READMEs updated

Verified e2e (kind stack + vite): temp-load md-checklist → ⏱ candidate ranked
first → checklist renders in sandbox → toggle saves (v2) and persists in the
file → session plugin gone after reload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… vocabulary, server-side validation, inline SDK

The plugin contract gets a version and a normative spec, so it can evolve
without breaking installed plugins.

- manifest gains protocol (absent = 1, the documented default covering all
  pre-field installs); hosts skip plugins declaring an unimplemented
  protocol instead of half-rendering them; the server rejects them at
  install
- match vocabulary (protocol 1 final): format accepts a string OR list;
  dataHas = top-level keys of parsed structured content (format-agnostic
  successor of jsonHas, which stays valid with frozen JSON-only semantics);
  dataKind object|array — the only way to claim a JSON array. Specificity
  counts the new constraints; unknown match keys are ignored by design
- builtin chart migrates jsonHas -> dataHas (same behavior)
- server: validate_manifest on PUT /workbench/plugins/:id — id charset +
  path-param match, title, protocol, legacy panels reject, per-renderer
  shape, match type-checks; 2 MiB bundle / 64 KiB manifest caps (413). The
  old "{}"-manifest default hole is closed; already-installed rows are
  never revalidated
- cheers-plugin-sdk.js (docs/arch/examples): ~50-line copy-paste-inline
  helper wrapping ready/render/save/resource; examples declare protocol: 1
- PLUGIN_DEVELOPMENT.md: protocol field + vocabulary + server error table +
  SDK section + explicit JSON-RPC/MCP-Apps deferral note; zh doc pointer

Tests: 8 new cargo cases (validation matrix), 14 vitest cases across the
registry vocabulary + manifest validation; full suites green (165 cargo /
41 vitest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four official plugins ship inside the gateway binary and seed into
workbench_plugins at startup, so a fresh install has a useful renderer set
with zero admin steps. They double as reference implementations (all built
on the inline SDK):

  cheers-checklist   md task lines -> interactive checklist
  cheers-table       JSON array of objects -> editable table, columns
                     inferred from the union of row keys (dataKind:"array")
  cheers-kanban-md   '## heading' columns + task-line cards; moves/toggles
                     rewrite only those lines, everything else byte-for-byte
  cheers-frontmatter flat 'key: value' frontmatter form; unparseable lines
                     read-only + preserved; body never touched

Seeding policy (pure decide(), unit- and integration-tested): the binary is
the source of truth (origin='system', migration 0048 adds the column + a
workbench_official_plugin_state version ledger); admin deletions stick
across restarts of the same release and are only undone by a release
shipping a higher manifest version; ids admins claimed are never touched.
The API refuses PUT on official rows (copy under a new id to customize);
DELETE stays allowed. A unit test walks every embedded bundle through
extract_manifest + validate_manifest so CI cannot ship a malformed one.

Also fixes the Dockerfile mtime-touch line to cover assets/ — include_str!
deps are tracked via dep-info mtimes, so an assets-only change would have
shipped a stale binary.

Frontend: Official badge + sticky-deletion confirm in Settings; PluginMeta
gains origin.

Verified on the kind stack: boot log seeds 4; same-version restart seeds 0
(idempotent, deletions stick); PUT on official id -> 400; legacy panels ->
400; 3 MiB bundle -> 413; todo.md offers 'Checklist · cheers-checklist'
from the installed set and renders/saves; Settings shows 4 Official badges.
cargo test 171 passed (+4 sqlx integration vs real Postgres); vitest 41.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 7.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v4...v7)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
…erving writes

Structured boards can now be .yaml/.yml, and — the point of choosing YAML
over JSON — their comments survive machine rewrites. The lens save path
patches the parsed Document (yamlDoc.applyEdits: deep diff -> setIn/deleteIn
on the CST) instead of re-serializing, so '# notes for humans/bots' and
blank lines ride through UI edits untouched.

Documented loss cases (correctness over comment retention): unparseable
input, multi-document streams, and anchors/aliases fall back to a full
re-stringify; an array whose length/order changed is replaced wholesale.

- Format layer: YAML_FMT with serialize(data, prevText) round-trip context
  (useFile threads the last-loaded text); .yaml seeds serialize as YAML
- registry: formatOf classifies yaml; dataHas/dataKind evaluate on parsed
  YAML (jsonHas stays frozen to JSON, tested); builtin table/kanban/chart
  claim ['json','yaml']
- builtin table becomes PICKABLE: columns come from template config when
  present, else inferred from the union of row keys (dataKind:'array' gates
  the offer) — this is also the official YAML answer, since sandboxed
  plugins would have to inline their own parser (documented)
- docs: match table + yaml plugin note + YAML 1.2 semantics warning

Tests: 11 yamlDoc round-trip cases (comments above/inline, blank lines,
key add/delete, nested edits, array-resize/anchor/multi-doc fallbacks),
5 registry yaml cases; 55 vitest total green.

Verified live (kind stack): seeded ydemo/rows.yaml (commented array) ->
builtin Table auto-offered with inferred name/role columns -> cell edit ->
Save -> Raw shows both comments intact plus the edit; metrics.yaml with
'series' renders the chart.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.1.0 to 26.1.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 26.1.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@codemirror/lang-markdown](https://github.com/codemirror/lang-markdown) from 6.5.0 to 6.5.1.
- [Changelog](https://github.com/codemirror/lang-markdown/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/lang-markdown/commits)

---
updated-dependencies:
- dependency-name: "@codemirror/lang-markdown"
  dependency-version: 6.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [agent-client-protocol](https://github.com/agentclientprotocol/rust-sdk) from 1.0.1 to 1.2.0.
- [Release notes](https://github.com/agentclientprotocol/rust-sdk/releases)
- [Commits](agentclientprotocol/rust-sdk@agent-client-protocol-http-v1.0.1...agent-client-protocol-http-v1.2.0)

---
updated-dependencies:
- dependency-name: agent-client-protocol
  dependency-version: 1.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.16 to 8.5.19.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.5.16...8.5.19)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.19
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 2.1.9 to 4.1.10.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 4.1.10
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [rustls](https://github.com/rustls/rustls) from 0.23.41 to 0.23.42.
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](rustls/rustls@v/0.23.41...v/0.23.42)

---
updated-dependencies:
- dependency-name: rustls
  dependency-version: 0.23.42
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [clap](https://github.com/clap-rs/clap) from 4.6.1 to 4.6.2.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](clap-rs/clap@clap_complete-v4.6.1...clap_complete-v4.6.2)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [toml](https://github.com/toml-rs/toml) from 0.8.23 to 1.1.3+spec-1.1.0.
- [Commits](toml-rs/toml@toml-v0.8.23...toml-v1.1.3)

---
updated-dependencies:
- dependency-name: toml
  dependency-version: 1.1.3+spec-1.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
The GitHub repository moved from haowei2000/Cheers to ElePerson/Cheers
(2026-07-16). Repo web links 301-redirect, but the GitHub Pages URL does
NOT — haowei2000.github.io/Cheers is dead — and GHCR packages don't
transfer either. Sweep every tracked reference to the old owner:

- READMEs: badges, release links, and the (broken) live-overview Pages
  link -> eleperson.github.io/Cheers
- runtime defaults: connector_release_repo (server/src/config.rs),
  install.sh CHEERS_CONNECTOR_REPO default, BotOnboardingWizard
  CONNECTOR_RELEASES_REPO, enrollment instructions text — releases moved
  with the repo, so the new owner is the correct default (old URLs also
  still redirect for anything already deployed)
- ghcr.io/haowei2000/* -> ghcr.io/eleperson/* in Helm/deployment docs,
  matching cd.yml's ${{ github.repository_owner }} (images land there on
  the next main push; container packages do not transfer with the repo)
- website/ landing pages, docs/help guides, CHANGELOG compare links,
  issue-template security-advisory URL, Chart.yaml home

Verified: github.com/ElePerson/Cheers, releases/latest, and
eleperson.github.io/Cheers all return 200; zero 'haowei2000' left in
tracked files; cargo check + tsc clean (modulo pre-existing PdfViewer).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The GitHub repo moved from haowei2000/Cheers to ElePerson/Cheers on
2026-07-16. Old links only work via GitHub's transfer redirect (and the
old GitHub Pages URL is already dead), so update the hardcoded owner in
user-facing surfaces: website pages, READMEs, docs/help guides, the
connector-download fallbacks (BotOnboardingWizard, gateway config
default, install.sh), the enrollment help text, and the Helm chart home
URL. Every rewritten URL was verified to resolve, including the
releases/latest connector asset download.

ghcr.io/haowei2000/* image references are left as-is: GHCR packages do
not transfer with the repo, and no public images exist under eleperson
yet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
thread_rng() -> rng(), Rng::gen_range -> RngExt::random_range

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- create ~/.cheers/workspace in setup (connector requires allowed_roots to exist)
- add troubleshooting row for allowed_roots does not exist
- point all links at ElePerson/Cheers after the repo transfer
- escape & in Q&A hrefs; unpin release tag in gh download callout

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…vior

- PLUGIN_DEVELOPMENT.md: cheers:render is sent on ready and after a
  conflicted save; external edits do not push a re-render
- pluginManifest.ts: correct the bundle-cap comment (server cap lands
  with install validation)
- WorkbenchDrawer: measure the 2 MiB cap in UTF-8 bytes; accept .htm
  and uppercase extensions on drop

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
chore: point repo references at ElePerson/Cheers after transfer
…gistry, validator parity

- SDK: enforce single-in-flight save (host does not correlate saves);
  document the rule as normative in PLUGIN_DEVELOPMENT.md
- registry.ts: replace literal NUL glob placeholders with \u0000 escapes
  so the file diffs as text on GitHub
- pluginManifest.ts: mirror the server's per-key manifest validation so
  session loads and installs accept the same manifests
- server: accept protocol 1.0 (JSON number equal to 1) — the frontend
  cannot distinguish 1.0 from 1 after JSON.parse
- examples: lit-review uses dataHas instead of deprecated jsonHas

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Literal 0x00 bytes in globToRegExp made git classify the file as
binary, hiding every diff of this file on GitHub. Same runtime value
via \u0000 escapes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
haowei2000 and others added 24 commits July 16, 2026 21:53
…nto HEAD

# Conflicts:
#	frontend/src/features/chat/workbench/renderers/registry.ts
- Dockerfile: make the asset cache-bust predicate actually match
  (relative find paths never matched */assets/*)
- workbench_official: checked i32 conversion for manifest version;
  SkipAdminClaimed logs at info
- checklist/kanban manifests: offer renderers for * [ ] bullets too
- table plugin: Set-based column dedup (survives constructor/toString keys)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s' into HEAD

# Conflicts:
#	frontend/src/features/chat/workbench/renderers/registry.ts
… cases

- builtin table: only offered for arrays of plain objects; render and
  update guard non-object rows so a null or scalar row can neither
  crash the app nor corrupt the file on save
- yamlDoc: preserve header comments of comment-only files across the
  first save; disable lineWidth refolding of untouched scalars; align
  the array-replacement contract comment with the code and name the
  same-length-reorder comment hazard
- docs: write-side YAML 1.1 ambiguity note (unquoted no/yes/on/off)
- pluginManifest: yaml joins the documented format list

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
chore: update owner references after repo transfer to ElePerson
…lop/actions/setup-node-7

chore(deps): Bump actions/setup-node from 4 to 7
…rs-acp-connector-rs/develop/clap-4.6.2

chore(deps): Bump clap from 4.6.1 to 4.6.2 in /packages/cheers-acp-connector-rs
…rs-acp-connector-rs/develop/rustls-0.23.42

chore(deps): Bump rustls from 0.23.41 to 0.23.42 in /packages/cheers-acp-connector-rs
# Conflicts:
#	website/README.md
#	website/index.html
#	website/index.zh-CN.html
…ntext-a7f6b6

docs(website): user-facing ACP connector guide (EN + 中文)
…rs-acp-connector-rs/develop/toml-1.1.3spec-1.1.0

chore(deps): Bump toml from 0.8.23 to 1.1.3+spec-1.1.0 in /packages/cheers-acp-connector-rs
…rs-acp-connector-rs/develop/agent-client-protocol-1.2.0

chore(deps): Bump agent-client-protocol from 1.0.1 to 1.2.0 in /packages/cheers-acp-connector-rs
…nd/develop/types/node-26.1.1

chore(deps-dev): Bump @types/node from 26.1.0 to 26.1.1 in /frontend
…nd/develop/codemirror/lang-markdown-6.5.1

chore(deps): Bump @codemirror/lang-markdown from 6.5.0 to 6.5.1 in /frontend
…nd/develop/postcss-8.5.19

chore(deps-dev): Bump postcss from 8.5.16 to 8.5.19 in /frontend
…nd/develop/vitest-4.1.10

chore(deps-dev): Bump vitest from 2.1.9 to 4.1.10 in /frontend
…s-acp-connector-rs/develop/rand-0.10.2

chore(deps): bump rand from 0.8.6 to 0.10.2 in /packages/cheers-acp-connector-rs
feat(workbench): session-level temporary plugins + normative plugin docs
feat(workbench): plugin protocol 1 — versioned manifest, match vocabulary, server validation, SDK
feat(workbench): official renderer plugin set, seeded by the gateway
feat(workbench): YAML boards with comment-preserving writes
@haowei2000
haowei2000 merged commit 8a940c1 into main Jul 16, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant