fix(convert): track code fences when splitting OpenClaw sections, and pin it with an invariant (#855)

convert_openclaw() split on `## ` without tracking fenced code blocks, tearing six fenced examples across SOUL.md/AGENTS.md in five agents and leaving dangling fences in each. Implementation from #854 (@guozi-lab): fence helpers in lib.sh used by convert.sh and lint-agents.sh, CommonMark indent aware. Regression test from #853 (@dajiaohuang): every source fenced block must land whole in exactly one output file — verified to fail on the unfixed converter.

Reported by @AmineOzil. Closes #849. Supersedes #853 and #854.

Co-Authored-By: fruit <200041037+guozi-lab@users.noreply.github.com>
Co-Authored-By: Wu Shuwen <108231307+dajiaohuang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Michael Sitarzewski
2026-09-12 11:57:20 -05:00
committed by GitHub
co-authored by fruit Wu Shuwen Claude Opus 5
parent 6d29a9b087
commit ad9264e309
5 changed files with 140 additions and 5 deletions
+21
View File
@@ -10,6 +10,10 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib.sh
. "$SCRIPT_DIR/lib.sh"
# Keep in sync with AGENT_DIRS in scripts/convert.sh
AGENT_DIRS=(
academic
@@ -123,7 +127,24 @@ lint_file() {
local soul_headers=0
local agents_headers=0
local fence_marker="" fence_len=0 fence_indent=0
while IFS= read -r line; do
# Skip fenced code blocks so ## doc-comment lines (e.g. GDScript `##`)
# and in-fence markdown headers aren't miscounted (issue #849).
if [[ -n "$fence_marker" ]]; then
if fence_closes_p "$line" "$fence_marker" "$fence_len" "$fence_indent"; then
fence_marker=""
fence_len=0
fence_indent=0
fi
continue
fi
if fence_open_p "$line"; then
fence_marker="${BASH_REMATCH[2]:0:1}"
fence_len=${#BASH_REMATCH[2]}
fence_indent=${#BASH_REMATCH[1]}
continue
fi
if [[ "$line" =~ ^##[[:space:]] ]]; then
local header_lower
header_lower=$(printf '%s' "$line" | tr '[:upper:]' '[:lower:]')