Commit Graph
5 Commits
Author SHA1 Message Date
DrSmoothl 7c0519f75f lint 2026-10-12 15:43:34 +08:00
DrSmoothl f6adadcd12 refactor(onebot): declare every action param the handler reads
Action handlers now only see fields from the param table. Extra client
keys are still ignored. Garbage values on declared numbers fail instead
of becoming zero.
2026-08-30 00:56:01 +08:00
DrSmoothl 14a61f4ce8 feat(onebot): add semantic role field + stream flag to action metadata
Phase 0 of the debug-console expansion. Introduces a closed `FieldRole`
union (group_id/user_id/member_id/message_id/file_id/file/image/record/
video/duration/timestamp/face_id) orthogonal to `type` (which governs
coercion), so the WebUI debug console can render semantic pickers instead
of forcing hand-written JSON.

- FieldDoc gains `role?`; Field gains a `.role()` modifier (survives
  optional/default/describe). toJsonSchema emits it as `x-role`.
- Semantic constructors f.groupId/userId/memberId/fileId/file/image/
  record/video/duration/timestamp/faceId wrap the coercion primitives and
  stamp a role (messageId backfilled). Media sources reject '' to preserve
  the empty-string guard they replace. faceId allows 0 (valid QQ face id).
- Extracted stringCore so f.string() and string-valued roles share it.
- ActionDoc gains `stream?`; defineStreamAction sets stream:true.
- Presets: groupAction injects f.groupId(); groupUserAction injects
  f.groupId() + f.memberId() (a group action's user_id is a member of
  that group). Backfills role onto 56 group_id / 7 member_id sites.
- Regenerated MCP catalog (79 x-role, 5 stream).

Adversarially reviewed: no coercion regression, member_id stamping has
zero false positives across all 7 groupUserAction sites, x-role is inert
to MCP consumers.
2026-06-30 15:42:25 +08:00
DrSmoothl 69c8960ea9 feat(mcp): @snowluma/mcp — read-only MCP server for the OneBot action catalog
A new published package that exposes every OneBot action's docs + a ready-to-use
JSON Schema to LLM clients over stdio. Tools: list_actions / get_action /
search_actions / list_categories, plus the whole catalog as a resource.

The catalog is a build-time snapshot generated from @snowluma/onebot's live
action specs (collectActionDocs()) — so it auto-tracks action add/remove and the
published package carries zero runtime dependency on the private onebot package.

action-kit enrichment (the data source):
- Field.toJsonSchema() per coercer (uint→integer/minimum:1, messageId→integer/
  not-const-0, int→min/max, string→minLength/maxLength, array→items, enum→enum).
- describe() composes a per-action inputSchema; ActionDoc gains inputSchema +
  category. action-docs.ts tags each doc with its domain category.

Wiring: onebot exports ./action-kit + ./action-docs; root build:all includes mcp;
mcp-npm-publish.yml mirrors the sdk/ui publish workflows (triggers on changes
under packages/mcp/** or packages/onebot/**, since the catalog derives from it).

onebot typecheck + 318 tests green; mcp typecheck/build/smoke green; the 142
registered OneBot action names are unchanged.
2026-06-02 22:45:30 +08:00
DrSmoothl 9b92f3825d refactor(onebot): declarative action-kit for param coercion + validation
Introduce packages/onebot/src/action-kit.ts — a zero-dependency,
type-inferring declarative layer for OneBot action params. Each action
declares its param contract (f.* coercers + optional cross-field rules)
and a `run` handler that receives typed, already-validated params.
Validation failures now return BAD_REQUEST naming the offending field
instead of falling through to ApiHandler's INTERNAL_ERROR catch.

- 141/142 actions migrated to defineAction/groupAction/groupUserAction
  across info/message/friend/group-*/request/extended; only
  .handle_quick_operation stays legacy (it needs the ApiHandler instance,
  which run() does not receive).
- f.messageId() distinguishes signed/non-zero message ids from positive
  group/user ids (f.uint()); int({min:0}).default(1800) fixes duration=0
  (unmute), which the old `|| 1800` silently swallowed.
- run(p, ctx, raw) exposes the raw params as an escape hatch for the
  irregular tail (alias-key fallbacks, arbitrary objects).
- action-docs.ts renders self-generated API docs from describe().
- ApiHandler dispatch / try-catch / response-wrapping unchanged (narrow seam).

Registered action name set is byte-identical before/after (142, verified
by runtime enumeration). Typecheck clean; onebot suite green (the
pre-existing websocket native-addon test failure is unrelated).
2026-06-02 15:21:46 +08:00