knit-rmd-html
Knit/render R Markdown (.Rmd) to HTML reliably in this repo (auto-bootstrap pandoc, set correct knit_root_dir, and run rmarkdown::render via a Python wrapper).
Install
npx skills add https://github.com/huangwb8/skills/tree/main/skills/beta/knit-rmd-html
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install huangwb8-skills@llmmart
git clone https://github.com/huangwb8/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole huangwb8/skills collection as a plugin from our marketplace. Git is the plain clone.
README
Knit Rmd HTML
当前版本:0.1.1。
这个 skill 用来把 .Rmd 文件稳定地渲染成 HTML,适合仓库里的高频 R Markdown 报告输出;如果你想生成 PDF、Word 或处理普通 Markdown,就不该直接用它。
用法
最推荐用法
请使用 knit-rmd-html skill 将这个 R Markdown 文件渲染成 HTML。
输入:`/path/to/report.Rmd`
输出:对应的 `.html` 文件,默认输出到同目录
进阶用法
请使用 knit-rmd-html skill 渲染这个 R Markdown 文件。
输入:`/path/to/report.Rmd`
输出:指定输出位置的 HTML 文件
另外,还有下列参数约束:
- 输出路径:`/path/to/out/report.html`
- 缺少 pandoc 时允许自动安装:是
- 日志尽量安静:是
能做什么
- 使用 Python 包装层调用
rmarkdown::render(),减少环境差异带来的失败。 - 缺少
pandoc时可自动引导安装。 - Windows 下兼容 Pandoc ZIP 的根目录与
bin/两类布局,并识别pandoc.exe。 - Rscript 输出固定按 UTF-8 解码,不依赖中文控制台的 GBK locale。
- 通过正确设置
knit_root_dir,让 Rmd 内相对路径更稳定。 - 适合本仓库内“把 Rmd 可靠地 knit 成 HTML”的固定场景。
- 不适合替代通用报告系统或其它输出格式转换器。
使用示例
示例 1:渲染单个 Rmd
请使用 knit-rmd-html skill 将这个 R Markdown 文件渲染成 HTML。
输入:`analysis/report.Rmd`
输出:`analysis/report.html`
示例 2:指定输出文件
请使用 knit-rmd-html skill 渲染这个文件。
输入:`analysis/report.Rmd`
输出:`./outputs/report-final.html`
示例 3:要求失败即报错
请使用 knit-rmd-html skill 渲染这个 Rmd。
输入:`report.Rmd`
输出:HTML 文件
另外,还有下列参数约束:
- 不自动安装依赖:是
- 输出日志:简洁
输出
- 默认输出:与输入
.Rmd同目录下的同名.html。 - 可以通过参数显式指定输出路径。
- 缺少
pandoc时可自动补齐到本地用户目录。 - 需要
Rscript可用;否则无法真正执行渲染。
配置
- 版本号由
config.yaml:skill_info.version统一管理,高频设置通过命令行参数控制。 - 最常用参数:
-o/--output--pandoc-version--no-install--quiet
备选用法(脚本/硬编码)
如果你已经在仓库里,直接运行脚本通常是最稳定的方式。
基础渲染
python3 knit-rmd-html/scripts/knit_rmd_html.py report.Rmd
指定输出文件
python3 knit-rmd-html/scripts/knit_rmd_html.py \
report.Rmd \
-o outputs/report.html
控制依赖安装与日志
python3 knit-rmd-html/scripts/knit_rmd_html.py \
report.Rmd \
--no-install \
--quiet
常见问题
Q:为什么这个 skill 不直接让我写 R 命令?
A:因为它的价值之一就是帮你把环境检测、pandoc 补齐和稳定渲染流程包装好。
Q:会自动安装什么?
A:主要是缺失的 pandoc。真正的渲染仍然依赖本地 Rscript 和 rmarkdown 运行环境。
Q:为什么输出默认在原文件旁边?
A:这是最符合直觉、也最不容易弄丢结果的默认行为。
Q:它能生成 PDF 吗?
A:这个 skill 的职责是 .Rmd -> HTML。如果你要别的格式,应该走其他专门技能或工具链。
Skill manifest
Knit Rmd → HTML(项目高频场景)
目标
Knit/render R Markdown (.Rmd) to HTML reliably in this repo (auto-bootstrap pandoc, set correct knit_root_dir, and run rmarkdown::render via a Python wrapper).
当用户说"knit 出 html / render Rmd / 生成 HTML 报告"时使用本 skill。
版本由 config.yaml:skill_info.version 统一管理。
流程
输入
输入为待渲染的 .Rmd 路径;可选输入包括项目根目录、输出文件路径、Pandoc 版本/下载选项和 rmarkdown::render 参数。渲染前需确认项目 knit_root_dir、R 和必要模板资源可用。
执行步骤
直接用法
- 在仓库根目录执行:
python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd- 输出默认写到
<input>.Rmd同目录:<input>.html
常用参数
- 指定输出文件:
python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd -o <output>.html
- 指定 pandoc 版本(默认
3.8.3):python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd --pandoc-version 3.8.3
- 不自动安装依赖(只做检测;缺什么就报错):
python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd --no-install
- 静默渲染输出:
python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd --quiet
设计要点(为何这样做)
- 不依赖 R 写脚本:外层用 Python 做编排与环境自检;真正的 knit 仍由
rmarkdown::render()执行。 - 自动补齐 pandoc:若系统无
pandoc,自动下载安装到~/.local/pandoc/并将~/.local/bin放到子进程PATH前面。 - 兼容 Windows ZIP:安全解压后递归寻找唯一的
pandoc/pandoc.exe,兼容根目录与bin/布局并拒绝歧义结果。 - 输出编码稳定:Rscript 日志始终按 UTF-8 解码并保留真实退出码,不依赖 Windows 控制台 locale。
- 相对路径更稳:用
knit_root_dir=dirname(input),确保 Rmd 内source("xxx.R")等相对路径在 knit 时仍可用。
工作原理
- 环境检测:检查
pandoc和Rscript是否在 PATH 中 - 自动安装:若缺少 pandoc,根据平台自动下载对应版本到
~/.local/pandoc/ - 渲染执行:通过 R 的
rmarkdown::render()执行 knit - 输出定位:默认输出到输入文件同目录,可通过
-o参数指定
输出
成功时在同级目录生成与 Rmd 同名的 HTML,或写入由 -o 指定的输出文件路径;同时保留渲染日志、Pandoc/依赖诊断和任务工作区中的临时产物,不改变输入 Rmd。
输出管理
BenszAPI 任务工作区
校验
校验 Rmd 路径和项目根目录、Pandoc/R 依赖、knit_root_dir 与输出 HTML 存在性;渲染退出码为 0 且 HTML 可读取时才报告成功。
失败与恢复
Pandoc/R 缺失、引导下载失败、路径越界、渲染超时或 rmarkdown::render 返回非零时,保留日志和诊断输出并报告可复现命令;若产生部分输出,由用户按需清理或隔离后再修复依赖/参数重试。
约束
公共硬约束
本块由 docs/templates/skill-common-constraints.md 统一维护;每个 SKILL.md 的 ## 约束 必须逐字同步本块,不得在副本中改写公共规则。
- 任务需要落盘时,使用唯一的
./.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/根目录;共享材料放入shared/,Skill 专属材料放入该 Skill 的input/、output/、log/。 - 正式交付物、源代码和正式计划按项目约定保存,不写入任务工作区;未经授权不覆盖、删除、迁移或远程写入。
- 项目维护变更检查 BAC 可用性并记录需求、AI 产出、工具结果、文件改动和验证摘要;BAC 只做过程审计,不替代署名、责任或合规判断。
- 不记录 API Key、访问令牌、密码、Cookie、环境/凭据文件、私有 Prompt、身份信息、本地用户名、主机名或不必要的大体积原始数据。
- 文件路径必须规范化并限制在授权项目范围内;外部 URL、子进程和网络访问遵循最小权限,防止路径遍历、SSRF 和命令注入。
- Skill 版本唯一记录在自身
config.yaml:skill_info.version;公开 API、协议、目录或配置变更同步文档与CHANGELOG.md。 bensz-collect-bugs是一个 Agent Skill;仅将 Bensz Agent Skill 或 Bensz 基础设施本身的设计缺陷交给它。先脱敏写入~/.bensz-skills/bugs/,当前任务不中断,只有用户明确要求才公开上报,禁止直接修改用户已安装的 Skill 源码。
Files (skills)
-
scripts
-
knit_rmd_html.py 8.3 KB
#!/usr/bin/env python3 import argparse import json import os import platform import shutil import subprocess import sys import tempfile import urllib.request import zipfile def _run(cmd, *, env=None, cwd=None): proc = subprocess.run( cmd, env=env, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, encoding="utf-8", errors="replace", ) return proc.returncode, proc.stdout def _which(cmd, env): return shutil.which(cmd, path=env.get("PATH")) def _ensure_dir(path): os.makedirs(path, exist_ok=True) def _detect_pandoc(env): pandoc = _which("pandoc", env) if not pandoc: return None, None code, out = _run([pandoc, "--version"], env=env) if code != 0: return pandoc, None first = out.splitlines()[0].strip() if out else None return pandoc, first def _github_latest_pandoc_tag(env): url = "https://api.github.com/repos/jgm/pandoc/releases/latest" req = urllib.request.Request(url, headers={"Accept": "application/vnd.github+json", "User-Agent": "knit-rmd-html-skill"}) with urllib.request.urlopen(req, timeout=30) as resp: data = json.loads(resp.read().decode("utf-8")) return data.get("tag_name") def _pandoc_asset_name(version, system, machine): system = system.lower() machine = machine.lower() if system == "darwin": if machine in ("arm64", "aarch64"): return f"pandoc-{version}-arm64-macOS.zip" if machine in ("x86_64", "amd64"): return f"pandoc-{version}-x86_64-macOS.zip" raise RuntimeError(f"Unsupported macOS arch: {machine}") if system == "linux": if machine in ("x86_64", "amd64"): return f"pandoc-{version}-linux-amd64.tar.gz" if machine in ("arm64", "aarch64"): return f"pandoc-{version}-linux-arm64.tar.gz" raise RuntimeError(f"Unsupported linux arch: {machine}") if system == "windows": if machine in ("x86_64", "amd64"): return f"pandoc-{version}-windows-x86_64.zip" if machine in ("arm64", "aarch64"): return f"pandoc-{version}-windows-arm64.zip" raise RuntimeError(f"Unsupported windows arch: {machine}") raise RuntimeError(f"Unsupported OS: {system}") def _install_pandoc_zip(zip_path, install_root): install_root = os.path.abspath(install_root) with zipfile.ZipFile(zip_path) as zf: for member in zf.infolist(): target = os.path.abspath(os.path.join(install_root, member.filename)) if os.path.commonpath([install_root, target]) != install_root: raise RuntimeError(f"Unsafe path in Pandoc zip: {member.filename}") zf.extractall(install_root) candidates = [] for root, _, filenames in os.walk(install_root): for filename in filenames: if filename.lower() in {"pandoc", "pandoc.exe"}: candidates.append(os.path.join(root, filename)) candidates.sort() if not candidates: raise RuntimeError("Pandoc zip extracted but no pandoc or pandoc.exe executable was found.") if len(candidates) > 1: relative = [os.path.relpath(path, install_root) for path in candidates] raise RuntimeError(f"Pandoc zip contains ambiguous executables: {', '.join(relative)}") return candidates[0] def _ensure_pandoc(env, *, version, no_install): pandoc, verline = _detect_pandoc(env) if pandoc: return pandoc, verline if no_install: raise RuntimeError("pandoc not found in PATH, and --no-install is set.") system = platform.system() machine = platform.machine() asset = _pandoc_asset_name(version, system, machine) url = f"https://github.com/jgm/pandoc/releases/download/{version}/{asset}" home = os.path.expanduser("~") pandoc_root = os.path.join(home, ".local", "pandoc") bin_root = os.path.join(home, ".local", "bin") _ensure_dir(pandoc_root) _ensure_dir(bin_root) zip_path = os.path.join(pandoc_root, asset) if not os.path.exists(zip_path): with urllib.request.urlopen(url, timeout=120) as resp, open(zip_path, "wb") as f: f.write(resp.read()) if not asset.endswith(".zip"): raise RuntimeError( f"Auto-install currently supports zip assets only (got {asset}). " f"Please install pandoc manually or use a zip-capable platform." ) # Extract into a versioned folder to keep installs reproducible install_root = os.path.join(pandoc_root, f"pandoc-{version}") if os.path.exists(install_root): shutil.rmtree(install_root) _ensure_dir(install_root) pandoc_bin = _install_pandoc_zip(zip_path, install_root) if not os.path.exists(pandoc_bin): raise RuntimeError("pandoc binary not found after installation.") try: os.chmod(pandoc_bin, 0o755) except OSError: pass link_name = "pandoc.exe" if pandoc_bin.lower().endswith(".exe") else "pandoc" link_path = os.path.join(bin_root, link_name) try: if os.path.islink(link_path) or os.path.exists(link_path): os.remove(link_path) os.symlink(pandoc_bin, link_path) except OSError: shutil.copy2(pandoc_bin, link_path) try: os.chmod(link_path, 0o755) except OSError: pass # Prepend ~/.local/bin to PATH for the current process & downstream env2 = dict(env) env2["PATH"] = os.pathsep.join([bin_root, env.get("PATH", "")]) pandoc, verline = _detect_pandoc(env2) if not pandoc: raise RuntimeError("pandoc installation finished but still not detectable.") return pandoc, verline def _ensure_rscript(env): rscript = _which("Rscript", env) if not rscript: raise RuntimeError("Rscript not found in PATH. Please install R first.") return rscript def main(): ap = argparse.ArgumentParser(description="Render a .Rmd to HTML (auto-bootstrap pandoc) via a Python wrapper.") ap.add_argument("input", help="Path to .Rmd") ap.add_argument("-o", "--output", default=None, help="Output HTML path (default: alongside input)") ap.add_argument("--pandoc-version", default="3.8.3", help="Pandoc version to auto-install when missing") ap.add_argument("--no-install", action="store_true", help="Do not auto-install pandoc / R packages; fail fast") ap.add_argument("--quiet", action="store_true", help="Quiet render output") args = ap.parse_args() inp = os.path.abspath(args.input) if not os.path.exists(inp): raise SystemExit(f"Input not found: {inp}") if not inp.lower().endswith(".rmd"): raise SystemExit("Input must be a .Rmd file.") out = args.output if out is None: base, _ = os.path.splitext(inp) out = base + ".html" out = os.path.abspath(out) env = dict(os.environ) try: pandoc, verline = _ensure_pandoc(env, version=args.pandoc_version, no_install=args.no_install) except Exception as e: raise SystemExit(f"[pandoc] {e}") # Make sure downstream R can see pandoc if installed into ~/.local/bin home = os.path.expanduser("~") env["PATH"] = os.pathsep.join([os.path.join(home, ".local", "bin"), env.get("PATH", "")]) try: rscript = _ensure_rscript(env) except Exception as e: raise SystemExit(f"[R] {e}") knit_root = os.path.dirname(inp) # Render via rmarkdown. Keep the R snippet minimal; orchestration is in Python. ensure_rmarkdown = ( "if (!requireNamespace('rmarkdown', quietly=TRUE)) {" + ( "stop('Package rmarkdown is required but missing (use --no-install to fail fast).', call.=FALSE);" if args.no_install else "install.packages('rmarkdown', repos='https://cloud.r-project.org');" ) + "}" ) render_call = ( "rmarkdown::render(" f"input={json.dumps(inp)}, " f"output_file={json.dumps(out)}, " f"knit_root_dir={json.dumps(knit_root)}, " f"quiet={str(bool(args.quiet)).upper()}" ")" ) r_expr = ensure_rmarkdown + ";" + render_call code, outlog = _run([rscript, "-e", r_expr], env=env, cwd=knit_root) if code != 0: sys.stdout.write(outlog) raise SystemExit(f"[render] Failed (exit={code}).") if not args.quiet and outlog.strip(): sys.stdout.write(outlog) print(f"[render] OK: {out}") if __name__ == "__main__": main()
-
-
CHANGELOG.md 726 B
# knit-rmd-html - 变更日志 遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/) 与语义化版本规范。 ## [Unreleased] ### Fixed(修复) - 修复 Windows Pandoc ZIP 布局并不固定为 `bin/pandoc` 的问题:解压后递归发现唯一的 `pandoc` / `pandoc.exe`,拒绝路径穿越、缺失和歧义结果,并保留 `.exe` 文件名供 Windows `PATH` 发现。 - 修复 Windows 中文 locale 下 Rscript 的 UTF-8 输出被按 GBK 解码的问题:子进程输出统一使用 UTF-8 并以 replacement 策略保留返回码和可读日志。 ## [0.1.0] ### Added(新增) - 初始化 R Markdown 到 HTML 的 Python 渲染入口,并支持缺少 Pandoc 时按固定版本安装。 -
config.yaml 183 B
skill_info: name: knit-rmd-html version: 0.1.1 description: 可靠地将 R Markdown 渲染为 HTML,并按需引导安装 Pandoc author: "Bensz Conan" category: R Markdown -
README.md 3.4 KB
# Knit Rmd HTML 当前版本:`0.1.1`。 这个 skill 用来把 `.Rmd` 文件稳定地渲染成 HTML,适合仓库里的高频 R Markdown 报告输出;如果你想生成 PDF、Word 或处理普通 Markdown,就不该直接用它。 ## 用法 ### 最推荐用法 ```text 请使用 knit-rmd-html skill 将这个 R Markdown 文件渲染成 HTML。 输入:`/path/to/report.Rmd` 输出:对应的 `.html` 文件,默认输出到同目录 ``` ### 进阶用法 ```text 请使用 knit-rmd-html skill 渲染这个 R Markdown 文件。 输入:`/path/to/report.Rmd` 输出:指定输出位置的 HTML 文件 另外,还有下列参数约束: - 输出路径:`/path/to/out/report.html` - 缺少 pandoc 时允许自动安装:是 - 日志尽量安静:是 ``` ## 能做什么 - 使用 Python 包装层调用 `rmarkdown::render()`,减少环境差异带来的失败。 - 缺少 `pandoc` 时可自动引导安装。 - Windows 下兼容 Pandoc ZIP 的根目录与 `bin/` 两类布局,并识别 `pandoc.exe`。 - Rscript 输出固定按 UTF-8 解码,不依赖中文控制台的 GBK locale。 - 通过正确设置 `knit_root_dir`,让 Rmd 内相对路径更稳定。 - 适合本仓库内“把 Rmd 可靠地 knit 成 HTML”的固定场景。 - 不适合替代通用报告系统或其它输出格式转换器。 ## 使用示例 ### 示例 1:渲染单个 Rmd ```text 请使用 knit-rmd-html skill 将这个 R Markdown 文件渲染成 HTML。 输入:`analysis/report.Rmd` 输出:`analysis/report.html` ``` ### 示例 2:指定输出文件 ```text 请使用 knit-rmd-html skill 渲染这个文件。 输入:`analysis/report.Rmd` 输出:`./outputs/report-final.html` ``` ### 示例 3:要求失败即报错 ```text 请使用 knit-rmd-html skill 渲染这个 Rmd。 输入:`report.Rmd` 输出:HTML 文件 另外,还有下列参数约束: - 不自动安装依赖:是 - 输出日志:简洁 ``` ## 输出 - 默认输出:与输入 `.Rmd` 同目录下的同名 `.html`。 - 可以通过参数显式指定输出路径。 - 缺少 `pandoc` 时可自动补齐到本地用户目录。 - 需要 `Rscript` 可用;否则无法真正执行渲染。 ## 配置 - 版本号由 `config.yaml:skill_info.version` 统一管理,高频设置通过命令行参数控制。 - 最常用参数: - `-o` / `--output` - `--pandoc-version` - `--no-install` - `--quiet` ## 备选用法(脚本/硬编码) 如果你已经在仓库里,直接运行脚本通常是最稳定的方式。 ### 基础渲染 ```bash python3 knit-rmd-html/scripts/knit_rmd_html.py report.Rmd ``` ### 指定输出文件 ```bash python3 knit-rmd-html/scripts/knit_rmd_html.py \ report.Rmd \ -o outputs/report.html ``` ### 控制依赖安装与日志 ```bash python3 knit-rmd-html/scripts/knit_rmd_html.py \ report.Rmd \ --no-install \ --quiet ``` ## 常见问题 ### Q:为什么这个 skill 不直接让我写 R 命令? A:因为它的价值之一就是帮你把环境检测、`pandoc` 补齐和稳定渲染流程包装好。 ### Q:会自动安装什么? A:主要是缺失的 `pandoc`。真正的渲染仍然依赖本地 `Rscript` 和 `rmarkdown` 运行环境。 ### Q:为什么输出默认在原文件旁边? A:这是最符合直觉、也最不容易弄丢结果的默认行为。 ### Q:它能生成 PDF 吗? A:这个 skill 的职责是 `.Rmd -> HTML`。如果你要别的格式,应该走其他专门技能或工具链。 -
SKILL.md 5.1 KB
--- name: knit-rmd-html description: Knit/render R Markdown (.Rmd) to HTML reliably in this repo (auto-bootstrap pandoc, set correct knit_root_dir, and run rmarkdown::render via a Python wrapper). metadata: author: Bensz Conan keywords: - knit-rmd-html --- # Knit Rmd → HTML(项目高频场景) ## 目标 Knit/render R Markdown (.Rmd) to HTML reliably in this repo (auto-bootstrap pandoc, set correct knit_root_dir, and run rmarkdown::render via a Python wrapper). 当用户说"knit 出 html / render Rmd / 生成 HTML 报告"时使用本 skill。 版本由 `config.yaml:skill_info.version` 统一管理。 ## 流程 ### 输入 输入为待渲染的 `.Rmd` 路径;可选输入包括项目根目录、输出文件路径、Pandoc 版本/下载选项和 `rmarkdown::render` 参数。渲染前需确认项目 `knit_root_dir`、R 和必要模板资源可用。 ### 执行步骤 #### 直接用法 - 在仓库根目录执行: - `python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd` - 输出默认写到 `<input>.Rmd` 同目录:`<input>.html` #### 常用参数 - 指定输出文件: - `python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd -o <output>.html` - 指定 pandoc 版本(默认 `3.8.3`): - `python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd --pandoc-version 3.8.3` - 不自动安装依赖(只做检测;缺什么就报错): - `python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd --no-install` - 静默渲染输出: - `python3 skills/knit-rmd-html/scripts/knit_rmd_html.py <input>.Rmd --quiet` #### 设计要点(为何这样做) - **不依赖 R 写脚本**:外层用 Python 做编排与环境自检;真正的 knit 仍由 `rmarkdown::render()` 执行。 - **自动补齐 pandoc**:若系统无 `pandoc`,自动下载安装到 `~/.local/pandoc/` 并将 `~/.local/bin` 放到子进程 `PATH` 前面。 - **兼容 Windows ZIP**:安全解压后递归寻找唯一的 `pandoc` / `pandoc.exe`,兼容根目录与 `bin/` 布局并拒绝歧义结果。 - **输出编码稳定**:Rscript 日志始终按 UTF-8 解码并保留真实退出码,不依赖 Windows 控制台 locale。 - **相对路径更稳**:用 `knit_root_dir=dirname(input)`,确保 Rmd 内 `source("xxx.R")` 等相对路径在 knit 时仍可用。 #### 工作原理 1. **环境检测**:检查 `pandoc` 和 `Rscript` 是否在 PATH 中 2. **自动安装**:若缺少 pandoc,根据平台自动下载对应版本到 `~/.local/pandoc/` 3. **渲染执行**:通过 R 的 `rmarkdown::render()` 执行 knit 4. **输出定位**:默认输出到输入文件同目录,可通过 `-o` 参数指定 ### 输出 成功时在同级目录生成与 Rmd 同名的 HTML,或写入由 `-o` 指定的输出文件路径;同时保留渲染日志、Pandoc/依赖诊断和任务工作区中的临时产物,不改变输入 Rmd。 ### 输出管理 #### BenszAPI 任务工作区 ### 校验 校验 Rmd 路径和项目根目录、Pandoc/R 依赖、`knit_root_dir` 与输出 HTML 存在性;渲染退出码为 0 且 HTML 可读取时才报告成功。 ### 失败与恢复 Pandoc/R 缺失、引导下载失败、路径越界、渲染超时或 `rmarkdown::render` 返回非零时,保留日志和诊断输出并报告可复现命令;若产生部分输出,由用户按需清理或隔离后再修复依赖/参数重试。 ## 约束 <!-- BEGIN COMMON CONSTRAINTS --> <!-- Source-Hash: sha256:15120201e9e0c7569517261d57ecefb63ac279c26ed13876f8e95b6dc35854d3 --> <!-- Template-ID: skill-common-constraints; Template-Version: 1; Sync-Policy: exact-block --> ### 公共硬约束 本块由 `docs/templates/skill-common-constraints.md` 统一维护;每个 `SKILL.md` 的 `## 约束` 必须逐字同步本块,不得在副本中改写公共规则。 - 任务需要落盘时,使用唯一的 `./.bensz-api/task-{yyyymmdd-hhmm}-{简短描述}/` 根目录;共享材料放入 `shared/`,Skill 专属材料放入该 Skill 的 `input/`、`output/`、`log/`。 - 正式交付物、源代码和正式计划按项目约定保存,不写入任务工作区;未经授权不覆盖、删除、迁移或远程写入。 - 项目维护变更检查 BAC 可用性并记录需求、AI 产出、工具结果、文件改动和验证摘要;BAC 只做过程审计,不替代署名、责任或合规判断。 - 不记录 API Key、访问令牌、密码、Cookie、环境/凭据文件、私有 Prompt、身份信息、本地用户名、主机名或不必要的大体积原始数据。 - 文件路径必须规范化并限制在授权项目范围内;外部 URL、子进程和网络访问遵循最小权限,防止路径遍历、SSRF 和命令注入。 - Skill 版本唯一记录在自身 `config.yaml:skill_info.version`;公开 API、协议、目录或配置变更同步文档与 `CHANGELOG.md`。 - `bensz-collect-bugs` 是一个 Agent Skill;仅将 Bensz Agent Skill 或 Bensz 基础设施本身的设计缺陷交给它。先脱敏写入 `~/.bensz-skills/bugs/`,当前任务不中断,只有用户明确要求才公开上报,禁止直接修改用户已安装的 Skill 源码。 <!-- End of canonical common constraints. --> <!-- END COMMON CONSTRAINTS -->
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.