Skip to content

feat: 新增通用 TRPG 扩展与属性 Hook - #1791

Open
MintCider wants to merge 6 commits into
sealdice:masterfrom
MintCider:feat/trpg-st-hooks
Open

MintCider wants to merge 6 commits into
sealdice:masterfrom
MintCider:feat/trpg-st-hooks

Conversation

@MintCider

@MintCider MintCider commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

概述

新增默认启用的 trpg 内置扩展,统一承载 .st.sn.team.sn.team 的既有实现及数据结构完整迁移到该扩展。

架构设计

  • trpg.st 使用独立的解析、事务与渲染流程,不依赖 coc7.stdnd5e.stCmdStOverrideInfo
  • 提供命令、解析、求值、提交、展示和导出阶段的 Hook;提交前的拒绝或异常会整批回滚。
  • 未注册 Hook 时,属性数据行为与通用旧 .st 保持一致;回复使用独立的 TRPG:* 文本模板。
  • 指令提供者继续遵循 relatedExt 优先级,现有 COC7 与 DND5E 模板仍使用各自的 .st

插件接入

新规则模板可声明 relatedExt: [trpg, my-rule],规则插件通过 seal.trpg.st.registerHooks 注册回调,并可按规则系统限定作用范围,实现属性上下限、操作跳过、整批拒绝及输出定制。

验证

  • go test ./dice -count=1
  • 相关测试通过 go test -race
  • golangci-lint v2.4.0:0 issues

Summary by Sourcery

引入一个新的内置、规则中立的 TRPG 扩展,该扩展负责通用角色卡和团卡相关指令,并为插件提供可挂钩的属性工作流。

New Features:

  • 添加内置扩展 trpg,默认启用,提供通用的 .st.sn.team 指令。
  • 引入新的 TRPG 属性指令流水线(trpg.st),在解析、评估、提交、展示和导出等阶段提供挂钩点。
  • 暴露 seal.trpg.st JavaScript API,用于注册挂钩、构造属性值和操作,以及清理挂钩。
  • 添加 TRPG 专用文本模板和帮助元数据,用于属性操作及拒绝场景。
  • 提供 TRPG 文档,说明用法、挂钩注册、事务语义以及数值构造器。

Enhancements:

  • 优化指令提供者的选择逻辑,使规则模板可以通过 relatedExt 选用 trpg.st,同时现有的 COC7 和 DND5E 模板继续使用各自的 .st
  • 确保在未注册任何挂钩时,通用 TRPG 属性行为与旧版 .st 语义一致,并使用相互隔离的回复模板。
  • 扩展扩展元数据(ExtInfo),为每个扩展存储 TRPG 角色卡挂钩,以保证 JS 重载行为可预测。

Documentation:

  • 创建 docs/trpg.md 文档,记录 TRPG 扩展、指令路由、挂钩阶段、事务性语义以及 JavaScript 集成 API。

Tests:

  • 添加内部测试,验证 trpg 扩展拥有中立的 .st.sn.team 指令,并且旧有注册已从 logcore 中移除。
  • 添加测试,确保在无挂钩时 trpg.st 行为与通用 COC7 .st 一致,并验证挂钩可以约束数值并在拒绝时执行原子回滚。
  • 添加测试,验证 JavaScript 挂钩注册、挂钩调用时的 panic 处理,以及不同跑团系统下指令提供者的排序行为。
Original summary in English

Summary by Sourcery

Introduce a new built-in, rule-neutral TRPG extension that owns generic character sheet and group card commands and adds a hookable attribute workflow for plugins.

New Features:

  • Add the trpg built-in extension that provides generic .st, .sn, and .team commands and is active by default.
  • Introduce a new TRPG attribute command pipeline (trpg.st) with hook points for parsing, evaluation, commit, display, and export.
  • Expose seal.trpg.st JavaScript APIs for registering hooks, constructing attribute values and operations, and clearing hooks.
  • Add TRPG-specific text templates and help metadata for attribute operations and rejections.
  • Provide TRPG documentation describing usage, hook registration, transaction semantics, and value constructors.

Enhancements:

  • Refine command provider selection so rule templates can opt into trpg.st via relatedExt while existing COC7 and DND5E templates continue using their own .st.
  • Ensure generic TRPG attribute behavior matches legacy .st semantics when no hooks are registered, with isolated reply templates.
  • Extend extension metadata (ExtInfo) to store TRPG sheet hooks per extension for predictable JS reload behavior.

Documentation:

  • Create docs/trpg.md documenting the TRPG extension, command routing, hook stages, transactional semantics, and JavaScript integration APIs.

Tests:

  • Add internal tests validating that the trpg extension owns neutral .st, .sn, and .team commands and that older registrations are removed from log and core.
  • Add tests to ensure trpg.st without hooks matches generic COC7 .st behavior and that hooks can clamp values and enforce atomic rollback on rejection.
  • Add tests verifying JavaScript hook registration, panic handling in hook invocations, and command provider ordering for different game systems.

@sourcery-ai

sourcery-ai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

新增一个内置且默认自动启用的 trpg 扩展,用于集中处理通用 TRPG 指令(.st.sn.team),提供可挂钩的事务型属性系统,将现有的 .sn.team 实现迁移到该扩展中,接好 JS API 和文本模板,并更新指令路由与测试以确保兼容性和钩子行为正确。

带钩子与事务性回滚的 trpg.st 指令生命周期序列图

sequenceDiagram
  actor User
  participant Dice
  participant CmdTrpgSt as getCmdTrpgSt.Solve
  participant TrpgStHookRunner as trpgStHookRunner
  participant ExtensionHooks as TrpgStHooks

  User->>Dice: .st hp+1
  Dice->>CmdTrpgSt: dispatch Solve(ctx, msg, cmdArgs)

  CmdTrpgSt->>TrpgStHookRunner: newTrpgStHookRunner(mctx, tmpl.Name)
  CmdTrpgSt->>TrpgStHookRunner: beforeCommand(event)
  TrpgStHookRunner-->>CmdTrpgSt: error or rejectReason
  alt rejected in beforeCommand
    CmdTrpgSt->>Dice: trpgStReplyRejected(mctx, msg, err)
    CmdTrpgSt-->>User: CmdExecuteResult{Matched:true, Solved:true}
  else proceed
    CmdTrpgSt->>CmdTrpgSt: cmdStReadOrMod(mctx, tmpl, input)
    CmdTrpgSt->>TrpgStHookRunner: afterParse(event)

    loop each TrpgStOperation
      CmdTrpgSt->>TrpgStHookRunner: beforeApply(event, operation)
      TrpgStHookRunner->>ExtensionHooks: BeforeApply(event, operation)
      ExtensionHooks-->>TrpgStHookRunner: maybe Skip/RejectReason

      CmdTrpgSt->>CmdTrpgSt: evaluate Operand / ProposedValue
      CmdTrpgSt->>TrpgStHookRunner: afterEvaluate(event, operation)
      TrpgStHookRunner->>ExtensionHooks: AfterEvaluate(event, operation)
    end

    CmdTrpgSt->>TrpgStHookRunner: beforeCommit(event)
    TrpgStHookRunner-->>CmdTrpgSt: error or rejectReason
    alt rejected in beforeCommit
      CmdTrpgSt->>CmdTrpgSt: snapshot.restore(attrs, mctx.Player)
      CmdTrpgSt->>Dice: trpgStReplyRejected(mctx, msg, err)
    else commit
      CmdTrpgSt->>CmdTrpgSt: apply changes to AttributesItem
      CmdTrpgSt->>TrpgStHookRunner: afterCommit(event)
      TrpgStHookRunner->>ExtensionHooks: AfterCommit(event)
      CmdTrpgSt->>Dice: ReplyToSender(mctx, msg, text+event.ReplySuffix)
    end
  end
Loading

File-Level Changes

Change Details Files
引入一个新的内置 trpg 扩展,负责通用 .st.sn.team 指令,并默认自动激活。
  • trpg 注册为官方、默认自动启用的扩展,为 stsnteam 指令提供独立的 CmdMap。
  • 更新全局扩展注册逻辑以包含新的 trpg 扩展。
  • 确保旧的 logcore 扩展不再注册 snteam,并通过测试验证迁移结果。
dice/ext_trpg.go
dice/ext.go
dice/ext_log.go
dice/ext_core.go
dice/ext_trpg_internal_test.go
实现一个新的 TRPG 角色卡(trpg.st)指令处理流水线,支持快照、钩子和事务型属性修改,并与 coc7.st/dnd5e.st 解耦。
  • 定义 getCmdTrpgSt,提供 .st 子指令(show、export、del、clr、fmt、通用 set/mod),并与属性存储及卡片类型处理集成。
  • 引入快照和恢复辅助方法,在错误或钩子拒绝时支持属性和玩家名称修改的一次性回滚。
  • 新增 trpgStHookRunner 来在相关扩展之间编排钩子的调用,覆盖指令、解析、应用、求值、提交、展示和导出阶段。
  • 实现 set 和 mod 应用辅助函数,遵守钩子、别名解析、默认值、计算值以及跳过/拒绝语义。
  • 处理简化的卡片名解析、卡片格式化,并与现有属性工具集成,在没有钩子时保持与旧版 .st 一致的行为。
dice/ext_trpg_st.go
为 TRPG 角色卡操作增加钩子 API,通过 seal.trpg.st 暴露给 JS,包括值与操作类型以及安全的钩子执行。
  • 定义 TrpgStValueTrpgStOperationTrpgStCommandEventTrpgStRenderEvent 作为 JS 可绑定类型,用于表示 DiceScript 的值、操作和事件。
  • 实现 registerTrpgStHooks,支持按扩展存储钩子(ExtInfo.TrpgStHooks)、系统范围控制,以及基于 relatedExt 与激活图的扩展解析。
  • 在 JS VM 初始化中,通过 seal.trpg.st 暴露构造函数(newIntValuenewFloatValuenewStringValuenewComputedValuenewOperation)和钩子注册/清理函数。
  • 添加支持 panic 安全的钩子调用(invokeTrpgStHook),包含 JS 启用检查和专用的 panic 错误类型,用于日志和错误传播。
  • 提供测试以验证 JavaScript 钩子注册、值钳制、删除跳过、原子回滚以及 panic 处理。
dice/dice.go
dice/dice_jsvm.go
dice/ext_trpg_st_hooks.go
dice/ext_trpg_internal_test.go
.sn(团卡)指令重构到 trpg 扩展中,同时保持原有行为和错误处理。
  • ErrGroupCardOverlongSetPlayerGroupCardByTemplate 移动到专门的 TRPG SN 模块。
  • trpg 内部重新实现 sn 指令(getCmdTrpgSn),保留帮助文本、权限警告、模板选择、长度检查以及自定义表达式支持。
  • log 扩展中移除旧的 sn 指令及其辅助函数,并改为通过 trpg 路由 .sn
  • trpg.st 处理中,通过 ctx.Player.AutoSetNameTemplate 保持属性变化后团卡名称的自动重置行为。
dice/ext_log.go
dice/ext_trpg_sn.go
dice/ext_trpg_st.go
为新的角色卡与钩子行为添加 TRPG 专用文本模板和文档。
  • 新增 TRPG 文本模板组,包含属性设置、删除、清空、增减、列表以及拒绝消息,并附相应的帮助元数据。
  • 将 TRPG 模板接入基础文本映射和帮助信息初始化流程。
  • 添加 docs/trpg.md,描述 trpg 扩展、钩子注册 API、执行阶段、拒绝与回滚语义以及 JS 构造函数。
dice/ext_trpg_text.go
dice/config.go
docs/trpg.md
调整指令提供者选择逻辑,使规则模板可以通过 relatedExt 选择 trpg.st,同时保持现有 COC7/DND5E 行为。
  • 使用游戏系统模板中的 relatedExt 信息来决定哪个扩展为给定系统提供 .st,确保 COC7/DND5E 模板继续使用各自的 .st 实现。
  • 确保在 relatedExt 中包含 trpg 的模板优先选择 trpg.st 作为角色卡提供者。
  • 添加测试以验证在不同系统/relatedExt 组合下指令扩展排序和 .st 提供者选择。
dice/ext_trpg_st_hooks.go
dice/ext_trpg_internal_test.go

Tips and commands

Interacting with Sourcery

  • 触发新评审: 在 Pull Request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub Issue: 通过回复评审评论的方式,让 Sourcery 从该评论创建一个 Issue。你也可以在评审评论中回复 @sourcery-ai issue 来从该评论创建 Issue。
  • 生成 Pull Request 标题: 在 Pull Request 标题中任意位置写上 @sourcery-ai,即可在任意时间生成标题。你也可以在 Pull Request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 Pull Request 摘要: 在 Pull Request 描述中任意位置写上 @sourcery-ai summary,即可在你想要的位置生成 PR 摘要。你也可以在 Pull Request 中评论 @sourcery-ai summary 来在任意时间(重新)生成摘要。
  • 生成评审者指南: 在 Pull Request 中评论 @sourcery-ai guide,即可在任意时间(重新)生成评审者指南。
  • 解决所有 Sourcery 评论: 在 Pull Request 中评论 @sourcery-ai resolve,即可标记所有 Sourcery 评论为已解决。如果你已经处理完所有评论并且不想再看到它们,这会很有用。
  • 撤销所有 Sourcery 评审: 在 Pull Request 中评论 @sourcery-ai dismiss,即可撤销所有现有的 Sourcery 评审。尤其在你希望从头开始新一轮评审时非常有用——别忘了再评论 @sourcery-ai review 来触发新评审!

Customizing Your Experience

访问你的 dashboard 以:

  • 启用或禁用评审功能,例如 Sourcery 生成的 Pull Request 摘要、评审者指南等。
  • 更改评审语言。
  • 添加、删除或编辑自定义评审指令。
  • 调整其他评审设置。

Getting Help

Original review guide in English

Reviewer's Guide

Adds a new built-in, auto-active trpg extension that centralizes generic TRPG commands (.st, .sn, .team) with a hookable, transactional attribute system, moves existing .sn and .team implementations into this extension, wires JS APIs and text templates, and updates command routing and tests to ensure compatibility and hook behavior.

Sequence diagram for trpg.st command lifecycle with hooks and transactional rollback

sequenceDiagram
  actor User
  participant Dice
  participant CmdTrpgSt as getCmdTrpgSt.Solve
  participant TrpgStHookRunner as trpgStHookRunner
  participant ExtensionHooks as TrpgStHooks

  User->>Dice: .st hp+1
  Dice->>CmdTrpgSt: dispatch Solve(ctx, msg, cmdArgs)

  CmdTrpgSt->>TrpgStHookRunner: newTrpgStHookRunner(mctx, tmpl.Name)
  CmdTrpgSt->>TrpgStHookRunner: beforeCommand(event)
  TrpgStHookRunner-->>CmdTrpgSt: error or rejectReason
  alt rejected in beforeCommand
    CmdTrpgSt->>Dice: trpgStReplyRejected(mctx, msg, err)
    CmdTrpgSt-->>User: CmdExecuteResult{Matched:true, Solved:true}
  else proceed
    CmdTrpgSt->>CmdTrpgSt: cmdStReadOrMod(mctx, tmpl, input)
    CmdTrpgSt->>TrpgStHookRunner: afterParse(event)

    loop each TrpgStOperation
      CmdTrpgSt->>TrpgStHookRunner: beforeApply(event, operation)
      TrpgStHookRunner->>ExtensionHooks: BeforeApply(event, operation)
      ExtensionHooks-->>TrpgStHookRunner: maybe Skip/RejectReason

      CmdTrpgSt->>CmdTrpgSt: evaluate Operand / ProposedValue
      CmdTrpgSt->>TrpgStHookRunner: afterEvaluate(event, operation)
      TrpgStHookRunner->>ExtensionHooks: AfterEvaluate(event, operation)
    end

    CmdTrpgSt->>TrpgStHookRunner: beforeCommit(event)
    TrpgStHookRunner-->>CmdTrpgSt: error or rejectReason
    alt rejected in beforeCommit
      CmdTrpgSt->>CmdTrpgSt: snapshot.restore(attrs, mctx.Player)
      CmdTrpgSt->>Dice: trpgStReplyRejected(mctx, msg, err)
    else commit
      CmdTrpgSt->>CmdTrpgSt: apply changes to AttributesItem
      CmdTrpgSt->>TrpgStHookRunner: afterCommit(event)
      TrpgStHookRunner->>ExtensionHooks: AfterCommit(event)
      CmdTrpgSt->>Dice: ReplyToSender(mctx, msg, text+event.ReplySuffix)
    end
  end
Loading

File-Level Changes

Change Details Files
Introduce a new built-in trpg extension that owns generic .st, .sn, and .team commands and is auto-activated by default.
  • Register trpg as an official, auto-active extension with its own CmdMap for st, sn, and team commands.
  • Update global extension registration to include the new trpg extension.
  • Ensure legacy log and core extensions no longer register sn and team, with tests verifying the move.
dice/ext_trpg.go
dice/ext.go
dice/ext_log.go
dice/ext_core.go
dice/ext_trpg_internal_test.go
Implement a new TRPG sheet (trpg.st) command pipeline with snapshots, hooks, and transactional attribute modification, decoupled from coc7.st/dnd5e.st.
  • Define getCmdTrpgSt providing .st subcommands (show, export, del, clr, fmt, generic set/mod) and integrate with attribute storage and card type handling.
  • Introduce snapshot and restore helpers to support all-or-nothing rollbacks for attribute and player-name changes on errors or hook rejections.
  • Add trpgStHookRunner to orchestrate hook invocation across related extensions for command, parse, apply, evaluate, commit, show, and export phases.
  • Implement set and mod application helpers that respect hooks, alias resolution, default values, computed values, and skip/reject semantics.
  • Handle simplified card name parsing, card formatting, and integration with existing attribute utilities, keeping behavior aligned with legacy .st when hooks are absent.
dice/ext_trpg_st.go
Add a hook API for TRPG sheet operations, exposed to JS via seal.trpg.st, including value and operation types and safe hook execution.
  • Define TrpgStValue, TrpgStOperation, TrpgStCommandEvent, and TrpgStRenderEvent as JS-bindable types representing DiceScript values, operations, and events.
  • Implement registerTrpgStHooks, per-extension hook storage (ExtInfo.TrpgStHooks), system scoping, and extension resolution based on relatedExt and activation graph.
  • Expose constructors (newIntValue, newFloatValue, newStringValue, newComputedValue, newOperation) and hook registration/clear functions via seal.trpg.st in the JS VM init.
  • Add panic-safe hook invocation (invokeTrpgStHook) with JS enablement checks and a dedicated panic error type for logging and error propagation.
  • Provide tests verifying JavaScript hook registration, clamping, delete skipping, atomic rollback, and panic handling.
dice/dice.go
dice/dice_jsvm.go
dice/ext_trpg_st_hooks.go
dice/ext_trpg_internal_test.go
Refactor .sn (group card) command into the trpg extension while preserving behavior and error handling.
  • Move ErrGroupCardOverlong and SetPlayerGroupCardByTemplate to a dedicated TRPG SN module.
  • Recreate sn command implementation (getCmdTrpgSn) inside trpg, maintaining help text, permission warnings, template selection, length checks, and custom expression support.
  • Remove the old sn command and helpers from the log extension and route .sn through trpg instead.
  • Keep autoreset of group card name on attribute changes via ctx.Player.AutoSetNameTemplate in trpg.st handling.
dice/ext_log.go
dice/ext_trpg_sn.go
dice/ext_trpg_st.go
Add TRPG-specific text templates and documentation for the new sheet and hook behavior.
  • Introduce TRPG text template group with messages for attribute set, delete, clear, increment/decrement, list, and rejection, plus corresponding help metadata.
  • Wire TRPG templates into the base text map and help info initialization.
  • Add docs/trpg.md describing the trpg extension, hook registration API, execution phases, rejection and rollback semantics, and JS constructors.
dice/ext_trpg_text.go
dice/config.go
docs/trpg.md
Adjust command provider selection so rule templates can opt into trpg.st via relatedExt while keeping existing COC7/DND5E behavior.
  • Use relatedExt information from game system templates to determine which extension provides .st for a given system, ensuring COC7/DND5E templates still use their own .st implementations.
  • Ensure templates that include trpg in relatedExt prefer trpg.st as the sheet provider.
  • Add tests validating command extension ordering and .st provider selection for different system/relatedExt combinations.
dice/ext_trpg_st_hooks.go
dice/ext_trpg_internal_test.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@MintCider MintCider changed the title 新增可扩展的通用 TRPG 属性指令 feat: 新增可扩展的通用 TRPG 属性指令 Aug 8, 2026
@MintCider
MintCider marked this pull request as ready for review August 8, 2026 17:30

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并留下了一些总体反馈:

  • getCmdTrpgSt 的 Solve 函数体积较大且逻辑复杂,把解析、钩子编排、快照/回滚以及回复格式化都混在一起处理;建议将不同子命令(showexportdelclrfmt、默认路径)拆分到更小的辅助函数中,以提升可读性和可维护性。
  • delclrfmt 和默认分支中,围绕运行钩子、检查 trpgStRejectReason、恢复快照,有大量重复的样板代码;可以考虑把这些模式抽取成共享的辅助函数,以减少重复,并让整体的事务行为更易于理解和推理。
给 AI Agent 的提示
Please address the comments from this code review:

## Overall Comments
- `getCmdTrpgSt` 的 Solve 函数体积较大且逻辑复杂,把解析、钩子编排、快照/回滚以及回复格式化都混在一起处理;建议将不同子命令(`show``export``del``clr``fmt`、默认路径)拆分到更小的辅助函数中,以提升可读性和可维护性。
-`del``clr``fmt` 和默认分支中,围绕运行钩子、检查 `trpgStRejectReason`、恢复快照,有大量重复的样板代码;可以考虑把这些模式抽取成共享的辅助函数,以减少重复,并让整体的事务行为更易于理解和推理。

## Individual Comments

### Comment 1
<location path="dice/ext_trpg_st_hooks.go" line_range="199" />
<code_context>
+	return ret
+}
+
+func invokeTrpgStHook(d *Dice, ext *ExtInfo, hook func()) (panicErr error) {
+	if ext == nil || hook == nil {
+		return nil
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Hook panic handling loses stack context and mixes error channels with normal errors.

Wrapping the hook in `recover` and returning `fmt.Errorf(...)` turns all panics into a generic error string and drops the stack trace, which makes failures hard to diagnose, especially for JS-side hooks. Consider logging the panic with `zap` (including a stack via `debug.Stack()` or similar) and clearly distinguishing panic-induced failures from normal hook errors (e.g., separate type or marker) so callers can react appropriately (continue, rollback, or surface richer diagnostics).
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The getCmdTrpgSt Solve function is quite large and complex, mixing parsing, hook orchestration, snapshot/rollback, and reply formatting; consider extracting the different subcommands (show, export, del, clr, fmt, default path) into smaller helpers to improve readability and maintainability.
  • There is a lot of repeated boilerplate around running hooks, checking trpgStRejectReason, and restoring snapshots in the del, clr, fmt, and default branches; factoring these patterns into shared helper functions would reduce duplication and make the transactional behavior easier to reason about.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `getCmdTrpgSt` Solve function is quite large and complex, mixing parsing, hook orchestration, snapshot/rollback, and reply formatting; consider extracting the different subcommands (`show`, `export`, `del`, `clr`, `fmt`, default path) into smaller helpers to improve readability and maintainability.
- There is a lot of repeated boilerplate around running hooks, checking `trpgStRejectReason`, and restoring snapshots in the `del`, `clr`, `fmt`, and default branches; factoring these patterns into shared helper functions would reduce duplication and make the transactional behavior easier to reason about.

## Individual Comments

### Comment 1
<location path="dice/ext_trpg_st_hooks.go" line_range="199" />
<code_context>
+	return ret
+}
+
+func invokeTrpgStHook(d *Dice, ext *ExtInfo, hook func()) (panicErr error) {
+	if ext == nil || hook == nil {
+		return nil
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Hook panic handling loses stack context and mixes error channels with normal errors.

Wrapping the hook in `recover` and returning `fmt.Errorf(...)` turns all panics into a generic error string and drops the stack trace, which makes failures hard to diagnose, especially for JS-side hooks. Consider logging the panic with `zap` (including a stack via `debug.Stack()` or similar) and clearly distinguishing panic-induced failures from normal hook errors (e.g., separate type or marker) so callers can react appropriately (continue, rollback, or surface richer diagnostics).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread dice/ext_trpg_st_hooks.go
@MintCider MintCider changed the title feat: 新增可扩展的通用 TRPG 属性指令 feat: 新增通用 TRPG 扩展与属性 Hook Aug 8, 2026
@MintCider
MintCider marked this pull request as draft August 8, 2026 18:23
@MintCider

Copy link
Copy Markdown
Contributor Author

补充说明:team 完整迁移到 trpg 后,core 扩展不再提供命令;其剩余职责仅为 OnGroupLeave 中的退群/被踢处理,包括通知以及按操作者记录黑名单分。该回调继续通过核心事件机制生效。

@MintCider
MintCider marked this pull request as ready for review August 8, 2026 18:27

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我已经审查了你的更改,一切看起来都很棒!


Sourcery 对开源项目是免费的——如果你喜欢我们的审查,请考虑分享它们 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据这些反馈改进你的代码审查。
Original comment in English

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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