From d2c3129d41e4c9e4455044e1ba688b380fc76ee0 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Tue, 21 Jul 2026 14:51:28 +0700 Subject: [PATCH] refactor(commands): standardize parameter conventions --- AGENTS.md | 7 +- README.md | 9 +- cmd/server/command_menu_test.go | 4 +- docs/command-parameter-conventions.md | 72 +++++++ .../260721-1011-telegram-command-discovery.md | 5 + ...0721-1446-command-parameter-conventions.md | 44 ++++ internal/modules/command_presentation_test.go | 8 +- internal/modules/misc/random_picker.go | 4 +- internal/modules/misc/wheelofnames_command.go | 4 +- ...-1418-command-parameter-schema-research.md | 193 ++++++++++++++++++ 10 files changed, 329 insertions(+), 21 deletions(-) create mode 100644 docs/command-parameter-conventions.md create mode 100644 docs/journals/260721-1446-command-parameter-conventions.md create mode 100644 plans/reports/260721-1418-command-parameter-schema-research.md diff --git a/AGENTS.md b/AGENTS.md index b1fe65c..8071184 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,11 +29,8 @@ deleting commands, update all related surfaces: - tests for registration, handlers, and command menu behavior - README/docs when behavior changes are user-visible -Use lowercase, descriptive parameter names in command metadata and usage text. -Include units or currencies when meaningful (for example, ``), use -`[...]` for optional input, append `...` for remaining free text, and use -parentheses to document structured input (for example, -``). Keep metadata, usage errors, examples, and tests exact. +Follow `docs/command-parameter-conventions.md` for all command parameter +metadata and usage text. Keep metadata, usage errors, examples, and tests exact. Telegram's native menu and `/help` show command syntax plus the summary without example invocations. diff --git a/README.md b/README.md index 6bc7302..e535c19 100644 --- a/README.md +++ b/README.md @@ -33,12 +33,9 @@ description: `/help` combines the full command syntax and summary on one line. Neither discovery surface includes example invocations. -For future commands, use lowercase descriptive parameter names. Include units -or currencies when they affect meaning (``, ``), use -square brackets for optional input (`[date]`), append `...` when an argument -accepts remaining text (`[target...]`), and describe structured input in -parentheses (``, ``). Keep command -metadata, handler usage text, tests, and this documentation aligned. +Future commands must follow the +[command parameter conventions](docs/command-parameter-conventions.md). Keep +command metadata, handler usage text, tests, and documentation aligned. ### Stock dividend commands diff --git a/cmd/server/command_menu_test.go b/cmd/server/command_menu_test.go index bf09d56..dd94cb6 100644 --- a/cmd/server/command_menu_test.go +++ b/cmd/server/command_menu_test.go @@ -67,7 +67,7 @@ func TestCommandDiscovery_AllPublicCommandsHaveSafeMetadata(t *testing.T) { "gold_sell": "", "lol": "[date]", "loldle": "[champion]", - "random": "", + "random": "", "stats": "[users | user | cmd ]", "stock_price": "", "stock_topup": "", @@ -78,7 +78,7 @@ func TestCommandDiscovery_AllPublicCommandsHaveSafeMetadata(t *testing.T) { "stock_dividend": " ", "trongtruonghop": "[target...]", "tth": "[target...]", - "wheelofnames": "", + "wheelofnames": "", "wordle": "[word]", } diff --git a/docs/command-parameter-conventions.md b/docs/command-parameter-conventions.md new file mode 100644 index 0000000..94cf149 --- /dev/null +++ b/docs/command-parameter-conventions.md @@ -0,0 +1,72 @@ +# Command Parameter Conventions + +## Overview + +Every Telegram command declares optional `Parameters` metadata. The bot reuses +that string in `/help` and Telegram's native command menu, so it must be short, +consistent, and understandable on a phone. + +Treat `Parameters` as display syntax, not as a validation schema. Handlers +remain responsible for parsing and validation. + +## Syntax + +| Meaning | Format | Example | +|---|---|---| +| Required value | `` | `` | +| Required comma-separated values | `` | `` | +| Optional value | `[name]` | `[date]` | +| Optional remaining text | `[name...]` | `[target...]` | +| Alternatives in an optional group | `[literal | literal ]` | `[users | user ]` | + +Use only constructs required by the command. Do not introduce a formal schema +language or extra punctuation without a user-facing need. + +## Naming + +- Use lowercase `snake_case`. +- Prefer one descriptive noun: ``, ``, ``. +- Include units or currencies when they prevent ambiguity: ``, + ``. +- Do not add primitive types such as `` or ``. +- Keep literal subcommands bare: `users`, `user`, `cmd`. +- Put spaces around `|` in alternatives. +- Do not repeat format prose inside a placeholder. +- Show punctuation that users must type exactly when omitting it would be + error-prone. `` and `` are approved compact + shapes. + +## Examples + +```text +/stock_buy +/lol [date] +/trongtruonghop [target...] +/stats [users | user | cmd ] +/stock_share_dividend +/random +``` + +## Change Checklist + +When adding or changing a command: + +1. Make `Parameters` match the handler's accepted argument order. +2. Keep the parameter string single-line and concise enough for Telegram's + command-description limit. +3. Update handler usage and error text to use the same syntax. +4. Update registration, handler, `/help`, and native-menu tests. +5. Update README or feature documentation when behavior is user-visible. +6. Follow the stats migration rules in `AGENTS.md` when a command name changes + or a command is deleted. + +## References + +- [POSIX.1-2024 utility conventions](https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap12.html) +- [GNU command-line interface standards](https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html) +- [Microsoft command-line syntax key](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/command-line-syntax-key) +- [Python argparse documentation](https://docs.python.org/3/library/argparse.html) +- [docopt usage-pattern grammar](https://github.com/docopt/docopt/blob/master/README.rst) + +The supporting project-specific analysis is in +[`plans/reports/260721-1418-command-parameter-schema-research.md`](../plans/reports/260721-1418-command-parameter-schema-research.md). diff --git a/docs/journals/260721-1011-telegram-command-discovery.md b/docs/journals/260721-1011-telegram-command-discovery.md index a0f841e..910ae54 100644 --- a/docs/journals/260721-1011-telegram-command-discovery.md +++ b/docs/journals/260721-1011-telegram-command-discovery.md @@ -1,5 +1,10 @@ # Telegram Command Discovery Journal +> Historical note: the later command-parameter convention simplifies +> `` to ``, keeping the literal delimiter +> visible without prose inside the placeholder. See +> `docs/command-parameter-conventions.md`. + ## Context Telegram's native command menu and `/help` exposed only short descriptions, diff --git a/docs/journals/260721-1446-command-parameter-conventions.md b/docs/journals/260721-1446-command-parameter-conventions.md new file mode 100644 index 0000000..00961a4 --- /dev/null +++ b/docs/journals/260721-1446-command-parameter-conventions.md @@ -0,0 +1,44 @@ +# Command Parameter Conventions Journal + +## Context + +Command parameter labels had grown organically, especially for comma-separated +arguments. Researched common CLI notation to establish a minimal display syntax +for Telegram's native menu, `/help`, and handler usage text. + +## What Changed + +- Added the evergreen `docs/command-parameter-conventions.md` reference with + concise rules for required, optional, variadic, alternative, and structured + parameters. +- Recorded the user-selected `` notation for required + comma-separated values. +- Updated `/random` and `/wheelofnames` metadata, usage text, and contract tests + from `` to ``. +- Linked project guidance and README command-discovery documentation to the + shared convention reference. + +## Reflection + +The compact notation communicates both one-or-more values and the literal comma +separator without turning display metadata into a schema language. Keeping the +rules in an evergreen document avoids repeating policy in project instructions +and feature docs. + +## Decisions + +- Parameter strings remain presentation-only; handlers own validation. +- `/random` and `/wheelofnames` parsing and runtime behavior remain unchanged. +- Metadata, usage errors, and tests must use the same exact notation. + +## Verification + +- Passed: focused command-presentation and misc tests. +- Passed: `go test ./...` +- Passed: `go vet ./...` +- Passed: `go build ./...` +- Passed: `golangci-lint run` + +## Next Steps + +- Apply the evergreen conventions whenever command parameters change. diff --git a/internal/modules/command_presentation_test.go b/internal/modules/command_presentation_test.go index e285bc7..b15a231 100644 --- a/internal/modules/command_presentation_test.go +++ b/internal/modules/command_presentation_test.go @@ -26,14 +26,14 @@ func TestCommandPresentation(t *testing.T) { menu: "Health check!", }, { - name: "variadic parameters keep ellipsis", + name: "concise parameter name", command: Command{ Name: "random", - Parameters: "", + Parameters: "", Description: "Pick one option", }, - invocation: "/random ", - menu: ". Pick one option.", + invocation: "/random ", + menu: ". Pick one option.", }, } diff --git a/internal/modules/misc/random_picker.go b/internal/modules/misc/random_picker.go index 65681b5..795d607 100644 --- a/internal/modules/misc/random_picker.go +++ b/internal/modules/misc/random_picker.go @@ -12,7 +12,7 @@ import ( "github.com/tiennm99/miti99bot/internal/modules/util/chathelper" ) -const randomUsage = "Usage: /random " +const randomUsage = "Usage: /random " func splitWheelOptions(arg string) []string { parts := strings.Split(arg, ",") @@ -30,7 +30,7 @@ func randomCommand() modules.Command { Name: "random", Visibility: modules.VisibilityPublic, Description: "Pick one random comma-separated option", - Parameters: "", + Parameters: "", Handler: func(ctx context.Context, b *bot.Bot, update *models.Update) error { if update.Message == nil { return nil diff --git a/internal/modules/misc/wheelofnames_command.go b/internal/modules/misc/wheelofnames_command.go index c15e610..acd096d 100644 --- a/internal/modules/misc/wheelofnames_command.go +++ b/internal/modules/misc/wheelofnames_command.go @@ -24,7 +24,7 @@ func wheelOfNamesCommand() modules.Command { Name: "wheelofnames", Visibility: modules.VisibilityPublic, Description: "Pick one comma-separated option with wheel GIF when configured", - Parameters: "", + Parameters: "", Handler: func(ctx context.Context, b *bot.Bot, update *models.Update) error { if update.Message == nil { return nil @@ -63,7 +63,7 @@ func wheelOfNamesCommand() modules.Command { } } -const wheelUsage = "Usage: /wheelofnames " +const wheelUsage = "Usage: /wheelofnames " func wheelResultCaption(result string) string { result = truncateWheelResultCaption(result) diff --git a/plans/reports/260721-1418-command-parameter-schema-research.md b/plans/reports/260721-1418-command-parameter-schema-research.md new file mode 100644 index 0000000..fbda0c6 --- /dev/null +++ b/plans/reports/260721-1418-command-parameter-schema-research.md @@ -0,0 +1,193 @@ +--- +type: research-report +conducted_at: 2026-07-21T14:18:00+07:00 +scope: Telegram command discovery syntax +status: complete +--- + +# Research Report: Minimal Command Parameter Schema + +## Summary + +Keep the project's current lightweight schema. It already matches familiar CLI +synopsis conventions closely enough: + +```text + required value +[name] optional value +[name...] optional remaining text +a | b alternatives inside one optional group +``` + +Do not add types such as ``. Common CLI usage lines describe +structure, not a type system. Use a descriptive name (``, +``) and put validation details in the summary or usage error. + +Only one current notation is needlessly heavy. After project-owner review, the +approved compact replacement is: + +```text + -> +``` + +This keeps the literal comma visible without putting prose inside the +placeholder. Keep `` for the same reason: the separator is +essential input syntax and the concise shape prevents a likely user error. + +## Contents + +- [Scope and method](#scope-and-method) +- [Evidence](#evidence) +- [Recommended schema](#recommended-schema) +- [Current command audit](#current-command-audit) +- [Rejected alternatives](#rejected-alternatives) +- [Next steps](#next-steps) +- [References](#references) +- [Unresolved questions](#unresolved-questions) + +## Scope and Method + +Evaluated only the syntax displayed after `/command` in Telegram's native menu +and `/help`. Criteria, in order: + +1. Understandable without a legend +2. Minimal visual noise on a phone +3. Accurate to the parser +4. Consistent across commands +5. Familiar to terminal users + +Sources span POSIX.1-2024, current GNU guidance, Python 3.14 documentation, +Microsoft's command-line syntax key, docopt's usage grammar, and Telegram's +current Bot API. The configured Gemini path was disabled. Web search returned +an authorization error, so primary sources were retrieved directly over HTTPS. + +## Evidence + +### Strong consensus + +- Square brackets mean optional material. POSIX, Microsoft, argparse, and + docopt all use this convention. +- Angle brackets are a recognized way to mark a value the user must replace. + POSIX explicitly permits ``; Microsoft defines angle-bracket + text as a placeholder. +- A vertical bar separates mutually exclusive alternatives. Microsoft and + docopt explicitly document this. +- An ellipsis indicates repetition. POSIX uses `[operand ...]`; docopt uses + `FILE ...` for one or more and `[FILE ...]` for zero or more. +- Metavariable names should explain the role of the value. Python argparse uses + `metavar` for this purpose and generates the structural punctuation itself. + +### Important nuance + +Traditional terminal help often uses uppercase metavariables such as `FILE` or +`FOO`. Lowercase angle-bracket names such as `` remain unambiguous and +are calmer in Telegram's compact UI. Changing case would add churn without +improving comprehension. + +POSIX's spaced ellipsis (`operand ...`) means repeated operands. This bot's +`[target...]` means one optional free-text remainder. That is a small local +extension, but it communicates the behavior better than `[target]`, which can +look limited to one word. Document it once and keep it consistent. + +## Recommended Schema + +Use only constructs the project currently needs: + +| Meaning | Format | Example | +|---|---|---| +| Required value | `` | `` | +| Required comma-separated values | `` | `` | +| Optional value | `[name]` | `[date]` | +| Optional remaining text | `[name...]` | `[target...]` | +| Optional alternatives | `[literal | literal ]` | `[users | user ]` | + +Naming rules: + +- Lowercase `snake_case`. +- Prefer one plain noun: ``, ``, ``. +- Include a unit when it prevents ambiguity: ``, ``. +- Do not encode primitive types: avoid `` and ``. +- Do not put format prose inside a placeholder. +- Include a compact value shape only when users must type its punctuation + exactly: ``, ``. +- Keep literal subcommands bare: `users`, `user`, `cmd`. +- Put spaces around `|`; readability is worth the two characters. + +This is presentation metadata, not a machine-validated schema language. Avoid +adding an AST, parser, enums, or type annotations until the bot needs generated +validation or completion. + +## Current Command Audit + +| Commands | Current | Recommendation | Reason | +|---|---|---|---| +| `/random`, `/wheelofnames` | `` | `` | Shows the literal delimiter without prose. | +| `/stats` | `[users | user | cmd ]` | Keep | Accurate compact grammar; `command_name` avoids confusing the value with a literal command. | +| `/trongtruonghop`, `/tth` | `[target...]` | Keep | Clearly signals optional multi-word remainder. | +| `/lol` | `[date]` | Keep | Minimal; accepted date shapes belong in the summary/error. | +| `/loldle`, `/wordle` | `[champion]`, `[word]` | Keep | Optional value accurately reflects start-without-argument behavior. | +| Coin commands | ``, ``, ` `, ` ` | Keep | Names expose currency and transaction intent without type noise. | +| Gold commands | ``, `` | Keep | Units are essential and concise. | +| Stock price/trade commands | ``, ``, ` ` | Keep | Conventional positional metavariables. | +| Stock dividend commands | ``, ``, `` combinations | Keep | The ratio shape is valuable syntax, not redundant prose. | + +Result: change two registrations and their matching usage/tests; leave every +other public parameter string unchanged. + +## Rejected Alternatives + +### Uppercase metavariables + +```text + +``` + +Familiar in man pages, but redundant when angle brackets already mark values. +It is visually louder and would touch every command for no behavior gain. + +### Inline type annotations + +```text + +``` + +Not a common shell synopsis convention. Longer, falsely formal, and still +cannot express real constraints such as positive integers or known tickers. + +### Generic names everywhere + +```text + +``` + +Short but ambiguous. Minimalism should remove redundancy, not meaning. + +### Full docopt grammar + +Docopt can represent required groups, nested alternatives, and repetition +precisely. The bot does not need that complexity. Adopt only its familiar +surface notation when a real command requires it. + +## Next Steps + +1. Change `/random` and `/wheelofnames` parameter metadata to ``. +2. Change their handler usage strings and exact-string tests at the same time. +3. Update README/AGENTS guidance: value format belongs in the summary or usage + error unless punctuation is essential, as with ``. +4. Keep current registration validation: non-empty descriptions, single-line + parameters, and Telegram's length limit. +5. Do not build a schema parser. + +## References + +- [POSIX.1-2024, Utility Conventions](https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap12.html) +- [GNU Standards, Command-Line Interfaces](https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html) +- [Microsoft command-line syntax key](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/command-line-syntax-key) +- [Python 3 argparse documentation](https://docs.python.org/3/library/argparse.html) +- [docopt usage-pattern grammar](https://github.com/docopt/docopt/blob/master/README.rst) +- [Telegram Bot API](https://core.telegram.org/bots/api#botcommand) + +## Unresolved Questions + +None. The recommendation is intentionally small and implementable without +changing command parsing or persisted data.