From afc71e63a776679cd33762db5bbf780a872e742e Mon Sep 17 00:00:00 2001 From: JWeBot Contributors Date: Fri, 16 Oct 2026 01:07:07 +0800 Subject: [PATCH] Release beta 1.0.0 baseline --- .gitignore | 1 + AGENTS.md | 6 +- CHANGELOG.md | 608 +++++++++++++++++- README.md | 80 +-- VERSION | 2 +- deploy/scripts/install-wechat-health-watch.sh | 6 + docs/command-catalog.md | 122 ++++ docs/command-routing.md | 7 +- docs/plugin-contract.md | 2 +- docs/project-rules.md | 8 +- docs/telemetry.md | 2 +- docs/versioning.md | 16 +- packages/jwebot-config/pyproject.toml | 2 +- .../src/jwebot_config/__init__.py | 2 +- packages/jwebot-extension-host/pyproject.toml | 6 +- .../src/jwebot_extension_host/__init__.py | 2 +- packages/jwebot-kernel/pyproject.toml | 8 +- .../src/jwebot_kernel/__init__.py | 2 +- .../jwebot-official-extensions/pyproject.toml | 4 +- .../jwebot_official_extensions/__init__.py | 2 +- .../local_commands.py | 66 +- packages/jwebot-sdk/pyproject.toml | 2 +- .../jwebot-sdk/src/jwebot_sdk/__init__.py | 2 +- pyproject.toml | 2 +- tests/test_deployment_scripts.py | 2 + tests/test_jwebot_edge.py | 3 + tools/check-config.sh | 4 +- tools/check-packages.sh | 13 +- 28 files changed, 872 insertions(+), 110 deletions(-) create mode 100644 docs/command-catalog.md diff --git a/.gitignore b/.gitignore index 8a575c5..ce4789c 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ id_ed25519* # Sensitive local notes homeserver-apikey-*.md +debug-*.md # macOS/editor .DS_Store diff --git a/AGENTS.md b/AGENTS.md index b9feb56..8cc3d54 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,9 +4,11 @@ These rules are mandatory for every automated change in this repository. ## Versioning -- Use `alpha X.Y.Z.MMDD`. +- Use `beta X.Y.Z.MMDD` for current beta releases. +- Python package versions use PEP 440 pre-release form, for example + `X.Y.Zb1+MMDD`. - Small changes increment only `Z`. -- Do not move to a new minor version without explicit user approval. +- Do not move to a new minor or stable version without explicit user approval. - Keep `VERSION`, root `pyproject.toml`, package versions, package `__version__`, `README.md`, and `CHANGELOG.md` synchronized. diff --git a/CHANGELOG.md b/CHANGELOG.md index 32179fa..5f94987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## beta 1.0.0.1016 - 2026-10-16 + +- Promote JWeBot from alpha to beta after the local, staging, privacy, and + production deployment gates stabilized. +- Consolidate the current reviewed local command set, including virtual coin + transfer, loans, repayment, group leaderboard, multiplayer lottery, + blackjack, Steam queries, and CS Major autochess. +- Externalize CS Major autochess game content into package JSON data files for + cards, coaches, narratives, draft/shop/economy rules, match formats, and + MR15/overtime settings. +- Add a maintained command catalog and keep debug session notes out of the + repository by default. +- Keep release validation on `tools/sync-local-extensions.py --check`, + `tools/check-local.sh`, and `tools/check-secrets.py --history`. + ## alpha 0.6.11.1015 - Add `/大富翁榜`, `/金币排行`, `/金币排行榜`, and `/richlist` for a @@ -117,7 +132,7 @@ deterministic local AI as seed four; it buys players, upgrades its coach, swaps its strongest lineup, and selects a counter tactic without an online model. -- Give Taffy a persistent host state machine: welcome and format briefing, +- Give the bot a persistent host state machine: welcome and format briefing, rotating human preparation order, turn enforcement, explicit handoffs, round introductions, matchup calls, overtime narration, advancement, and championship presentation. @@ -144,7 +159,7 @@ - Add per-game personal sequence numbers and `/游戏记录` (`/gamehistory`) for prize draws, lottery rounds, and blackjack hands. - Prefix game output with the configured player label and game number, such as - `Jacky #1:...`; aliases share the same counter and account. + `Player #1:...`; aliases share the same counter and account. ## alpha 0.6.2.1015 @@ -162,7 +177,7 @@ stand in a separate command. Combined forms return this workflow without opening a game or deducting funds. - Prefix blackjack hands, status and settlement replies with the current - group-scoped player's configured display label, such as `jacky:...`. + group-scoped player's configured display label, such as `player:...`. ## alpha 0.6.1.1015 @@ -213,18 +228,581 @@ backup; pre-public operational history remains only in protected local archives. -## Pre-Public Milestones +## alpha 0.5.11.1015 -Earlier alpha work established: +- Reduce the conservative follow-latest scroll burst from a fixed `25ms` to + `1ms` between each of the existing 30 wheel events. +- Reuse the XDamage producer's verified WeChat window identifier in the + adaptive ready-layout gate instead of rediscovering the same window before + each screenshot. +- Preserve the shared GUI lock, ready-window geometry gate, second screenshot, + and loaded-bottom visual confirmation. +- Add privacy-safe per-step capture telemetry and regression coverage for the + optimized slow path. -- adaptive OCR and XDamage capture; -- guarded GUI send with visual confirmation; -- durable ACK/final delivery ordering; -- privacy-safe latency telemetry; -- capability-limited SDK contracts; -- signed extension artifacts and isolated Host execution; -- reviewed command ownership and generated adapters; -- coordinated production backup, health gates, and rollback. +## alpha 0.5.10.1015 -Private host, person, address, account, incident, and deployment details are -intentionally omitted from the public changelog. +- Prioritize queued fast acknowledgements and local-command replies over queued + final replies in the guarded GUI sender. +- Keep the active GUI send non-preemptive and preserve strict FIFO ordering + within each priority class through a monotonic sequence number. +- Raise the adaptive recorder CPU quota from `150%` to `250%` to reduce + screenshot subprocess stalls under OCR and GUI contention. +- Add deterministic coverage for ACK/local priority, final FIFO ordering, + single-sender serialization, and clean worker shutdown. + +## alpha 0.5.9.1014 + +- Preserve both capture call contracts in the adaptive ready-window wrapper: + zero arguments for startup/polling and one verified window identifier for the + optimized XDamage producer. +- Fix the alpha 0.5.8 internal `CaptureProducerError` restart loop that began on + the first relevant XDamage event. +- Add direct regression tests for both ready-gated capture signatures. + +## alpha 0.5.8.1014 + +- Recover one unseen bottom-most bot trigger when a viewport resync has no + visual overlap, instead of silently dropping the new command. +- Persist a bounded recent-trigger visual history so an old command is not + replayed by a later no-overlap resync; ordinary messages remain fail-closed. +- Seed that history from one startup baseline before enabling recovery, so a + service restart cannot replay a visible pre-existing command. +- Reuse the XDamage monitor's verified WeChat window identifier and the + maximize gate's geometry result, removing one redundant window lookup and + one redundant geometry subprocess from each changed-frame capture. +- Add regression coverage for unseen-trigger recovery, seen-trigger replay + suppression, signature migration, and the optimized capture path. + +## alpha 0.5.7.1014 + +- Replace the single direct-request worker with two parallel generation workers + and one strictly ordered GUI delivery worker for ordinary chat and Steam + requests. +- Keep final replies in durable `created_at, event_id` order even when a newer + provider call completes first; failed acknowledgements and exhausted requests + remain terminal and do not block later replies. +- Separate generation and delivery retry counters so each phase retains its + complete retry budget. +- Wake generation and delivery workers immediately on enqueue, generation + completion, and acknowledgement instead of adding a one-second idle polling + delay to the normal path. +- Split direct-queue telemetry into `direct_generation` and `direct_delivery` + phases and add concurrency, ordering, ACK-race, retry, Steam, and duplicate + regression coverage. + +## alpha 0.5.6.1014 + +- Preserve both pre-draft and post-draft group fingerprint gates while + capturing only the configured title region instead of decoding the complete + WeChat window twice per GUI send. +- Keep the previous full-window fingerprint path as a compatibility fallback + for older adaptive upstream modules. +- Add GUI sender coverage for the title-region primary path, full-window + fallback, and visual group-mismatch fail-closed handling. + +## alpha 0.5.5.1014 + +- Accept incoming WeChat bubbles up to `900px` wide so long single-line bot + mentions are not discarded before OCR; preserve position, height, area, and + outgoing-bubble exclusion gates. +- Wait for adaptive OCR warmup and a first baseline capture from the current + service start before reporting `adaptive ready` or successful deployment. +- Fail and roll back deployment if the adaptive service exits or cannot + establish its recorder baseline within 90 seconds. +- Retry the WeChat ready-window gate for up to 30 seconds and discover the + exact `Weixin` window by both class and title before failing closed. +- Pin production privilege switching and X11 inspection to verified absolute + executable paths so a restricted root `PATH` cannot masquerade as a missing + WeChat window. + +## alpha 0.5.4.1014 + +- Stabilize visible-message sequence alignment with thresholded binary + sender/body fingerprints while retaining exact RGB keys for OCR cache + invalidation. +- Reset 0.5.3 exact-visual recorder state to a safe no-reply baseline during + the signature migration. +- Prefix coordinated deploy phases with `[JWeBot]`, report explicit + `starting`, `ready`, and `active` states, and run user installation from the + target home to avoid inherited `/root` working-directory warnings. + +## alpha 0.5.3.1014 + +- Align visible message sequences with existing exact bubble visual + fingerprints instead of OCR text, preventing scroll/resync OCR drift from + dropping a newly mentioned slash command. +- Reset legacy text-signature recorder state to a no-reply visual baseline on + startup, avoiding duplicate replay during the signature-scheme migration. +- Preserve repeated identical commands as separate visual occurrences. + +## alpha 0.5.2.1014 + +- Print an ASCII pixel-art project signature only after the coordinated + production deployer passes every cutover gate and disables rollback. + +## alpha 0.5.1.1014 + +- Exclude the static bottom-left input hint from the realtime text ROI so an + empty WeChat input box is not misclassified as dirty. +- Label the corrected ROI as `input_text_core_v2` in bridge telemetry, keeping + pre-fix and post-fix production evidence distinguishable. + +## alpha 0.5.0.1014 + +- Move visible WeChat delivery onto a persistent in-process GUI sender queue + hosted by the adaptive recorder, avoiding per-message bridge subprocesses for + ACK, local-command replies, and final deliveries. +- Add a private AF_UNIX sender socket so Edge delivery helpers submit final + replies to the same serialized GUI queue instead of racing the input box. +- Combine clear, paste, ROI draft flag, post-draft group check, Enter send, + ROI clear confirmation, and send-button fallback into one bridge call. +- Confirm the input ROI is empty after Ctrl-A/Backspace before using it as the + paste baseline, preventing repeated `喵......` ACK drafts from being mistaken + for paste failures. + +## alpha 0.4.15.1014 + +- Force adaptive recorder logging to INFO so GUI bridge timing telemetry is + visible on ACK and final delivery paths. +- Allow ROI, poll, pixel-threshold, flag, and coordinate fields through the + packaged runtime telemetry sanitizer. + +## alpha 0.4.14.1014 + +- Replace full-input send confirmation with a left-side input-text ROI flag so + draft and send confirmation poll only the region that should visibly change. +- Restore the guarded send order to Enter first, then click the scaled send + button only as a fallback when ROI clearing is not visually confirmed. +- Emit ROI coordinates, flag state, flag wait time, confirmation source, and + bridge stderr tail diagnostics for GUI delivery failures. + +## alpha 0.4.13.1014 + +- Emit detailed guarded GUI delivery timings for lock acquisition, pre/post + draft screenshots, group fingerprint checks, bridge subprocess duration, + draft paste confirmation polling, send-button confirmation polling, Enter + fallback, callback hooks, and total send time. +- Return per-step timing metadata from the adaptive GUI bridge so ACK and final + delivery reports can attribute fixed waits, screenshot confirmation, VNC + input, and fallback paths without logging message text. + +## alpha 0.4.12.1014 + +- Optimize guarded WeChat GUI delivery by clicking the scaled send button first + and polling for visual confirmation instead of waiting on fixed sleeps. +- Preserve the Enter-key fallback when the button path is not visually + confirmed. + +## alpha 0.4.11.1014 + +- Add explicit `edge.fast_ack.*` and `recorder.fast_ack.*` telemetry names + alongside the existing ACK metrics, making fast acknowledgement latency + independently filterable without breaking historical dashboards. + +## alpha 0.4.10.1014 + +- Cache configured person-alias rows once per group and make configured + identity persistence idempotent, eliminating thousands of redundant + `FULL`-synchronous SQLite commits during Edge startup. +- Reduce measured production host systemd socket readiness on the production database + snapshot from more than 90 seconds to about one second. + +## alpha 0.4.9.1014 + +- Wait up to 45 seconds for the newly started Edge socket and health response + before deciding that a production cutover failed, while still failing + immediately if systemd marks the service failed. + +## alpha 0.4.8.1014 + +- Keep the adaptive OCR process alive while WeChat is absent or awaiting login, + then resume capture against the ready main window without a systemd restart + storm. +- Install the reviewed `wechat_local_ocr.py` beside the adaptive runtime instead + of importing an independently managed root copy. +- Add a root-coordinated production deploy that records both systemd + topologies, backs up root and user files plus SQLite, disables both legacy OCR + units, and rolls back all layers when a health gate fails. +- Require empty OCR queues, a ready WeChat window, Edge socket health, stable + adaptive restart counts, and SQLite integrity before accepting a production + cutover. +- Preserve incoming service state in legacy install and upgrade tools; legacy + OCR now remains disabled unless an operator explicitly opts in. +- Prevent Extension Host imports from writing bytecode into verified releases, + and exclude only standard interpreter cache files from source packaging. +- Add deployment contract tests and shell-aware syntax validation to the local + release gate. + +## alpha 0.4.7.1014 + +- Prewarm RapidOCR recognition and detection paths before live capture. +- Cache successful bubble recognition by bounded exact visual fingerprint, + recognize only new or changed crops, and periodically revalidate the cache. +- Persist OCR command events through atomic file replacement plus file and + directory `fsync`, then immediately wake the in-process responder while + retaining the one-second recovery scan. +- Name the three execution paths explicitly as `local-command`, `deepseek`, and + `openclaw` in Edge responses and privacy-safe routing telemetry. +- Add signed plugin description/help metadata, validate it through Host health, + generate bundled `/功能列表` output automatically, and update plugin creation + tooling and author documentation. + +## alpha 0.4.6.1014 + +- Add a repeatable local performance baseline for OCR preprocessing, sequence + alignment, durable ACK/queue state, and real signed Host process execution. +- Add a structured telemetry-log analyzer with p50, p95, maximum, status, and + event-count summaries. +- Measure queue waiting, capture-buffer age, ACK end-to-end latency, and final + Edge delivery latency without recording message content. +- Establish the bottleneck order from local measurements and existing runtime + evidence: RapidOCR, provider generation, polling wakeups, then one-shot Host + startup; SQLite and sequence work remain below 2 ms p95 locally. +- Document the evidence, measurement gaps, and optimization order for later + `0.4.x` iterations. + +## alpha 0.4.5.1014 + +- Close the approved repository-only Extension Host migration scope. +- Treat an invalid installed signed release as a startup failure rather than a + preferred-mode fallback; only missing or startup-unhealthy Hosts may fall + back. +- Enforce the end-to-end Host deadline after Kernel service execution and + expand transport-error telemetry. +- Document completed local work, explicitly deferred external operations, and + the next measurement-led OCR/queue/ACK performance-analysis phase. + +## alpha 0.4.4.1014 + +- Add privacy-safe structured telemetry for OCR, routing, ACK preparation and + confirmation, queues, providers, Host processes, service brokering, and final + GUI delivery. +- Hash event and group identifiers, reject message-body fields, and retain only + low-cardinality process-local counts and latency summaries. +- Expose telemetry summaries through Edge health without making telemetry part + of delivery correctness. +- Instrument OCR capture/recognition/queue stages and distinguish ACK GUI + delivery from Edge confirmation. +- Document ACK ordering and the measurement points needed for future OCR, + queue, Host-startup, and provider latency optimization. + +## alpha 0.4.3.1014 + +- Require a signed release to pass isolated Host health before atomic + activation; failed new releases are removed without switching `current`. +- Add explicit local-only health bypass for packaging environments. +- Complete real-process parity coverage for all 12 reviewed plugins, including + memory CRUD, both stateful games, dice challenge, rankings, history, and + Steam fast-ACK final generation. +- Fix Host protocol writes so broker messages bypass redirected plugin stdout + without exposing plugin output to the parent protocol. + +## alpha 0.4.2.1014 + +- Load installed signed plugin manifests into a deterministic startup catalog + and freeze command ownership before routing. +- Add `in-process`, `prefer-host`, and `host-only` Edge execution modes with + subprocess or AF_UNIX Host transports. +- Route signed healthy plugins through the isolated Host while preserving + Kernel-direct commands and Steam fast-ACK queueing. +- Permit startup fallback for missing or unhealthy preferred Hosts, but never + replay an active invocation after a possible stateful service call. +- Add real subprocess end-to-end coverage from Edge through the generated + adapter, Host protocol, Kernel service broker, and final reply. + +## alpha 0.4.1.1014 + +- Add bounded bidirectional JSON-line service brokering between isolated + Extension Host processes and Kernel-owned service profiles. +- Enforce declared profile ownership, call IDs, call count, message size, and + end-to-end process/socket deadlines. +- Add Host health inventory responses and broker support to both subprocess and + AF_UNIX clients. +- Keep service errors generic across the isolation boundary. + +## alpha 0.4.0.1014 + +- Start the approved `0.4.x` local extension-host migration and performance + instrumentation milestone. +- Keep signing-pipeline integration, key rotation, PR rehearsal, target-machine + provisioning, deployment, and Linux verification deferred. + +## alpha 0.3.1.1014 + +- Add OpenSSH `sshsig` publisher signatures for canonical extension release + records. +- Bind the publisher principal, release filename, artifact metadata, source + digest, manifest author, and exact file list through one signed payload. +- Require trusted publisher verification for activation, Host loading, and + rollback; unsigned paths now require an explicit local-test override. +- Persist the canonical signature record with each installed release and + re-verify it before execution or rollback. +- Add signing support to package, verify, activate, rollback, and standalone + release-signing tools. +- Keep production host provisioning, deployment, and systemd validation deferred. + +## alpha 0.3.0.1014 + +- Close the `0.2.x` complete-function migration after the corrected granular + plugin ownership model passed the full local gate. +- Start the approved `0.3.x` baseline with Kernel-direct operational commands, + official-owned person memory, and 11 project-owned plugins. +- Keep Linux deployment and systemd verification explicitly deferred. + +## alpha 0.2.6.1014 + +- Replace grouped plugin domains with one plugin per independently + understandable function. +- Keep dice and dice challenge as one complete project-authored collection. +- Make person-memory the only official-authored command plugin. +- Move feature list, status, and balance to unconditional Kernel-direct + routing. +- Add required manifest author metadata and release-record schema version 2. +- Generate 11 project plugin packages under the reviewed local-extension namespace and keep only + person-memory under `extensions/official`. +- Rename the canonical rollback switch to + `JWEBOT_LOCAL_EXTENSIONS_ENABLED`, while accepting the old environment key + as a compatibility fallback. + +## alpha 0.2.5.1014 + +- Move the complete Steam provider into `jwebot-official-extensions`. +- Migrate fixed roster, group aliases, mode filtering, single-person lookup, + cache, API batching, proxy enforcement, and error classification. +- Preserve the existing public `SteamClient`, `SteamUnavailable`, API base, and + Mihomo default exports through the packaged Edge runtime. +- Keep the no-direct-network-fallback regression tests passing. + +## alpha 0.2.4.1014 + +- Add full official-adapter versus compatibility-path parity tests. +- Cover every stateless command family, all memory operations, every + dice-challenge phase, guess-number lifecycle, RPS lifecycle, status, balance, + Steam generation, and restart persistence. +- Make parity and persistence checks part of the permanent local/CI gate. + +## alpha 0.2.3.1014 + +- Route all known local commands through generated official SDK adapters by + default. +- Execute stateful behavior through named in-process service brokers without + exposing raw Ledger or providers to adapters. +- Preserve the Steam fast-ACK asynchronous path through the official adapter. +- Add `JWEBOT_OFFICIAL_EXTENSIONS_ENABLED=0` as a compatibility rollback to + direct command-engine dispatch. +- Keep unknown slash-command errors on the compatibility path. +- Install generated adapter modules with the official package. + +## alpha 0.2.2.1014 + +- Add reviewed `service_profiles` as a narrow SDK/manifest capability. +- Generate real Host-loadable packages for all seven official function domains. +- Register every existing alias through SDK command adapters. +- Delegate complex stateful behavior through named Kernel service profiles + instead of exposing raw Ledger or provider objects. +- Add synchronization checks so official manifests, adapters, docs, and command + ownership cannot drift. +- Validate, source-scan, and package every official extension in CI. + +## alpha 0.2.1.1014 + +- Move the complete local command engine out of the Edge runtime into the + installable `jwebot-official-extensions` package. +- Preserve all command replies, persistence, deterministic seeds, game state + machines, memory operations, rankings, status, balance, and Steam behavior. +- Inject Ledger, Steam, balance, reply-cleaning, identity, and memory-policy + brokers from Kernel instead of importing Edge internals. +- Add a unique ownership map covering every current command kind and alias. +- Add an authoritative migration matrix documenting every command subfunction + and non-command Kernel responsibility. + +## alpha 0.2.0.1014 + +- Start the approved `0.2` full-function migration milestone. +- Move the complete Edge runtime into `jwebot-kernel`. +- Keep `jwebot_edge.py` as a compatibility CLI and module alias so existing + imports and runtime monkeypatches continue to affect implementation globals. +- Update tests and the installer for the packaged runtime. +- Preserve all existing command, queue, ledger, model, memory, broadcast, and + delivery behavior. +- Do not deploy or validate on Linux in this stage. + +## alpha 0.1.11.1014 + +- Add a bounded AF_UNIX client matching the systemd socket-activated Host + design. +- Send one canonical JSON request, half-close the write side, and read one + bounded response. +- Fail closed on socket timeout, unavailable socket, malformed response, and + Host error status. +- Keep the socket client disconnected from the current production Edge path. + +## alpha 0.1.10.1014 + +- Add uninstalled systemd socket/service templates for the extension Host. +- Specify a fixed unprivileged identity, AF_UNIX-only private network, + read-only system/release paths, empty capabilities, syscall filtering, and + CPU/memory/process/runtime limits. +- Add static sandbox-policy checks and unit tests. +- Require explicit target-host provisioning and systemd verification before + any future enablement. + +## alpha 0.1.9.1014 + +- Add the Kernel-side extension Host client with a minimal inherited + environment and isolated process group. +- Enforce parent wall-time deadlines and kill the entire Host process group on + timeout. +- Bound request, response, and stderr sizes and reject malformed protocol + responses. +- Limit plugin stdout/stderr inside the Host. +- Hash both plugin log messages and field-name sets instead of emitting plugin + text. +- Test timeout child-process cleanup and environment-secret exclusion. +- Keep the client disconnected from the production Edge path. + +## alpha 0.1.8.1014 + +- Add an installable `jwebot-extension-host` package. +- Re-verify installed release content, manifest, and source policy before import. +- Enforce exact declared command registration and freeze it before invocation. +- Add a bounded single-request JSON stdin/stdout protocol. +- Scrub inherited environment values and redirect plugin stdout away from IPC. +- Keep storage, HTTP, and scheduling brokers fail-closed. +- Return generic plugin failure classes without exception text. +- Do not connect the Host to Edge or install it on production host. + +## alpha 0.1.7.1014 + +- Add verified release installation under full source-digest directories. +- Add locked, atomic `current` and `previous` activation pointers. +- Re-verify installed release file lists, records, and source content before + reuse. +- Add explicit local activation and rollback tools with no default production + path. +- Test rollback, tampered artifacts, tampered installed content, unsafe + pointers, and private installed-file permissions. +- Do not execute extension code or modify production host. + +## alpha 0.1.6.1014 + +- Add deterministic, content-addressed extension release artifacts. +- Add canonical source and artifact SHA-256 records. +- Verify artifacts without extraction and reject path traversal, non-regular + members, expansion limits, file-list drift, and content tampering. +- Refuse replacement of an existing digest-addressed artifact with different + bytes. +- Build and verify the example extension artifact in Gitea Actions. +- Explicitly defer publisher signing and production host activation to a later phase. + +## alpha 0.1.5.1014 + +- Add a static extension source-policy preflight before packaging. +- Reject unapproved imports, file/process/socket access, dynamic execution + builtins, and dunder attribute traversal. +- Enforce source count, size, UTF-8, syntax, and symlink limits. +- Make `validate-plugin.py` validate both manifest and source policy. +- Document that static policy is a CI prefilter, not a replacement for OS + process isolation. + +## alpha 0.1.4.1014 + +- Restrict extension command names to Unicode word characters, dots, and + hyphens. +- Reject quote/newline template injection before plugin skeleton files are + created. +- Add manifest and generator regression tests while preserving Chinese command + names. + +## alpha 0.1.3.1014 + +- Add a safe command-extension generator that refuses invalid IDs, invalid + commands, path traversal, and overwriting existing extensions. +- Add official and friend extension namespaces. +- Add an author guide, SDK API reference, and reusable AI-author prompt. +- Include author tooling and required documentation in the repository gate. + +## alpha 0.1.2.1014 + +- Add a deterministic extension catalog that accepts reviewed manifests only + during startup. +- Reject duplicate plugin IDs and case-insensitive command ownership conflicts. +- Freeze registration before runtime command resolution. +- Keep catalog views immutable and require explicit command-token boundaries. + +## alpha 0.1.1.1014 + +- Make `jwebot-kernel` the authoritative pure routing implementation used by + the existing Edge compatibility entrypoint. +- Preserve the existing `jwebot_edge.py` public function shapes for current + callers and tests. +- Update the production host installer to deploy and roll back the SDK and Kernel package + directories together with the compatibility scripts. +- Do not deploy or restart any production service in this repository change. + +## alpha 0.1.0.1014 + +- Start the approved `0.1` milestone with installable `jwebot-sdk` and + `jwebot-kernel` packages. +- Add versioned event, reply, fact, and extension-result contracts. +- Add capability-limited context protocols that expose no GUI, group selector, + raw ledger, environment, shell, or unrestricted network access. +- Add strict plugin manifest validation and pure local/chat/cloud routing + primitives. +- Add a minimal `/hello` command extension and package boundary tests. +- Keep all existing root runtime entrypoints unchanged for production host compatibility. + +## alpha 0.0.7.1014 + +- Move unit tests into `tests/`. +- Update tests to load root compatibility entrypoints from the repository root. +- Update local verification commands to discover tests from `tests/`. + +## alpha 0.0.6.1014 + +- Add repository-safe configuration templates under `config/examples/`. +- Add `docs/configuration-guide.md` for runtime configuration ownership and + deployment destinations. +- Add `tools/check-config.sh` and include it in the local migration gate. +- Keep real secrets and production host runtime files outside Git. + +## alpha 0.0.5.1014 + +- Add a Gitea Actions workflow that runs the standard local migration gate on + push and pull request. +- Add `requirements-dev.txt` for local and CI test dependencies. +- Document dependency installation in `README.md`. + +## alpha 0.0.4.1014 + +- Move home-backup operational material into `ops/home-backup/`. +- Move the TigerVNC config snippet into `deploy/config/`. +- Keep backup material in the repository for reference while separating it from + the bot runtime path. + +## alpha 0.0.3.1014 + +- Add `tools/check-local.sh` as the standard local migration gate. +- Wire the gate to compile Python entrypoints, validate shell scripts, reject + active emergency debug hooks outside their archive docs, and run the full + unittest suite. +- Document the local check command in `README.md`. + +## alpha 0.0.2.1014 + +- Remove temporary emergency HTTP debug hooks from production Python entrypoints. +- Preserve removed hook context in `docs/debug/emergency-hooks-archive.md`. +- Add `docs/configuration-inventory.md` to document hardcoded addresses, paths, + service names, dimensions, models, and their migration policy. +- Keep historical incident markdown unchanged for auditability. + +## alpha 0.0.1.1014 + +- Establish the repository version baseline for the private alpha migration. +- Move operational docs into `docs/`. +- Move deployment scripts, defaults, and systemd units into `deploy/`. +- Move the cloud responder prompt workspace into `agents/wechat-responder/`. +- Move the old direct OpenClaw watcher into `legacy/`. +- Keep current Python runtime entrypoints at repository root to preserve test and + deployment compatibility during the first migration step. diff --git a/README.md b/README.md index 204b383..c04aa47 100644 --- a/README.md +++ b/README.md @@ -8,43 +8,15 @@ JWeBot 是运行于 Linux 的单群微信自动回复系统。它通过本地 OC 观察选定的微信窗口,将消息写入持久化 Edge 账本,调用经过审核的命令插件, 并通过带视觉确认的 GUI 发送链路回复。 -当前版本:`alpha 0.6.11.1015`。 +当前版本:`beta 1.0.0.1016`,更新日期:2026-10-16。 -0.6.1 新增本地上下文总结、人物与别名索引、单人虚拟金币游戏,并增加 -两秒画面复核以补抓遗漏的消息变化。命令和游戏管理规则见 -[0.6.1 插件说明](docs/local-plugins-0.6.1.md)。 -0.6.2 为 DeepSeek 流式回复增加 30 秒总时限,避免未结束的上游连接长期 -占满生成 worker;21 点开局金额明确作为本局下注,并兼容 OCR 丢失空格。 -21 点牌面和结算以当前玩家展示名开头。快速 ACK、重试和严格顺序投递 -规则保持不变。 -0.6.3 将彩票改为群内多人轮次,加入报名、状态、主持人开奖和取消; -抽奖、彩票、21 点统一使用 `Jacky #N:...` 局号并支持 `/游戏记录`。 -完整玩法见[多人彩票与游戏记录](docs/group-lottery-0.6.3.md)。 -0.6.4 新增 2~8 人 CS Major 自走棋:职业选手卡池、属性/定位/战术 -克制、小组单循环、1v4 与 2v3 淘汰赛,以及 BO3/BO5 的 MR15 加时赛。 -完整规则见[CS Major 自走棋设计稿](docs/cs-major-autochess-design.md)。 -0.6.5 将 AI 测试模式扩展到双人:两名真人可一键补入 AI 战队 A、B, -两支 AI 独立运营。 -0.6.6 重构自走棋流程:开赛后三轮选秀,第一轮从固定 10 人教练池中 -选教练,第二、三轮选选手;随后进入训练赛、小组赛、挑战、淘汰赛和 -总决赛。主持消息会拆分为多条回复;所有需要推进的阶段由相关真人发送 -`/结束回合` 自动进入下一步,已淘汰玩家不会再收到赛前准备提示。 -0.6.7 继续强化文字自走棋体验:卡池扩充到 100+ 人、教练库扩充到 -18 人;训练赛改为按参赛人数生成的真实对阵轮次;单图比分由 MR15 -逐回合模拟产生,不再使用固定比分档;赛事叙事素材扩充到 120+ 条, -D 牌、锁店、调阵容和战术窗口会在轮次之间自然提示。 -0.6.8 增加旧版自走棋 active 状态兼容:如果群里残留 0.6.6/0.6.7 -之前创建的未完成赛事,新的 `/自走棋开始` 会原子归档旧档案并开启新版 -赛季,不需要维护人员手工改库。 -0.6.9 将 CS Major 自走棋的公开游戏数据拆出到包内 JSON:选手卡池、 -教练池、叙事素材、商店概率、经济奖励、选秀节奏、羁绊阈值、赛制和 -MR15/加时参数都由数据文件驱动,启动时会校验字段、ID 和素材数量。 -同版新增虚拟金币转账:`/转账 对方 金额` 会在同一事务内扣款入账, -收款人需先发送 `/金币` 初始化账户。 -0.6.10 新增虚拟金币贷款:`/贷款 [金额]` 最多借入 500 金币,`/还款` -可按金额或全部归还;每个账户同一时间最多一笔未还贷款。 -0.6.11 新增 `/大富翁榜`、`/金币排行`,按当前群金币余额展示排行榜, -有未还贷款时会在榜单中标注。 +1.0 Beta 收口了当前稳定功能:本地命令插件、人物与上下文索引、 +Steam 状态与时长查询、虚拟金币游戏、多人彩票、21 点、CS Major +自走棋、生产部署与回滚门禁。CS Major 自走棋的选手、教练、叙事和规则 +已经外置为包内 JSON,虚拟金币支持转账、贷款、还款和群内排行榜。 + +完整命令见[命令目录](docs/command-catalog.md)。历史版本记录见 +[CHANGELOG](CHANGELOG.md)。 ### 运行流程 @@ -290,9 +262,17 @@ visually confirmed GUI bridge. Current version: ```text -alpha 0.6.11.1015 +beta 1.0.0.1016 ``` +Updated: 2026-10-16. + +The 1.0 Beta baseline consolidates the stable local command set, person and +context indexes, Steam presence/playtime queries, virtual coin games, +multiplayer lottery, blackjack, CS Major autochess, and production deployment +gates. CS Major autochess game content is now packaged as JSON data, and +virtual coins support transfer, loans, repayment, and group leaderboards. + ## Runtime Flow ```text @@ -358,7 +338,8 @@ migration, debug archives, and root deployment settings. ## Commands The built-in command inventory is generated from reviewed plugin descriptors. -Common commands include: +See the full [command catalog](docs/command-catalog.md). Common commands +include: ```text /功能列表 @@ -387,25 +368,12 @@ the final separator shown below: /steam时长Dota2人=玩家名 ``` -Version 0.6.1 adds local `/context 100|200|300` extractive summaries, -`/people` and `/person` lookup, and `/wallet`, `/draw`, `/lottery`, `/blackjack` -single-player virtual coin games. Chinese aliases share the same implementations. -Accounts receive 1000 virtual coins once; funds, game state and event replay -results commit together. `/richlist` shows a group-scoped coin leaderboard. -`/transfer name amount` moves virtual coins between initialized group-scoped -accounts in one ledger transaction. OCR display aliases identify group-scoped -people; `/loan amount` and `/repay` manage one capped virtual coin loan per -account. Native WeChat account IDs are unavailable. See +Chinese aliases share the same implementations as their English counterparts. +Virtual coin funds, game state, transfers, loans, repayments, and replay +responses commit through the same ledger transaction path. Native WeChat +account IDs are unavailable, so accounts are scoped by OCR display identity and +configured aliases. See [plugin rules and capture reconciliation](docs/local-plugins-0.6.1.md). -Version 0.6.2 adds a 30-second total deadline to direct DeepSeek streams so an -unfinished upstream response cannot occupy both generation workers for about -15 minutes. Blackjack start amounts are the current round's stake; compact OCR -forms are accepted, while hit/stand remain explicit follow-up commands. -Blackjack hand and settlement replies start with the current player's configured -display label. ACKs, retries, and ordered final delivery remain unchanged. -Version 0.6.3 replaces instant lottery tickets with persistent multiplayer -group rounds, adds indexed personal game history, and raises blackjack stakes -to 1-500 coins. See [multiplayer lottery and game records](docs/group-lottery-0.6.3.md). Steam prefers private per-person SteamID mappings from the active profile and uses the corresponding group display IDs and aliases. Without a private roster, diff --git a/VERSION b/VERSION index 9634937..8024b6a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -alpha 0.6.11.1015 +beta 1.0.0.1016 diff --git a/deploy/scripts/install-wechat-health-watch.sh b/deploy/scripts/install-wechat-health-watch.sh index 20c98ac..89f2e0f 100755 --- a/deploy/scripts/install-wechat-health-watch.sh +++ b/deploy/scripts/install-wechat-health-watch.sh @@ -238,6 +238,8 @@ trap rollback EXIT HUP INT TERM jwebot_log "user runtime preflight starting" test -x "$runtime_python" for path in \ + "$source_dir/VERSION" \ + "$source_dir/CHANGELOG.md" \ "$runtime_source_dir/$ocr_script_name" \ "$runtime_source_dir/$script_name" \ "$runtime_source_dir/$adaptive_script_name" \ @@ -280,6 +282,8 @@ jwebot_log "user runtime backup starting path=$backup_dir" install -d -m 0700 "$target_dir" "$unit_dir" "$config_dir" "$backup_dir" save_unit_states for name in \ + VERSION \ + CHANGELOG.md \ "$ocr_script_name" \ "$script_name" \ "$adaptive_script_name" \ @@ -330,6 +334,8 @@ systemctl --user stop \ >/dev/null 2>&1 || true jwebot_log "user runtime files install starting" +install -m 0600 "$source_dir/VERSION" "$target_dir/VERSION" +install -m 0600 "$source_dir/CHANGELOG.md" "$target_dir/CHANGELOG.md" install -m 0700 "$runtime_source_dir/$ocr_script_name" "$target_dir/$ocr_script_name" install -m 0700 "$runtime_source_dir/$script_name" "$target_dir/$script_name" install -m 0700 "$runtime_source_dir/$adaptive_script_name" "$target_dir/$adaptive_script_name" diff --git a/docs/command-catalog.md b/docs/command-catalog.md new file mode 100644 index 0000000..75ad273 --- /dev/null +++ b/docs/command-catalog.md @@ -0,0 +1,122 @@ +# JWeBot Command Catalog + +Current baseline: `beta 1.0.0.1016`. + +This catalog records the reviewed commands shipped with the built-in local +extensions. Runtime ownership is frozen at startup from the generated +descriptor inventory; plugin code delegates to reviewed service profiles. + +## System + +| Command | Alias | Purpose | +|---|---|---| +| `/功能列表` | `/help` | Show the command list. | +| `/状态` | `/status` | Show local runtime status. | +| `/version` | - | Show installed package versions plus the latest changelog date and summary. | +| `/debug` | - | Show privacy-safe telemetry diagnostics. | +| `/余额` | - | Show configured direct-provider balance status. | + +## Context And People + +| Command | Alias | Purpose | +|---|---|---| +| `/上下文 [100|200|300]` | `/context` | Summarize recent local text in the current group. | +| `/人物列表 [页码]` | `/people` | List known group-scoped people. | +| `/人物 [名称或别名]` | `/person` | Look up one configured or observed person. | +| `/记住 内容` | - | Store a local memory entry for the current person. | +| `/我的记忆` | - | Show the current person's memory entries. | +| `/人物记忆 显示名` | - | Show memory entries for a person. | +| `/忘记 关键词` | - | Remove matching local memory entries. | +| `/记忆帮助` | - | Show memory command help. | + +## Group Insights + +| Command | Alias | Purpose | +|---|---|---| +| `/扫码排行` | - | Show scan ranking for the current group. | +| `/复读榜` | - | Show repeat ranking for the current group. | +| `/查记录 关键词` | - | Search local group history by keyword. | + +## Virtual Coins And Games + +| Command | Alias | Purpose | +|---|---|---| +| `/金币` | `/wallet` | Initialize or show the current person's virtual coin account. | +| `/大富翁榜 [人数]` | `/金币排行`, `/金币排行榜`, `/richlist` | Show the group-scoped coin leaderboard. | +| `/转账 对方 金额` | `/transfer name amount` | Transfer virtual coins to an initialized group account. | +| `/贷款 [金额]` | `/loan amount`, `/借款` | Borrow up to 500 virtual coins. | +| `/还款 [金额|全部]` | `/repay [amount|all]` | Repay an active virtual coin loan. | +| `/抽奖 [金额]` | `/draw` | Play a single-player prize draw. | +| `/彩票 开始` | `/lottery start` | Open a multiplayer lottery round. | +| `/彩票 报名 数字 金额` | `/lottery join` | Join or update a lottery entry. | +| `/彩票 状态` | `/lottery status` | Show the current lottery round. | +| `/彩票 开奖` | `/lottery draw` | Host-only draw for the current lottery round. | +| `/彩票 取消` | `/lottery cancel` | Host-only cancellation with refunds. | +| `/21点 开始 [1-500]` | `/blackjack start` | Start a blackjack round with the chosen stake. | +| `/21点 要牌` | `/blackjack hit` | Draw one blackjack card. | +| `/21点 停牌` | `/blackjack stand` | Stand and settle against the dealer. | +| `/21点 状态` | `/blackjack status` | Show the current blackjack round. | +| `/21点 结束` | `/blackjack end` | End the current blackjack round. | +| `/游戏记录 [页码]` | `/gamehistory` | Show indexed personal game history. | +| `/游戏帮助` | `/games` | Show local game rules. | + +## Random And Session Games + +| Command | Alias | Purpose | +|---|---|---| +| `/丢骰子 [NdM]` | - | Roll dice. | +| `/丢骰子挑战` | `/骰子挑战` | Run a dice challenge. | +| `/翻硬币` | - | Flip a coin. | +| `/随机数 [范围]` | - | Draw a random number. | +| `/抽签 [内容...]` | - | Draw lots from provided options. | +| `/今日运势` | - | Show a deterministic daily fortune. | +| `/猜数字 开始 [上限]` | - | Start a group guessing game. | +| `/猜数字 数字` | - | Guess in the active guessing game. | +| `/石头剪刀布 开始` | - | Start a rock-paper-scissors session. | +| `/石头剪刀布 加入` | - | Join the active session. | +| `/石头剪刀布 出 石头|剪刀|布` | - | Submit a move. | +| `/石头剪刀布 状态` | - | Show session status. | +| `/石头剪刀布 结算` | - | Settle the session. | +| `/石头剪刀布 结束` | - | End the session. | + +## Steam + +| Command | Alias | Purpose | +|---|---|---| +| `/steam 在线` | - | Show configured Steam online status. | +| `/steam 游戏` | - | Show current games. | +| `/steam 全部` | - | Show full configured Steam presence. | +| `/steam 刷新` | - | Refresh cached Steam data. | +| `/steam 时长 游戏名` | `/steam时长游戏名` | Query playtime for a game. | +| `/steam时长游戏名、玩家名` | `/steam时长游戏名人=玩家名` | Query one player's game playtime. | + +## CS Major Autochess + +| Command | Alias | Purpose | +|---|---|---| +| `/自走棋开始` | - | Create a new IEM 盐田 Major season. | +| `/自走棋报名` | - | Register the current player. | +| `/自走棋加AI战队` | - | Add local deterministic AI teams for testing. | +| `/自走棋开赛` | - | Start the event from registration. | +| `/自走棋状态` | - | Show the current event state. | +| `/自走棋档案` | - | Show archived event information. | +| `/选1` ... `/选10` | - | Draft coaches, players, or shop cards depending on phase. | +| `/刷新` | - | Refresh the shop. | +| `/锁定` | - | Lock or unlock the shop. | +| `/阵容` | - | Show lineup, bench, coach, gold, and synergies. | +| `/赛程` | - | Show the current event schedule. | +| `/升级教练` | - | Upgrade the team's coach level when rules allow it. | +| `/上阵 备战编号 [首发位]` | - | Move a bench player into the starting lineup. | +| `/下阵 首发位` | - | Move a starting player out when rules allow it. | +| `/出售 备战编号` | - | Sell a bench player. | +| `/战术 火力|稳定|残局` | - | Set the team's tactical focus. | +| `/结束回合` | - | Mark readiness and advance when required players are ready. | + +## Notes + +- Commands must be sent in the configured WeChat group and normally mention the + bot, depending on deployment configuration. +- OCR whitespace loss is tolerated for selected compact forms such as + `/steam时长Dota2` and `/21点开始100`. +- Real profiles, Steam IDs, person context, message payloads, and secrets are + never stored in this repository. diff --git a/docs/command-routing.md b/docs/command-routing.md index 1c3fab8..3b0270e 100644 --- a/docs/command-routing.md +++ b/docs/command-routing.md @@ -1,7 +1,7 @@ # Command Registration And Execution Paths Status: authoritative local registration and routing contract for -`alpha 0.6.x`. +`beta 1.0.x`. ## Three Execution Paths @@ -46,7 +46,7 @@ because each bubble position still produces its own `IncomingMessage`. Changed pixels force fresh OCR. The cache is bounded and periodically revalidated. -For the three local plugins added in `alpha 0.6.1.1015`, including bilingual +For the local plugins introduced during the 0.6.x line, including bilingual commands, person identity limitations and atomic single-player game settlement, see [local plugin rules](local-plugins-0.6.1.md). @@ -146,7 +146,8 @@ descriptors unless they are strictly Kernel-only. The current official operational commands are: - `/状态` and `/status`: server, Edge, OCR, and queue status. -- `/version`: installed JWeBot package versions. +- `/version`: installed JWeBot package versions plus the latest changelog date + and summary. - `/debug`: recent privacy-safe telemetry p50/p95/max summary. These commands delegate to Kernel-owned service profiles through generated diff --git a/docs/plugin-contract.md b/docs/plugin-contract.md index fca0e5d..7cce0f3 100644 --- a/docs/plugin-contract.md +++ b/docs/plugin-contract.md @@ -1,6 +1,6 @@ # Plugin Contract -Status: authoritative for the `alpha 0.6.x` extension API. +Status: authoritative for the `beta 1.0.x` extension API. ## Scope diff --git a/docs/project-rules.md b/docs/project-rules.md index ad388af..3798f24 100644 --- a/docs/project-rules.md +++ b/docs/project-rules.md @@ -6,9 +6,11 @@ exception. ## Release Discipline -- Version format is `alpha X.Y.Z.MMDD`. -- Patch changes increment `Z`; minor version changes require explicit user - approval. +- Version format is `beta X.Y.Z.MMDD` for current beta releases. +- Python package versions use the matching PEP 440 beta form, such as + `X.Y.Zb1+MMDD`. +- Patch changes increment `Z`; minor, major, or stable-release changes require + explicit user approval. - A release change must update: - `VERSION`; - root `pyproject.toml`; diff --git a/docs/telemetry.md b/docs/telemetry.md index f8574c8..3041944 100644 --- a/docs/telemetry.md +++ b/docs/telemetry.md @@ -1,6 +1,6 @@ # Runtime Telemetry And ACK Semantics -Status: local instrumentation contract for `alpha 0.6.x`. +Status: local instrumentation contract for `beta 1.0.x`. ## What ACK Means diff --git a/docs/versioning.md b/docs/versioning.md index 5e6dd55..05b8836 100644 --- a/docs/versioning.md +++ b/docs/versioning.md @@ -1,20 +1,24 @@ # Versioning -JWeBot uses an alpha version string: +JWeBot uses a human-readable product version string: ```text -alpha X.Y.Z.MMDD +beta X.Y.Z.MMDD ``` Rules: -- `alpha` means the public API and deployment process may still change. +- `beta` means the project has passed the local, staging, privacy, and + production-safety gates expected for wider testing, while still allowing + controlled breaking changes before a stable release. - `X.Y.Z` is the project version. - `MMDD` is the delivery date. +- Python package versions use PEP 440 pre-release form. For beta builds, + `beta 1.0.0.1016` maps to `1.0.0b1+1016`. - Normal small updates increment only the patch version, for example - `alpha 0.0.1.1014` to `alpha 0.0.2.1014`. -- Minor versions such as `0.1.x` require explicit user review and milestone - approval. + `beta 1.0.0.1016` to `beta 1.0.1.1016`. +- Minor, major, or stable-release changes require explicit user review and + milestone approval. - Local repository migration does not imply a production deployment. - Production services must not be changed unless the operator explicitly asks for deployment or runtime verification. diff --git a/packages/jwebot-config/pyproject.toml b/packages/jwebot-config/pyproject.toml index 3396cee..63dd3ce 100644 --- a/packages/jwebot-config/pyproject.toml +++ b/packages/jwebot-config/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-config" -version = "0.6.11a0+1015" +version = "1.0.0b1+1016" description = "Profile-based configuration compiler for JWeBot" requires-python = ">=3.9" dependencies = [ diff --git a/packages/jwebot-config/src/jwebot_config/__init__.py b/packages/jwebot-config/src/jwebot_config/__init__.py index a52de0b..cea55d4 100644 --- a/packages/jwebot-config/src/jwebot_config/__init__.py +++ b/packages/jwebot-config/src/jwebot_config/__init__.py @@ -36,4 +36,4 @@ __all__ = [ "write_default_profile", ] -__version__ = "0.6.11a0+1015" +__version__ = "1.0.0b1+1016" diff --git a/packages/jwebot-extension-host/pyproject.toml b/packages/jwebot-extension-host/pyproject.toml index 8e92ec6..58bc83f 100644 --- a/packages/jwebot-extension-host/pyproject.toml +++ b/packages/jwebot-extension-host/pyproject.toml @@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-extension-host" -version = "0.6.11a0+1015" +version = "1.0.0b1+1016" description = "Single-release, single-invocation process host for JWeBot extensions" requires-python = ">=3.9" dependencies = [ - "jwebot-sdk==0.6.11a0+1015", - "jwebot-kernel==0.6.11a0+1015", + "jwebot-sdk==1.0.0b1+1016", + "jwebot-kernel==1.0.0b1+1016", ] [project.scripts] diff --git a/packages/jwebot-extension-host/src/jwebot_extension_host/__init__.py b/packages/jwebot-extension-host/src/jwebot_extension_host/__init__.py index 11a90f9..4e1cb7a 100644 --- a/packages/jwebot-extension-host/src/jwebot_extension_host/__init__.py +++ b/packages/jwebot-extension-host/src/jwebot_extension_host/__init__.py @@ -16,4 +16,4 @@ __all__ = [ "process_request", ] -__version__ = "0.6.11a0+1015" +__version__ = "1.0.0b1+1016" diff --git a/packages/jwebot-kernel/pyproject.toml b/packages/jwebot-kernel/pyproject.toml index 7a0b727..c50887c 100644 --- a/packages/jwebot-kernel/pyproject.toml +++ b/packages/jwebot-kernel/pyproject.toml @@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-kernel" -version = "0.6.11a0+1015" +version = "1.0.0b1+1016" description = "Stable routing and extension authority for JWeBot" requires-python = ">=3.9" dependencies = [ - "jwebot-config==0.6.11a0+1015", - "jwebot-sdk==0.6.11a0+1015", - "jwebot-official-extensions==0.6.11a0+1015", + "jwebot-config==1.0.0b1+1016", + "jwebot-sdk==1.0.0b1+1016", + "jwebot-official-extensions==1.0.0b1+1016", "tomli>=2; python_version < '3.11'", ] diff --git a/packages/jwebot-kernel/src/jwebot_kernel/__init__.py b/packages/jwebot-kernel/src/jwebot_kernel/__init__.py index 7ca75a3..e893cf7 100644 --- a/packages/jwebot-kernel/src/jwebot_kernel/__init__.py +++ b/packages/jwebot-kernel/src/jwebot_kernel/__init__.py @@ -107,4 +107,4 @@ __all__ = [ "verify_installed_release_signature", ] -__version__ = "0.6.11a0+1015" +__version__ = "1.0.0b1+1016" diff --git a/packages/jwebot-official-extensions/pyproject.toml b/packages/jwebot-official-extensions/pyproject.toml index 1304257..8489b77 100644 --- a/packages/jwebot-official-extensions/pyproject.toml +++ b/packages/jwebot-official-extensions/pyproject.toml @@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-official-extensions" -version = "0.6.11a0+1015" +version = "1.0.0b1+1016" description = "Reviewed local command adapters and broker implementation for JWeBot" requires-python = ">=3.9" dependencies = [ - "jwebot-sdk==0.6.11a0+1015", + "jwebot-sdk==1.0.0b1+1016", ] [tool.setuptools.packages.find] diff --git a/packages/jwebot-official-extensions/src/jwebot_official_extensions/__init__.py b/packages/jwebot-official-extensions/src/jwebot_official_extensions/__init__.py index c00738c..d3ce791 100644 --- a/packages/jwebot-official-extensions/src/jwebot_official_extensions/__init__.py +++ b/packages/jwebot-official-extensions/src/jwebot_official_extensions/__init__.py @@ -90,4 +90,4 @@ __all__ = [ "render_feature_list", ] -__version__ = "0.6.11a0+1015" +__version__ = "1.0.0b1+1016" diff --git a/packages/jwebot-official-extensions/src/jwebot_official_extensions/local_commands.py b/packages/jwebot-official-extensions/src/jwebot_official_extensions/local_commands.py index 063b698..efe7569 100644 --- a/packages/jwebot-official-extensions/src/jwebot_official_extensions/local_commands.py +++ b/packages/jwebot-official-extensions/src/jwebot_official_extensions/local_commands.py @@ -11,6 +11,7 @@ import subprocess import time from collections import Counter from datetime import datetime, timezone +from pathlib import Path from typing import Any, Callable from zoneinfo import ZoneInfo @@ -26,6 +27,7 @@ BEIJING_TIMEZONE = ZoneInfo("Asia/Shanghai") DICE_PATTERN = re.compile(r"^(?:(\d{1,2})[dD](\d{1,3}))?$") RANDOM_NUMBER_PATTERN = re.compile(r"^(-?\d{1,6})\s+(-?\d{1,6})$") MULTI_REPLY_MARKER = "\x1eJWEBOT_MULTI_REPLY_V1\x1e" +CHANGELOG_HEADING = re.compile(r"^##\s+(.+?)(?:\s+-\s+(\d{4}-\d{2}-\d{2}))?\s*$") class LocalCommandError(RuntimeError): @@ -401,13 +403,75 @@ class LocalCommandEngine: return "unknown" return str(getattr(module, "__version__", "unknown")) + @staticmethod + def changelog_candidates() -> list[Path]: + candidates: list[Path] = [] + module_path = Path(__file__).resolve() + for parent in (module_path.parent, *module_path.parents): + candidates.append(parent / "CHANGELOG.md") + candidates.append(Path.cwd() / "CHANGELOG.md") + seen: set[Path] = set() + unique: list[Path] = [] + for candidate in candidates: + if candidate in seen: + continue + seen.add(candidate) + unique.append(candidate) + return unique + + @classmethod + def latest_changelog(cls) -> dict[str, str]: + for path in cls.changelog_candidates(): + if not path.is_file(): + continue + text = path.read_text(encoding="utf-8") + lines = text.splitlines() + for index, line in enumerate(lines): + match = CHANGELOG_HEADING.match(line) + if not match: + continue + version = match.group(1).strip() + updated_at = (match.group(2) or "").strip() + bullet_parts: list[str] = [] + collecting = False + for item in lines[index + 1 :]: + if item.startswith("## "): + break + if item.startswith("- "): + if collecting: + break + collecting = True + bullet_parts.append(item[2:].strip()) + continue + if collecting: + if item.startswith(" "): + bullet_parts.append(item.strip()) + continue + if not item.strip(): + break + summary = normalize_text(" ".join(bullet_parts)) + return { + "version": version, + "updated_at": updated_at or "unknown", + "summary": summary or "暂无更新摘要", + } + return { + "version": "unknown", + "updated_at": "unknown", + "summary": "未找到 CHANGELOG.md", + } + def jwebot_version(self) -> str: + changelog = self.latest_changelog() return ( "JWeBot 版本:" f"kernel {self.package_version('jwebot_kernel')}," f"sdk {self.package_version('jwebot_sdk')}," "official " - f"{self.package_version('jwebot_official_extensions')}" + f"{self.package_version('jwebot_official_extensions')}\n" + f"最新版本:{changelog['version']}\n" + f"更新时间:{changelog['updated_at']}\n" + f"更新摘要:{changelog['summary']}" ) @staticmethod diff --git a/packages/jwebot-sdk/pyproject.toml b/packages/jwebot-sdk/pyproject.toml index 409298f..eb18497 100644 --- a/packages/jwebot-sdk/pyproject.toml +++ b/packages/jwebot-sdk/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "jwebot-sdk" -version = "0.6.11a0+1015" +version = "1.0.0b1+1016" description = "Typed, capability-limited extension API for JWeBot plugins" requires-python = ">=3.9" dependencies = [] diff --git a/packages/jwebot-sdk/src/jwebot_sdk/__init__.py b/packages/jwebot-sdk/src/jwebot_sdk/__init__.py index 90224d1..72156ab 100644 --- a/packages/jwebot-sdk/src/jwebot_sdk/__init__.py +++ b/packages/jwebot-sdk/src/jwebot_sdk/__init__.py @@ -38,4 +38,4 @@ __all__ = [ "SingleGroupContext", ] -__version__ = "0.6.11a0+1015" +__version__ = "1.0.0b1+1016" diff --git a/pyproject.toml b/pyproject.toml index 7b103a6..3664cd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.jwebot] -release = "alpha 0.6.11.1015" +release = "beta 1.0.0.1016" production_deployments_enabled_by_default = false [tool.jwebot.workspace] diff --git a/tests/test_deployment_scripts.py b/tests/test_deployment_scripts.py index 2b1224f..c5d9943 100644 --- a/tests/test_deployment_scripts.py +++ b/tests/test_deployment_scripts.py @@ -50,6 +50,8 @@ class DeploymentScriptTests(unittest.TestCase): def test_user_installer_owns_the_complete_adaptive_runtime(self): source = USER_INSTALLER.read_text(encoding="utf-8") for required in ( + "CHANGELOG.md", + "VERSION", "wechat_local_ocr.py", "wechat_health_watch.py", "wechat_adaptive_recorder.py", diff --git a/tests/test_jwebot_edge.py b/tests/test_jwebot_edge.py index a0c61d3..a4972b1 100644 --- a/tests/test_jwebot_edge.py +++ b/tests/test_jwebot_edge.py @@ -867,6 +867,9 @@ class LedgerAndApplicationTests(unittest.TestCase): self.assertEqual(version["route"], "local") self.assertIn("JWeBot 版本", version["text"]) self.assertIn("kernel", version["text"]) + self.assertIn("最新版本:beta 1.0.0.1016", version["text"]) + self.assertIn("更新时间:2026-10-16", version["text"]) + self.assertIn("更新摘要:Promote JWeBot", version["text"]) self.assertEqual(debug["route"], "local") self.assertIn("调试埋点", debug["text"]) self.assertEqual(balance["route"], "local") diff --git a/tools/check-config.sh b/tools/check-config.sh index 0007456..7471c5a 100755 --- a/tools/check-config.sh +++ b/tools/check-config.sh @@ -5,10 +5,10 @@ cd "$(dirname "$0")/.." version=$(cat VERSION) case "$version" in - alpha\ [0-9]*.[0-9]*.[0-9]*.[0-9][0-9][0-9][0-9]) + beta\ [0-9]*.[0-9]*.[0-9]*.[0-9][0-9][0-9][0-9]) ;; *) - echo "VERSION must match: alpha X.Y.Z.MMDD" >&2 + echo "VERSION must match: beta X.Y.Z.MMDD" >&2 exit 1 ;; esac diff --git a/tools/check-packages.sh b/tools/check-packages.sh index 105acb4..bf0aa0f 100755 --- a/tools/check-packages.sh +++ b/tools/check-packages.sh @@ -4,7 +4,16 @@ set -eu cd "$(dirname "$0")/.." release=$(cat VERSION) -version=${release#alpha } +case "$release" in + beta\ *) + stage=b + version=${release#beta } + ;; + *) + echo "Cannot derive package version from VERSION" >&2 + exit 1 + ;; +esac old_ifs=$IFS IFS=. set -- $version @@ -13,7 +22,7 @@ if [ "$#" -ne 4 ]; then echo "Cannot derive package version from VERSION" >&2 exit 1 fi -package_version="$1.$2.$3a0+$4" +package_version="$1.$2.$3${stage}1+$4" for path in \ packages/jwebot-config/pyproject.toml \