Skip to content

Give Bevelina her three asked-for powers: file download, file upload, custom emoji - #9

Merged
Octember merged 1 commit into
mainfrom
claude/tools-for-next-time-9dd405
Jul 30, 2026
Merged

Give Bevelina her three asked-for powers: file download, file upload, custom emoji#9
Octember merged 1 commit into
mainfrom
claude/tools-for-next-time-9dd405

Conversation

@Octember

Copy link
Copy Markdown
Owner

From the #bevelina thread — asked what tools would have made the :anya: emoji job self-serve, she named three: download the original slack attachment (not the 48px preview), upload a generated file back into the thread, and create/update custom emoji.

What this adds

  • src/tools/slack.ts — the slack registry moves out of main.ts into its own tested module and gains:
    • download_file — fetches an attachment's original bytes (via the adapter's existing downloadFile) into <workspace>/files/. Host-pinned to files.slack.com so the bot token can never ride to an arbitrary URL; save names are sanitized against traversal.
    • upload_file — Slack's files.getUploadURLExternal → PUT → files.completeUploadExternal flow, addressed exactly like reply (venueId + threadRootId). Ungated speech, but restricted to files inside her own workspace — the daemon's filesystem is not hers to post.
    • emoji_setadmin.emoji.add with replace-on-exists (remove + re-add). Statically outward, so it rides the confirmation flow. Needs a new optional SLACK_ADMIN_TOKEN env (admin user token); without it, it fails in room-safe language.
  • Inbox rendering — attachment lines now carry mimetype and url_private (the router already persisted them; inbox narrowed them away), so a turn can actually address the original file.
  • KNOWN_TOOLS derives from SLACK_TOOL_NAMES; deploy/policy.example.yaml documents the grants.

To go live

  1. Merge + deploy to tag-daemon.
  2. Grant download_file / upload_file / emoji_set to bevelina in the live policy.yaml (hot-reloads).
  3. Slack app needs files:read (already has, per the adapter) and files:write for uploads.
  4. emoji_set caveat: admin.emoji.add is the documented API and it's Enterprise Grid only. On a standard workspace it will fail friendly — worth knowing before wiring SLACK_ADMIN_TOKEN.

13 new tests; full suite (382), typecheck, lint all green.

🤖 Generated with Claude Code

…et custom emoji

Bevelina's own asks from the :anya: thread — she could edit the image but not
reach the original attachment, post the result, or land the emoji herself.

- tools/slack.ts: the slack registry moves out of main.ts (testable, one place)
  and grows download_file (original bytes into <workspace>/files; bot token only
  ever rides to files.slack.com), upload_file (reserve→put→complete flow,
  addressed like reply, workspace-paths only), and emoji_set (admin.emoji.add,
  replace-on-exists; outward, so it waits for a go-ahead; fails room-safe when
  SLACK_ADMIN_TOKEN is absent).
- inbox/service: attachment lines now carry mimetype + url_private so the
  original file is addressable from the turn, not just named.
- policy.example.yaml documents the grants; KNOWN_TOOLS derives from
  SLACK_TOOL_NAMES.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Octember
Octember merged commit e560437 into main Jul 30, 2026
1 check passed
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