agent-slack-0.10.2
checks.x86_64-linux.pkgs-agent-slack
· build #7798
· raw
1Using versionCheckHook
unpackPhase
2unpacking source archive /nix/store/cgqwcm1zgrhk5gmlmpjpi0rc8f2zg5kh-source3source root is sourcebunSetInstallCacheDirPhase
4Using bun root: "/build/source"bunPatchPhase
5patching script interpreter paths in .6./scripts/install-skill.sh: interpreter directive changed from "#!/usr/bin/env bash" to "/nix/store/10dxp0qxqxxsyiljrh2kp0xqhz6arhcx-bash-5.3p15/bin/bash"7./scripts/release.sh: interpreter directive changed from "#!/bin/sh" to "/nix/store/10dxp0qxqxxsyiljrh2kp0xqhz6arhcx-bash-5.3p15/bin/sh"8./scripts/update-nix-sources.sh: interpreter directive changed from "#!/usr/bin/env bash" to "/nix/store/10dxp0qxqxxsyiljrh2kp0xqhz6arhcx-bash-5.3p15/bin/bash"configurePhase
9no configure script, doing nothingbunNodeModulesInstallPhase
10/build/source /build/source11bun install flags: --linker=isolated --ignore-scripts12bun install v1.4.2 (744846f84)13 📦 Installing [69/69] 14+ @types/node@22.19.815+ @types/semver@7.7.116+ @types/turndown@5.0.617+ bun-types@1.3.918+ oxfmt@0.31.019+ oxlint@1.49.020+ semver@7.7.421+ simple-git-hooks@2.13.122+ typescript@5.9.323+ @slack/web-api@7.13.024+ commander@14.0.325+ hysnappy@1.1.026+ node-emoji@2.2.027+ turndown@7.2.228+ turndown-plugin-gfm@1.0.229+ zod@4.3.6303168 packages installed [1.75s]32/build/sourcebuildPhase
33Bundled 360 modules in 848ms3435 agent-slack.js 1.98 MB (entry point)36checkPhase
37bun test v1.4.2 (744846f84)3839test/reactions.test.ts:40✓ reactions compaction > includes reactions only when enabled [52.21ms]41✓ reactions compaction > preserves W-prefixed user IDs while compacting reactions [10.41ms]42✓ reactions compaction > adds forwarded thread metadata for shared messages with thread_ts [25.21ms]4344test/update.test.ts:45✓ compareSemver > equal versions return 0 [0.32ms]46✓ compareSemver > strips v prefix [0.17ms]47✓ compareSemver > newer major [0.06ms]48✓ compareSemver > newer minor [0.03ms]49✓ compareSemver > newer patch [0.01ms]50✓ compareSemver > older version returns negative [0.01ms]51✓ compareSemver > handles 0.x versions [0.05ms]5253test/files.test.ts:54✓ downloadSlackFile > downloads file and writes to disk [55.01ms]55✓ downloadSlackFile > returns cached path when file already exists [0.78ms]56✓ downloadSlackFile > throws SlackDownloadError on HTTP 404 [12.21ms]57✓ downloadSlackFile > throws SlackDownloadError with httpStatus on HTTP error [4.10ms]58✓ downloadSlackFile > throws SlackDownloadError on HTML auth page [0.56ms]59✓ downloadSlackFile > throws SlackDownloadError on network error [7.58ms]60✓ downloadSlackFile > throws SlackDownloadError when reading html body fails [8.54ms]61✓ downloadSlackFile > throws SlackDownloadError when reading binary body fails [3.97ms]62✓ tryDownloadSlackFile > returns ok result on success [12.01ms]63✓ tryDownloadSlackFile > returns failure result on HTTP 404 [4.19ms]64✓ tryDownloadSlackFile > returns failure result on network error [7.98ms]65✓ tryDownloadSlackFile > propagates disk/write errors [8.09ms]66Warning: skipping file F1: Downloaded auth/login page instead of canvas content (token may be expired)67✓ downloadMessageFiles > records canvas auth failures as structured errors [13.83ms]68Warning: skipping file F2: Failed to download file (404)69✓ downloadMessageFiles > records non-canvas download failures with a local error path [15.92ms]7071test/render.test.ts:72✓ renderSlackMessageContent > prefers blocks [0.19ms]73✓ renderSlackMessageContent > preserves usergroup and broadcast elements from rich text [0.51ms]74✓ renderSlackMessageContent > omits malformed usergroup and broadcast elements [0.09ms]75✓ renderSlackMessageContent > falls back to attachments when text is empty [0.07ms]76✓ renderSlackMessageContent > includes section fields and button URLs [0.07ms]77✓ renderSlackMessageContent > includes attachment fields [0.06ms]78✓ renderSlackMessageContent > renders forwarded message with author and source link [0.34ms]79✓ renderSlackMessageContent > renders forwarded message with author name only [0.08ms]80✓ renderSlackMessageContent > renders forwarded message with no author [0.05ms]81✓ renderSlackMessageContent > includes forwarded file links in quoted forwarded body [0.08ms]82✓ renderSlackMessageContent > renders nested forwarded attachments similarly to normal attachments [0.09ms]83✓ renderSlackMessageContent > deduplicates repeated forwarded body content [0.10ms]84✓ renderSlackMessageContent > handles cyclic forwarded attachments without infinite recursion [0.06ms]85✓ renderSlackMessageContent > does not treat link unfurl as forwarded message [0.05ms]86✓ renderSlackMessageContent > combines blocks and non-shared attachments [0.05ms]8788test/users.test.ts:89✓ resolveUserId > returns user ids unchanged [0.45ms]90✓ resolveUserId > returns W-prefixed user ids unchanged [0.08ms]91✓ resolveUserId > resolves @handle via users.list [0.35ms]92✓ resolveUserId > resolves email via users.lookupByEmail [0.09ms]93✓ resolveUserId > resolves @handle case-insensitively [0.09ms]94✓ resolveUserId > falls back to users.list when lookupByEmail is unavailable [0.19ms]9596test/format-outbound.test.ts:97✓ formatOutboundSlackText > promotes bare user IDs to Slack mention tokens [4.64ms]98✓ formatOutboundSlackText > leaves already-formatted mention tokens alone [0.12ms]99✓ formatOutboundSlackText > leaves already-formatted usergroup mention tokens alone [0.03ms]100✓ formatOutboundSlackText > promotes broadcast mentions [0.05ms]101✓ formatOutboundSlackText > escapes bare < > & in literal text [0.02ms]102✓ formatOutboundSlackText > does not escape inside already-formatted Slack tokens [0.03ms]103✓ formatOutboundSlackText > does not promote email-like or mid-word @ [0.02ms]104✓ formatOutboundSlackText > handles empty input [0.01ms]105✓ formatOutboundSlackText > real-world CI dump stays readable with mention + URL [0.02ms]106107test/parse-limit.test.ts:108✓ parseLimit > returns undefined when no value given [0.10ms]109✓ parseLimit > parses valid positive integers [0.13ms]110✓ parseLimit > rejects non-numeric strings [0.07ms]111✓ parseLimit > rejects zero [0.02ms]112✓ parseLimit > rejects negative numbers [0.02ms]113✓ parseLimit > rejects floats (uses integer part) [0.01ms]114✓ requireMessageTs > returns trimmed ts when present [0.04ms]115✓ requireMessageTs > throws when missing [0.02ms]116✓ requireMessageTs > throws when blank [0.02ms]117118test/message-reaction-filters.test.ts:119✓ parseReactionFilters > normalizes shortcodes, names, and unicode [0.62ms]120✓ parseReactionFilters > returns empty array when unset [0.12ms]121✓ passesReactionNameFilters > matches when required reaction is present [0.26ms]122✓ passesReactionNameFilters > does not match when required reaction is missing [0.05ms]123✓ passesReactionNameFilters > does not match when excluded reaction is present [0.17ms]124✓ passesReactionNameFilters > matches when excluded reaction is absent [0.04ms]125✓ passesReactionNameFilters > supports with + without together [0.03ms]126✓ requireOldestWhenReactionFiltersUsed > returns oldest when no reaction filters are used [0.08ms]127✓ requireOldestWhenReactionFiltersUsed > returns trimmed oldest when reaction filters are used [0.03ms]128✓ requireOldestWhenReactionFiltersUsed > throws when reaction filters are used without oldest [0.06ms]129130test/channel-admin.test.ts:131✓ parseInviteUsersCsv > splits comma-separated values, trims whitespace, and deduplicates [0.54ms]132✓ parseInviteUsersCsv > returns empty array when input has no values [0.04ms]133✓ splitEmailsFromInviteTargets > separates email targets from non-email targets [0.14ms]134✓ splitEmailsFromInviteTargets > deduplicates emails [0.16ms]135136test/url.test.ts:137✓ parseSlackMessageUrl > parses archives URL with p<digits> [0.42ms]138✓ parseSlackMessageUrl > captures thread_ts from query when present [0.06ms]139✓ buildSlackMessageUrl > builds a permalink for a root message [0.12ms]140✓ buildSlackMessageUrl > includes thread metadata for replies [0.09ms]141142test/compact-json.test.ts:143✓ pruneEmpty > drops null/undefined/empty containers [3.52ms]144145test/channel-command.test.ts:146✓ channel list command > defaults to users.conversations for current user [31.78ms]147✓ channel list command > with --user id uses users.conversations and sets user directly [7.82ms]148✓ channel list command > with --user handle resolves via users.list before users.conversations [9.12ms]149✓ channel list command > with --user unknown handle is a hard error [38.29ms]150✓ channel list command > with --all uses conversations.list [1.14ms]151✓ channel list command > forwards --limit and --cursor [5.29ms]152✓ channel list command > --all and --user is a hard error [4.40ms]153✓ channel list command > invalid --limit is a hard error [0.85ms]154✓ channel list command > help text documents single-page pagination model [0.28ms]155✓ channel mark command > URL target extracts workspace from URL [5.11ms]156✓ channel mark command > URL target rejects --workspace flag [0.82ms]157✓ channel mark command > channel target requires --ts [3.71ms]158✓ channel mark command > URL target allows --ts override [1.21ms]159✓ channel mark command > channel target with --ts calls conversations.mark [0.71ms]160161test/help-contracts.test.ts:162✓ agent-facing help contracts > message send documents non-obvious formatting and scheduling behavior [171.38ms]163✓ agent-facing help contracts > message compose identifies its CI send behavior [1.15ms]164✓ agent-facing help contracts > Slack-native drafts document DM targeting and inherited-broadcast controls [13.71ms]165✓ agent-facing help contracts > scheduled cancellation identifies its required channel [0.90ms]166✓ agent-facing help contracts > Later reminders identify named-day timezone behavior [39.66ms]167✓ agent-facing help contracts > canvas creation identifies source and credential constraints [0.65ms]168✓ agent-facing help contracts > canvas editing identifies operations, targeting, and content constraints [0.58ms]169✓ agent-facing help contracts > channel mark distinguishes URL and non-URL workspace handling [0.60ms]170✓ agent-facing help contracts > DM help states Slack's group size limit [61.87ms]171172test/canvas-create.test.ts:173✓ createCanvasFromMarkdown > sends Markdown content, title, and channel to canvases.create [0.57ms]174✓ createCanvasFromMarkdown > rejects empty Markdown before calling Slack [0.16ms]175✓ createCanvasFromMarkdown > rejects a success response without a canvas id [0.10ms]176✓ createCanvasFromMarkdown > uses Slack's Markdown canvas method with imported browser credentials [0.14ms]177✓ createCanvasFromMarkdown > rejects channel tabs with browser credentials before calling Slack [0.09ms]178✓ editCanvas > sends the documented replace change [0.58ms]179✓ editCanvas > sends the documented replace section change [0.03ms]180✓ editCanvas > sends the documented insert before change [0.02ms]181✓ editCanvas > sends the documented insert after change [0.01ms]182✓ editCanvas > sends the documented insert at start change [0.01ms]183✓ editCanvas > sends the documented insert at end change184✓ editCanvas > sends the documented delete section change185✓ editCanvas > sends the documented rename change [0.01ms]186✓ editCanvas > rejects invalid combinations before calling Slack [0.37ms]187✓ editCanvas > rejects empty Markdown and canvas ids before calling Slack [0.12ms]188✓ editCanvas > rejects Markdown over Slack's per-change limit before calling Slack [134.11ms]189✓ readCanvasMarkdownInput > reads a Markdown file without changing its contents [2.67ms]190✓ readCanvasMarkdownInput > accepts a Markdown blob [0.22ms]191✓ readCanvasMarkdownInput > requires exactly one source [0.19ms]192✓ readCanvasMarkdownInput > rejects an empty source [0.11ms]193✓ canvas create command > creates from an inline blob in the selected workspace [1.82ms]194✓ canvas create command > creates from a file and resolves a channel tab [8.17ms]195✓ canvas create command > rejects browser-auth channel tabs before resolving the channel [0.79ms]196✓ canvas create command > rejects missing or conflicting sources before authenticating [1.14ms]197✓ canvas edit command > replaces a canvas from a Markdown URL target [1.90ms]198✓ canvas edit command > inserts content from a file and passes a section id [19.33ms]199✓ canvas edit command > renames without a Markdown source [0.94ms]200✓ canvas edit command > rejects delete content and malformed inputs before authenticating [0.72ms]201✓ canvas edit command > rejects browser credentials before calling canvases.edit [0.44ms]202203test/drafts.test.ts:204✓ padDraftTs > pads short fractional parts to 7 digits [0.13ms]205✓ padDraftTs > leaves 7-digit fractional parts unchanged [0.02ms]206✓ padDraftTs > leaves timestamps without a fractional part unchanged [0.01ms]207✓ draftTextToBlocks > wraps plain text in a rich_text section [1.21ms]208✓ draftTextToBlocks > converts bullet lists to rich_text lists [0.24ms]209✓ parseDraftRecord > parses a raw draft into a compact shape [9.81ms]210✓ parseDraftRecord > returns null for records without an id [0.08ms]211✓ listDrafts > requests active drafts and parses the result [0.50ms]212✓ listDrafts > omits is_active when activeOnly is false [0.11ms]213✓ createDraft > sends blocks, destination, and composer flag [4.04ms]214✓ createDraft > omits thread fields for channel drafts [0.28ms]215✓ createDraft > includes file_ids on the wire when fileIds is supplied [6.37ms]216✓ updateDraft > sends draft_id and a padded last-updated ts [0.66ms]217✓ deleteDraft > deletes with an explicit last-updated ts [0.25ms]218✓ deleteDraft > fetches the last-updated ts from drafts.list when omitted [0.31ms]219✓ deleteDraft > throws when the draft does not exist [0.09ms]220✓ findDraft > lists all drafts (including inactive) and finds by id [0.11ms]221✓ findDraft > prefers a matching record that has last_updated_ts over a malformed duplicate [0.09ms]222223test/upload.test.ts:224✓ uploadFilesForDraft > never shifts ids between files when the completion response omits one [27.05ms]225✓ uploadFilesForDraft > falls back to staged ids when the completion response length disagrees [22.23ms]226✓ uploadFilesForDraft > stages every file, then completes them in one call with no channel binding [13.73ms]227✓ uploadFilesForDraft > a later staging failure leaves nothing completed (no orphaned files) [30.99ms]228✓ uploadFilesForDraft > throws and completes nothing when a path does not exist [0.67ms]229✓ uploadFilesForDraft > throws and completes nothing when a byte POST fails [10.87ms]230✓ uploadFilesForDraft > throws when files.completeUploadExternal fails [21.00ms]231✓ uploadFilesForDraft > throws when the path is a directory [8.19ms]232✓ uploadLocalFileToSlack (shared-helper regression) > still binds the completed file to a channel with an initial comment [1.29ms]233234test/mrkdwn.test.ts:235✓ slackMrkdwnToMarkdown > converts Slack-style links [0.13ms]236✓ slackMrkdwnToMarkdown > converts user and channel mentions [0.05ms]237✓ slackMrkdwnToMarkdown > converts :emoji: shortcodes to unicode [0.04ms]238239test/workspace-selector.test.ts:240✓ resolveWorkspaceSelector > matches exact URL [0.18ms]241✓ resolveWorkspaceSelector > matches unique substring by host/team [0.44ms]242✓ resolveWorkspaceSelector > matches unique substring by workspace name [0.06ms]243✓ resolveWorkspaceSelector > returns ambiguity when selector matches multiple workspaces [0.16ms]244✓ resolveWorkspaceSelector > returns no match when selector does not match [0.05ms]245246test/message-compact.test.ts:247✓ toCompactMessage > includes file with path on successful download [0.33ms]248✓ toCompactMessage > includes file with error on failed download [0.11ms]249✓ toCompactMessage > excludes files with no downloadedPaths entry [0.04ms]250✓ toCompactMessage > mixes successful and failed downloads [0.08ms]251✓ toCompactMessage > failed download preserves file metadata for content-type filtering [0.05ms]252✓ passesContentTypeFilter with failed downloads > image message with failed download still passes image filter [0.15ms]253✓ passesContentTypeFilter with failed downloads > snippet message with failed download still passes snippet filter [0.06ms]254✓ passesContentTypeFilter with failed downloads > message without download entry has no files and passes text filter [0.05ms]255✓ toCompactMessage filename preservation > does not fall back to title when name is missing [0.05ms]256257test/rich-text.test.ts:258✓ parseInlineElements > plain text returns single text element [0.09ms]259✓ parseInlineElements > *bold* is parsed with bold style [0.17ms]260✓ parseInlineElements > _italic_ is parsed with italic style [0.06ms]261✓ parseInlineElements > ~strike~ is parsed with strike style [0.04ms]262✓ parseInlineElements > `code` is parsed with code style [0.04ms]263✓ parseInlineElements > :emoji: shortcode is parsed as an emoji element [0.04ms]264✓ parseInlineElements > emoji names with underscores are not parsed as italic text [0.03ms]265✓ parseInlineElements > time-like colon text is not parsed as an emoji element [0.02ms]266✓ parseInlineElements > <url|label> is parsed as link with text [0.15ms]267✓ parseInlineElements > <url> is parsed as link without text [0.03ms]268✓ parseInlineElements > <mailto|label> is parsed as link with text [0.02ms]269✓ parseInlineElements > non-url angle bracket text is preserved as text [0.03ms]270✓ parseInlineElements > non-url labeled angle bracket text is preserved as text [0.03ms]271✓ parseInlineElements > channel mention tokens are parsed as channel elements [0.02ms]272✓ parseInlineElements > bare channel mention tokens are parsed as channel elements [0.02ms]273✓ parseInlineElements > usergroup mention tokens are parsed as usergroup elements [0.02ms]274✓ textToRichTextBlocks > plain text returns null [0.09ms]275✓ textToRichTextBlocks > inline-only formatting returns null by default [0.11ms]276✓ textToRichTextBlocks > non-url angle bracket text does not trigger rich text blocks [0.08ms]277✓ textToRichTextBlocks > mixed non-url angle bracket text and formatting preserves brackets [0.26ms]278✓ textToRichTextBlocks > inline-only formatting can produce rich text blocks [0.07ms]279✓ textToRichTextBlocks > mailto links can produce rich text blocks when inline formatting is included [0.05ms]280✓ textToRichTextBlocks > channel mentions can produce rich text blocks when inline formatting is included [0.05ms]281✓ textToRichTextBlocks > bullet list with - prefix [0.19ms]282✓ textToRichTextBlocks > bullet list with bullet character [0.48ms]283✓ textToRichTextBlocks > sub-bullets with indentation [0.12ms]284✓ textToRichTextBlocks > white bullet sub-bullets under bullet [0.06ms]285✓ textToRichTextBlocks > mixed text and bullets [0.06ms]286✓ textToRichTextBlocks > numbered list [0.08ms]287✓ textToRichTextBlocks > bold text in list items is parsed [0.08ms]288✓ textToRichTextBlocks > emoji and channel references in list items are parsed [0.12ms]289✓ textToRichTextBlocks > Slack manual links and CommonMark links remain distinct in list items [0.07ms]290✓ textToRichTextBlocks > code block is preserved [0.05ms]291✓ textToRichTextBlocks > blockquote is preserved [0.14ms]292293test/error-message.test.ts:294✓ errorMessage > returns the message for a plain error [0.19ms]295✓ errorMessage > stringifies non-Error values [0.04ms]296✓ errorMessage > appends a single Error cause [0.04ms]297✓ errorMessage > appends AggregateError causes from a failed fetch through a dead proxy [0.19ms]298✓ errorMessage > walks multi-level cause chains [0.22ms]299✓ errorMessage > terminates on a self-referential cause instead of looping forever [0.05ms]300✓ errorMessage > terminates on a longer cause cycle [0.03ms]301✓ errorMessage > does not crash on a cause that cannot be stringified [0.20ms]302✓ errorMessage > does not crash on a non-Error thrown value that cannot be stringified [0.03ms]303✓ errorMessage > caps how far a long cause chain is walked [0.27ms]304✓ errorMessage > collapses a cause that merely restates its parent [0.03ms]305306test/channels.test.ts:307✓ conversations list helpers > listUserConversations calls users.conversations with defaults [0.30ms]308✓ conversations list helpers > listUserConversations forwards user/limit/cursor [0.35ms]309✓ conversations list helpers > listAllConversations calls conversations.list with defaults [0.44ms]310✓ conversations list helpers > listAllConversations forwards limit/cursor [0.19ms]311✓ conversations list helpers > listUserConversations passes through small limits [0.12ms]312✓ conversations list helpers > listUserConversations clamps high limits to 1000 [0.10ms]313✓ conversations list helpers > normalizeConversationsPage extracts channels and next cursor [0.06ms]314✓ conversations list helpers > normalizeConversationsPage handles missing response_metadata [0.04ms]315✓ conversations list helpers > normalizeConversationsPage handles empty next_cursor [0.15ms]316✓ conversations list helpers > listConversationsViaCounts enumerates channels/mpims/ims and enriches via conversations.info [1.04ms]317✓ conversations list helpers > listConversationsViaCounts keeps the id when conversations.info fails [0.65ms]318✓ conversations list helpers > listConversationsViaCounts slices to limit and skips entries without an id [0.27ms]319320test/message-draft-actions.test.ts:321✓ createDraftAction > creates a draft addressed to a channel id [103.05ms]322✓ createDraftAction > rejects --broadcast without a thread [6.14ms]323✓ createDraftAction > rejects --broadcast for a DM (user) target [0.65ms]324✓ createDraftAction > rejects --broadcast for a D... channel-id (DM) target [0.19ms]325✓ createDraftAction > rejects --broadcast on a channel name with no thread before any network call [58.25ms]326✓ createDraftAction > rejects --broadcast on a DM message URL before fetching the message [0.44ms]327✓ createDraftAction > uploads --attach files and wires their file ids into the draft [437.72ms]328✓ createDraftAction > aborts before any upload or drafts.create when an --attach path is missing [29.91ms]329✓ updateDraftAction > text-only edit preserves destination, thread, broadcast, and file ids [1.13ms]330✓ updateDraftAction > re-addressing a broadcast thread draft to a non-thread channel clears broadcast instead of erroring [0.61ms]331✓ updateDraftAction > explicit --broadcast on a non-thread draft still errors [0.63ms]332✓ updateDraftAction > refuses to update a scheduled draft rather than clearing its schedule [0.63ms]333✓ updateDraftAction > refuses a text-only update on a multi-destination draft, but allows re-addressing [0.52ms]334✓ updateDraftAction > re-addressing to a different thread does not inherit the old broadcast flag [0.32ms]335✓ updateDraftAction > --no-broadcast clears an inherited broadcast flag on a same-thread edit [0.31ms]336✓ updateDraftAction > rejects --broadcast when re-addressing to a DM (user) target [0.45ms]337✓ updateDraftAction > changing only --thread-ts (no --channel) does not inherit the old broadcast flag [51.24ms]338✓ updateDraftAction > rejects --broadcast on an existing DM-destination draft [0.59ms]339✓ updateDraftAction > rejects --broadcast when re-addressing to a channel name with no thread, before resolving it [0.26ms]340✓ updateDraftAction > merges --attach file ids into the draft's existing file_ids [55.28ms]341✓ updateDraftAction > merges --attach while de-duplicating ids already on the draft [299.17ms]342✓ deleteDraftAction > auto-fetches and pads last_updated_ts when omitted [1.01ms]343✓ listDraftsAction > hydrates channel display names [1.18ms]344{345 "ok": true,346 "draft": {347 "id": "Dr123",348 "destinations": [349 {350 "channel_id": "C11111111",351 "thread_ts": "1700000000.100000"352 }353 ]354 }355}356✓ message draft update (commander --broadcast wiring) > omitting broadcast flags does not force broadcast on (no Commander default-true gotcha) [61.87ms]357{358 "ok": true,359 "draft": {360 "id": "Dr123",361 "destinations": [362 {363 "channel_id": "C11111111",364 "thread_ts": "1700000000.100000",365 "broadcast": true366 }367 ]368 }369}370✓ message draft update (commander --broadcast wiring) > --broadcast sets broadcast true [90.29ms]371{372 "ok": true,373 "draft": {374 "id": "Dr123",375 "destinations": [376 {377 "channel_id": "C11111111",378 "thread_ts": "1700000000.100000"379 }380 ]381 }382}383✓ message draft update (commander --broadcast wiring) > --no-broadcast clears an inherited broadcast flag [7.29ms]384{385 "ok": true,386 "draft": {387 "id": "DrNew",388 "destinations": [389 {390 "channel_id": "C11111111"391 }392 ]393 }394}395✓ message draft create (commander --attach wiring) > collects repeatable --attach flags into an array [139.69ms]396✓ message draft unknown subcommand > old `message draft <target>` usage points to `message compose` [23.34ms]397✓ draft attachments: orphan prevention across auth-retry and failed drafts > #2 create: a drafts.create auth failure retries work WITHOUT re-uploading files [201.65ms]398✓ draft attachments: orphan prevention across auth-retry and failed drafts > #2 update: a drafts.update auth failure retries work WITHOUT re-uploading files [111.56ms]399✓ draft attachments: orphan prevention across auth-retry and failed drafts > #3 create: a non-auth drafts.create failure deletes the uploaded file [428.65ms]400✓ draft attachments: orphan prevention across auth-retry and failed drafts > #3 update: a stale drafts.update failure deletes the newly uploaded file only [233.15ms]401✓ draft attachments: orphan prevention across auth-retry and failed drafts > a failed draft with no attachments does not attempt files.delete [0.71ms]402403test/search-query.test.ts:404✓ W-prefixed user IDs in search > resolves a W-prefixed user ID to a from filter [0.64ms]405✓ W-prefixed user IDs in search > returns a W-prefixed user ID without scanning users [0.67ms]406407test/message-send.test.ts:408✓ sendMessage > posts a normal message when no attachments are passed [1.81ms]409✓ sendMessage > --no-unfurl disables link and media previews for immediate sends [0.25ms]410✓ sendMessage > opens and sends to a DM for a W-prefixed user target [0.40ms]411✓ sendMessage > returns a permalink when the workspace was resolved implicitly [0.19ms]412✓ sendMessage > threaded reply returns thread_ts distinct from ts [177.64ms]413✓ sendMessage > --reply-broadcast with --thread-ts sends reply_broadcast: true [0.34ms]414✓ sendMessage > --reply-broadcast omits the field from chat.postMessage when flag is absent [0.23ms]415✓ sendMessage > --reply-broadcast without --thread-ts throws [0.29ms]416✓ sendMessage > --reply-broadcast on a URL target broadcasts using the message's derived thread_ts [1.09ms]417✓ sendMessage > --reply-broadcast on a DM target throws (broadcasting is not meaningful for DMs) [0.31ms]418✓ sendMessage > --reply-broadcast works alongside --blocks payload [170.23ms]419✓ sendMessage > uploads attachment and uses message text as initial comment [37.22ms]420✓ sendMessage > --no-unfurl cannot be combined with file attachments [0.38ms]421✓ sendMessage > sends initial comment only for the first attachment [57.02ms]422✓ sendMessage > uploads attachment without text when text is empty [2.09ms]423✓ sendMessage > --blocks: reads Block Kit JSON from file and passes through unchanged [8.05ms]424✓ sendMessage > --blocks: errors when JSON is not an array [26.91ms]425✓ sendMessage > --blocks: errors on malformed JSON [108.46ms]426✓ sendMessage > --blocks: overrides markdown-to-rich-text conversion when text is also provided [64.00ms]427✓ sendMessage > sends Slack manual links in lists as rich-text link blocks [0.66ms]428✓ sendMessage > --blocks: errors when an array element is not an object [38.53ms]429✓ sendMessage > --schedule sends through chat.scheduleMessage and returns scheduled metadata [1.28ms]430✓ sendMessage > --schedule-in computes a relative post_at [0.63ms]431✓ sendMessage > --no-unfurl disables link and media previews for scheduled sends [0.67ms]432✓ sendMessage > --schedule composes with blocks, thread replies, and reply broadcast [23.52ms]433✓ sendMessage > --schedule cannot be combined with file attachments [0.52ms]434✓ composeMessage > --no-unfurl disables link and media previews when CI sends immediately [1.51ms]435✓ composeMessage > keeps Slack's default preview behavior for a standard CI send [0.78ms]436✓ composeMessage > --no-unfurl disables previews for a URL target when CI sends immediately [1.81ms]437✓ scheduled message management > lists scheduled messages and forwards channel filters [25.23ms]438✓ scheduled message management > cancels scheduled messages with the required channel id [1.07ms]439✓ scheduled message time parsing > parses absolute ISO timestamps with explicit timezones [0.25ms]440✓ scheduled message time parsing > parses named relative times like monday 9am [113.27ms]441✓ scheduled message time parsing > rejects schedule times beyond Slack's 120 day limit [0.21ms]442✓ editMessage > edits a normal text message without blocks [0.87ms]443✓ editMessage > edits literal angle bracket text without blocks [0.24ms]444✓ editMessage > edits a message URL with a link label without blocks [0.29ms]445✓ editMessage > edits an inline mailto link without escaping it [9.60ms]446✓ editMessage > edits an inline usergroup mention without escaping it [0.43ms]447✓ editMessage > edits a channel target with inline formatting without blocks [0.23ms]448✓ editMessage > edits a channel target with rich text blocks when text contains a list [0.29ms]449✓ editMessage > edits a normal message without blocks when no --blocks file is passed [0.16ms]450✓ editMessage > edits a message URL with Block Kit JSON from file [34.35ms]451✓ editMessage > edits a channel target with --ts and Block Kit JSON from file [1.25ms]452453test/client.test.ts:454✓ SlackApiClient browser multipart transport > retries HTTP 429 responses using Retry-After [15.37ms]455456test/later.test.ts:457✓ fetchLaterItems > returns counts only when countsOnly is true [0.90ms]458✓ fetchLaterItems > filters to message items only [0.92ms]459✓ fetchLaterItems > filters by state [12.48ms]460✓ fetchLaterItems > state 'all' returns all items [0.42ms]461✓ fetchLaterItems > respects limit [0.20ms]462✓ fetchLaterItems > hydrates message content [0.31ms]463✓ fetchLaterItems > resolves DM user display names [0.23ms]464✓ fetchLaterItems > truncates long message content [0.20ms]465✓ updateLaterMark > sends mark=completed via multipart [0.23ms]466✓ updateLaterMark > sends mark=archived via multipart [0.10ms]467✓ updateLaterMark > sends mark=uncompleted via multipart [0.39ms]468✓ updateLaterMark > sends mark=unarchived via multipart [0.14ms]469✓ saveLater > calls saved.add with correct params [0.47ms]470✓ removeLater > calls saved.delete with correct params [0.49ms]471✓ setLaterReminder > calls saved.update via multipart with date_due [0.24ms]472✓ parseReminderDuration > parses minutes [0.40ms]473✓ parseReminderDuration > parses hours [0.06ms]474✓ parseReminderDuration > parses fractional hours [0.22ms]475✓ parseReminderDuration > parses days [0.05ms]476✓ parseReminderDuration > parses 'tomorrow' as next day 9 AM [0.18ms]477✓ parseReminderDuration > parses day names [0.06ms]478✓ parseReminderDuration > passes through unix timestamps [0.03ms]479✓ parseReminderDuration > supports verbose unit names [0.17ms]480✓ parseReminderDuration > throws on invalid input [0.13ms]481482test/emoji.test.ts:483✓ normalizeSlackReactionName > accepts :shortcode: [0.07ms]484✓ normalizeSlackReactionName > accepts raw names [0.03ms]485✓ normalizeSlackReactionName > accepts unicode emoji [0.09ms]486487test/search-files.test.ts:488Warning: skipping file F1: Failed to download file (404)489✓ searchFilesViaSearchApi > skips failed downloads and keeps later successful matches [19.22ms]490Warning: skipping file F1: Failed to download file (404)491✓ searchFilesInChannelsFallback > continues after a failed download in files.list results [18.96ms]492✓ SlackApiClient browser API guards > fails fast on rate-limit retry windows by default [1.48ms]493✓ SlackApiClient browser API guards > surfaces request timeouts with the Slack method name [0.37ms]494495test/desktop-auth-paths.test.ts:496✓ Windows Store Slack package detection > matches known Microsoft Store package identifiers [0.17ms]497✓ Windows Store Slack package detection > does not match unrelated packages [0.03ms]498499test/search-command.test.ts:500✓ search referenced users > searchSlack returns shared referenced_users while preserving canonical ids [42.71ms]501✓ search referenced users > search command forwards --refresh-users and bypasses cached user lookups [12.55ms]502503test/user-id.test.ts:504✓ isUserId > accepts U-prefixed and W-prefixed Slack user IDs [0.05ms]505✓ isUserId > preserves the existing length and character restrictions [0.04ms]506507test/messages.test.ts:508✓ fetchThread > returns the thread root and replies in chronological order [0.91ms]509510test/targets.test.ts:511✓ parseMsgTarget > parses slack message URLs [0.17ms]512✓ parseMsgTarget > accepts #channel [0.06ms]513✓ parseMsgTarget > accepts bare channel names [0.05ms]514✓ parseMsgTarget > accepts channel IDs [0.04ms]515✓ parseMsgTarget > accepts user IDs as DM targets [0.04ms]516✓ parseMsgTarget > accepts W-prefixed user IDs as DM targets [0.03ms]517✓ parseMsgTarget > accepts user IDs with leading/trailing whitespace [0.03ms]518✓ parseMsgTarget > does not treat short U-prefixed strings as user IDs [0.03ms]519✓ parseMsgTarget > does not treat short W-prefixed strings as user IDs [0.02ms]520521test/leveldb-reader.test.ts:522✓ leveldb-reader > readChromiumLevelDB > returns empty array for non-existent directory [4.85ms]523✓ leveldb-reader > readChromiumLevelDB > returns empty array for empty directory [0.78ms]524✓ leveldb-reader > readChromiumLevelDB > reads entries from SSTable files [32.86ms]525✓ leveldb-reader > readChromiumLevelDB > reads entries from log files [54.09ms]526✓ leveldb-reader > readChromiumLevelDB > reads from both SSTable and log files [1.82ms]527✓ leveldb-reader > readChromiumLevelDB > handles .sst file extension [13.79ms]528✓ leveldb-reader > findKeysContaining > filters entries by key substring [12.07ms]529✓ leveldb-reader > findKeysContaining > returns empty array when no matches [47.49ms]530✓ leveldb-reader > edge cases > handles invalid SSTable (wrong magic) [0.76ms]531✓ leveldb-reader > edge cases > handles empty SSTable file [4.80ms]532✓ leveldb-reader > edge cases > handles SSTable smaller than footer size [0.65ms]533534test/safe-mode.test.ts:535✓ isSafeModeEnabled > enabled via CLI flag [0.24ms]536✓ isSafeModeEnabled > enabled for env value "1" [0.04ms]537✓ isSafeModeEnabled > enabled for env value "true" [0.01ms]538✓ isSafeModeEnabled > enabled for env value "TRUE"539✓ isSafeModeEnabled > enabled for env value "yes"540✓ isSafeModeEnabled > enabled for env value "on"541✓ isSafeModeEnabled > enabled for env value " 1 "542✓ isSafeModeEnabled > disabled for env value "0" [0.02ms]543✓ isSafeModeEnabled > disabled for env value "false"544✓ isSafeModeEnabled > disabled for env value "off"545✓ isSafeModeEnabled > disabled for env value "no"546✓ isSafeModeEnabled > disabled for env value ""547✓ isSafeModeEnabled > disabled when env var is unset and flag is absent [0.02ms]548✓ safeModeBlockedError > names the blocked action [0.25ms]549✓ redirectSendToDraft > rejects unsupported send option {550 attach: [ "./report.md" ],551} [0.48ms]552✓ redirectSendToDraft > rejects unsupported send option {553 blocks: "/tmp/blocks.json",554} [0.02ms]555✓ redirectSendToDraft > rejects unsupported send option {556 schedule: "2030-01-01T00:00:00Z",557} [0.01ms]558✓ redirectSendToDraft > rejects unsupported send option {559 scheduleIn: "3h",560}561✓ redirectSendToDraft > rejects unsupported send option {562 replyBroadcast: true,563}564✓ redirectSendToDraft > lists all unsupported flags at once [0.09ms]565✓ redirectSendToDraft > rejects in CI where no interactive editor is available [2.24ms]566⚠ Safe mode active: redirecting "message send" → draft editor. Nothing posts until a human sends it from the editor.567✓ redirectSendToDraft > opens a draft with the send text and thread context [0.49ms]568569test/user-cache.test.ts:570✓ user-cache helpers > collectReferencedUserIds excludes reaction users by default [0.18ms]571✓ user-cache helpers > collectReferencedUserIds includes reaction users when enabled [0.09ms]572✓ user-cache helpers > toReferencedUsers returns only resolved users keyed by id [0.09ms]573574test/html-to-md.test.ts:575✓ htmlToMarkdown > converts basic HTML to markdown [32.54ms]576577 399 pass578 0 fail579 817 expect() calls580Ran 399 tests across 38 files. [10.68s]fixupPhase
581shrinking RPATHs of ELF executables and libraries in /nix/store/632yy8i3jabgb7kf9pqbw0n3l4fs5apl-agent-slack-0.10.2582checking for references to /build/ in /nix/store/632yy8i3jabgb7kf9pqbw0n3l4fs5apl-agent-slack-0.10.2...583patching script interpreter paths in /nix/store/632yy8i3jabgb7kf9pqbw0n3l4fs5apl-agent-slack-0.10.2installCheckPhase
584Executing versionCheckPhase585Successfully managed to find version 0.10.2 in the output of the command /nix/store/632yy8i3jabgb7kf9pqbw0n3l4fs5apl-agent-slack-0.10.2/bin/agent-slack --version5860.10.2587Finished versionCheckPhase588no Makefile or custom installCheckPhase, doing nothing