(args: {
channel: string;
threadTs: string;
filePath: string;
initialComment: string | undefined;
sender: string;
agentId: string | undefined;
workspace: string | undefined;
})
| 121 | } |
| 122 | |
| 123 | async function uploadFileToThread(args: { |
| 124 | channel: string; |
| 125 | threadTs: string; |
| 126 | filePath: string; |
| 127 | initialComment: string | undefined; |
| 128 | sender: string; |
| 129 | agentId: string | undefined; |
| 130 | workspace: string | undefined; |
| 131 | }): Promise<void> { |
| 132 | const allowedThread = loadAllowedSlackThreadOrBail(args.workspace); |
| 133 | if (!existsSync(args.filePath) || !statSync(args.filePath).isFile()) { |
| 134 | throw new Error( |
| 135 | `--file path is missing or not a regular file: ${args.filePath}` |
| 136 | ); |
| 137 | } |
| 138 | // Non-operators can only upload files from the run workspace. |
| 139 | if (allowedThread !== undefined) { |
| 140 | assertThreadAllowed(args.threadTs, allowedThread); |
| 141 | if (!args.workspace) { |
| 142 | throw new Error( |
| 143 | "--file requires --workspace so uploads stay confined to the run's workspace" |
| 144 | ); |
| 145 | } |
| 146 | assertFileInsideWorkspace(args.filePath, args.workspace); |
| 147 | } |
| 148 | const slack = createSlackAdapter(args.channel); |
| 149 | if (!slack) { |
| 150 | throw new Error("SLACK_BOT_TOKEN not set; cannot upload Slack file"); |
| 151 | } |
| 152 | const content = readFileSync(args.filePath); |
| 153 | const initial = |
| 154 | args.initialComment ?? `${args.sender} attached ${basename(args.filePath)}`; |
| 155 | const safeInitial = requireSafeCommentBody(initial); |
| 156 | await slack.uploadFileToThread({ |
| 157 | threadTs: args.threadTs, |
| 158 | filename: basename(args.filePath), |
| 159 | content, |
| 160 | initialComment: appendAgentFooter(safeInitial, args.agentId), |
| 161 | }); |
| 162 | } |
| 163 | |
| 164 | function requireSafeCommentBody(body: string): string { |
| 165 | const result = redactBody(body); |
no test coverage detected