Repository navigation
Conversation
…r own files Slash commands are now `CommandModule`s (src/commands/types.ts: command, description, operatorOnly, allowlisted, hidden, handle(ctx, deps)) listed in menu order by `COMMAND_MODULES` in src/commands/index.ts. - registerCommandHandlers walks the registry and applies the operator-only and ALLOWED_CHAT_IDS gates centrally from module flags (same silent ignore and log lines as before), after the per-chat rate limiter. - registerCommands / setMyCommands and /help list module commands in registry order; COMMANDS is derived from the registry. - /contracts and /preview are written in the full module shape as the first examples; replies are byte-identical. - createCommandModule normalises a definition (flag defaults, description from COMMAND_DESCRIPTIONS); defineCommand still registers ad-hoc modules and accepts the older handler/chatAllowlist spellings. - src/bot.ts is rebuilt around the registry, dropping the duplicated pre-registry handler table and helpers left by earlier merges that kept main from compiling; the unknown-command hint and rate limiter are wired through the same path. - src/notifications/format.ts: resolve the duplicated claim_created cases and `head` declarations left by a merge (load-time SyntaxError). - tests/command-registry.test.mjs covers names, order and authorization; CONTRIBUTING/README/CHANGELOG describe the module pattern. Closes mimir-stellar#327
The scan-secrets CI gate flagged 11 fixture strings in five test files
(address-activity, audit-check-cli, cycle-summary, health-auth,
safe-error-message). They are fake values, so build them with
[...].join("") like the rest of the suite does instead of weakening
the scanner. Values are unchanged.
…merge 68c5530 (mimir-stellar#546, health bearer token) replaced instead of extended the tail of BotConfig, the collector's network() parser and the loadConfig fields. That removed linkPreviewMarket/Squad, routes, logSample*, logBufferLines, telegramWebhookUrl, telegramApiRoot and mimirAppUrl and broke loadConfig at runtime (c.network is not a function). Restore them from the parent commit, keeping healthAuthToken.
…ier moved mimir-stellar#698 added SendExtra.eventName and disable_notification for SILENT_EVENTS in bot.ts; mimir-stellar#709 moved createNotifier to src/notifications/notifier.ts from an older copy, so the poller's eventName no longer typechecked and low-priority events were sent loudly again. Re-apply the mimir-stellar#698 change.
- commands/unknown.ts (mimir-stellar#726): non-null reads in the bounded levenshtein rows - notifications/amount-display.ts (mimir-stellar#728): USCD_DECIMALS typo; accept the documented string input by converting to bigint before formatUsdc - rpc-compare-cli.ts (mimir-stellar#701): drop unused imports/params, guard indexed push - i18n.ts: drop the orphan 'ping' description. /ping is not in COMMAND_NAMES (not registered since mimir-stellar#700) and has no es translation, which also broke the en/es description parity test.
…neric-decode generic-decode (mimir-stellar#543) was written against stellar-sdk 16 (switch(), value()) but merged after the bump to 17 (mimir-stellar#527), where an ScVal exposes its arm as a 'type' string and its payload as a 'value' getter. Accept both shapes, and update the test helpers to the SDK 17 constructors (Uint128Parts/Uint256Parts, no TimePoint/Duration wrappers).
…pe validation mimir-stellar#658 started rejecting BOT_TOKEN values that are not <digits>:<35+ chars>, which also rejected the mock profile's deliberate MOCK-PROFILE-NOT-A-BOT-TOKEN placeholder, so MIMIR_PROFILE=mock no longer loaded without a real token.
… shape mimir-stellar#658 made loadConfig reject tokens whose secret part is shorter than 35 url-safe characters, but the config-loading fixtures still used short fakes (123:fake, 34 As, ...). Lengthen them; they stay obviously fake and are still built from parts so the secret scan stays clean.
17 test files imported ../src/*.js or ../src/*.ts directly. CI runs plain 'node --test' against the build, where ../src/*.js does not exist and .ts files cannot resolve their own .js imports, so these files failed before running a single test. Point them at ../dist/ (186 other test files already do).
mimir-stellar#546 reads HEALTH_AUTH_TOKEN and documents it in .env.example, but never added it to CONFIG_KEYS, so the .env.example consistency check (mimir-stellar#723) and config provenance did not know about it. Mark it secret.
/ping has not been registered since mimir-stellar#700 (the help and menu tests pin the 11 registered handlers), so the generated command reference no longer lists it. Regenerated with scripts/gen-command-docs.mjs.
…llar-sdk 17 stellar-sdk 17 (mimir-stellar#527) makes scValToNative return undefined for anything that is not an ScVal where 16 threw, so a garbage event value decoded as an empty payload instead of an 'unknown' one. Reject non-ScVal input in decode's native() so malformed values keep surfacing as unknown. Port the affected tests' ScVal builders to the SDK 17 API: scvU64 takes a bigint (no 'new xdr.Uint64'), and ScVal maps convert with scValToNative instead of .map()/entry.key()/entry.val().
scripts/validate-fixtures.mjs (mimir-stellar#652) expected a flat array of {id, contract, ledger, name} events, but tests/fixtures/events.json is the documented {config, cases: [{id, kind, expect, event}]} catalog, so it rejected the real fixtures ('fixtures must be an array of events'). Validate the catalog as docs/contributor-fixtures.md describes, and pick up an events.json from the working directory as tests/fixtures.test.mjs expects. Cases are independent, so the per-contract monotonic ledger rule is dropped.
81f727f added a category icon to claim_created notifications but did not refresh tests/fixtures/golden, so the determinism check failed. Regenerated with 'node scripts/gen-golden-corpus.mjs --update'; only the five claim_created fixtures change.
and mimir-stellar#609 - i128-amounts: mimir-stellar#639 renders every settled-market share with its percentage of the gross; the i128-max case still expected the old single line. - ordering: mimir-stellar#609 rejects malformed getEvents pages and non-object entries with RpcResponseShapeError (so the poller keeps its cursor), but the older ordering tests expected them to be skipped as empty pages. Assert the rejection and keep the decode-to-unknown coverage for entries that pass the guard.
…, mimir-stellar#672, mimir-stellar#674) were never merged Each of these PRs landed only its test file; the module under test never reached main, so the files failed at import. Skip them with an explicit reason pointing at the PR instead of deleting them.
…mounts
escapeMarkdownV2 listed '+' twice and missed '-', so a negative amount
would be rejected by Telegram's entity parser. displayUsdc('') rendered
'0' because BigInt('') is 0n; an empty amount now throws.
Several inputs were off by a factor of ten from the displayed values, a few relied on 3 decimals despite the default maxDecimals of 2, and the 2^63 case and the reserved-character string were miscomputed.
mimir-stellar#647 pinned a '+5s' / '+2 30' format that chainClockLabel never had and referenced an undefined NOY. The wording is user-visible and has been 'local clock 5.0s ahead of chain' since mimir-stellar#288, so the test was wrong.
mimir-stellar#645 was written for an EVM-shaped API (0x hashes, chainId, a single event argument) and referenced an undefined markerEvent. Exercise the real eventExplorerUrl(config, event) / explorerKeyboard(config, event) with Stellar events and 64-hex hashes, covering the same cases.
The mimir-stellar#660 test expected unescaped text and 'Test Network'/'Public Network' labels that aboutMessage never produced; the message text is user-visible and stays as is.
mimir-stellar#668 tested a 'Notifications sent: N' layout the builder never emitted and called the nonexistent assert.typeof. Pin the real output and cover multi-day uptime.
mimir-stellar#665 guessed at record()/stats() shapes, percentiles and a sample window that RpcTiming never had; by design (mimir-stellar#309) it keeps O(1) aggregates only. Assert the real summary() figures and the exact formatRpcTiming line.
With no last run on record, start() fired immediately (stamped with the upcoming slot) and then fired again when that slot arrived. A first start now waits for the next boundary; missed-run catch-up is unchanged.
advanceTo yielded two microtasks, too few for FileLastRunStore's real reads, so the scheduled tick never finished before the assertions. Wait until the scheduler re-arms. mkdtemp used a relative prefix and created its directories inside the repo.
The logger has always normalised to lowercase and supports only text and json; mimir-stellar#673 expected uppercase values and a 'pretty' format.
…ref id The per-chat cap alias was mangled to 'pathMaxFollowsPerChat' in the mimir-stellar#676 merge, so it was silently ignored. A ref like 'market:a:b' was accepted with id 'a:b'; ids may no longer contain ':'.
The suite runs under node --test and Jest is not a dependency, so the file failed at import of @jest/globals.
…imir-stellar#709 suites The mimir-stellar#700 merge interleaved two versions of this file into a module that declared deps twice and could not load. Restore every test from both, using mimir-stellar#700's names (validatePauseConfirmData, pauseConfirmKeyboard, handlePauseConfirmCallback). mimir-stellar#709's '/pause calls pause() at once' case is dropped: /pause sends mimir-stellar#694's confirmation prompt.
…only withReadOnlyDir chmod'ed the temp dir to 0555 before each case wrote its 'previous' file, so every case died with EACCES in its own setup and never reached the writer under test. Make the dir read-only after seeding (the cursor case already did), and skip with a reason when running as root.
…es in the temp dir Only the cursor, counters, lock and status files were redirected, so each smoke run (in CI and from e2e-smoke-script.test.mjs) wrote data/send-journal.jsonl into the repo and broke hermetic-data's data/-holds-only-.gitkeep check.
…lar#609 mimir-stellar#609's rpc-guard rejects getEvents pages whose events lack a string id or are not objects (RpcResponseShapeError), so the poller keeps its cursor. The older mimir-stellar#232/mimir-stellar#310 cases still expected those events to be scanned and deduplicated by composite key. Assert the rejection, keep the malformed- XDR degrade case with a valid id, and leave composite-key coverage to dedup.test.mjs.
makeConfig only redirected cursorFile, so pollers started by these tests wrote counters, status, lock, audit and send-journal files into the repo's data/ through loadConfig's defaults.
It is a placeholder, never a real transaction, so it must not become an explorer link. Pinned by tx-hash.test.mjs (mimir-stellar#651).
…red) A config object without the field (anything built before mimir-stellar#546, or by hand) made every health route answer 401, because only null meant 'no token'. Non-loopback binds still require a token at config load.
'run' was passed to node as the script path, so node tried to load ./run and both CLI cases failed with MODULE_NOT_FOUND / exit 1.
…ir-stellar#654 mimir-stellar#654 (a test-only issue) also rewrote src/redact.ts: URL userinfo was replaced with the literal '{$REDACTED}C', query credentials with '$d{$REDACTED}', the userinfo pattern no longer required 'user:pass', and the bot-in-URL token rule consumed a trailing character instead of looking ahead. Restore the file to its pre-mimir-stellar#654 state (only comment text differs otherwise).
redactChatId has always kept the sign and last four digits (or an @username's first character), and /filters shows that to operators; mimir-stellar#654 expected '[REDACTED]' for every input.
…o's data/ The clean-checkout end-to-end test loads the mock profile and overrode only some state paths, so the poller fell back to ./data/counters.json and ./data/send-journal.jsonl and left them behind after npm test. Point every state file at the test's temp dir, as scripts/e2e-smoke.mjs already does.
danvenger
pushed a commit
to danvenger/telegram-bot
that referenced
this pull request
Oct 23, 2026
…unks as mimir-stellar#732) Upstream main does not pass its own CI, so this PR's checks cannot go green on their own. Bring in the main-repair hunks from mimir-stellar#732 (feat/command-registry-327), line-for-line identical so the two PRs merge cleanly, without the command-registry feature itself (src/commands/types.ts, index/registry rewrite, command-registry tests and docs are NOT included): - tests: build token-shaped fixtures from parts so `npm run scan:secrets` passes (address-activity, audit-check-cli, cycle-summary, health-auth, safe-error-message) - src/bot.ts: drop the duplicated pre-registry handler table and helpers left by earlier merges (39 syntax errors); taken from mimir-stellar#732 except that dispatch() keeps main's CommandModule field names (operatorOnly/ chatAllowlist/handler); the rate-limiter deps mimir-stellar#732 adds to CommandDeps are declared via a module augmentation in src/commands/rate-limit.ts - config/notifier/i18n/amount-display/rpc-compare/generic-decode and the rest of mimir-stellar#732's main-repair fixes and test realignments that typecheck, build, `npm test` and the e2e smoke need
enliven17
pushed a commit
that referenced
this pull request
Oct 25, 2026
…rders (#734) * feat(bot): render squad resolution with pool totals and payout ratio * fix(ci): repair merge damage and secret-scan findings on main (same hunks as #732) Upstream main does not pass its own CI, so this PR's checks cannot go green on their own. Bring in the main-repair hunks from #732 (feat/command-registry-327), line-for-line identical so the two PRs merge cleanly, without the command-registry feature itself (src/commands/types.ts, index/registry rewrite, command-registry tests and docs are NOT included): - tests: build token-shaped fixtures from parts so `npm run scan:secrets` passes (address-activity, audit-check-cli, cycle-summary, health-auth, safe-error-message) - src/bot.ts: drop the duplicated pre-registry handler table and helpers left by earlier merges (39 syntax errors); taken from #732 except that dispatch() keeps main's CommandModule field names (operatorOnly/ chatAllowlist/handler); the rate-limiter deps #732 adds to CommandDeps are declared via a module augmentation in src/commands/rate-limit.ts - config/notifier/i18n/amount-display/rpc-compare/generic-decode and the rest of #732's main-repair fixes and test realignments that typecheck, build, `npm test` and the e2e smoke need --------- Co-authored-by: danvenger <342099042+danvenger@users.noreply.github.com> Co-authored-by: v <v@v>
…ry-327 # Conflicts: # src/bot.ts
…fail the run poller.stop() does not wait for an in-flight cycle, so on Node 20 the cursor writer could still be creating files when rm() ran, failing with ENOTEMPTY. Retry the removal briefly and ignore an already-gone dir.
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description:
• Commands are now modules (src/commands/types.ts) listed in order in src/commands/index.ts. /contracts and /preview are the first examples.
• registerCommandHandlers and registerCommands walk the registry. Operator-only and allowlist checks run in one place, based on each module's flags.
• /help and setMyCommands follow registry order. Every reply is exactly the same as before.
• Cleaned up leftover merge damage in src/bot.ts and src/notifications/format.ts that kept main from loading.
• Updated CONTRIBUTING, README and CHANGELOG.
Testing:
• New tests/command-registry.test.mjs: 22 passed
• tests/bot.test.mjs (11) and tests/help-command.test.mjs (5) pass unchanged
Closes #327