Commit Graph
442 Commits
Author SHA1 Message Date
tiennm99 f9bf45eae8 docs(newsletter): add newsletter 121 2026-07-09 18:19:44 +07:00
tiennm99 9ade768ef7 fix(skills): prefer newsletter terminology 2026-07-09 11:04:08 +07:00
tiennm99 85bc702cf5 docs(newsletter): add newsletter 120 2026-07-09 11:03:44 +07:00
tiennm99 33a985c1f3 docs(newsletter): add backlog newsletter tags 2026-07-08 09:22:18 +07:00
tiennm99 b993fae170 docs(newsletter): add newsletter 119 2026-07-08 00:21:02 +07:00
tiennm99 69cec2486a docs(newsletter): add newsletter 118 2026-07-07 00:06:08 +07:00
tiennm99 6f5b33c60a docs(newsletter): add newsletter 117 2026-07-05 22:18:14 +07:00
tiennm99 700a38ad4f docs(newsletter): add newsletter 116 2026-07-05 21:59:20 +07:00
tiennm99 00abc92af0 feat(newsletter): add newsletter 115 2026-07-04 22:17:11 +07:00
tiennm99 4a05c5b5db feat(newsletter): add newsletter 114 2026-07-04 18:01:32 +07:00
tiennm99 daa7d49da9 fix(newsletter): preserve source article titles 2026-07-04 18:01:32 +07:00
github-actions[bot] 1ede184d27 chore(projects): refresh projects list 2026-06-30 01:56:55 +07:00
tiennm99 4066164bf3 feat(referral): add Aiven managed data platform referral 2026-06-28 09:38:25 +07:00
tiennm99 b35d2b4457 docs(newsletter): add newsletter 113 2026-06-24 18:14:21 +07:00
tiennm99 3c4b66d38f feat: publish Newsletter #112 2026-06-24 10:38:46 +07:00
github-actions[bot] 9c01b94753 chore(projects): refresh projects list 2026-06-24 02:00:40 +07:00
github-actions[bot] b826cc4ea1 chore(projects): refresh projects list 2026-06-23 02:59:11 +07:00
github-actions[bot] 12b36c5449 chore(projects): refresh projects list 2026-06-22 01:13:38 +07:00
github-actions[bot] 12528f9bed chore(projects): refresh projects list 2026-06-20 01:27:02 +07:00
github-actions[bot] 220b6a5e20 chore(projects): refresh projects list 2026-06-14 01:02:06 +07:00
github-actions[bot] 519861a0c1 chore(projects): refresh projects list 2026-06-13 01:57:44 +07:00
tiennm99 1e1f0af492 feat: publish Newsletter #111 2026-06-11 21:23:03 +07:00
tiennm99 c9556a27af feat: publish Newsletter #110 2026-06-07 15:39:25 +07:00
tiennm99 17e1ff6404 feat(post): add newsletter #109 — IDE history, debugging, containers, AI coding, vector indexing 2026-06-06 06:21:13 +07:00
tiennm99 c753ca0fea refactor(referral): reorder AI coding platform providers
- Move Z.ai and MiniMax to the top of the section
- Place Xiaomi MiMo directly above ModelArk
2026-06-05 09:38:14 +07:00
tiennm99 7f1f0623cb fix(referral): simplify MiniMax description, remove personal reward amount 2026-06-04 17:59:10 +07:00
tiennm99 f54207916e feat(referral): update MiniMax description — 5 voucher, Jul 1 deadline, add minimax.png 2026-06-04 17:56:54 +07:00
tiennm99 c8b6c09c94 feat(post): add newsletter #108 — AI coding, mental models, developer productivity 2026-06-04 17:50:18 +07:00
tiennm99 348f3d4c0c fix(referral): add missing mimo.png image 2026-06-04 17:39:13 +07:00
tiennm99 a00659613d feat(referral): add thank-you note 2026-06-04 17:27:25 +07:00
tiennm99 be306ff8b7 feat(referral): add Xiaomi MiMo Open Platform referral 2026-06-04 17:20:59 +07:00
tiennm99 e0969dfeda feat(referral): add Alibaba Cloud referral program 2026-06-04 17:19:58 +07:00
tiennm99 3684375d4f feat(post): add Gemini CLI / Antigravity as 4th AI coding tool
- Add Gemini CLI and Antigravity to the list of tools used
- Add dedicated section with deprecation timeline (June 18 cutoff)
- Update tags with Gemini CLI and Antigravity
2026-06-04 15:13:56 +07:00
tiennm99 033bcc60d8 feat(post): add post on rotating AI coding tools to maximize subscription value 2026-06-04 09:43:32 +07:00
tiennm99 550dde44ab feat(referral): mark friend's claude pass as out of stock 2026-06-03 09:52:05 +07:00
tiennm99 8699294561 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 067ad3e13d feat(referral): prioritize opencode go referral 2026-06-01 16:44:47 +07:00
tiennm99 7ba652bd0d feat(referral): add opencode go referral 2026-06-01 16:36:47 +07:00
tiennm99 9078e27e11 feat(newsletter): add Newsletter #107 with articles and bonus images 2026-05-30 21:22:06 +07:00
tiennm99 cbba4583a0 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 6044550378 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 17468e5653 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 659fe47c03 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 cbb18cf2d3 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 1e42f36701 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 9d19e99c4c docs(newsletter): add Newsletter #106 2026-05-29 00:24:59 +07:00
tiennm99 66eef5847e docs(newsletter): add Newsletter #105 2026-05-27 22:10:44 +07:00
tiennm99 3896e99a53 docs(newsletter): add Newsletter #104 2026-05-24 23:58:59 +07:00
tiennm99 03df6b526d docs(newsletter): add Newsletter #103
11 articles covering AI coding, career lessons, email internals,
Git performance, binary search optimization, Swiss tables, and more.
2026-05-23 22:22:33 +07:00
github-actions[bot] 95d07be400 chore(projects): refresh projects list 2026-05-18 00:46:50 +07:00