From writing-skills
Collects raw materials from daily notes, Pinboard, Douban, Telegram, calendars, reminders, photos, RSS digests, and plrom diffs for biweekly diary templates on macOS.
npx claudepluginhub niracler/skill --plugin writing-skillsThis skill uses the workspace's default tool permissions.
收集双周记写作素材。从日记、书签、豆瓣、Telegram、日历、提醒事项、照片、RSS 精选、plrom 变更等
Drafts structured weekly software development reports from git logs, Obsidian work logs, YAML schedules, GitHub PRs, 云效 tasks, and calendars. Use for 周报 or end-of-week summaries.
Generates structured daily journal entries from AI agent's perspective, capturing projects, wins, frustrations, learnings, and emotions. Useful for diary, journal, or self-reflection requests.
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Share bugs, ideas, or general feedback.
收集双周记写作素材。从日记、书签、豆瓣、Telegram、日历、提醒事项、照片、RSS 精选、plrom 变更等 多个来源抓取过去 2-4 周的素材,整理成周记模板结构,供用户手写周记时参考。
这个 skill 不代写周记 — 周记的灵魂在于你自己的文字和反思。它只负责把散落各处的碎片聚合起来, 让你写的时候不遗漏重要的事。
| Tool | Type | Required | Install |
|---|---|---|---|
| macOS | system | Yes | This skill requires macOS |
| reminders-cli | cli | Yes | brew install keith/formulae/reminders-cli |
| icalBuddy | cli | Yes | brew install ical-buddy |
| curl | cli | Yes | Built-in on macOS |
| git | cli | Yes | Built-in or brew install git |
PINBOARD_AUTH_TOKEN | env var | Yes | See pinboard-manager skill for setup |
Do NOT proactively verify these tools on skill load. If a command fails due to a missing tool, skip that data source and continue with what's available.
| Path | Purpose |
|---|---|
~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/Archives/日记(Daily)/ | Daily diary entries |
~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/Areas/生活(Life)/周记(Weekly)/ | Output location for 周记 (legacy) |
~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/Areas/生活(Life)/月记(Monthly)/ | Output location for 月记 (current) |
~/Library/Mobile Documents/iCloud~md~obsidian/Documents/Note/templates/monthly.md | 周记 template |
~/code/ai-dev/repos/rss-agent/output/daily/ | AI-curated RSS daily digests |
~/code/nini-dev/repos/plrom/README.md | plrom source file (人 X 社区 X 物), has its own git repo |
┌──────────────────────────────────────────────────────────────┐
│ biweekly-collector 完整流程(~15-20min) │
└──────────────────────────────────────────────────────────────┘
┌──────────────────┐
│ 用户触发素材收集 │
└──────┬───────────┘
│
▼
┌────────────────────────────────────┐
│ 1. 确认时间范围 + 创建文件 (~2min) │
└──────┬─────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ 2. 并行数据收集(subagent) (~5-8min) │
│ ┌─ 日记条目提取 │
│ ├─ Pinboard 书签 │
│ ├─ 豆瓣动态 (RSS) │
│ ├─ Telegram 频道 (RSS) │
│ ├─ Apple Calendar 事件 │
│ ├─ Apple Reminders 完成项 │
│ ├─ RSS 精选摘要 │
│ └─ plrom git diff │
└──────┬──────────────────────────────────────┘
│
▼
┌────────────────────────────────────┐
│ 3. 整理素材到模板结构 (~3min) │
└──────┬─────────────────────────────┘
│
▼
┌────────────────────────────────────┐
│ 4. 展示 + 用户确认写入 (~3min) │
└──────┬─────────────────────────────┘
│
▼
┌──────┐
│ 完成 │
└──────┘
The biweekly diary covers a flexible period (2-4 weeks). Ask the user:
Claude: 「这次周记要覆盖什么时间段?」
建议:3/10 - 3/23(两周)
或者你可以指定其他范围(最短两周,最长一个月)
Suggest a default based on the last entry's date. Scan both Areas/生活(Life)/周记(Weekly)/ and
Areas/生活(Life)/月记(Monthly)/ for the most recent entry to calculate the gap.
The 周记 naming convention is YYYYMM-N-title.md:
YYYYMM: year-month of the period's end dateN: the nth entry of that month (1, 2, 3...)title: a short descriptive title chosen by the userAsk the user for a title, or offer to decide later after seeing the materials.
Create the file using the template from templates/monthly.md. The output directory can be
either 周记(Weekly)/ or 月记(Monthly)/ — ask the user or accept if they specify a path directly:
---
aliases:
tags:
- 周记
date: {start_date}
modified: {today}
---
> {用户稍后填写的开场白}
## 关于现实生活的记录
> [!info]
> 我所有的周记或许并没有谎言,起码没有主动撒谎的部分。但其中的内容可能都具有某种倾向性,例如隐藏了某些未言明的黑暗成分,或者说是选择性的表达。
<!-- 以下是收集到的素材,请根据这些素材手写正文 -->
### 素材:生活事件与日记摘要
{collected_diary_materials}
### 素材:日历事件
{collected_calendar_events}
### 素材:当前提醒事项(个人相关)
{collected_reminders}
### 素材:plrom 变更
{collected_plrom_diff}
## 👀 还看了什么
### 📚 🎬 📺 作品
| 作品 & 产品名 | 媒介 | 进度 | 打分 | 吐槽 |
| -------- | --- | --- | --- | --- |
{collected_douban_entries}
### 🌐 文章
{collected_articles}
### 素材:RSS 精选回顾
{collected_rss_digests}
### 素材:Telegram 频道分享
{collected_telegram_posts}
## 后记
<!-- 这里是你的个人反思空间 -->
Launch subagents for each data source concurrently. Each source is independent — if one fails, skip it and continue.
Read each daily note within the date range from Archives/日记(Daily)/.
Extract content from three sections:
## 1 title Journal → personal events, reflections, photos## 2 Work Log → skim for personal-interest items (skip formal 周报 content)## 3 Today I Learn → TIL entries, media impressionsOutput format:
#### 3/10 (周一)
- 在图书馆看了《断舍离》
- 跟朋友 L 约了羽毛球
#### 3/11 (周二)
- Home Assistant Dashboard 大整理
- 看完了《迷宫饭》第二季
Preserve the user's original voice — summarize but don't rewrite. Include photo references
(![[filename]] or ) as-is.
Fetch bookmarks from the date range:
curl -s "https://api.pinboard.in/v1/posts/all?auth_token=$PINBOARD_AUTH_TOKEN&format=json&fromdt={start_date}T00:00:00Z&todt={end_date}T23:59:59Z"
Format each bookmark as:
- [Title](url) - {description if any} `{tags}`
Group by week or by tag category if there are many.
Fetch the user's Douban interest feed. Try direct feed first, fall back to RSSHub:
# Try direct feed first
curl -s "https://www.douban.com/feed/people/niracler/interests"
# If empty or blocked, use RSSHub
curl -s "https://rsshub.app/douban/people/niracler/interests"
Parse the RSS/Atom entries. Extract:
Format into the 作品 table rows:
| 《作品名》 | 电影 | 100% | 8 | 用户的短评 |
If the Douban feed is unavailable or empty, note this and the user can fill manually.
Fetch the user's Telegram channel RSS:
curl -s "https://tg.niracler.com/rss.xml"
The feed is standard RSS 2.0 with <content:encoded> HTML bodies. Important parsing notes:
<content:encoded> text<a href="/search/..."> links (e.g., #pinboard, #bilibili,
#梦, #暴论, #网易云音乐). Extract via regex for categorization.Use a script to filter strictly:
# Fetch and filter Telegram RSS by date range
curl -s "https://tg.niracler.com/rss.xml" | python3 -c "
import sys, xml.etree.ElementTree as ET
from email.utils import parsedate_to_datetime
from datetime import datetime, timezone
start = datetime({start_year}, {start_month}, {start_day}, tzinfo=timezone.utc)
end = datetime({end_year}, {end_month}, {end_day}, 23, 59, 59, tzinfo=timezone.utc)
tree = ET.parse(sys.stdin)
for item in tree.findall('.//item'):
pub = item.find('pubDate')
if pub is not None:
dt = parsedate_to_datetime(pub.text)
if start <= dt <= end:
title = item.find('title')
link = item.find('link')
print(f'{dt.strftime(\"%m/%d\")} | {title.text if title is not None and title.text else \"(untitled)\"} | {link.text}')
"
Group by hashtag category when possible:
#### 文章分享 (#pinboard)
- [Article title](url) - user's comment
#### 随想 (#暴论)
- 3/15: "some thought..."
#### 其他
- 3/12: 新电脑到了
Use icalBuddy to query calendar events within the date range:
icalBuddy -sd -ic "Personal,Learn&Create" \
eventsFrom:{start_date} to:{end_date}
Key flags:
-sd: separate by date (groups events under date headers)-ic "Personal,Learn&Create": include only personal calendars, skip "Work" and
"Scheduled Reminders" calendars (reminders are captured separately via reminders-cli)The output is already well-structured with date grouping. Include personal events (meetups, appointments, trips, hobbies) but skip recurring work meetings.
To list available calendar names: icalBuddy calendars
Query current reminders to capture what the user is tracking and planning:
reminders show-all
This returns all active (uncompleted) reminders across all lists, with due dates and notes. For the 月记, current reminders are more valuable than completed ones — they show what the user is actively focused on: life goals, relationship maintenance schedules, recurring habits, upcoming plans, and learning checkpoints.
Filter the output to personal-relevant lists (生活, 健康, 人际关系, 阅读, 提醒) and skip pure work items (提醒 list items about specific work tasks like "sunlite: switch API").
Read the AI-curated daily digest files from ~/code/ai-dev/repos/rss-agent/output/daily/.
For each day in the range, read YYYY-MM-DD.md if it exists. Each daily digest contains:
Extract the highest-scored articles (score >= 70) as "this period's reading highlights". Deduplicate against Pinboard bookmarks (same URL = already captured via Pinboard). Also deduplicate against Telegram channel shares (same URL).
The plrom repo (~/code/nini-dev/repos/plrom/) is a standalone git repo that tracks
"人 X 社区 X 物" — the user's curated list of people, communities, and things they follow.
It auto-syncs to the blog via GitHub Actions.
Check what changed during the period:
cd ~/code/nini-dev/repos/plrom
git log --since="{start_date}" --until="{end_date}" --oneline
# If there are commits, get the diff
FIRST_COMMIT=$(git log --since="{start_date}" --format="%H" --reverse | head -1)
if [ -n "$FIRST_COMMIT" ]; then
git diff "$FIRST_COMMIT"^..HEAD -- README.md
fi
If there are changes, summarize what was added/removed:
The plrom page has sections: 人 (技术博主/作家/漫画家/导演/UP主/TG芳邻/播客/歌手/淘宝店主), 组织或社区, 物 (软件/硬件/游戏). This captures the user's evolving interests and discoveries.
After all data is collected, organize the materials into the skeleton file created in Step 1.
生活事件 — merge diary entries + calendar events + completed reminders into a chronological narrative scaffold. Group related events (e.g., consecutive days of a trip).
作品 table — merge Douban entries with any media mentioned in diary TIL sections. Deduplicate by title. Keep the user's original comments when available.
文章 section — merge Pinboard bookmarks + RSS digest highlights + Telegram shares. Deduplicate by URL. Prefer Pinboard entries (they have the user's own description). Format like historical 周记 entries:
- [Title](url) - one-line comment from user or AI summary
plrom diff — present as a "discoveries" subsection showing what's new.
Photos — collect all ![[image]] and  references from diary entries.
List them in context so the user can select which to include.
Show the user a summary of what was collected:
素材收集完成!以下是各来源的数量统计:
📔 日记条目: 12 天有内容
📌 Pinboard 书签: 8 条
🎬 豆瓣动态: 3 部作品
📱 Telegram 分享: 15 条
📅 日历事件: 6 个
✅ 完成的提醒: 9 项
📰 RSS 精选: 22 篇(去重后 17 篇)
🔄 plrom 变更: +3 新增, -1 移除
已写入文件:Areas/生活(Life)/月记(Monthly)/202603-title.md
你可以在 Obsidian 中打开这个文件,在素材基础上写你的周记。
Ask if the user wants to:
Write the final organized materials to the file.
| Source unavailable | Behavior |
|---|---|
| Daily notes missing for some days | Use available days, note gaps |
| Pinboard token not set | Skip, note "Pinboard 数据未获取" |
| Douban feed empty or blocked | Try RSSHub fallback: https://rsshub.app/douban/people/niracler/interests; if still empty, leave table for manual fill |
| Telegram RSS unreachable | Skip, note it |
| Calendar access denied | Run icalBuddy calendars to test access; if denied, suggest ! tccutil reset Calendar |
| rss-agent output missing | Skip, note "RSS 精选未找到" |
| plrom repo not found | Skip plrom diff |
| Issue | Fix |
|---|---|
| Douban RSS returns empty | Douban may block direct RSS; try via RSSHub: https://rsshub.app/douban/people/niracler/interests |
| icalBuddy calendar name mismatch | Run icalBuddy calendars to list exact names; adjust -ic filter accordingly |
| Too many Pinboard results | Add tag filter or increase fromdt precision |
| plrom has no commits in range | Normal — plrom updates are infrequent |
| Telegram RSS has no date filter | Fetch all entries, filter by pubDate in the date range |
| File already exists | Ask user: overwrite / append / use different name |
| Output path: 周记 vs 月记 | User may use 月记(Monthly)/ instead of 周记(Weekly)/. Ask or accept if user specifies a path directly |