360 Secure SkillHub
360 安全技能中心

Markdown 转手机网页 · MD Out of Chat

该 Skill 用本地 Python 脚本把用户指定的 .md 文件转成手机浏览器可打开的单页 HTML,样式偏移动端友好;也可对某个目录下一层的 .md 做批量转换,并按 today/week/7d/指定日期过滤改动时间。默认纯本地、无账号与 API Key,公开链接需用户明确请求并确认。

bonniegeng-max
bonniegeng-max
热度 56.16
最近更新 2026-10-12 10:07:06
分类:效率依赖:代码执行 / 读写文件应用场景:文件转换 / 工作流

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add md-out-of-chat
Metadata
name
md-out-of-chat
description
把 Markdown 文件变成手机能直接打开的单页 HTML——本地运行、不上传、不需要账号和 API Key。支持一次转换一个文件,也支持把一个目录里「今天 / 本周」改动过的 .md 批量转成手机可读页面(无状态文件、不依赖定时任务)。Convert a Markdown file into a mobile-friendly, local HTML page that opens in any phone browser — markdown to html, chat export reader, batch convert a folder of recent notes (today / this week). WeChat/Feishu/Slack/Discord-friendly view. Use when a .md report, note, or chat export needs to be read or shared on a phone, or when you're away from your computer and want everything you made today readable on mobile. Runs 100% locally with no API key, no account, no upload. A public web URL is produced only when the user explicitly asks for it AND confirms, using a trusted deploy tool. This skill does not generate images or screenshots. Respond in the user's current language.
version
1.6.1
homepage
https://github.com/bonniegeng-max/md-out-of-chat
license
MIT
metadata
{"clawdbot":{"emoji":"📄","requires":{"bins":["python3"],"packages":[],"env":[]}}}

md-out-of-chat

Pulling Markdown out of chat, into something people can actually read.

AI agents live in chat (WeChat, Feishu, Slack, Discord, …) and love to write .md. But .md doesn't render well in any of those apps. Code breaks, tables misalign, links look dead. This skill is the bridge: it takes a .md file and turns it into a mobile-friendly, copyable, shareable view.

Activation

Only activate this skill when both conditions hold: (1) the user explicitly mentions it by name (e.g. "use md-out-of-chat", "用 md-out-of-chat 转换"), and (2) the user identifies a concrete input — a .md file path, an attached file, a file selected in the conversation, or (for batch export) a named folder. Do not activate on vague phrases alone ("show me this", "转一下", "convert this"), and never infer conversion targets from chat history. Only read the file(s) the user explicitly identified. Never deploy, publish, or invoke other tools unless the user separately requests and confirms that action.

The Problem

  • .md files cannot be opened in WeChat on mobile
  • Code blocks break layout on small screens
  • Tables misalign columns on mobile
  • When you're away from your computer, you can't view what your assistant just made

Input

  • Path to a .md file
  • Optional output type: html (local file, default) or web (public URL — see the strict conditions below)

Output

  • Default: a local .html file that opens in any mobile browser
  • web: a public URL only if the user explicitly asks for it, explicitly confirms before anything is deployed, and the assistant has a trusted deploy tool; otherwise fall back to local HTML
  • This skill does not generate PNG screenshots or images. If the user asks for an image, explain that rendering an HTML file to PNG is up to the host environment's own tools — do not invoke other tools automatically.

Not the same as

  • A Markdown viewer or note-taking app — it converts one file you name into a page you can open on a phone. It is not a live editor, and it does not keep a library.
  • An image generator — no PNG/JPG output. If a picture is needed, that belongs to the host environment's own tools.
  • A publish tool — local HTML is the default. A public URL is produced only after an explicit, separately confirmed request.

Design Spec (Blue / White / Gray — Minimal & Clean)

Colors

  • Primary: #1F4E79 (deep blue, used for titles & headings)
  • Accent: #3B7DD8 (bright blue, used for emphasis)
  • Background: #F5F7FA (light gray)
  • Card: #FFFFFF (white)
  • Text: #333333 (main) / #666666 (secondary)
  • Border: #E1E5EB

Typography

  • Body: system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif
  • Code: "SF Mono", Menlo, Monaco, Consolas, monospace
  • Base size: 16px (auto-shrinks on small screens)

Block Rules

Headings (h1–h6)

  • Color: deep blue
  • Weight: 600
  • h1: 24px / h2: 20px / h3: 18px
  • h1 has a 2px bottom border

Paragraphs

  • 16px, line-height 1.7
  • Inline: **bold** → strong, *italic* → em, `code` → inline code

Tables

  • Column-aligned
  • Header: deep blue background, white text, bold
  • Zebra striping (odd / even rows)
  • white-space: nowrap on headers
  • Wraps in a scrollable container on narrow screens

Code Blocks

  • Top label shows the language (e.g. PYTHON, SQL, BASH)
  • Syntax highlighting per language:
    • Keywords: red, bold
    • Strings: green
    • Numbers: blue
    • Comments: gray, italic
  • Horizontal scroll for long lines
  • Never breaks layout

Lists

  • Unordered: bullet points
  • Ordered: numbered
  • Task lists: - [ ] / - [x] render as checkboxes (done items struck through)
  • 6px vertical spacing between items

Blockquotes

  • > lines render as a left-accent-border quote block, gray text

Links

  • [text](url) renders as styled anchor; only http: / https: / mailto: schemes allowed (XSS-safe)
  • Long URLs wrap on mobile (word-break: break-all)

Inline in table cells

  • Cell content supports bold / italic / inline code / links
  • \| escapes a literal pipe inside cells

Output Type Decision

Default to local HTML for safety and privacy. Only produce a public web URL when the user explicitly asks for one, explicitly confirms, and the assistant has a safe deploy path. Do not generate screenshots — this skill produces HTML only.

Default: Local HTML

When the user asks to view a Markdown file without specifying the output type, generate a local .html file. Tell the user where it is and that it can be opened on a phone browser.

About Images / Screenshots

This skill does not render PNGs. If the user asks for a screenshot:

  • Tell them the HTML file is ready and can be opened in any mobile browser.
  • If the host environment has its own screenshot/browser tool, the user can ask for it separately — do not invoke other tools automatically on this skill's behalf.

When to Generate a Public Web URL

Generate a public URL only when all of these hold:

  • The user explicitly says "web" / "link" / "URL" / "公开链接"
  • The user explicitly confirms deployment before anything is published
  • The assistant has a trusted, temporary deploy tool available

Never generate a public URL silently. If deployment is not available, fall back to local HTML and explain why. build_and_deploy.sh is off by default — run it only after the user explicitly asks for a deployable folder.

Batch Export · 批量导出(今天 / 本周)

When you're away from your computer and want everything you made recently readable on your phone, convert a whole folder in one pass. Triggered by "导出今天" / "导出本周" / "batch export today" together with an explicitly named folder — never guess a folder.

python3 md2share.py <目录>                    # 该目录下所有 .md(只扫一层)
python3 md2share.py <目录> --since=today      # 只转今天改过的
python3 md2share.py <目录> --since=week       # 只转本周(周一 00:00 起)改过的
python3 md2share.py <目录> --since=7d         # 最近 7 天
python3 md2share.py <目录> --since=2026-09-20 # 指定日期之后
python3 md2share.py <目录> <输出目录>          # 输出集中到另一个目录

Rules for batch mode:

  • Statically stateless. The time filter reads each file's own modification time. No index file, no manifest, no .md-out-of-chat/ state, nothing to go stale — this is why the skill stays a pure converter.
  • One level only. Only *.md directly inside the named folder is converted. Subfolders are never walked, so pointing at a broad folder cannot cascade through your whole disk.
  • Explicit input. The user names the folder. Do not pick a folder from history or infer it from context.
  • Output beside the source by default (note.md → note.html), or into the second argument if given. Existing .html files are simply overwritten with the fresh render.
  • No silent scheduling. This is a manual, on-demand action. The skill does not register cron jobs or background timers — if you want it to run on a schedule, that belongs to the host platform's own automation, configured by the user.
  • Report the count and the list of written files so the user knows exactly what was produced.

Mobile Responsive

  • Body padding shrinks on < 480px width
  • Container padding: 32px → 20px
  • Code font shrinks: 14px → 13px
  • Table font shrinks: 14px → 13px

Privacy

  • Runs locally by default. The core md2share.py only reads the input .md and writes a local .html file.
  • Batch mode is read-only on your source files. It lists *.md in the folder you named, compares against each file's own modification time, and writes only .html output. It creates no state file, index, or tracking directory, and it never moves, renames, or deletes anything.
  • build_and_deploy.sh only prepares a local dist/ folder; it does not upload anything and is off by default.
  • This skill includes no browser automation code and does not generate screenshots.
  • A public URL is produced only when the user explicitly requests it, explicitly confirms, and the assistant has a trusted deploy tool.
  • Local images (![alt](./image.png)) are embedded as base64 only if they live in the same directory as the Markdown file or a subdirectory of it. Absolute paths and directory traversal (../) are never embedded. Image files are validated by content (magic bytes) before embedding, and every embedded file path is logged to stderr so the user can audit exactly what was read.
  • Remote images are never fetched automatically; they are rendered as a link placeholder to avoid network requests.
  • Generated HTML is fully escaped. All Markdown text, code content, and code-fence language labels are HTML-escaped before being written into the output page (language labels are additionally restricted to a safe character set), so untrusted Markdown cannot inject scripts into the generated page.
  • The user does not need to register any account.
  • This skill never sends user content to external APIs without explicit consent.

Usage Example

# 1. Write or place your .md file
# 2. Generate a local HTML file (default: local images under .md dir are embedded)
python3 md2share.py my-notes.md

# 3. Batch: convert a whole folder, optionally only what changed recently
python3 md2share.py ~/notes --since=today

# 4. (Optional, only on explicit request) Build dist/ for deployment
./build_and_deploy.sh my-notes.md

Files

  • md2share.py — Core script (md → local html; single file or one-level folder batch)
  • build_and_deploy.sh — Optional local build helper (prepares dist/; off by default)
  • SKILL.md — This file

Limitations

  • MD parser supports nested lists (any depth, mixed ordered/unordered) and images (local images embedded as base64 only from the Markdown file's directory or its subdirectories; absolute paths and ../ traversal are never embedded; image content is validated via magic bytes before embedding; every embedded path is logged to stderr; remote images rendered as a link placeholder so no network request is made)
  • No screenshot/PNG output — this skill produces HTML only
  • Batch mode scans exactly one folder level (*.md beside each other); it does not recurse into subfolders, and it keeps no record of what it converted before — re-running simply re-renders
  • Footnotes: [^id] refs render as superscript anchors, definitions collected into a NOTES section at the bottom with back-links
  • Table of contents: when the document has 3+ h2 headings, a collapsible TOC with anchor links is generated at the top (mobile-friendly, dark-mode aware)
  • Horizontal rules (---, ***, ___) render as styled dividers
  • Dark mode: follows prefers-color-scheme with a manual toggle that remembers the choice
  • Code highlighter covers python / javascript / typescript / bash / sql / java / c / cpp / go / rust / php / ruby / kotlin / swift / json / yaml / css out of the box (with common aliases: py, js, ts, sh, golang, rs, yml, kt, rb, c++); other languages render as plain text with a label
  • Highlighter is regex-based (single-pass tokenize: comment → string → keyword → number, no nesting bugs)