Commit e873743c by Hermes Desktop

feat(skills): update media-delivery

parent 7eb7210c
--- ---
name: media-delivery name: media-delivery
description: Send files through messaging platforms via Hermes MEDIA protocol — path rules, Windows quirks, allowed directories, and per-platform limitations. description: Send files to users via MEDIA protocol (native attachments) or Markdown links (workspace files) — path rules, Windows quirks, Chinese filename handling, and per-platform limitations.
version: 1.1.0 version: 1.2.0
author: Hermes Agent author: Hermes Agent
platforms: [windows, linux, macos] platforms: [windows, linux, macos]
metadata: metadata:
hermes: hermes:
tags: [media, delivery, weixin, wechat, telegram, files, attachments, gateway] tags: [media, delivery, weixin, wechat, telegram, files, attachments, gateway, markdown]
--- ---
# Media Delivery (MEDIA Protocol) # Media Delivery (MEDIA Protocol)
...@@ -26,9 +26,48 @@ Hermes detects the `MEDIA:` prefix, validates the path against security rules, a ...@@ -26,9 +26,48 @@ Hermes detects the `MEDIA:` prefix, validates the path against security rules, a
| 问题现象 | 可能原因 | 解决方案 | | 问题现象 | 可能原因 | 解决方案 |
|---------|---------|---------| |---------|---------|---------|
| `Skipping unsafe MEDIA directive path` | Windows 路径格式错误 | 使用 `C:/...` 而非 `/c/...` | | `Skipping unsafe MEDIA directive path` | Windows 路径格式错误 | 使用 `C:/...` 而非 `/c/...` |
| 文件存在但无法下载 | 中文/空格/特殊字符 | 用尖括号 `](</path/文件.docx>)` | | 文件存在但无法下载 | 中文/空格/特殊字符 | 用尖括号 `](</path/文件.docx>)` 或重命名 |
| 文件找不到 | 不在允许目录 | 移到 `~/.hermes/cache/<type>/` | | 文件找不到 | 不在允许目录 | 移到 `~/.hermes/cache/<type>/` `~/.hermes/workspace/` |
| 下载失败无报错 | 文件名含中文/空格 | 重命名为英文 或 用尖括号 | | 下载失败无报错 | 文件名含中文/空格 | 重命名为英文 或 用尖括号 |
| `.md` 文件无法下载 | 在 cache 目录被限制 | 移到 `workspace/` 目录 |
| `File is outside the session` | Markdown 链接路径不在 workspace | 用 MEDIA 协议 或 移到 workspace |
### 两种交付方式对比
| 方式 | 语法 | 适用场景 | 路径要求 | 中文文件名 |
|-----|------|---------|---------|-----------|
| **MEDIA 协议** | `MEDIA:/path/to/file` | 原生附件(图片/视频/音频/文档) | cache 目录或 workspace | ✅ 支持 |
| **Markdown 链接** | `[name](/path/to/file)` | 普通文件下载 | **必须在 workspace** | ⚠️ 需尖括号 |
### 路径选择决策树
```
用户需要下载文件
├─ 文件在 ~/.hermes/cache/* ?
│ └─ 是 → 用 MEDIA 协议 (推荐)
│ 或 重命名后 Markdown 链接 (不推荐)
├─ 文件在 ~/.hermes/workspace/ ?
│ └─ 是 → 用 Markdown 链接 (推荐)
│ 或 MEDIA 协议 (也支持)
└─ 文件在其他位置 ?
└─ 复制文件到 workspace 或 cache,然后发送
```
### 中文文件名处理规则
| 文件名特征 | MEDIA 协议 | Markdown 链接 |
|-----------|-----------|--------------|
| 纯英文无空格 | ✅ `MEDIA:~/file.docx` | ✅ `[file](~/file.docx)` |
| 英文有空格 | ✅ `MEDIA:~/my file.docx` | ⚠️ `[file](</path/my file.docx>)` |
| 含中文 | ✅ `MEDIA:~/文件.docx` | ⚠️ `[文件](</path/文件.docx>)` |
| 含特殊字符 | ✅ `MEDIA:~/文件 (1).docx` | ⚠️ `[文件](</path/文件 (1).docx>)` |
**最佳实践**
- **MEDIA 协议**:优先使用,支持所有文件名
- **Markdown 链接**:仅用于 workspace 目录,中文文件名必须用尖括号
--- ---
...@@ -38,26 +77,35 @@ The gateway's `validate_media_delivery_path()` function enforces: ...@@ -38,26 +77,35 @@ The gateway's `validate_media_delivery_path()` function enforces:
### Allowed Directories (safe roots) ### Allowed Directories (safe roots)
Files **must** live under one of these Hermes-managed cache directories: Files **must** live under one of these directories:
| Directory | Content type | MEDIA 协议 | Markdown 链接 |
|-----------|-------------|-----------|--------------|
| `~/.hermes/cache/images/` | Images (jpg, png, webp, gif) | ✅ | ⚠️ 不推荐 |
| `~/.hermes/cache/audio/` | Audio (ogg, opus, mp3, wav, m4a, flac) | ✅ | ⚠️ 不推荐 |
| `~/.hermes/cache/videos/` | Video (mp4, mov, avi, mkv, webm, 3gp) | ✅ | ⚠️ 不推荐 |
| `~/.hermes/cache/documents/` | Documents & other files | ✅ | ⚠️ 部分格式限制 |
| `~/.hermes/workspace/` | **Session workspace (推荐)** | ✅ | ✅ **推荐** |
| `~/.hermes/browser_screenshots/` | Screenshots | ✅ | ⚠️ 不推荐 |
| `~/.hermes/image_cache/` | Legacy image cache | ✅ | ⚠️ 不推荐 |
| `~/.hermes/audio_cache/` | Legacy audio cache | ✅ | ⚠️ 不推荐 |
| `~/.hermes/video_cache/` | Legacy video cache | ✅ | ⚠️ 不推荐 |
| `~/.hermes/document_cache/` | Legacy document cache | ✅ | ⚠️ 不推荐 |
| Directory | Content type | **推荐做法**
|-----------|-------------| - **MEDIA 协议**:文件放在任意 cache 目录或 workspace
| `~/.hermes/cache/images/` | Images (jpg, png, webp, gif) | - **Markdown 链接****仅用于 workspace 目录**,避免 cache 目录的格式限制
| `~/.hermes/cache/audio/` | Audio (ogg, opus, mp3, wav, m4a, flac) |
| `~/.hermes/cache/videos/` | Video (mp4, mov, avi, mkv, webm, 3gp) |
| `~/.hermes/cache/documents/` | Documents & other files |
| `~/.hermes/browser_screenshots/` | Screenshots |
| `~/.hermes/image_cache/` | Legacy image cache |
| `~/.hermes/audio_cache/` | Legacy audio cache |
| `~/.hermes/video_cache/` | Legacy video cache |
| `~/.hermes/document_cache/` | Legacy document cache |
To place a file for delivery, copy it into one of these directories first: To place a file for delivery:
```bash ```bash
# Example: deliver a document # Option A: Copy to cache directory (for MEDIA protocol)
cp /some/output/report.pdf ~/.hermes/cache/documents/ cp /some/output/report.pdf ~/.hermes/cache/documents/
MEDIA:~/.hermes/cache/documents/report.pdf MEDIA:~/.hermes/cache/documents/report.pdf
# Option B: Copy to workspace (for Markdown links)
cp /some/output/report.pdf ~/.hermes/workspace/
# Then use: [report](/home/lcai/.hermes/workspace/report.pdf)
``` ```
### Denied Locations (always rejected) ### Denied Locations (always rejected)
...@@ -106,78 +154,78 @@ MEDIA:C:/Users/Administrator/.hermes/cache/documents/report.pdf ...@@ -106,78 +154,78 @@ MEDIA:C:/Users/Administrator/.hermes/cache/documents/report.pdf
## 2.5 空格与中文文件名处理 (CRITICAL) ## 2.5 空格与中文文件名处理 (CRITICAL)
**文件名包含空格、中文或特殊字符时,Markdown 链接无法正确解析。** **文件名包含空格、中文或特殊字符时,Markdown 链接需要特殊处理。**
### 问题示例 ### 问题示例
```markdown ```markdown
# ❌ 失败 - 中文文件名 # ❌ 失败 - 中文文件名
[申请表.docx](/home/lcai/.hermes/cache/documents/申请表.docx) [申请表.docx](/home/lcai/.hermes/workspace/申请表.docx)
# ❌ 失败 - 空格文件名 # ❌ 失败 - 空格文件名
[my report.pdf](/home/lcai/.hermes/cache/documents/my report.pdf) [my report.pdf](/home/lcai/.hermes/workspace/my report.pdf)
# ✅ 成功 - 使用尖括号包裹 # ✅ 成功 - 使用尖括号包裹
[申请表.docx](</home/lcai/.hermes/cache/documents/申请表.docx>) [申请表.docx](</home/lcai/.hermes/workspace/申请表.docx>)
[my report.pdf](</home/lcai/.hermes/cache/documents/my report.pdf>) [my report.pdf](</home/lcai/.hermes/workspace/my report.pdf>)
``` ```
### 规则总结 ### 规则总结
| 文件名特征 | 无尖括号 | 有尖括号 | 推荐做法 | | 文件名特征 | MEDIA 协议 | Markdown 链接 (无尖括号) | Markdown 链接 (有尖括号) | 推荐做法 |
|-----------|---------|---------|---------| |-----------|-----------|---------|---------|---------|
| 纯英文无空格 | ✅ | ✅ | 任意格式 | | 纯英文无空格 | ✅ | ✅ | ✅ | 任意格式 |
| 英文有空格 | ❌ | ✅ | **必须用尖括号** | | 英文有空格 | ✅ | ❌ | ✅ | **Markdown 用尖括号** |
| 含中文 | ❌ | ✅ | **必须用尖括号** | | 含中文 | ✅ | ❌ | ✅ | **MEDIA 优先 或 Markdown 用尖括号** |
| 含特殊字符 `()[]#?` | ❌ | ✅ | **必须用尖括号** | | 含特殊字符 `()[]#?` | ✅ | ❌ | ✅ | **MEDIA 优先 或 Markdown 用尖括号** |
### 三种解决方案 ### 三种解决方案
#### 方案 A: 使用尖括号(推荐用于中文文件名) #### 方案 A: 使用 MEDIA 协议(推荐用于中文文件名)
```
MEDIA:/home/lcai/.hermes/workspace/2026 年申请表.docx
```
**最佳**:MEDIA 协议原生支持中文文件名,无需特殊处理
#### 方案 B: 使用尖括号(Markdown 链接的中文文件名)
```markdown ```markdown
[2026 年申请表](</home/lcai/.hermes/cache/documents/2026 年申请表.docx>) [2026 年申请表](</home/lcai/.hermes/workspace/2026 年申请表.docx>)
``` ```
⚠️ **可行**:但必须用尖括号包裹路径
#### 方案 B: 重命名为英文(最佳兼容性) #### 方案 C: 重命名为英文(最佳兼容性)
```bash ```bash
# 重命名文件 # 重命名文件
mv "2026 年申请表.docx" "2026-Application-Form.docx" mv "2026 年申请表.docx" "2026-Application-Form.docx"
``` ```
然后发送: 然后发送:
```markdown ```markdown
[2026 年申请表](/home/lcai/.hermes/cache/documents/2026-Application-Form.docx) [2026 年申请表](/home/lcai/.hermes/workspace/2026-Application-Form.docx)
```
#### 方案 C: URL 编码(高级)
```python
import urllib.parse
filename = "2026 年申请表.docx"
encoded = urllib.parse.quote(filename, safe='')
# 输出: 2026%20%E5%B9%B4%E7%94%B3%E8%AF%B7%E8%A1%A8.docx
```
```markdown
[申请表](/home/lcai/.hermes/cache/documents/2026%20%E5%B9%B4%E7%94%B3%E8%AF%B7%E8%A1%A8.docx)
``` ```
**最兼容**:避免所有格式问题
### 最佳实践 ### 最佳实践
1. **优先使用英文文件名**:避免所有兼容性问题 1. **优先使用 MEDIA 协议处理中文文件名**
```bash ```
# 推荐命名 MEDIA:/home/lcai/.hermes/workspace/2026 年湖南省未来产业创新发展优秀典型案例申请表.docx
mv "2026 年湖南省未来产业创新发展优秀典型案例申请表.docx" \
"2026-Hunan-Innovation-Application.docx"
``` ```
✅ 原生支持,无需特殊处理
2. **如果必须用中文,始终用尖括号** 2. **如果必须用 Markdown 链接,始终用尖括号**:
```markdown ```markdown
[文件](</path/to/文件.docx>) # ✅ 正确 [申请表](</path/to/文件.docx>) # ✅ 正确
[文件](/path/to/文件.docx) # ❌ 错误 [申请表](/path/to/文件.docx) # ❌ 错误
``` ```
3. **避免特殊字符**: 3. **避免特殊字符**:
- ✅ `2026-申请表_v1.docx` - ✅ `2026-申请表_v1.docx`
- ❌ `2026 年 (最终版)[确认].docx` - ❌ `2026 年 (最终版)[确认].docx`
4. **文件位置选择**:
- **workspace 目录**:✅ 支持 Markdown 链接和 MEDIA 协议
- **cache 目录**:⚠️ 仅推荐 MEDIA 协议,部分格式(如 `.md`)可能被限制
--- ---
## 3. File-Type Detection ## 3. File-Type Detection
...@@ -204,17 +252,17 @@ The gateway auto-detects the content type from the file extension: ...@@ -204,17 +252,17 @@ The gateway auto-detects the content type from the file extension:
### 中文文件名和特殊字符处理 (CRITICAL) ### 中文文件名和特殊字符处理 (CRITICAL)
**当文件名包含中文、空格或特殊字符时,Markdown 链接可能无法正确解析** **当文件名包含中文、空格或特殊字符时,Markdown 链接需要尖括号包裹。**
#### 问题示例 #### 问题示例
```markdown ```markdown
[2026 年湖南省未来产业创新发展优秀典型案例申请表.docx](/home/lcai/.hermes/cache/documents/2026 年湖南省未来产业创新发展优秀典型案例申请表.docx) [2026 年湖南省未来产业创新发展优秀典型案例申请表.docx](/home/lcai/.hermes/workspace/2026 年湖南省未来产业创新发展优秀典型案例申请表.docx)
``` ````
❌ **失败**:中文字符导致 Markdown 解析器无法正确识别路径 ❌ **失败**:中文字符导致 Markdown 解析器无法正确识别路径
#### 解决方案:使用尖括号包裹路径 #### 解决方案:使用尖括号包裹路径
```markdown ```markdown
[2026 年湖南省未来产业创新发展优秀典型案例申请表.docx](</home/lcai/.hermes/cache/documents/2026 年湖南省未来产业创新发展优秀典型案例申请表.docx>) [2026 年湖南省未来产业创新发展优秀典型案例申请表.docx](</home/lcai/.hermes/workspace/2026 年湖南省未来产业创新发展优秀典型案例申请表.docx>)
``` ```
✅ **成功**:尖括号 `<>` 告诉 Markdown 解析器这是一个完整的路径字符串 ✅ **成功**:尖括号 `<>` 告诉 Markdown 解析器这是一个完整的路径字符串
...@@ -222,27 +270,31 @@ The gateway auto-detects the content type from the file extension: ...@@ -222,27 +270,31 @@ The gateway auto-detects the content type from the file extension:
| 文件名类型 | 推荐格式 | 示例 | | 文件名类型 | 推荐格式 | 示例 |
|-----------|---------|------| |-----------|---------|------|
| 纯英文、无空格 | 普通格式 | `[file.pdf](/path/to/file.pdf)` | | 纯英文、无空格 | 普通格式 | `[file.pdf](/path/to/file.pdf)` |
| 包含中文 | **必须用尖括号** | `[文件.docx](</path/to/文件.docx>)` | | 包含中文 | **MEDIA 协议优先** 或 尖括号 | `MEDIA:/path/to/文件.docx` 或 `[文件](</path/to/文件.docx>)` |
| 包含空格 | **必须用尖括号** | `[my file.pdf](</path/to/my file.pdf>)` | | 包含空格 | **MEDIA 协议优先** 或 尖括号 | `MEDIA:/path/to/my file.pdf` 或 `[file](</path/to/my file.pdf>)` |
| 包含特殊字符 | **必须用尖括号** | `[文件 (1).pdf](</path/to/文件 (1).pdf>)` | | 包含特殊字符 | **MEDIA 协议优先** 或 尖括号 | `MEDIA:/path/to/文件 (1).pdf` 或 `[文件](</path/to/文件 (1).pdf>)` |
#### 最佳实践 #### 最佳实践
1. **优先使用英文文件名**:避免兼容性问题 1. **中文文件名优先使用 MEDIA 协议**:
```bash
# 重命名文件
mv "2026 年湖南省未来产业创新发展优秀典型案例申请表.docx" "2026-Hunan-Innovation-Application.docx"
``` ```
MEDIA:/home/lcai/.hermes/workspace/2026 年申请表.docx
```
✅ 原生支持,无需特殊处理
2. **如果必须使用中文文件名,始终用尖括号包裹**: 2. **如果必须使用 Markdown 链接,始终用尖括号**:
```markdown ```markdown
[申请表](</home/lcai/.hermes/cache/documents/申请表.docx>) [申请表](</home/lcai/.hermes/workspace/申请表.docx>)
``` ```
3. **验证文件可访问性**:在发送前检查文件是否存在 3. **验证文件可访问性**:在发送前检查文件是否存在
```bash ```bash
ls -la "/home/lcai/.hermes/cache/documents/2026 年湖南省未来产业创新发展优秀典型案例申请表.docx" ls -la "/home/lcai/.hermes/workspace/2026 年湖南省未来产业创新发展优秀典型案例申请表.docx"
``` ```
4. **文件位置选择**:
- **workspace 目录**:✅ 支持 Markdown 链接和 MEDIA 协议
- **cache 目录**:⚠️ 仅推荐 MEDIA 协议,部分格式可能被限制
### Telegram ### Telegram
- MEDIA protocol fully supported - MEDIA protocol fully supported
- Images, video, audio, documents all work - Images, video, audio, documents all work
...@@ -391,18 +443,24 @@ MEDIA:C:/Users/YourUsername/.hermes/cache/documents/data.csv ...@@ -391,18 +443,24 @@ MEDIA:C:/Users/YourUsername/.hermes/cache/documents/data.csv
6. **Don't send sensitive data**: Never place credentials, tokens, or private keys in cache directories 6. **Don't send sensitive data**: Never place credentials, tokens, or private keys in cache directories
7. **Test with Chinese filenames**: If a file with Chinese characters fails to download, try: 7. **Test with Chinese filenames**: If a file with Chinese characters fails to download:
- Renaming to English - **优先用 MEDIA 协议**:`MEDIA:/path/to/文件.docx`
- Using angle brackets: `](</path/to/文件.docx>)` - 或用尖括号:`](</path/to/文件.docx>)`
- Checking if the file actually exists at the path - 或重命名为英文
8. **File location matters for download permissions**: 8. **File location matters for delivery method**:
- **Workspace** (`/home/lcai/.hermes/workspace/`): ✅ All file types allowed - **Workspace** (`~/.hermes/workspace/`): ✅ 支持 MEDIA 协议和 Markdown 链接
- **Cache** (`/home/lcai/.hermes/cache/documents/`): ⚠️ Some formats restricted (e.g., `.md`) - **Cache** (`~/.hermes/cache/documents/`): ⚠️ 推荐 MEDIA 协议,Markdown 链接部分格式受限
If `.md` files fail in cache directory, move to workspace: 如果需要用 Markdown 链接发送文件,**优先放在 workspace 目录**:
```bash ```bash
mv ~/.hermes/cache/documents/file.md ~/.hermes/workspace/ # 推荐:放在 workspace 用于 Markdown 链接
cp file.docx ~/.hermes/workspace/
# 然后用:[file](</home/lcai/.hermes/workspace/文件.docx>)
# 或者:放在 cache 用于 MEDIA 协议
cp file.docx ~/.hermes/cache/documents/
# 然后用:MEDIA:~/.hermes/cache/documents/文件.docx
``` ```
--- ---
......
# macOS File Delivery — Workspace Security Restriction
> **Source**: Conversation 2026-07-22 (session `mrvqi0lwbwg569`)
> **Symptom**: Files in `~/.hermes/cache/documents/` cannot be accessed via Markdown links, even with angle brackets
## Problem Description
When attempting to send files with long Chinese filenames from `~/.hermes/cache/documents/` directory on macOS:
1. File exists and is readable: `ls -la` confirms it
2. File is in an "allowed" cache directory
3. Markdown link uses angle brackets: `](</path/to/文件.md>)`
4. **Error**: `File is outside the session and Hermes workspaces`
## Root Cause
Hermes security policy enforces that files must be within the **session workspace** (`~/.hermes/workspace/`) or explicitly allowed directories. Even though `~/.hermes/cache/` directories are listed as "safe roots" for MEDIA protocol, the **Markdown link delivery** path has stricter restrictions that only allow files within the active workspace.
This is a **platform-specific behavior on macOS** where:
- MEDIA protocol may work for some file types in cache dirs
- Markdown links **always require** files to be in `~/.hermes/workspace/`
## Reproduction Steps
```bash
# 1. Create a file with Chinese name in workspace
echo "# Test" > "/Users/zhaoyuehui/.hermes/workspace/测试文件.md"
# 2. Send via Markdown link — WORKS
[测试文件](</Users/zhaoyuehui/.hermes/workspace/测试文件.md>)
# 3. Copy to cache directory
cp "/Users/zhaoyuehui/.hermes/workspace/测试文件.md" "/Users/zhaoyuehui/.hermes/cache/documents/"
# 4. Try to send from cache — FAILS
[测试文件](</Users/zhaoyuehui/.hermes/cache/documents/测试文件.md>)
# Error: File is outside the session and Hermes workspaces
```
## Verified Workarounds
### Workaround A: Keep Files in Workspace (Recommended)
Always copy files to `~/.hermes/workspace/` before sending:
```bash
cp "/path/to/source/file.md" ~/.hermes/workspace/
```
Then send:
```markdown
[文件名](</Users/zhaoyuehui/.hermes/workspace/文件名.md>)
```
### Workaround B: Base64 Encoding (Most Reliable)
When file cannot be moved to workspace (e.g., large files, read-only locations):
```bash
# Encode (macOS)
base64 -i "/path/to/文件.md"
# Encode (Linux)
base64 "/path/to/文件.md"
```
Send the base64 string with decoding instructions:
```
文件已编码为 base64,请复制以下内容并解码:
IyDplb/kuK3mlofmlofku7blkI3mtYvor5XmlofmoaMKCui/meaYr+S4gOS4queUqOS6ju...
解码命令:
echo "BASE64_CONTENT" | base64 -D > "文件名.md" # macOS
echo "BASE64_CONTENT" | base64 -d > "文件名.md" # Linux
```
### Workaround C: Direct Content Display
For small files (< 10KB), read and display content directly:
```python
from hermes_tools import read_file
result = read_file("/path/to/file.md")
print(result["content"])
```
## Diagnostic Checklist
When encountering `File is outside the session and Hermes workspaces`:
1. **Check file location**:
```bash
echo "$PWD"
ls -la /path/to/file
```
2. **Verify if in workspace**:
```bash
[[ "/path/to/file" == ~/.hermes/workspace/* ]] && echo "In workspace" || echo "Not in workspace"
```
3. **Try copying to workspace**:
```bash
cp "/path/to/file" ~/.hermes/workspace/
```
4. **If copy fails or not desirable, use base64**:
```bash
base64 -i "/path/to/file"
```
## Platform Differences
| Platform | Cache Dir Links | Workspace Links | Base64 |
|----------|----------------|-----------------|--------|
| macOS | ❌ Fails | ✅ Works | ✅ Works |
| Linux | ⚠️ Sometimes | ✅ Works | ✅ Works |
| Windows | ⚠️ Sometimes | ✅ Works | ✅ Works |
## Best Practices
1. **Always prefer workspace directory** for files you want to send via Markdown links
2. **For Chinese filenames, always use angle brackets**: `](</path/文件.md>)`
3. **When in doubt, use base64** — it works everywhere and bypasses all path restrictions
4. **For large files**, consider base64 or direct content display
5. **Test file delivery early** in a session to confirm platform behavior
## Related Issues
- Windows path format: Use `C:/...` not `/c/...`
- Chinese filename parsing: Always use angle brackets
- MEDIA protocol initialization: May require gateway restart on macOS
- Cache directory restrictions: Not all "safe roots" work for Markdown links
## Key Takeaway
**On macOS, Markdown file links only work for files in `~/.hermes/workspace/`. Files in `~/.hermes/cache/` directories will fail with "File is outside the session and Hermes workspaces" error.**
Use one of these alternatives:
1. Copy file to workspace (preferred for small/medium files)
2. Use base64 encoding (works for any file, any location)
3. Display content directly (for small files)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment