feat: add Slack markdown/text file support for input and output#16
Merged
electronicBlacksmith merged 4 commits intomainfrom Apr 11, 2026
Merged
feat: add Slack markdown/text file support for input and output#16electronicBlacksmith merged 4 commits intomainfrom
electronicBlacksmith merged 4 commits intomainfrom
Conversation
Adds inbound .md/.txt file reading as prompt text (in-memory, no disk write) and outbound .md file upload with summary for responses that exceed Slack's block size limit, with graceful fallback to chunking on upload failure.
The createSSEResponse tests leak listeners into the module-level Set because the ReadableStream is never cancelled. Use a baseline count instead of assuming zero.
fbd0f6a to
03e1b7d
Compare
4 tasks
…ode fence Two bugs in the loop final-notice Slack output: 1. extractStateSummary pre-truncated the state.md body at 3500 chars before postToChannel's upload branch ever ran, so the uploaded response.md only contained the first 3500 chars + "…(truncated)". Removed truncation from the extractor (renamed extractStateBody); the cap now applies only in postToChannel's chunked fallback path via a new optional inlineFallbackMaxChars arg, so the upload gets the full body and the fallback stays bounded. 2. postFinalNotice wrapped the summary in triple-backticks, which made every middle chunk render as an unterminated code block when splitMessage had to chunk the fallback. Dropped the outer fence; the state file is already markdown. Restructured postFinalNotice to post a short header and then the body as two sequential postToChannel calls. The uploaded file stays free of the notebook header, and each message is individually sensible if the upload path can't be used. Also added files:write to slack-app-manifest.yaml so fresh installs pick up the scope the upload branch needs.
Two follow-ups from code review of the previous commit:
1. inlineFallbackMaxChars is now guarded against negative, NaN, and
non-finite values. Previously a negative cap would make
text.slice(0, -1) post "all but the last char" plus a truncation
notice, defeating the cap. No current caller passes a bad value, but
the validation removes the footgun. Added a regression test.
2. The "even number of triple-backticks" test in slack.test.ts was
vacuous: it used plain-prose input containing zero backticks, so the
assertion (0 % 2 === 0) was always true regardless of the code under
test. Replaced with an explicit not.toContain("```") assertion that
directly guards against the removed outer-fence wrapper being
reintroduced.
Also documented in a comment that splitMessage is not code-fence aware,
so a bounded body containing a long fenced block can still produce
half-open fences in the chunked fallback. Fixing that is out of scope
for this path (the upload path sidesteps it entirely).
Owner
Author
|
Pushed two follow-up commits fixing the loop final-notice issues in this feature's file-upload path:
Two bugs in how the loop's final notice uses the new file-upload fallback:
Also added
Follow-ups from a dual code review (Sonnet 4.6 + Copilot GPT-5):
Verification
Tests added/updated
|
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.
Summary
.md/.txtfile uploads in Slack, which are read into memory and injected as prompt text (no disk write).mdfile with a summary message instead of being chunked across multiple messagesfiles:writescope, API error, etc.)Changed files
src/channels/types.ts"text"to attachment type union,textContentfieldsrc/channels/slack-files.tsisTextFile(),hasNulBytes(),uploadSlackFile(), text file download supportsrc/channels/slack-formatter.tsgenerateSummary()for file upload summariessrc/channels/slack.tsextractTextFileContent(), inbound text extraction, outbound file upload insend()/postToChannel()/updateWithFeedback()src/index.tsTest plan
bun run typecheckpassesbun run lintpassesevents.test.ts, reproduces onmain).mdfile to Phantom in Slack, verify content is used as prompt.mdfile attachmentfiles:writescope for outbound uploads