* refactor(skills): use explicit skill-command scope APIs
* test(skills): cover scoped listing and telegram allowlist
* fix(skills): add mergeSkillFilters edge-case tests and simplify dead code
Cover unrestricted-co-tenant and empty-allowlist merge paths in
skill-commands tests. Remove dead ternary in bot-handlers pagination.
Add clarifying comments on undefined vs [] filter semantics.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(skills): collapse scope functions into single listSkillCommandsForAgents
Replace listSkillCommandsForAgentIds, listSkillCommandsForAllAgents, and
the deprecated listSkillCommandsForAgents with a single function that
accepts optional agentIds and falls back to all agents when omitted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(skills): harden realpathSync race and add missing test coverage
- Wrap fs.realpathSync in try-catch to gracefully skip workspaces that
disappear between existsSync and realpathSync (TOCTOU race).
- Log verbose diagnostics for missing/unresolvable workspace paths.
- Add test for overlapping allowlists deduplication on shared workspaces.
- Add test for graceful skip of missing workspaces.
- Add test for pagination callback without agent suffix (default agent).
- Clean up temp directories in skill-commands tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(telegram): warn when nativeSkillsEnabled but no agent route is bound
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use runtime.log instead of nonexistent runtime.warn
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(telegram): accept messages from group members in allowlisted groups
Issue #4559: Telegram bot was silently dropping messages from non-paired users
in allowlisted group chats due to overly strict sender filtering.
The fix adds a check to distinguish between:
1. Group itself is allowlisted → accept messages from any member
2. Group is NOT allowlisted → only accept from allowlisted senders
Changes:
- Check if group ID is in the allowlist (or allowlist is wildcard)
- Only reject sender if they're not in allowlist AND group is not allowlisted
- Improved logging to indicate the actual reason for rejection
This preserves security controls while fixing the UX issue where group members
couldn't participate unless individually allowlisted.
Backwards compatible: existing allowlists continue to work as before.
* style: format telegram fix for oxfmt compliance
* refactor(telegram): clarify group allowlist semantics in fix for #4559
Changes:
- Rename 'isGroupInAllowlist' to 'isGroupChatIdInAllowlist' for clarity
- Expand comments to explain the semantic distinction:
* Group chat ID in allowlist -> accept any group member (fixes#4559)
* Group chat ID NOT in allowlist -> enforce sender allowlist (preserves security)
- This addresses concerns about config semantics raised in code review
The fix maintains backward compatibility:
- 'groupAllowFrom' with group chat IDs now correctly acts as group enablement
- 'groupAllowFrom' with sender IDs continues to work as sender allowlist
- Operators should use group chat IDs for group enablement, sender IDs for sender control
Note: If operators were using 'groupAllowFrom' with group IDs expecting sender-level
filtering, they should migrate to a separate sender allowlist config. This is the
intended behavior per issue #4559.
* Telegram: allow per-group groupPolicy overrides
* Telegram: support per-group groupPolicy overrides (#9775) (thanks @nicolasstanley)
---------
Co-authored-by: George Pickett <gpickett00@gmail.com>
* Telegram: remove @ts-nocheck from bot.ts and bot-message-dispatch.ts
- bot/types.ts: TelegramContext.me uses UserFromGetMe (Grammy) instead of manual inline type
- bot.ts: remove 6 unsafe casts (as any, as unknown, as object), use Grammy types directly
- bot.ts: remove dead message_thread_id access on reactions (not in Telegram Bot API)
- bot.ts: remove resolveThreadSessionKeys import (no longer needed for reactions)
- bot-message-dispatch.ts: replace ': any' with DispatchTelegramMessageParams type
- bot-message-dispatch.ts: add sticker.fileId guard before cache access
- bot.test.ts: update reaction tests, remove dead DM thread-reaction test
* Telegram: remove duplicate bot.catch handler (only the last one runs in Grammy)
* Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077)