actions/checkout@v4 defaults to depth=1. When the CI amends the
triggering commit and force-pushes, the shallow history replaces
the full history on the remote — wiping all prior commits.
Fix: set fetch-depth: 0 for full clone.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avoids extra bot commits that cause push rejections. Uses --amend
and --force-with-lease so dist/openclaw changes fold into the
original commit cleanly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SKILL.md Step 6 restructured:
- 6.1: extract 3-5 concrete entities from article before prompting
- 6.2: generate cover only (1 API call, test direction early)
- 6.3: validate cover (interactive: ask user; auto: self-check entities)
- 6.4: batch inline images using cover's style for consistency
visual-prompts.md:
- Add "entity anchoring" hard rule: every prompt must include ≥2 article
entities; ban vague terms as sole subject ("科技感", "未来感")
- Add anti-pattern → good-pattern examples
- Inline images must reuse cover's style description for consistency
Addresses #9
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Append size instruction to prompt (Gemini has no native size param)
- Move API key from URL query string to x-goog-api-key header
- Check status_code before parsing JSON to handle non-JSON error responses
- Remove unnecessary Session with trust_env=False
- Remove f-prefix from strings with no interpolation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the smoke-test main() with a proper argparse CLI that accepts
a URL and --name, validates the name, fetches + extracts + analyzes the
article, calls generate_theme_yaml(), and writes the YAML to
toolkit/themes/. Prints a human-readable theme report with color values
and typography. Adds `learn-theme` subcommand to toolkit/cli.py
(delegates to subprocess call of scripts/learn_theme.py).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add `generate_theme_yaml()` that builds a complete theme YAML by loading
the professional-clean template CSS, substituting extracted colors and
typography, and deriving a dark-mode palette via `derive_darkmode()`.
Adds `import yaml`, `import argparse`, `from pathlib import Path`, and
module-level constants `TEMPLATE_THEME` / `THEMES_DIR`.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fetch_article: catch RequestException, add raise_for_status()
- Extract _attach_title() shared by fetch_article and _load_from_file
- text_light: only search foreground colors, not background values
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Excludes dominant text color from accent candidates; blockquote-first
quote_bg heuristic avoids picking up decorative divider colors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New feature to extract formatting themes from WeChat article URLs.
Covers color extraction, typography analysis, and theme YAML generation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
WeChat API returns Content-Type without charset, causing requests to
default to ISO-8859-1. Chinese content was decoded as mojibake.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- learn_edits.py: prioritize output_file field from history.yaml,
fall back to title slug matching, then largest file
- SKILL.md: add output_file field to history.yaml schema
- Fixes wrong file match when multiple articles share the same date
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- publisher.py: add get_draft() to fetch draft content by media_id,
add html_to_plaintext() for HTML→text conversion
- learn_edits.py: add --from-wechat flag that auto-fetches latest draft
from WeChat, converts both sides to plaintext, and diffs
- learn_edits.py: add markdown_to_plaintext() for local file conversion
- SKILL.md: update edit workflow — both local and WeChat edits supported
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Step 8.2 guidance: edits must be in output/ markdown, not WeChat
draft box, for learn-edits to work
- Update 8.3 "学习我的修改" entry with same note
- Renumber 8.2→8.2 (edit advice) + 8.3→8.3 (reply) for clarity
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename "Tier 3 评估" to "综合评估", describe dimensions directly
(tone variance, density rhythm, pacing, readability) without
referencing anti-detection framework
- Reframe composite_score from "0=human, 100=AI" to "0=high quality,
100=issues found"
- Change 5.3 role from "gate control" to "supplementary verification"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add article self-check ("检查一下"): generation report + quality advice
- Record enhance_strategy in history.yaml
- Replace Zhuque test data with persona style descriptions in README
- Update descriptions: anti-AI focus → content quality focus
- Remove stale parameter optimization references
- Sync all trigger words across README, auxiliary functions, and Step 8.3
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Problem: AI articles scored MORE human (avg 26.2) than actual human
articles (avg 44.0) — opposite of 朱雀's judgment. AI was gaming the
linear scoring by over-optimizing broken sentences, self-correction,
paragraph variance, etc.
Fix: Two calibration layers added after raw scoring:
1. Bell-curve scoring for 5 over-optimizable dimensions (broken_sentences,
self_correction, sentence_length_range, paragraph_length_variance,
banned_words). Score peaks at human article average, penalizes both
too-low AND too-high values.
2. Over-optimization penalty: 15% global penalty when 60%+ of checks
score above 0.8, indicating suspiciously "perfect" articles.
Results:
Before: Human avg=44.0, AI avg=26.2 (WRONG direction)
After: Human avg=42.5, AI avg=44.0 (CORRECT direction)
A/B test now agrees with 朱雀 (exemplar version scores better)
Baselines derived from 15 human articles tested on 2026-03-30.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Step 4.6: add quick self-check after writing (banned words, sentence
variance, negative emotion) to fix obvious issues before Step 5
- Step 5.2: tighten rewrite scope to specific sentences only, max 3
fixes per round, reduce max rounds from 3 to 2
- Step 5.3: reduce scoring rewrite from 3 rounds to 2, mark
DONE_WITH_CONCERNS instead of infinite loops when score stays >50
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename closing_style → closing_tendency in all 5 personas, making it
a soft preference rather than a hard constraint
- Add closing variation rule + 6 closing patterns table to writing-guide.md
- Step 4.5: LLM judges best closing from content; checks history.yaml
last 3 articles to avoid repeating the same closing_type
- Step 8.1: record closing_type in history.yaml for dedup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add transition segment to user exemplar injection (was 3 segments,
now 4 to match seeds path)
- Clarify priority chain: playbook > persona > exemplar > writing-guide
- Add exemplar fallback row to error handling table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Seeds demonstrate anti-AI structural patterns (sentence variance, real
negative emotion, self-correction, abrupt closings) without imposing a
specific writing style. Step 4.4 falls back to seeds when the user's
exemplar library is empty.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prompts users to import articles when exemplar library is empty,
without blocking the pipeline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>