these 2 derivations will be built: /nix/store/p6wdjikjk1vrrpmk7l47wyllrdch7rkm-agent-slack-0.10.2.drv /nix/store/k0ky683alzn5z5pfglppbqjryl0vqm8q-check-agent-slack.drv building '/nix/store/p6wdjikjk1vrrpmk7l47wyllrdch7rkm-agent-slack-0.10.2.drv' on 'ssh-ng://customer@mac02.m.ntd.one' building '/nix/store/p6wdjikjk1vrrpmk7l47wyllrdch7rkm-agent-slack-0.10.2.drv' agent-slack-0.10.2> Using versionCheckHook agent-slack-0.10.2> Running phase: unpackPhase agent-slack-0.10.2> unpacking source archive /nix/store/cgqwcm1zgrhk5gmlmpjpi0rc8f2zg5kh-source agent-slack-0.10.2> source root is source agent-slack-0.10.2> Running phase: patchPhase agent-slack-0.10.2> Running phase: bunSetInstallCacheDirPhase agent-slack-0.10.2> Using bun root: "/nix/var/nix/builds/nix-2639-371822206/source" agent-slack-0.10.2> Running phase: bunPatchPhase agent-slack-0.10.2> patching script interpreter paths in . agent-slack-0.10.2> ./scripts/install-skill.sh: interpreter directive changed from "#!/usr/bin/env bash" to "/nix/store/lb6nd0iyy9x0bm7yfx2fkw0wbjllg4ic-bash-5.3p15/bin/bash" agent-slack-0.10.2> ./scripts/update-nix-sources.sh: interpreter directive changed from "#!/usr/bin/env bash" to "/nix/store/lb6nd0iyy9x0bm7yfx2fkw0wbjllg4ic-bash-5.3p15/bin/bash" agent-slack-0.10.2> ./scripts/release.sh: interpreter directive changed from "#!/bin/sh" to "/nix/store/lb6nd0iyy9x0bm7yfx2fkw0wbjllg4ic-bash-5.3p15/bin/sh" agent-slack-0.10.2> Running phase: updateAutotoolsGnuConfigScriptsPhase agent-slack-0.10.2> Running phase: configurePhase agent-slack-0.10.2> no configure script, doing nothing agent-slack-0.10.2> Running phase: bunNodeModulesInstallPhase agent-slack-0.10.2> /nix/var/nix/builds/nix-2639-371822206/source /nix/var/nix/builds/nix-2639-371822206/source agent-slack-0.10.2> bun install flags: --linker=isolated --backend=symlink --ignore-scripts agent-slack-0.10.2> bun install v1.4.2 (744846f84) agent-slack-0.10.2> agent-slack-0.10.2> + @types/node@22.19.8 agent-slack-0.10.2> + @types/semver@7.7.1 agent-slack-0.10.2> + @types/turndown@5.0.6 agent-slack-0.10.2> + bun-types@1.3.9 agent-slack-0.10.2> + oxfmt@0.31.0 agent-slack-0.10.2> + oxlint@1.49.0 agent-slack-0.10.2> + semver@7.7.4 agent-slack-0.10.2> + simple-git-hooks@2.13.1 agent-slack-0.10.2> + typescript@5.9.3 agent-slack-0.10.2> + @slack/web-api@7.13.0 agent-slack-0.10.2> + commander@14.0.3 agent-slack-0.10.2> + hysnappy@1.1.0 agent-slack-0.10.2> + node-emoji@2.2.0 agent-slack-0.10.2> + turndown@7.2.2 agent-slack-0.10.2> + turndown-plugin-gfm@1.0.2 agent-slack-0.10.2> + zod@4.3.6 agent-slack-0.10.2> agent-slack-0.10.2> 66 packages installed [424.00ms] agent-slack-0.10.2> /nix/var/nix/builds/nix-2639-371822206/source agent-slack-0.10.2> Running phase: buildPhase agent-slack-0.10.2> Bundled 360 modules in 36ms agent-slack-0.10.2> agent-slack-0.10.2> agent-slack.js 1.98 MB (entry point) agent-slack-0.10.2> agent-slack-0.10.2> Running phase: checkPhase agent-slack-0.10.2> bun test v1.4.2 (744846f84) agent-slack-0.10.2> agent-slack-0.10.2> test/users.test.ts: agent-slack-0.10.2> ✓ resolveUserId > returns user ids unchanged [0.23ms] agent-slack-0.10.2> ✓ resolveUserId > returns W-prefixed user ids unchanged [0.03ms] agent-slack-0.10.2> ✓ resolveUserId > resolves @handle via users.list [0.13ms] agent-slack-0.10.2> ✓ resolveUserId > resolves email via users.lookupByEmail [0.03ms] agent-slack-0.10.2> ✓ resolveUserId > resolves @handle case-insensitively [0.03ms] agent-slack-0.10.2> ✓ resolveUserId > falls back to users.list when lookupByEmail is unavailable [0.09ms] agent-slack-0.10.2> agent-slack-0.10.2> test/desktop-auth-paths.test.ts: agent-slack-0.10.2> ✓ Windows Store Slack package detection > matches known Microsoft Store package identifiers [0.03ms] agent-slack-0.10.2> ✓ Windows Store Slack package detection > does not match unrelated packages agent-slack-0.10.2> agent-slack-0.10.2> test/format-outbound.test.ts: agent-slack-0.10.2> ✓ formatOutboundSlackText > promotes bare user IDs to Slack mention tokens [0.25ms] agent-slack-0.10.2> ✓ formatOutboundSlackText > leaves already-formatted mention tokens alone [0.02ms] agent-slack-0.10.2> ✓ formatOutboundSlackText > leaves already-formatted usergroup mention tokens alone agent-slack-0.10.2> ✓ formatOutboundSlackText > promotes broadcast mentions agent-slack-0.10.2> ✓ formatOutboundSlackText > escapes bare < > & in literal text [0.01ms] agent-slack-0.10.2> ✓ formatOutboundSlackText > does not escape inside already-formatted Slack tokens [0.04ms] agent-slack-0.10.2> ✓ formatOutboundSlackText > does not promote email-like or mid-word @ agent-slack-0.10.2> ✓ formatOutboundSlackText > handles empty input agent-slack-0.10.2> ✓ formatOutboundSlackText > real-world CI dump stays readable with mention + URL agent-slack-0.10.2> agent-slack-0.10.2> test/leveldb-reader.test.ts: agent-slack-0.10.2> ✓ leveldb-reader > readChromiumLevelDB > returns empty array for non-existent directory [1.52ms] agent-slack-0.10.2> ✓ leveldb-reader > readChromiumLevelDB > returns empty array for empty directory [0.44ms] agent-slack-0.10.2> ✓ leveldb-reader > readChromiumLevelDB > reads entries from SSTable files [1.67ms] agent-slack-0.10.2> ✓ leveldb-reader > readChromiumLevelDB > reads entries from log files [0.74ms] agent-slack-0.10.2> ✓ leveldb-reader > readChromiumLevelDB > reads from both SSTable and log files [0.66ms] agent-slack-0.10.2> ✓ leveldb-reader > readChromiumLevelDB > handles .sst file extension [0.58ms] agent-slack-0.10.2> ✓ leveldb-reader > findKeysContaining > filters entries by key substring [0.68ms] agent-slack-0.10.2> ✓ leveldb-reader > findKeysContaining > returns empty array when no matches [0.62ms] agent-slack-0.10.2> ✓ leveldb-reader > edge cases > handles invalid SSTable (wrong magic) [0.46ms] agent-slack-0.10.2> ✓ leveldb-reader > edge cases > handles empty SSTable file [0.49ms] agent-slack-0.10.2> ✓ leveldb-reader > edge cases > handles SSTable smaller than footer size [0.35ms] agent-slack-0.10.2> agent-slack-0.10.2> test/messages.test.ts: agent-slack-0.10.2> ✓ fetchThread > returns the thread root and replies in chronological order [0.80ms] agent-slack-0.10.2> agent-slack-0.10.2> test/workspace-selector.test.ts: agent-slack-0.10.2> ✓ resolveWorkspaceSelector > matches exact URL [0.11ms] agent-slack-0.10.2> ✓ resolveWorkspaceSelector > matches unique substring by host/team [0.11ms] agent-slack-0.10.2> ✓ resolveWorkspaceSelector > matches unique substring by workspace name [0.02ms] agent-slack-0.10.2> ✓ resolveWorkspaceSelector > returns ambiguity when selector matches multiple workspaces [0.17ms] agent-slack-0.10.2> ✓ resolveWorkspaceSelector > returns no match when selector does not match [0.02ms] agent-slack-0.10.2> agent-slack-0.10.2> test/help-contracts.test.ts: agent-slack-0.10.2> ✓ agent-facing help contracts > message send documents non-obvious formatting and scheduling behavior [1.28ms] agent-slack-0.10.2> ✓ agent-facing help contracts > message compose identifies its CI send behavior [0.94ms] agent-slack-0.10.2> ✓ agent-facing help contracts > Slack-native drafts document DM targeting and inherited-broadcast controls [0.82ms] agent-slack-0.10.2> ✓ agent-facing help contracts > scheduled cancellation identifies its required channel [0.14ms] agent-slack-0.10.2> ✓ agent-facing help contracts > Later reminders identify named-day timezone behavior [0.35ms] agent-slack-0.10.2> ✓ agent-facing help contracts > canvas creation identifies source and credential constraints [0.24ms] agent-slack-0.10.2> ✓ agent-facing help contracts > canvas editing identifies operations, targeting, and content constraints [0.24ms] agent-slack-0.10.2> ✓ agent-facing help contracts > channel mark distinguishes URL and non-URL workspace handling [0.14ms] agent-slack-0.10.2> ✓ agent-facing help contracts > DM help states Slack's group size limit [0.11ms] agent-slack-0.10.2> agent-slack-0.10.2> test/channel-command.test.ts: agent-slack-0.10.2> ✓ channel list command > defaults to users.conversations for current user [2.77ms] agent-slack-0.10.2> ✓ channel list command > with --user id uses users.conversations and sets user directly [0.26ms] agent-slack-0.10.2> ✓ channel list command > with --user handle resolves via users.list before users.conversations [0.15ms] agent-slack-0.10.2> ✓ channel list command > with --user unknown handle is a hard error [0.12ms] agent-slack-0.10.2> ✓ channel list command > with --all uses conversations.list [0.13ms] agent-slack-0.10.2> ✓ channel list command > forwards --limit and --cursor [0.09ms] agent-slack-0.10.2> ✓ channel list command > --all and --user is a hard error [0.08ms] agent-slack-0.10.2> ✓ channel list command > invalid --limit is a hard error [0.06ms] agent-slack-0.10.2> ✓ channel list command > help text documents single-page pagination model [0.04ms] agent-slack-0.10.2> ✓ channel mark command > URL target extracts workspace from URL [0.47ms] agent-slack-0.10.2> ✓ channel mark command > URL target rejects --workspace flag [0.12ms] agent-slack-0.10.2> ✓ channel mark command > channel target requires --ts [0.09ms] agent-slack-0.10.2> ✓ channel mark command > URL target allows --ts override [0.19ms] agent-slack-0.10.2> ✓ channel mark command > channel target with --ts calls conversations.mark [0.17ms] agent-slack-0.10.2> agent-slack-0.10.2> test/user-id.test.ts: agent-slack-0.10.2> ✓ isUserId > accepts U-prefixed and W-prefixed Slack user IDs agent-slack-0.10.2> ✓ isUserId > preserves the existing length and character restrictions agent-slack-0.10.2> agent-slack-0.10.2> test/mrkdwn.test.ts: agent-slack-0.10.2> ✓ slackMrkdwnToMarkdown > converts Slack-style links [0.06ms] agent-slack-0.10.2> ✓ slackMrkdwnToMarkdown > converts user and channel mentions [0.03ms] agent-slack-0.10.2> ✓ slackMrkdwnToMarkdown > converts :emoji: shortcodes to unicode [0.06ms] agent-slack-0.10.2> agent-slack-0.10.2> test/rich-text.test.ts: agent-slack-0.10.2> ✓ parseInlineElements > plain text returns single text element [0.24ms] agent-slack-0.10.2> ✓ parseInlineElements > *bold* is parsed with bold style [0.02ms] agent-slack-0.10.2> ✓ parseInlineElements > _italic_ is parsed with italic style agent-slack-0.10.2> ✓ parseInlineElements > ~strike~ is parsed with strike style agent-slack-0.10.2> ✓ parseInlineElements > `code` is parsed with code style agent-slack-0.10.2> ✓ parseInlineElements > :emoji: shortcode is parsed as an emoji element [0.01ms] agent-slack-0.10.2> ✓ parseInlineElements > emoji names with underscores are not parsed as italic text agent-slack-0.10.2> ✓ parseInlineElements > time-like colon text is not parsed as an emoji element agent-slack-0.10.2> ✓ parseInlineElements > is parsed as link with text [0.02ms] agent-slack-0.10.2> ✓ parseInlineElements > is parsed as link without text [0.01ms] agent-slack-0.10.2> ✓ parseInlineElements > is parsed as link with text [0.01ms] agent-slack-0.10.2> ✓ parseInlineElements > non-url angle bracket text is preserved as text [0.06ms] agent-slack-0.10.2> ✓ parseInlineElements > non-url labeled angle bracket text is preserved as text agent-slack-0.10.2> ✓ parseInlineElements > channel mention tokens are parsed as channel elements agent-slack-0.10.2> ✓ parseInlineElements > bare channel mention tokens are parsed as channel elements [0.04ms] agent-slack-0.10.2> ✓ parseInlineElements > usergroup mention tokens are parsed as usergroup elements [0.02ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > plain text returns null [0.13ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > inline-only formatting returns null by default [0.02ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > non-url angle bracket text does not trigger rich text blocks [0.01ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > mixed non-url angle bracket text and formatting preserves brackets [0.04ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > inline-only formatting can produce rich text blocks [0.03ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > mailto links can produce rich text blocks when inline formatting is included [0.01ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > channel mentions can produce rich text blocks when inline formatting is included [0.02ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > bullet list with - prefix [0.06ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > bullet list with bullet character [0.12ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > sub-bullets with indentation [0.03ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > white bullet sub-bullets under bullet [0.02ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > mixed text and bullets [0.01ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > numbered list [0.02ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > bold text in list items is parsed [0.01ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > emoji and channel references in list items are parsed [0.02ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > Slack manual links and CommonMark links remain distinct in list items [0.06ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > code block is preserved [0.07ms] agent-slack-0.10.2> ✓ textToRichTextBlocks > blockquote is preserved [0.02ms] agent-slack-0.10.2> agent-slack-0.10.2> test/message-reaction-filters.test.ts: agent-slack-0.10.2> ✓ parseReactionFilters > normalizes shortcodes, names, and unicode [0.36ms] agent-slack-0.10.2> ✓ parseReactionFilters > returns empty array when unset agent-slack-0.10.2> ✓ passesReactionNameFilters > matches when required reaction is present [0.04ms] agent-slack-0.10.2> ✓ passesReactionNameFilters > does not match when required reaction is missing agent-slack-0.10.2> ✓ passesReactionNameFilters > does not match when excluded reaction is present agent-slack-0.10.2> ✓ passesReactionNameFilters > matches when excluded reaction is absent agent-slack-0.10.2> ✓ passesReactionNameFilters > supports with + without together agent-slack-0.10.2> ✓ requireOldestWhenReactionFiltersUsed > returns oldest when no reaction filters are used [0.01ms] agent-slack-0.10.2> ✓ requireOldestWhenReactionFiltersUsed > returns trimmed oldest when reaction filters are used agent-slack-0.10.2> ✓ requireOldestWhenReactionFiltersUsed > throws when reaction filters are used without oldest [0.03ms] agent-slack-0.10.2> agent-slack-0.10.2> test/parse-limit.test.ts: agent-slack-0.10.2> ✓ parseLimit > returns undefined when no value given agent-slack-0.10.2> ✓ parseLimit > parses valid positive integers agent-slack-0.10.2> ✓ parseLimit > rejects non-numeric strings agent-slack-0.10.2> ✓ parseLimit > rejects zero agent-slack-0.10.2> ✓ parseLimit > rejects negative numbers agent-slack-0.10.2> ✓ parseLimit > rejects floats (uses integer part) agent-slack-0.10.2> ✓ requireMessageTs > returns trimmed ts when present agent-slack-0.10.2> ✓ requireMessageTs > throws when missing agent-slack-0.10.2> ✓ requireMessageTs > throws when blank agent-slack-0.10.2> agent-slack-0.10.2> test/message-compact.test.ts: agent-slack-0.10.2> ✓ toCompactMessage > includes file with path on successful download [0.48ms] agent-slack-0.10.2> ✓ toCompactMessage > includes file with error on failed download [0.03ms] agent-slack-0.10.2> ✓ toCompactMessage > excludes files with no downloadedPaths entry [0.02ms] agent-slack-0.10.2> ✓ toCompactMessage > mixes successful and failed downloads [0.02ms] agent-slack-0.10.2> ✓ toCompactMessage > failed download preserves file metadata for content-type filtering [0.01ms] agent-slack-0.10.2> ✓ passesContentTypeFilter with failed downloads > image message with failed download still passes image filter [0.03ms] agent-slack-0.10.2> ✓ passesContentTypeFilter with failed downloads > snippet message with failed download still passes snippet filter [0.02ms] agent-slack-0.10.2> ✓ passesContentTypeFilter with failed downloads > message without download entry has no files and passes text filter [0.01ms] agent-slack-0.10.2> ✓ toCompactMessage filename preservation > does not fall back to title when name is missing [0.01ms] agent-slack-0.10.2> agent-slack-0.10.2> test/user-cache.test.ts: agent-slack-0.10.2> ✓ user-cache helpers > collectReferencedUserIds excludes reaction users by default [0.36ms] agent-slack-0.10.2> ✓ user-cache helpers > collectReferencedUserIds includes reaction users when enabled [0.02ms] agent-slack-0.10.2> ✓ user-cache helpers > toReferencedUsers returns only resolved users keyed by id [0.06ms] agent-slack-0.10.2> agent-slack-0.10.2> test/message-send.test.ts: agent-slack-0.10.2> ✓ sendMessage > posts a normal message when no attachments are passed [0.60ms] agent-slack-0.10.2> ✓ sendMessage > --no-unfurl disables link and media previews for immediate sends [0.06ms] agent-slack-0.10.2> ✓ sendMessage > opens and sends to a DM for a W-prefixed user target [0.13ms] agent-slack-0.10.2> ✓ sendMessage > returns a permalink when the workspace was resolved implicitly [0.05ms] agent-slack-0.10.2> ✓ sendMessage > threaded reply returns thread_ts distinct from ts [0.06ms] agent-slack-0.10.2> ✓ sendMessage > --reply-broadcast with --thread-ts sends reply_broadcast: true [0.04ms] agent-slack-0.10.2> ✓ sendMessage > --reply-broadcast omits the field from chat.postMessage when flag is absent [0.04ms] agent-slack-0.10.2> ✓ sendMessage > --reply-broadcast without --thread-ts throws [0.08ms] agent-slack-0.10.2> ✓ sendMessage > --reply-broadcast on a URL target broadcasts using the message's derived thread_ts [0.27ms] agent-slack-0.10.2> ✓ sendMessage > --reply-broadcast on a DM target throws (broadcasting is not meaningful for DMs) [0.04ms] agent-slack-0.10.2> ✓ sendMessage > --reply-broadcast works alongside --blocks payload [0.52ms] agent-slack-0.10.2> ✓ sendMessage > uploads attachment and uses message text as initial comment [0.74ms] agent-slack-0.10.2> ✓ sendMessage > --no-unfurl cannot be combined with file attachments [0.06ms] agent-slack-0.10.2> ✓ sendMessage > sends initial comment only for the first attachment [0.88ms] agent-slack-0.10.2> ✓ sendMessage > uploads attachment without text when text is empty [0.71ms] agent-slack-0.10.2> ✓ sendMessage > --blocks: reads Block Kit JSON from file and passes through unchanged [0.33ms] agent-slack-0.10.2> ✓ sendMessage > --blocks: errors when JSON is not an array [0.30ms] agent-slack-0.10.2> ✓ sendMessage > --blocks: errors on malformed JSON [0.30ms] agent-slack-0.10.2> ✓ sendMessage > --blocks: overrides markdown-to-rich-text conversion when text is also provided [0.39ms] agent-slack-0.10.2> ✓ sendMessage > sends Slack manual links in lists as rich-text link blocks [0.16ms] agent-slack-0.10.2> ✓ sendMessage > --blocks: errors when an array element is not an object [0.34ms] agent-slack-0.10.2> ✓ sendMessage > --schedule sends through chat.scheduleMessage and returns scheduled metadata [0.19ms] agent-slack-0.10.2> ✓ sendMessage > --schedule-in computes a relative post_at [0.11ms] agent-slack-0.10.2> ✓ sendMessage > --no-unfurl disables link and media previews for scheduled sends [0.04ms] agent-slack-0.10.2> ✓ sendMessage > --schedule composes with blocks, thread replies, and reply broadcast [0.47ms] agent-slack-0.10.2> ✓ sendMessage > --schedule cannot be combined with file attachments [0.05ms] agent-slack-0.10.2> ✓ composeMessage > --no-unfurl disables link and media previews when CI sends immediately [0.34ms] agent-slack-0.10.2> ✓ composeMessage > keeps Slack's default preview behavior for a standard CI send [0.07ms] agent-slack-0.10.2> ✓ composeMessage > --no-unfurl disables previews for a URL target when CI sends immediately [0.29ms] agent-slack-0.10.2> ✓ scheduled message management > lists scheduled messages and forwards channel filters [0.25ms] agent-slack-0.10.2> ✓ scheduled message management > cancels scheduled messages with the required channel id [0.13ms] agent-slack-0.10.2> ✓ scheduled message time parsing > parses absolute ISO timestamps with explicit timezones [0.03ms] agent-slack-0.10.2> ✓ scheduled message time parsing > parses named relative times like monday 9am [4.86ms] agent-slack-0.10.2> ✓ scheduled message time parsing > rejects schedule times beyond Slack's 120 day limit [0.04ms] agent-slack-0.10.2> ✓ editMessage > edits a normal text message without blocks [0.17ms] agent-slack-0.10.2> ✓ editMessage > edits literal angle bracket text without blocks [0.05ms] agent-slack-0.10.2> ✓ editMessage > edits a message URL with a link label without blocks [0.06ms] agent-slack-0.10.2> ✓ editMessage > edits an inline mailto link without escaping it [0.04ms] agent-slack-0.10.2> ✓ editMessage > edits an inline usergroup mention without escaping it [0.04ms] agent-slack-0.10.2> ✓ editMessage > edits a channel target with inline formatting without blocks [0.04ms] agent-slack-0.10.2> ✓ editMessage > edits a channel target with rich text blocks when text contains a list [0.07ms] agent-slack-0.10.2> ✓ editMessage > edits a normal message without blocks when no --blocks file is passed [0.05ms] agent-slack-0.10.2> ✓ editMessage > edits a message URL with Block Kit JSON from file [0.34ms] agent-slack-0.10.2> ✓ editMessage > edits a channel target with --ts and Block Kit JSON from file [0.27ms] agent-slack-0.10.2> agent-slack-0.10.2> test/compact-json.test.ts: agent-slack-0.10.2> ✓ pruneEmpty > drops null/undefined/empty containers [0.03ms] agent-slack-0.10.2> agent-slack-0.10.2> test/search-query.test.ts: agent-slack-0.10.2> ✓ W-prefixed user IDs in search > resolves a W-prefixed user ID to a from filter [0.17ms] agent-slack-0.10.2> ✓ W-prefixed user IDs in search > returns a W-prefixed user ID without scanning users [0.06ms] agent-slack-0.10.2> agent-slack-0.10.2> test/message-draft-actions.test.ts: agent-slack-0.10.2> ✓ createDraftAction > creates a draft addressed to a channel id [1.30ms] agent-slack-0.10.2> ✓ createDraftAction > rejects --broadcast without a thread [0.08ms] agent-slack-0.10.2> ✓ createDraftAction > rejects --broadcast for a DM (user) target [0.04ms] agent-slack-0.10.2> ✓ createDraftAction > rejects --broadcast for a D... channel-id (DM) target [0.02ms] agent-slack-0.10.2> ✓ createDraftAction > rejects --broadcast on a channel name with no thread before any network call [0.04ms] agent-slack-0.10.2> ✓ createDraftAction > rejects --broadcast on a DM message URL before fetching the message [0.04ms] agent-slack-0.10.2> ✓ createDraftAction > uploads --attach files and wires their file ids into the draft [1.72ms] agent-slack-0.10.2> ✓ createDraftAction > aborts before any upload or drafts.create when an --attach path is missing [0.22ms] agent-slack-0.10.2> ✓ updateDraftAction > text-only edit preserves destination, thread, broadcast, and file ids [0.33ms] agent-slack-0.10.2> ✓ updateDraftAction > re-addressing a broadcast thread draft to a non-thread channel clears broadcast instead of erroring [0.04ms] agent-slack-0.10.2> ✓ updateDraftAction > explicit --broadcast on a non-thread draft still errors [0.06ms] agent-slack-0.10.2> ✓ updateDraftAction > refuses to update a scheduled draft rather than clearing its schedule [0.05ms] agent-slack-0.10.2> ✓ updateDraftAction > refuses a text-only update on a multi-destination draft, but allows re-addressing [0.07ms] agent-slack-0.10.2> ✓ updateDraftAction > re-addressing to a different thread does not inherit the old broadcast flag [0.03ms] agent-slack-0.10.2> ✓ updateDraftAction > --no-broadcast clears an inherited broadcast flag on a same-thread edit [0.03ms] agent-slack-0.10.2> ✓ updateDraftAction > rejects --broadcast when re-addressing to a DM (user) target [0.03ms] agent-slack-0.10.2> ✓ updateDraftAction > changing only --thread-ts (no --channel) does not inherit the old broadcast flag [0.04ms] agent-slack-0.10.2> ✓ updateDraftAction > rejects --broadcast on an existing DM-destination draft [0.07ms] agent-slack-0.10.2> ✓ updateDraftAction > rejects --broadcast when re-addressing to a channel name with no thread, before resolving it [0.08ms] agent-slack-0.10.2> ✓ updateDraftAction > merges --attach file ids into the draft's existing file_ids [0.79ms] agent-slack-0.10.2> ✓ updateDraftAction > merges --attach while de-duplicating ids already on the draft [0.39ms] agent-slack-0.10.2> ✓ deleteDraftAction > auto-fetches and pads last_updated_ts when omitted [0.11ms] agent-slack-0.10.2> ✓ listDraftsAction > hydrates channel display names [0.21ms] agent-slack-0.10.2> { agent-slack-0.10.2> "ok": true, agent-slack-0.10.2> "draft": { agent-slack-0.10.2> "id": "Dr123", agent-slack-0.10.2> "destinations": [ agent-slack-0.10.2> { agent-slack-0.10.2> "channel_id": "C11111111", agent-slack-0.10.2> "thread_ts": "1700000000.100000" agent-slack-0.10.2> } agent-slack-0.10.2> ] agent-slack-0.10.2> } agent-slack-0.10.2> } agent-slack-0.10.2> ✓ message draft update (commander --broadcast wiring) > omitting broadcast flags does not force broadcast on (no Commander default-true gotcha) [0.28ms] agent-slack-0.10.2> { agent-slack-0.10.2> "ok": true, agent-slack-0.10.2> "draft": { agent-slack-0.10.2> "id": "Dr123", agent-slack-0.10.2> "destinations": [ agent-slack-0.10.2> { agent-slack-0.10.2> "channel_id": "C11111111", agent-slack-0.10.2> "thread_ts": "1700000000.100000", agent-slack-0.10.2> "broadcast": true agent-slack-0.10.2> } agent-slack-0.10.2> ] agent-slack-0.10.2> } agent-slack-0.10.2> } agent-slack-0.10.2> ✓ message draft update (commander --broadcast wiring) > --broadcast sets broadcast true [0.15ms] agent-slack-0.10.2> { agent-slack-0.10.2> "ok": true, agent-slack-0.10.2> "draft": { agent-slack-0.10.2> "id": "Dr123", agent-slack-0.10.2> "destinations": [ agent-slack-0.10.2> { agent-slack-0.10.2> "channel_id": "C11111111", agent-slack-0.10.2> "thread_ts": "1700000000.100000" agent-slack-0.10.2> } agent-slack-0.10.2> ] agent-slack-0.10.2> } agent-slack-0.10.2> } agent-slack-0.10.2> ✓ message draft update (commander --broadcast wiring) > --no-broadcast clears an inherited broadcast flag [0.08ms] agent-slack-0.10.2> { agent-slack-0.10.2> "ok": true, agent-slack-0.10.2> "draft": { agent-slack-0.10.2> "id": "DrNew", agent-slack-0.10.2> "destinations": [ agent-slack-0.10.2> { agent-slack-0.10.2> "channel_id": "C11111111" agent-slack-0.10.2> } agent-slack-0.10.2> ] agent-slack-0.10.2> } agent-slack-0.10.2> } agent-slack-0.10.2> ✓ message draft create (commander --attach wiring) > collects repeatable --attach flags into an array [1.26ms] agent-slack-0.10.2> ✓ message draft unknown subcommand > old `message draft ` usage points to `message compose` [0.21ms] agent-slack-0.10.2> ✓ draft attachments: orphan prevention across auth-retry and failed drafts > #2 create: a drafts.create auth failure retries work WITHOUT re-uploading files [0.46ms] agent-slack-0.10.2> ✓ draft attachments: orphan prevention across auth-retry and failed drafts > #2 update: a drafts.update auth failure retries work WITHOUT re-uploading files [0.55ms] agent-slack-0.10.2> ✓ draft attachments: orphan prevention across auth-retry and failed drafts > #3 create: a non-auth drafts.create failure deletes the uploaded file [0.41ms] agent-slack-0.10.2> ✓ draft attachments: orphan prevention across auth-retry and failed drafts > #3 update: a stale drafts.update failure deletes the newly uploaded file only [0.46ms] agent-slack-0.10.2> ✓ draft attachments: orphan prevention across auth-retry and failed drafts > a failed draft with no attachments does not attempt files.delete [0.05ms] agent-slack-0.10.2> agent-slack-0.10.2> test/channel-admin.test.ts: agent-slack-0.10.2> ✓ parseInviteUsersCsv > splits comma-separated values, trims whitespace, and deduplicates [0.03ms] agent-slack-0.10.2> ✓ parseInviteUsersCsv > returns empty array when input has no values agent-slack-0.10.2> ✓ splitEmailsFromInviteTargets > separates email targets from non-email targets [0.03ms] agent-slack-0.10.2> ✓ splitEmailsFromInviteTargets > deduplicates emails agent-slack-0.10.2> agent-slack-0.10.2> test/targets.test.ts: agent-slack-0.10.2> ✓ parseMsgTarget > parses slack message URLs [0.02ms] agent-slack-0.10.2> ✓ parseMsgTarget > accepts #channel agent-slack-0.10.2> ✓ parseMsgTarget > accepts bare channel names agent-slack-0.10.2> ✓ parseMsgTarget > accepts channel IDs agent-slack-0.10.2> ✓ parseMsgTarget > accepts user IDs as DM targets agent-slack-0.10.2> ✓ parseMsgTarget > accepts W-prefixed user IDs as DM targets agent-slack-0.10.2> ✓ parseMsgTarget > accepts user IDs with leading/trailing whitespace agent-slack-0.10.2> ✓ parseMsgTarget > does not treat short U-prefixed strings as user IDs agent-slack-0.10.2> ✓ parseMsgTarget > does not treat short W-prefixed strings as user IDs agent-slack-0.10.2> agent-slack-0.10.2> test/search-command.test.ts: agent-slack-0.10.2> ✓ search referenced users > searchSlack returns shared referenced_users while preserving canonical ids [1.50ms] agent-slack-0.10.2> ✓ search referenced users > search command forwards --refresh-users and bypasses cached user lookups [1.54ms] agent-slack-0.10.2> agent-slack-0.10.2> test/upload.test.ts: agent-slack-0.10.2> ✓ uploadFilesForDraft > never shifts ids between files when the completion response omits one [0.74ms] agent-slack-0.10.2> ✓ uploadFilesForDraft > falls back to staged ids when the completion response length disagrees [0.71ms] agent-slack-0.10.2> ✓ uploadFilesForDraft > stages every file, then completes them in one call with no channel binding [0.65ms] agent-slack-0.10.2> ✓ uploadFilesForDraft > a later staging failure leaves nothing completed (no orphaned files) [0.69ms] agent-slack-0.10.2> ✓ uploadFilesForDraft > throws and completes nothing when a path does not exist [0.18ms] agent-slack-0.10.2> ✓ uploadFilesForDraft > throws and completes nothing when a byte POST fails [0.45ms] agent-slack-0.10.2> ✓ uploadFilesForDraft > throws when files.completeUploadExternal fails [1.16ms] agent-slack-0.10.2> ✓ uploadFilesForDraft > throws when the path is a directory [0.34ms] agent-slack-0.10.2> ✓ uploadLocalFileToSlack (shared-helper regression) > still binds the completed file to a channel with an initial comment [0.39ms] agent-slack-0.10.2> agent-slack-0.10.2> test/html-to-md.test.ts: agent-slack-0.10.2> ✓ htmlToMarkdown > converts basic HTML to markdown [2.29ms] agent-slack-0.10.2> agent-slack-0.10.2> test/safe-mode.test.ts: agent-slack-0.10.2> ✓ isSafeModeEnabled > enabled via CLI flag [0.02ms] agent-slack-0.10.2> ✓ isSafeModeEnabled > enabled for env value "1" [0.01ms] agent-slack-0.10.2> ✓ isSafeModeEnabled > enabled for env value "true" agent-slack-0.10.2> ✓ isSafeModeEnabled > enabled for env value "TRUE" agent-slack-0.10.2> ✓ isSafeModeEnabled > enabled for env value "yes" agent-slack-0.10.2> ✓ isSafeModeEnabled > enabled for env value "on" agent-slack-0.10.2> ✓ isSafeModeEnabled > enabled for env value " 1 " agent-slack-0.10.2> ✓ isSafeModeEnabled > disabled for env value "0" agent-slack-0.10.2> ✓ isSafeModeEnabled > disabled for env value "false" agent-slack-0.10.2> ✓ isSafeModeEnabled > disabled for env value "off" agent-slack-0.10.2> ✓ isSafeModeEnabled > disabled for env value "no" agent-slack-0.10.2> ✓ isSafeModeEnabled > disabled for env value "" agent-slack-0.10.2> ✓ isSafeModeEnabled > disabled when env var is unset and flag is absent agent-slack-0.10.2> ✓ safeModeBlockedError > names the blocked action [0.01ms] agent-slack-0.10.2> ✓ redirectSendToDraft > rejects unsupported send option { agent-slack-0.10.2> attach: [ "./report.md" ], agent-slack-0.10.2> } [0.09ms] agent-slack-0.10.2> ✓ redirectSendToDraft > rejects unsupported send option { agent-slack-0.10.2> blocks: "/tmp/blocks.json", agent-slack-0.10.2> } agent-slack-0.10.2> ✓ redirectSendToDraft > rejects unsupported send option { agent-slack-0.10.2> schedule: "2030-01-01T00:00:00Z", agent-slack-0.10.2> } agent-slack-0.10.2> ✓ redirectSendToDraft > rejects unsupported send option { agent-slack-0.10.2> scheduleIn: "3h", agent-slack-0.10.2> } agent-slack-0.10.2> ✓ redirectSendToDraft > rejects unsupported send option { agent-slack-0.10.2> replyBroadcast: true, agent-slack-0.10.2> } agent-slack-0.10.2> ✓ redirectSendToDraft > lists all unsupported flags at once [0.02ms] agent-slack-0.10.2> ✓ redirectSendToDraft > rejects in CI where no interactive editor is available [0.04ms] agent-slack-0.10.2> ⚠ Safe mode active: redirecting "message send" → draft editor. Nothing posts until a human sends it from the editor. agent-slack-0.10.2> ✓ redirectSendToDraft > opens a draft with the send text and thread context [0.09ms] agent-slack-0.10.2> agent-slack-0.10.2> test/files.test.ts: agent-slack-0.10.2> ✓ downloadSlackFile > downloads file and writes to disk [1.46ms] agent-slack-0.10.2> ✓ downloadSlackFile > returns cached path when file already exists [0.37ms] agent-slack-0.10.2> ✓ downloadSlackFile > throws SlackDownloadError on HTTP 404 [0.27ms] agent-slack-0.10.2> ✓ downloadSlackFile > throws SlackDownloadError with httpStatus on HTTP error [0.18ms] agent-slack-0.10.2> ✓ downloadSlackFile > throws SlackDownloadError on HTML auth page [0.20ms] agent-slack-0.10.2> ✓ downloadSlackFile > throws SlackDownloadError on network error [0.26ms] agent-slack-0.10.2> ✓ downloadSlackFile > throws SlackDownloadError when reading html body fails [0.22ms] agent-slack-0.10.2> ✓ downloadSlackFile > throws SlackDownloadError when reading binary body fails [0.16ms] agent-slack-0.10.2> ✓ tryDownloadSlackFile > returns ok result on success [0.37ms] agent-slack-0.10.2> ✓ tryDownloadSlackFile > returns failure result on HTTP 404 [0.16ms] agent-slack-0.10.2> ✓ tryDownloadSlackFile > returns failure result on network error [0.12ms] agent-slack-0.10.2> ✓ tryDownloadSlackFile > propagates disk/write errors [0.36ms] agent-slack-0.10.2> Warning: skipping file F1: Downloaded auth/login page instead of canvas content (token may be expired) agent-slack-0.10.2> ✓ downloadMessageFiles > records canvas auth failures as structured errors [1.23ms] agent-slack-0.10.2> Warning: skipping file F2: Failed to download file (404) agent-slack-0.10.2> ✓ downloadMessageFiles > records non-canvas download failures with a local error path [0.63ms] agent-slack-0.10.2> agent-slack-0.10.2> test/channels.test.ts: agent-slack-0.10.2> ✓ conversations list helpers > listUserConversations calls users.conversations with defaults [0.08ms] agent-slack-0.10.2> ✓ conversations list helpers > listUserConversations forwards user/limit/cursor [0.03ms] agent-slack-0.10.2> ✓ conversations list helpers > listAllConversations calls conversations.list with defaults [0.03ms] agent-slack-0.10.2> ✓ conversations list helpers > listAllConversations forwards limit/cursor [0.02ms] agent-slack-0.10.2> ✓ conversations list helpers > listUserConversations passes through small limits [0.02ms] agent-slack-0.10.2> ✓ conversations list helpers > listUserConversations clamps high limits to 1000 [0.02ms] agent-slack-0.10.2> ✓ conversations list helpers > normalizeConversationsPage extracts channels and next cursor [0.01ms] agent-slack-0.10.2> ✓ conversations list helpers > normalizeConversationsPage handles missing response_metadata agent-slack-0.10.2> ✓ conversations list helpers > normalizeConversationsPage handles empty next_cursor agent-slack-0.10.2> ✓ conversations list helpers > listConversationsViaCounts enumerates channels/mpims/ims and enriches via conversations.info [0.18ms] agent-slack-0.10.2> ✓ conversations list helpers > listConversationsViaCounts keeps the id when conversations.info fails [0.06ms] agent-slack-0.10.2> ✓ conversations list helpers > listConversationsViaCounts slices to limit and skips entries without an id [0.06ms] agent-slack-0.10.2> agent-slack-0.10.2> test/update.test.ts: agent-slack-0.10.2> ✓ compareSemver > equal versions return 0 [0.04ms] agent-slack-0.10.2> ✓ compareSemver > strips v prefix agent-slack-0.10.2> ✓ compareSemver > newer major agent-slack-0.10.2> ✓ compareSemver > newer minor agent-slack-0.10.2> ✓ compareSemver > newer patch agent-slack-0.10.2> ✓ compareSemver > older version returns negative agent-slack-0.10.2> ✓ compareSemver > handles 0.x versions agent-slack-0.10.2> agent-slack-0.10.2> test/reactions.test.ts: agent-slack-0.10.2> ✓ reactions compaction > includes reactions only when enabled [0.10ms] agent-slack-0.10.2> ✓ reactions compaction > preserves W-prefixed user IDs while compacting reactions [0.02ms] agent-slack-0.10.2> ✓ reactions compaction > adds forwarded thread metadata for shared messages with thread_ts [0.14ms] agent-slack-0.10.2> agent-slack-0.10.2> test/emoji.test.ts: agent-slack-0.10.2> ✓ normalizeSlackReactionName > accepts :shortcode: [0.01ms] agent-slack-0.10.2> ✓ normalizeSlackReactionName > accepts raw names agent-slack-0.10.2> ✓ normalizeSlackReactionName > accepts unicode emoji [0.02ms] agent-slack-0.10.2> agent-slack-0.10.2> test/client.test.ts: agent-slack-0.10.2> ✓ SlackApiClient browser multipart transport > retries HTTP 429 responses using Retry-After [0.61ms] agent-slack-0.10.2> agent-slack-0.10.2> test/url.test.ts: agent-slack-0.10.2> ✓ parseSlackMessageUrl > parses archives URL with p [0.03ms] agent-slack-0.10.2> ✓ parseSlackMessageUrl > captures thread_ts from query when present [0.02ms] agent-slack-0.10.2> ✓ buildSlackMessageUrl > builds a permalink for a root message [0.01ms] agent-slack-0.10.2> ✓ buildSlackMessageUrl > includes thread metadata for replies agent-slack-0.10.2> agent-slack-0.10.2> test/render.test.ts: agent-slack-0.10.2> ✓ renderSlackMessageContent > prefers blocks [0.04ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > preserves usergroup and broadcast elements from rich text [0.15ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > omits malformed usergroup and broadcast elements [0.04ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > falls back to attachments when text is empty [0.04ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > includes section fields and button URLs [0.04ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > includes attachment fields [0.03ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > renders forwarded message with author and source link [0.05ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > renders forwarded message with author name only [0.02ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > renders forwarded message with no author [0.02ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > includes forwarded file links in quoted forwarded body [0.02ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > renders nested forwarded attachments similarly to normal attachments [0.02ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > deduplicates repeated forwarded body content [0.02ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > handles cyclic forwarded attachments without infinite recursion [0.02ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > does not treat link unfurl as forwarded message [0.01ms] agent-slack-0.10.2> ✓ renderSlackMessageContent > combines blocks and non-shared attachments [0.01ms] agent-slack-0.10.2> agent-slack-0.10.2> test/later.test.ts: agent-slack-0.10.2> ✓ fetchLaterItems > returns counts only when countsOnly is true [0.20ms] agent-slack-0.10.2> ✓ fetchLaterItems > filters to message items only [0.22ms] agent-slack-0.10.2> ✓ fetchLaterItems > filters by state [0.11ms] agent-slack-0.10.2> ✓ fetchLaterItems > state 'all' returns all items [0.04ms] agent-slack-0.10.2> ✓ fetchLaterItems > respects limit [0.04ms] agent-slack-0.10.2> ✓ fetchLaterItems > hydrates message content [0.05ms] agent-slack-0.10.2> ✓ fetchLaterItems > resolves DM user display names [0.04ms] agent-slack-0.10.2> ✓ fetchLaterItems > truncates long message content [0.04ms] agent-slack-0.10.2> ✓ updateLaterMark > sends mark=completed via multipart [0.05ms] agent-slack-0.10.2> ✓ updateLaterMark > sends mark=archived via multipart [0.02ms] agent-slack-0.10.2> ✓ updateLaterMark > sends mark=uncompleted via multipart [0.01ms] agent-slack-0.10.2> ✓ updateLaterMark > sends mark=unarchived via multipart [0.01ms] agent-slack-0.10.2> ✓ saveLater > calls saved.add with correct params [0.03ms] agent-slack-0.10.2> ✓ removeLater > calls saved.delete with correct params [0.03ms] agent-slack-0.10.2> ✓ setLaterReminder > calls saved.update via multipart with date_due [0.04ms] agent-slack-0.10.2> ✓ parseReminderDuration > parses minutes [0.08ms] agent-slack-0.10.2> ✓ parseReminderDuration > parses hours agent-slack-0.10.2> ✓ parseReminderDuration > parses fractional hours agent-slack-0.10.2> ✓ parseReminderDuration > parses days agent-slack-0.10.2> ✓ parseReminderDuration > parses 'tomorrow' as next day 9 AM [0.03ms] agent-slack-0.10.2> ✓ parseReminderDuration > parses day names agent-slack-0.10.2> ✓ parseReminderDuration > passes through unix timestamps agent-slack-0.10.2> ✓ parseReminderDuration > supports verbose unit names [0.01ms] agent-slack-0.10.2> ✓ parseReminderDuration > throws on invalid input [0.03ms] agent-slack-0.10.2> agent-slack-0.10.2> test/drafts.test.ts: agent-slack-0.10.2> ✓ padDraftTs > pads short fractional parts to 7 digits agent-slack-0.10.2> ✓ padDraftTs > leaves 7-digit fractional parts unchanged agent-slack-0.10.2> ✓ padDraftTs > leaves timestamps without a fractional part unchanged agent-slack-0.10.2> ✓ draftTextToBlocks > wraps plain text in a rich_text section [0.04ms] agent-slack-0.10.2> ✓ draftTextToBlocks > converts bullet lists to rich_text lists [0.02ms] agent-slack-0.10.2> ✓ parseDraftRecord > parses a raw draft into a compact shape [0.10ms] agent-slack-0.10.2> ✓ parseDraftRecord > returns null for records without an id agent-slack-0.10.2> ✓ listDrafts > requests active drafts and parses the result [0.09ms] agent-slack-0.10.2> ✓ listDrafts > omits is_active when activeOnly is false [0.04ms] agent-slack-0.10.2> ✓ createDraft > sends blocks, destination, and composer flag [0.07ms] agent-slack-0.10.2> ✓ createDraft > omits thread fields for channel drafts [0.03ms] agent-slack-0.10.2> ✓ createDraft > includes file_ids on the wire when fileIds is supplied [0.03ms] agent-slack-0.10.2> ✓ updateDraft > sends draft_id and a padded last-updated ts [0.10ms] agent-slack-0.10.2> ✓ deleteDraft > deletes with an explicit last-updated ts [0.08ms] agent-slack-0.10.2> ✓ deleteDraft > fetches the last-updated ts from drafts.list when omitted [0.15ms] agent-slack-0.10.2> ✓ deleteDraft > throws when the draft does not exist [0.02ms] agent-slack-0.10.2> ✓ findDraft > lists all drafts (including inactive) and finds by id [0.05ms] agent-slack-0.10.2> ✓ findDraft > prefers a matching record that has last_updated_ts over a malformed duplicate [0.03ms] agent-slack-0.10.2> agent-slack-0.10.2> test/search-files.test.ts: agent-slack-0.10.2> Warning: skipping file F1: Failed to download file (404) agent-slack-0.10.2> ✓ searchFilesViaSearchApi > skips failed downloads and keeps later successful matches [1.07ms] agent-slack-0.10.2> Warning: skipping file F1: Failed to download file (404) agent-slack-0.10.2> ✓ searchFilesInChannelsFallback > continues after a failed download in files.list results [1.01ms] agent-slack-0.10.2> ✓ SlackApiClient browser API guards > fails fast on rate-limit retry windows by default [0.40ms] agent-slack-0.10.2> ✓ SlackApiClient browser API guards > surfaces request timeouts with the Slack method name [0.09ms] agent-slack-0.10.2> agent-slack-0.10.2> test/error-message.test.ts: agent-slack-0.10.2> ✓ errorMessage > returns the message for a plain error [0.07ms] agent-slack-0.10.2> ✓ errorMessage > stringifies non-Error values [0.02ms] agent-slack-0.10.2> ✓ errorMessage > appends a single Error cause [0.01ms] agent-slack-0.10.2> ✓ errorMessage > appends AggregateError causes from a failed fetch through a dead proxy [0.02ms] agent-slack-0.10.2> ✓ errorMessage > walks multi-level cause chains [0.01ms] agent-slack-0.10.2> ✓ errorMessage > terminates on a self-referential cause instead of looping forever agent-slack-0.10.2> ✓ errorMessage > terminates on a longer cause cycle agent-slack-0.10.2> ✓ errorMessage > does not crash on a cause that cannot be stringified [0.03ms] agent-slack-0.10.2> ✓ errorMessage > does not crash on a non-Error thrown value that cannot be stringified agent-slack-0.10.2> ✓ errorMessage > caps how far a long cause chain is walked [0.11ms] agent-slack-0.10.2> ✓ errorMessage > collapses a cause that merely restates its parent [0.01ms] agent-slack-0.10.2> agent-slack-0.10.2> test/canvas-create.test.ts: agent-slack-0.10.2> ✓ createCanvasFromMarkdown > sends Markdown content, title, and channel to canvases.create [0.14ms] agent-slack-0.10.2> ✓ createCanvasFromMarkdown > rejects empty Markdown before calling Slack [0.04ms] agent-slack-0.10.2> ✓ createCanvasFromMarkdown > rejects a success response without a canvas id [0.02ms] agent-slack-0.10.2> ✓ createCanvasFromMarkdown > uses Slack's Markdown canvas method with imported browser credentials [0.03ms] agent-slack-0.10.2> ✓ createCanvasFromMarkdown > rejects channel tabs with browser credentials before calling Slack [0.03ms] agent-slack-0.10.2> ✓ editCanvas > sends the documented replace change [0.19ms] agent-slack-0.10.2> ✓ editCanvas > sends the documented replace section change agent-slack-0.10.2> ✓ editCanvas > sends the documented insert before change agent-slack-0.10.2> ✓ editCanvas > sends the documented insert after change agent-slack-0.10.2> ✓ editCanvas > sends the documented insert at start change agent-slack-0.10.2> ✓ editCanvas > sends the documented insert at end change agent-slack-0.10.2> ✓ editCanvas > sends the documented delete section change agent-slack-0.10.2> ✓ editCanvas > sends the documented rename change agent-slack-0.10.2> ✓ editCanvas > rejects invalid combinations before calling Slack [0.10ms] agent-slack-0.10.2> ✓ editCanvas > rejects empty Markdown and canvas ids before calling Slack [0.04ms] agent-slack-0.10.2> ✓ editCanvas > rejects Markdown over Slack's per-change limit before calling Slack [5.56ms] agent-slack-0.10.2> ✓ readCanvasMarkdownInput > reads a Markdown file without changing its contents [0.58ms] agent-slack-0.10.2> ✓ readCanvasMarkdownInput > accepts a Markdown blob [0.04ms] agent-slack-0.10.2> ✓ readCanvasMarkdownInput > requires exactly one source [0.03ms] agent-slack-0.10.2> ✓ readCanvasMarkdownInput > rejects an empty source [0.02ms] agent-slack-0.10.2> ✓ canvas create command > creates from an inline blob in the selected workspace [0.49ms] agent-slack-0.10.2> ✓ canvas create command > creates from a file and resolves a channel tab [0.73ms] agent-slack-0.10.2> ✓ canvas create command > rejects browser-auth channel tabs before resolving the channel [0.20ms] agent-slack-0.10.2> ✓ canvas create command > rejects missing or conflicting sources before authenticating [0.11ms] agent-slack-0.10.2> ✓ canvas edit command > replaces a canvas from a Markdown URL target [0.48ms] agent-slack-0.10.2> ✓ canvas edit command > inserts content from a file and passes a section id [0.60ms] agent-slack-0.10.2> ✓ canvas edit command > renames without a Markdown source [0.13ms] agent-slack-0.10.2> ✓ canvas edit command > rejects delete content and malformed inputs before authenticating [0.16ms] agent-slack-0.10.2> ✓ canvas edit command > rejects browser credentials before calling canvases.edit [0.10ms] agent-slack-0.10.2> agent-slack-0.10.2> 399 pass agent-slack-0.10.2> 0 fail agent-slack-0.10.2> 817 expect() calls agent-slack-0.10.2> Ran 399 tests across 38 files. [243.00ms] agent-slack-0.10.2> Running phase: installPhase agent-slack-0.10.2> Running phase: fixupPhase agent-slack-0.10.2> checking for references to /nix/var/nix/builds/nix-2639-371822206/ in /nix/store/8v7h5iprb7p7dx4wyn0vddrqbqxwkrkq-agent-slack-0.10.2... agent-slack-0.10.2> patching script interpreter paths in /nix/store/8v7h5iprb7p7dx4wyn0vddrqbqxwkrkq-agent-slack-0.10.2 agent-slack-0.10.2> Running phase: installCheckPhase agent-slack-0.10.2> Executing versionCheckPhase agent-slack-0.10.2> Successfully managed to find version 0.10.2 in the output of the command /nix/store/8v7h5iprb7p7dx4wyn0vddrqbqxwkrkq-agent-slack-0.10.2/bin/agent-slack --version agent-slack-0.10.2> 0.10.2 agent-slack-0.10.2> Finished versionCheckPhase agent-slack-0.10.2> no Makefile or custom installCheckPhase, doing nothing building '/nix/store/k0ky683alzn5z5pfglppbqjryl0vqm8q-check-agent-slack.drv' on 'ssh-ng://customer@mac02.m.ntd.one' building '/nix/store/k0ky683alzn5z5pfglppbqjryl0vqm8q-check-agent-slack.drv' upload niks3: ok