release: public alpha 0.6.0 baseline

This commit is contained in:
JWeBot Contributors
2026-10-15 03:58:31 +08:00
commit d4242ae07c
238 changed files with 37724 additions and 0 deletions
@@ -0,0 +1,273 @@
"""Ownership map for Kernel commands and reviewed local extensions."""
from __future__ import annotations
from dataclasses import dataclass
LOCAL_COMMAND_ALIASES = {
"功能列表": "feature_list",
"帮助": "feature_list",
"help": "feature_list",
"丢骰子": "dice",
"骰子": "dice",
"丢骰子挑战": "dice_challenge",
"骰子挑战": "dice_challenge",
"翻硬币": "coin",
"随机数": "random_number",
"抽签": "draw_lot",
"今日运势": "daily_fortune",
"猜数字": "guess_number",
"猜": "guess_number",
"石头剪刀布": "rps",
"记住": "remember",
"我的记忆": "my_memory",
"忘记": "forget_memory",
"人物记忆": "person_memory",
"记忆帮助": "memory_help",
"扫码排行": "scan_ranking",
"扫码榜": "scan_ranking",
"今日扫码": "scan_ranking",
"复读榜": "repeat_ranking",
"复读": "repeat_ranking",
"查记录": "history_search",
"历史搜索": "history_search",
"状态": "local_status",
"status": "server_status",
"version": "jwebot_version",
"debug": "telemetry_debug",
"余额": "deepseek_balance",
"steam": "steam_friends",
}
@dataclass(frozen=True)
class LocalExtensionDescriptor:
extension_id: str
author: str
description: str
help_entries: tuple[str, ...]
command_kinds: tuple[str, ...]
@property
def directory(self) -> str:
return self.author.casefold()
@property
def commands(self) -> tuple[str, ...]:
owned = set(self.command_kinds)
return tuple(
f"/{alias}"
for alias, kind in LOCAL_COMMAND_ALIASES.items()
if kind in owned
)
@dataclass(frozen=True)
class KernelCommandDescriptor:
description: str
help_entries: tuple[str, ...]
command_kinds: tuple[str, ...]
OFFICIAL_AUTHOR = "official"
JWEBOT_AUTHOR = "jwebot"
DIRECT_KERNEL_COMMANDS = (
KernelCommandDescriptor(
description="查看由插件元数据自动生成的功能列表",
help_entries=("/功能列表(别名 /帮助、/help)",),
command_kinds=("feature_list",),
),
KernelCommandDescriptor(
description="查看 DeepSeek 账户余额",
help_entries=("/余额",),
command_kinds=("deepseek_balance",),
),
)
DIRECT_KERNEL_COMMAND_KINDS = frozenset(
kind
for descriptor in DIRECT_KERNEL_COMMANDS
for kind in descriptor.command_kinds
)
LOCAL_EXTENSIONS = (
LocalExtensionDescriptor(
extension_id="person-memory",
author=OFFICIAL_AUTHOR,
description="管理个人和同群人物记忆",
help_entries=(
"/记住 内容;/我的记忆;/忘记 关键词或全部;"
"/人物记忆 [显示名]",
),
command_kinds=(
"remember",
"my_memory",
"forget_memory",
"person_memory",
"memory_help",
),
),
LocalExtensionDescriptor(
extension_id="server-status",
author=OFFICIAL_AUTHOR,
description="服务器状态",
help_entries=("/状态;/status",),
command_kinds=("local_status", "server_status"),
),
LocalExtensionDescriptor(
extension_id="jwebot-version",
author=OFFICIAL_AUTHOR,
description="JWeBot 版本",
help_entries=("/version",),
command_kinds=("jwebot_version",),
),
LocalExtensionDescriptor(
extension_id="debug-telemetry",
author=OFFICIAL_AUTHOR,
description="埋点 p50/p95",
help_entries=("/debug",),
command_kinds=("telemetry_debug",),
),
LocalExtensionDescriptor(
extension_id="dice",
author=JWEBOT_AUTHOR,
description="骰子和多人骰子挑战",
help_entries=(
"/丢骰子 [NdM]",
"/丢骰子挑战 [5d6|5d20|状态|结算|战绩|结束]",
),
command_kinds=("dice", "dice_challenge"),
),
LocalExtensionDescriptor(
extension_id="coin",
author=JWEBOT_AUTHOR,
description="抛一枚硬币",
help_entries=("/翻硬币",),
command_kinds=("coin",),
),
LocalExtensionDescriptor(
extension_id="random-number",
author=JWEBOT_AUTHOR,
description="在指定整数范围内取随机数",
help_entries=("/随机数 最小值 最大值",),
command_kinds=("random_number",),
),
LocalExtensionDescriptor(
extension_id="draw-lot",
author=JWEBOT_AUTHOR,
description="抽取一条本地签文",
help_entries=("/抽签",),
command_kinds=("draw_lot",),
),
LocalExtensionDescriptor(
extension_id="daily-fortune",
author=JWEBOT_AUTHOR,
description="生成当天稳定一致的运势",
help_entries=("/今日运势",),
command_kinds=("daily_fortune",),
),
LocalExtensionDescriptor(
extension_id="guess-number",
author=JWEBOT_AUTHOR,
description="群内持久化猜数字游戏",
help_entries=(
"/猜数字 开始 [上限];/猜 数字;/猜数字 [状态|结束]",
),
command_kinds=("guess_number",),
),
LocalExtensionDescriptor(
extension_id="rock-paper-scissors",
author=JWEBOT_AUTHOR,
description="多人石头剪刀布游戏",
help_entries=(
"/石头剪刀布 [开始|加入|出 选择|状态|结算|结束]",
),
command_kinds=("rps",),
),
LocalExtensionDescriptor(
extension_id="scan-ranking",
author=JWEBOT_AUTHOR,
description="查看北京时间今日扫码排行",
help_entries=("/扫码排行",),
command_kinds=("scan_ranking",),
),
LocalExtensionDescriptor(
extension_id="repeat-ranking",
author=JWEBOT_AUTHOR,
description="查看北京时间今日复读排行",
help_entries=("/复读榜",),
command_kinds=("repeat_ranking",),
),
LocalExtensionDescriptor(
extension_id="history-search",
author=JWEBOT_AUTHOR,
description="搜索本地群聊文字记录",
help_entries=("/查记录 关键词",),
command_kinds=("history_search",),
),
LocalExtensionDescriptor(
extension_id="steam-presence",
author=JWEBOT_AUTHOR,
description="Steam 状态与时长",
help_entries=(
"/steam;/steam时长 游戏[、玩家]",
),
command_kinds=("steam_friends",),
),
)
def extension_for_kind(kind: str) -> LocalExtensionDescriptor | None:
return next(
(
extension
for extension in LOCAL_EXTENSIONS
if kind in extension.command_kinds
),
None,
)
def render_feature_list() -> str:
lines = ["功能列表(由内核和插件描述自动生成)"]
for descriptor in DIRECT_KERNEL_COMMANDS:
lines.append(
f"[内核] {descriptor.description}:"
+ ";".join(descriptor.help_entries)
)
for descriptor in LOCAL_EXTENSIONS:
lines.append(
f"[{descriptor.author}/{descriptor.extension_id}] "
f"{descriptor.description}:"
+ ";".join(descriptor.help_entries)
)
lines.extend(
(
"[DeepSeek] 普通 @JWeBot 消息走本地直连 DeepSeek",
"[OpenClaw] @JWeBot #任务进入 OpenClaw",
)
)
return "\n".join(lines)
def _validate_inventory() -> None:
extension_kinds = [
kind
for extension in LOCAL_EXTENSIONS
for kind in extension.command_kinds
]
if len(extension_kinds) != len(set(extension_kinds)):
raise RuntimeError("local extension command ownership overlaps")
known_kinds = set(LOCAL_COMMAND_ALIASES.values())
if set(extension_kinds) | DIRECT_KERNEL_COMMAND_KINDS != known_kinds:
raise RuntimeError("local command inventory is incomplete")
if set(extension_kinds) & DIRECT_KERNEL_COMMAND_KINDS:
raise RuntimeError("Kernel commands cannot be extension-owned")
if any(
not extension.description or not extension.help_entries
for extension in LOCAL_EXTENSIONS
):
raise RuntimeError("local extensions must provide help metadata")
_validate_inventory()