33 Commits
Author SHA1 Message Date
tiennm99 210d2cdbea feat(newsletter): protect code, verdicts and author notes in rewrites
protected-lines now keeps fenced code blocks (re-indent allowed) and
**Đánh giá:** verdict lines, and leaves summary sub-headings and short
italic key-point labels rewritable. The rewrite skill skips posts
without the AI-Assisted tag.
2026-09-27 21:47:31 +07:00
tiennm99 c0eecc1263 feat(newsletter): add mt-rewrite-newsletter skill and protected-lines guard 2026-09-27 21:47:30 +07:00
tiennm99 baab3d443a refactor(skills): invoke the Node engine and centralise the command reference
Switches every call site to `node scripts/newsletter` and, in the same pass,
fixes three structural problems in the skill layer.

The seven subcommands were spelled out in five files; they are now enumerated
once in docs/newsletter/engine-commands.md, and every other mention is a link
except where a skill inlines the one or two commands it actually invokes. The
shared post mechanics move out of mt-add-url's directory into docs/newsletter/,
so no skill owns another skill's documentation and both runtimes reach it by a
repository-relative path. The Codex adapters become symlinks to their canonical
counterparts, which removes the parallel frontmatter that could drift.

Two skills are renamed for a uniform mt-<verb>-<object> scheme: mt-add-post
becomes mt-add-article, since it adds an article to a post, and mt-webfetch
becomes mt-fetch-url. The other four already conformed. Note that $mt-add-post
and mt-webfetch no longer resolve; no alias directories are left behind, because
two names for one skill is the duplication this change removes.

Trigger wording in the frontmatter descriptions is left alone apart from the
renamed tokens and the corrected fetch-tier summary: those strings are how the
runtimes decide whether to invoke a skill.

Setup documentation now states the npm ci prerequisite. The engine has
dependencies, so unlike its predecessor it does not run on a bare clone.
2026-09-18 16:24:34 +07:00
tiennm99 f759f7a8ba feat(newsletter): report post entry tally after each URL add 2026-09-11 17:33:46 +07:00
tiennm99 57ff9fadf3 docs(newsletter): add newsletter 131
Drop the key-points bullet list from newsletter article entries; summaries are prose paragraphs only.
2026-09-11 09:45:02 +07:00
tiennm99 8884014fc8 docs(skills): document fetch fallback chain and pinned target post
Add a reader-proxy tier after defuddle, stop skipping URLs that only fail a
plain classifier fetch, let a session pin an earlier draft as the target post,
and tighten Substack image candidate handling (dedupe, stable numbering,
reuse a resolved source post across a batch).
2026-09-09 09:25:35 +07:00
tiennm99 e8451d8c24 refactor(scripts): migrate newsletter engine from Node to Go
One Go binary with a subcommand per former script, invoked as
'go run ./scripts/newsletter <command>' from repo root. Stdlib only;
publications config embedded via go:embed (go run recompiles on edit).
Behavior parity verified side-by-side before deleting the JS —
see plans/reports/parity-260818-newsletter-go-migration-report.md.

Permissions: allow 'Bash(go *)', drop 'Bash(node *)' and the redundant
'Write(content)' rule (Edit rules cover all file-editing tools).
2026-08-18 21:43:57 +07:00
tiennm99 4290592847 fix(newsletter): preserve source-language image labels 2026-07-11 18:36:03 +07:00
tiennm99 8cb340a364 fix(skills): keep user communication in English 2026-07-10 11:34:59 +07:00
tiennm99 b97ff25e4e fix(skills): prefer newsletter terminology 2026-07-09 11:04:08 +07:00
tiennm99 e92f4682df fix(newsletter): preserve source article titles 2026-07-04 18:01:32 +07:00
tiennm99 8f4e1928d8 feat(tooling): run blog from Claude Code, OpenCode & Codex on shared engine
Extract newsletter scripts to a neutral scripts/newsletter/ engine and add
side-by-side support for all three AI coding tools off one source of truth.

- Move 9 scripts + substack config from .claude/skills/**/scripts to
  scripts/newsletter/ (history preserved); fix PROJECT_ROOT depth and
  cross-require/config paths; repoint all SKILL.md invocations
- Add canonical AGENTS.md; reduce CLAUDE.md to an @AGENTS.md import
- Add opencode.json (permissions, no MCP); skills auto-discovered in place
- Add codex/prompts/*.md (6 prompts) + copy installers (install.sh/.ps1)
- Add docs/multi-tool-usage.md (setup, per-tool invocation, teardown) + README pointer
2026-06-02 14:07:22 +07:00
tiennm99 d262159742 refactor(skills): fix dedup edge cases and modularize mt-* scripts
- fix checkDuplicate false-negative on Substack cover images (uuid with no size suffix)
- stop cleanUrl from corrupting the query string on unparseable input
- extract shared fetchWithTimeout into url-utils (consistent timer cleanup)
- split find-substack-post html/rss helpers into html-text-utils
- scan content/post for duplicates, matching the other scripts
- correct doc drift in mt-add-image/mt-add-url and drop plan-phase code comment
2026-05-30 20:31:50 +07:00
tiennm99 eada44d407 refactor(skills): share Substack image helpers and harden URL dedup/routing
- extract isSubstackImage/substackImageUuid into shared url-utils
- route Substack images by host (handles f_auto/.avif/extensionless CDN URLs)
- replace grep-based duplicate check with boundary-aware pure-JS scan
- share one fetch budget across publications in deep sitemap crawl
- expand file-extension classification (avif/heic/mkv/pptx/etc.)
2026-05-30 20:13:27 +07:00
tiennm99 5f78b3e2be feat(mt-add-image): confirm image label from source post candidates
ByteByteGo images carry no caption/alt and image order cannot be mapped to
titles automatically (sponsor and video items interleave). Extract the source
post's TOC topic titles as candidates and let the user pick the matching label
(caption is used directly when a publication provides one; typing is always
available). Validated against newsletters 101-106: the correct title appears
in the candidate set for all 8 images.
2026-05-30 17:23:10 +07:00
tiennm99 f40103fe82 feat(skills): add mt-add-image handler with Substack source lookup
Add the image handler in the meta-dispatch architecture. Given an image
URL it resolves a label and inserts it into the newsletter Bonus -> Images.

For Substack-hosted images, decode the S3 image UUID and find the source
post across configured publications (ByteByteGo by default): RSS feed first,
then a sitemap crawl up to ~3 months back. Label priority is figure caption,
then post title, then a user-typed name. Non-Substack images are best-effort
then ask. Publications are configurable and the skill offers to add a new one
when the user identifies it.

Wire mt-add-url to dispatch the image route to mt-add-image (previously a
fallback). Update the project skills list.
2026-05-30 16:55:47 +07:00
tiennm99 f5fa315ea1 feat(skills): split newsletter URL workflow into meta dispatcher + handlers
Add mt-add-url meta skill that classifies a URL and auto-dispatches to a
handler skill: articles to mt-add-post, YouTube links to the new
mt-add-video (Bonus -> Videos with a Vietnamese title + short summary).
Unsupported types (image, etc.) prompt the user to add or extend a skill;
image support is deferred to a future mt-add-image handler.

Shared logic (add-url.js router, url-utils.js, find-newsletter-number.js)
and a shared post-mechanics reference live under mt-add-url/. mt-add-post
is reduced to an article-only handler. add-url.js detects watch/youtu.be/
shorts, normalizes to the canonical watch URL, dedups by video id, and
fetches the title via oEmbed. checkDuplicate uses execFileSync (no shell).
2026-05-30 16:23:27 +07:00
tiennm99 6ebf27714a fix(mt-add-post): preserve YouTube video id in duplicate check
bareUrl() dropped the query string, collapsing every youtube.com/watch
URL to the same bare key and flagging all YouTube links as duplicates.
Keep host identity params (v for youtube) so distinct videos are not
treated as duplicates.
2026-05-30 15:48:52 +07:00
tiennm99 a9cbf48f48 refactor(skills): convert mt-webfetch script to Node.js for project consistency 2026-04-14 21:46:33 +07:00
tiennm99 4df75a25fb feat(skills): add mt-webfetch fallback + improve mt-add-post URL cleaning and duplicate detection 2026-04-14 21:41:15 +07:00
tiennm99 6925d731bf refactor(skills): convert shell scripts to Node.js
Replace bash scripts with cross-platform Node.js equivalents for
mt-add-post and mt-add-tags skills. Update SKILL.md references.
2026-04-02 16:44:48 +07:00
tiennm99 eae318510a fix(skills): target only content/post files in mt-add-tags proactive commit check 2026-03-17 22:11:42 +07:00
tiennm99 6d6b8774cd feat(skills): set 2-3 tags for regular posts, 6-7 for newsletter posts in mt-add-tags 2026-03-17 22:10:13 +07:00
tiennm99 d6113cb3ed feat(skills): add list_existing_tags.sh script for future tag normalization 2026-03-17 21:40:05 +07:00
tiennm99 0680a0bfaf feat(skills): add disabled tag normalization step to mt-add-tags (pending tag standard) 2026-03-17 21:27:24 +07:00
tiennm99 35108a42f3 fix(skills): add UTC+7 timezone to date calls in find_newsletter_number.sh 2026-03-17 20:50:38 +07:00
tiennm99 66a0717a28 fix(skills): align skill names with folder names using hyphens 2026-03-17 09:39:19 +07:00
tiennm99 5823a65552 feat(skills): add mt:add-tags skill for Hugo post tag generation
Adds a new skill that analyzes post content and generates 6-7 relevant
tags, checks existing tags, and asks for user confirmation before writing.
Also triggers proactively when committing posts with minimal tags.
2026-03-11 20:56:32 +07:00
tiennm99 d8bcde325d chore: consolidate settings, enhance skill scripts, and reformat content
- Migrate settings from settings.local.json to settings.json with expanded permissions
- Add helper scripts (find_newsletter_number.sh, prepare_url.sh) to mt-add-post skill
- Update skill documentation and configuration
- Apply consistent formatting across config, content, and layout files
- Update workflow, gitignore, and netlify configuration
2026-03-11 18:29:56 +07:00
tiennm99 0d21e4b69b refactor(skills): rename miti-add-post to mt:add-post
Moves skill from .agents/skills/ to .claude/skills/ (Claude Code only)
and renames it to mt:add-post with directory mt-add-post.
2026-03-09 10:08:52 +07:00
tiennm99 18313b016b refactor(skills): rename add-post to miti-add-post
Add custom prefix to distinguish custom skills from third-party ones.
2026-03-07 10:11:40 +07:00
tiennm99 4424566925 fix(skills): remove spurious symlink in add-post skill directory 2026-03-07 10:11:40 +07:00
tiennm99 fac2a72677 refactor(skills): extract add-post workflow into reusable skill
Moves URL processing workflow from AGENTS.md into a dedicated skill at
.agents/skills/add-post. Simplifies AGENTS.md to only contain project info
and development server instructions. Creates symlink in .claude/skills/ for
skill discovery.
2026-03-07 10:11:40 +07:00