Building AI-powered automation skills, productivity tools, and knowledge systems for individual developers and AI-native workflows.
I create production-ready automation skills across multiple AI platforms (OpenCode, Hermes, OpenClaw, Claude), focusing on:
- Skill-based AI orchestration — turning workflows into reusable, composable skills
- Multilingual content automation — English ↔ Chinese/Traditional Chinese
- Developer productivity tools — Chrome extensions, CLI utilities, API integrations
- AI platform experimentation — deeply hands-on with OpenCode, Hermes, OpenClaw, Claude, and OpenRouter
All code prioritizes clarity over cleverness: simple, readable, portable, and easy to fork.
⚡ OpenCode — the growing collection, auto-published to ClawHub
My OpenCode skills live in ai-thoughts/.opencode/skills/ and publish to ClawHub automatically on every push to j3ffyang — no local installs, one owner account. The one to open first:
asd-ste100— write and audit agent instructions in ASD-STE100's rules: one action per sentence, condition first, one name per item. Ships a deterministic linter for sentence length, semicolons, banned words, and passive voice.
The rest of the collection — article translation, Traditional-Chinese twin sync, Astro sync, and resize-for-banner for Twitter/X headers only (LinkedIn and blog headers take the original image) — is in the repo linked below.
| Platform | Repo | Purpose | Latest | Status |
|---|---|---|---|---|
| OpenCode ⚡ | ai-thoughts/.opencode/skills | asd-ste100 — ASD-STE100 rules for agent instructions, with a linter (--stats, --check). Auto-published to ClawHub on every push to j3ffyang. |
docs: publish STE100 article (Oct 2026) |
🔄 Active |
| Hermes ⚕ | hermes-custom-skills | Specialized skills for Hermes Agent — autonomous workflows, content generation, task orchestration. | docs: add README and CONTRIBUTING (Apr 2026) |
🔄 Active |
| OpenClaw 🦞 | openclaw-custom-skills | Production skills for OpenClaw published to ClawHub. Multilingual blog publishing, media generation. | add chinese edition (Apr 2026) |
🔄 Active |
| Claude Code | claude-custom-skills | Automation skills for Claude Code — productivity hacks, data export, content workflows. | add i18n support to README (Apr 2026) |
✨ Stable |
| Multi-platform | ai-custom-skills | Production-ready skills across platforms (Claude Code, Hermes, OpenClaw) — content creation, data export, workflow automation. | docs: point all ClawHub links to clawhub.ai/j3ffyang (Oct 2026) |
🔄 Active |
| Repo | Purpose | Articles |
|---|---|---|
| ai-thoughts | Articles & essays: AI platforms (OpenClaw, Hermes), solo entrepreneurship, privacy, technical deep-dives. Bilingual: English + Simplified/Traditional Chinese | 51 articles |
| Repo | Purpose | Type | Latest |
|---|---|---|---|
| chrome-extensions | Monorepo of Chrome extensions: sum2chn (translate & summarize web pages → Simplified Chinese MD), twitter2md (X post → Markdown, ext + Node CLI), twitter-bookmark-summarizer (summarize tweets via GPT-4o) |
Chrome Ext + CLI | docs: add top-level README and MIT license (Aug 2026) |
Timeline is editorial — edit it directly in scripts/portfolio_template.md, then regenerate.
- Oct 26: Published "Replace Cursor with a Minimal VSCodium AppImage" — English plus Simplified and Traditional Chinese twins, a 16:9 infographic, and a 5:2 banner, and synced to the Astro blog; a 3-function editor (git-tagged tree, Vim keys, Mermaid + local PlantUML) in one AppImage, with the honest 795 MiB Electron footprint and a one-step uninstall
- Oct 23: Published "Where Does Brave's Leo AI Keep Your Data?" — English plus Simplified and Traditional Chinese twins, a 16:9 infographic, and a 5:2 banner; the local store turns out to be decryptable with Chromium's public
peanutskey on a machine with no keyring - Oct 23: Restricted
resize-for-bannerto Twitter/X only — LinkedIn and blog headers accept the original image — and codified "register an article only after it is committed and pushed" in AGENTS.md, which removed three uncommitted rows from the manifest - Oct 20: Published "The Rules, Not the Words: ASD-STE100 for Agent Instructions" — English plus Simplified and Traditional Chinese twins, a 16:9 infographic, and a 5:2 banner
- Oct 20: Added the
asd-ste100skill and a--statssummary mode to its linter; rewrote both working-rule AGENTS.md files to the same standard (18 and 15 linter errors to zero) and logged the diffs - Oct 20: Added a
portfolio_latest: falseopt-out, so an article whose doc is not committed yet stays counted but off the front-page list; recorded a per-genre precision rule (approximate figures in essays, exactness in code and measurements) - Oct 7: Refreshed the portfolio timeline and skills list, and dropped the WIP
encrypt-linuxrow from the article index until the articles are ready - Oct 7: Published "What Should You Know to Work Well with an AI Agent?" in three versions — English, Simplified Chinese, and its first Traditional-Chinese
-zh-hant.mdtwin - Oct 7: Added the
simplified-to-traditionalskill —-zh-hans→-zh-hanttwin sync with OpenCC (s2twp), permanent cross-links, and--check; published to ClawHub 1.0.0 - Oct 7: Renamed the translation skill
translate-to-chn→translate-to-zh-hansand published it to ClawHub 1.0.0 - Oct 7: Standardized the Simplified-Chinese suffix as
-zh-hans.mdacross AGENTS.md, the skills, and the README generator'sdesc_zhcheck — legacy-chn.mdfiles kept as-is until explicitly migrated - Oct 4: Finished and published "Agent session persistence in OpenCode" (file-dated Sep 20, completed today) — bilingual (EN + ZH) with its own infographic — and refreshed the already-published "What Should You Know to Work Well with an AI Agent?"; both registered in the article index and portfolio
- Sep 30: Added the
security-writeup-bad-effectsskill, averify_md_boxes.pybox-diagram verifier, and a global AGENTS.md "Host safety" rule; cross-posted the Brisova malware analysis to Medium and X (5:2 banner, plus a platform-filter-safe rewrite of one exploit-describing line) - Sep 29: Published "Anatomy of a Malicious GitHub Invite — The Brisova Build-Time Payload" (EN + ZH) with infographic; added the
untrusted-code-safetyskill and its global AGENTS.md "Untrusted code safety" contract - Sep 27: Published "Choosing a Model for OpenCode via OpenRouter" with infographic and Twitter banner
- Sep 21: Published the
rdr2-playthroughskill to ClawHub; reworked the portfolio pipeline so each account self-publishes its own README (no cross-account PAT or mirror) - Sep 21: Expanded the portfolio Code Highlights with automation tooling (
clawhub_publish.py,sync_profile.py,gen_readmes.py) - Sep 20: Published "Extracting PowerPoint to Markdown Without Losing a Byte" (EN + ZH) with infographic and the
pptx-extractskill - Sep 17: Added the
normalize-whitespaceandsync-config-with-sampleskills - Sep 15: Added an auto-generated ClawHub skills table and switched READMEs to recency ordering
- Sep 15: Published the Chinese translation of the "create SKILL.md, AGENTS.md, and PERSONA.md on the fly" essay
- Sep 14: Published "Create SKILL.md, AGENTS.md, and PERSONA.md on the fly" with hero infographic and Twitter banner; renamed the ClawHub publish skill to
publish-skills - Sep 14: Refined the
bold-highlightsskill — sparser bolding, no list bolds - Sep 2: Reworked the GPD dual-AMD eGPU article with mermaid diagrams, new image assets, and an Arch sign-off
- Aug 8: Added
scripts/unwrap_md.py— auto-wraps article and skill prose to one-paragraph-per-line, preserving code fences, tables, and list nesting - Aug 8: Published the AI agent collaboration playbook — what a real multi-repo ClawHub auto-publish project taught about AGENTS.md, SKILL.md, and project boundaries
- Aug 7: Published AMD iGPU + eGPU setup guide for GPD Win4 (bilingual EN/ZH) with verification commands and stable DRM symlinks
- Aug 4: Merged the three Chrome extensions (
sum2chn,twitter2md,twitter-bookmark-summarizer) into a singlechrome-extensionsmonorepo - Early Aug: Published "Why OpenCode is the best AI agent setup for me" essay and the Ollama → llama.cpp local-LLM deep-dive (draft)
- Jul 31: Published the Hermes Agent skills/plugins cleanup guide (bilingual)
- Jul 21-22: Published Obsidian + Karpathy LLM Wiki local search guide and the "unknown unknowns" essay (bilingual)
- Jul 14: Added Brave browser privacy analysis (bilingual) to
ai-thoughts - Jul 14: Polished and committed two blog posts with bilingual README updates
- Early Jul: Releasing v1 of
sum2chnChrome extension (translation + summarization)
- Jun: Completed
twitter2mdChrome extension and Node.js CLI tool - Jun: Refactored
twitterBookmarkSumto use popup-triggered summarization - May: Released
twitter2mdfor X post extraction as Markdown
- Apr: Published first Hermes Agent articles and tutorials in
ai-thoughts - Mar: Established
openclaw-custom-skillsrepo on ClawHub - Feb: Began deep-dive experimentation with OpenClaw and Hermes platforms
Automation tooling that keeps this portfolio, its READMEs, and its ClawHub skills in sync.
Repo: ai-thoughts | Language: Python | Purpose: Render PORTFOLIO.md from a template + articles.yaml + git log
def render(data: dict) -> str:
out = TEMPLATE.read_text(encoding="utf-8")
values = {
"ARTICLE_COUNT": str(article_count()),
"LATEST_ARTICLES": latest_articles(data),
"LAST_UPDATED": last_updated(),
}
for key, value in values.items():
out = out.replace("{{" + key + "}}", value)
leftover = sorted(set(re.findall(r"\{\{[A-Z_]+\}\}", out)))
if leftover:
print(f"error: unfilled placeholders: {leftover}", file=sys.stderr)
sys.exit(1)
return outWhy it matters: Turns articles.yaml + git log into a fresh PORTFOLIO.md with zero hand-editing, and --check mode keeps the committed file honest in CI.
Repo: ai-thoughts | Language: Python | Purpose: Join hard-wrapped paragraphs into single-line paragraphs while preserving code fences, tables, and lists
def glue(a: str, b: str) -> str:
a_end, b_start = a[-1:], b[:1]
if CJK.match(a_end) and CJK.match(b_start):
return "" # 中文之间不加空格
return " "Why it matters: Article and skill prose is stored one-paragraph-per-line (auto-wrapped); this tool restores that convention across docs/ and .opencode/skills/ without touching structure — and --check flags any file that drifts.
Repo: ai-thoughts | Language: YAML + Python | Purpose: Publish .opencode/skills/ to ClawHub on every push — no local CLI
name: ClawHub Skill Sync
on:
push:
branches: [main]
paths:
- ".opencode/skills/**"
- ".github/workflows/clawhub-skill-sync.yml"
workflow_dispatch:
jobs:
publish:
if: github.event_name != 'pull_request' && github.repository_owner == 'j3ffyang'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7.0.1
- uses: oven-sh/setup-bun@<sha>
with:
bun-version: 1.3.10
- name: Checkout ClawHub CLI
uses: actions/checkout@v7.0.1
with:
repository: openclaw/clawhub
ref: v0.23.3
path: clawhub-source
- name: Install ClawHub CLI dependencies
working-directory: clawhub-source
run: bun install --frozen-lockfile
- name: Publish skills to ClawHub
env:
CLAWHUB_TOKEN: ${{ secrets.clawhub_token }}
run: python3 scripts/clawhub_publish.pyWhy it matters: Publishing runs the ClawHub CLI directly instead of the reusable workflow, so the five real statuses the CLI can return — unchanged, would-publish, submitted, published, pending-publication — are all treated as success. (The upstream reusable workflow only maps three of them, so a successful async publish showed up as a red ✗.) The repository_owner guard still stops the two remotes from double-publishing to one ClawHub account.
Repo: publish-skills skill | Language: Shell | Purpose: Confirm what's live on ClawHub via the read-only skills API
# What's actually live? Check latestVersion + owner.handle
curl -s -H "Authorization: Bearer $CLH_TOKEN" \
https://clawhub.ai/api/v1/skills/<slug>Why it matters: Turns "the workflow failed" into a verified fact — the API call proves a skill published even when the upstream workflow's status mapping reports a false failure.
Repo: ai-thoughts | Language: Python | Purpose: Drive the pinned ClawHub CLI to publish every .opencode/skills/* folder, treating all five real statuses as success
OK_STATUSES = {"unchanged", "would-publish", "submitted", "published", "pending-publication"}
...
status = json.loads(completed.stdout).get("status")
if status in OK_STATUSES:
ok.append({"slug": target.name, "status": status})
else:
failed.append({"slug": target.name, "status": status, "message": f"Unknown publish status: {status}"})Why it matters: The upstream reusable workflow only maps three of the five statuses, so a successful async publish (pending-publication) surfaced as a red ✗. This treats all five as success and prints an ok/failed JSON summary the workflow can trust — while the repository_owner guard still stops the two remotes from double-publishing to one ClawHub account.
Status: legacy. The PORTFOLIO.md pipeline superseded this script; kept as a record.
Repo: negtivSpace | Language: Python | Purpose: Recompute every derived number in the profile README (skills, repos, articles, Quick Links) from the nested repos
def apply(pattern: str, repl: str, desc: str, flags: int = 0) -> None:
nonlocal text
new, n = re.subn(pattern, repl, text, flags=flags)
if n:
text = new
edits.append(desc)
else:
failures.append(desc)
for pattern, repl, desc in subs:
apply(pattern, repl, desc)Why it matters: Counts drift the moment a skill or article is added; one pass regenerates them, and the script exits non-zero if any expected section fails to match, so drift surfaces instead of shipping silently. Counting only git-tracked skill dirs keeps local leftovers from skewing the result versus CI.
Repo: ai-thoughts | Language: Python | Purpose: Rebuild README.md and README_zh.md from articles.yaml, with a --check mode for CI
if args.check:
ok = True
for target, generated in ((README_EN, en), (README_ZH, zh)):
current = target.read_text(encoding="utf-8") if target.exists() else None
if current != generated:
ok = False
print(f"stale: {target.name} is out of date")
return 0 if ok else 1Why it matters: Both language READMEs come from one manifest, so the English and Chinese indexes can't diverge, and --check makes CI fail on a stale README rather than letting it drift.
Languages: Python, JavaScript, TypeScript, Bash, YAML
AI Platforms:
- OpenCode — terminal-native AI coding agent; my daily driver
- OpenClaw — local agent orchestration
- Hermes Agent — autonomous workflow automation
- Claude Code — AI-native coding
- OpenRouter — unified LLM gateway
APIs & Services:
- Anthropic Claude (Sonnet, Opus)
- OpenRouter (100+ model access)
- Chrome Extension APIs
- Twitter/X API v2
- Web scraping & DOM manipulation
Tools:
- Git + GitHub
- GitHub Actions — CI/CD automation (YAML workflows)
- Node.js + npm
- Python 3.10+
- Markdown-first documentation
- Skills > Projects — I think in workflows. Every tool becomes a reusable skill.
- Multilingual by default — English + Chinese (Simplified + Traditional)
- Code clarity wins — Readable Python/JS beats clever one-liners. Always.
- Composition over bloat — Small, focused repos that work well together.
- Learn in public — Detailed articles about what works (and what doesn't).
- GitHub: @negtivspace
- Blog: ai-thoughts — 51 articles on AI, privacy, and entrepreneurship
- Gists & Experiments: Personal gists
From ai-thoughts (most recent published articles):
- "Health Records an Agent Can Audit" (Oct 2026) — A two-layer skill for AI-assisted review of personal and family medical records: append-only data, conflict protocol, change gate, evidence grading — and the honest list of what it still cannot do
- "The Rules, Not the Words: ASD-STE100 for Agent Instructions" (Oct 2026) — ASD-STE100 Simplified Technical English for agent instructions — the standard's history and rules, three worked examples, a linter-backed before-and-after measurement of two rule files, and a skill that applies the rules without flattening essay voice; with a visual summary infographic
- "Replace Cursor with a Minimal VSCodium AppImage" (Oct 2026) — Replacing Cursor with a VSCodium AppImage and three Open VSX extensions — git status tags in the file tree, Vim keys, Mermaid in the built-in preview and local PlantUML; why Cursor's forced agent and backend routing are the real problem, what telemetry surface remains, the settings that make the editor inert, and an honest 795 MiB Electron footprint with a one-step uninstall; with a visual summary infographic
- "Where Does Brave's Leo AI Keep Your Data?" (Oct 2026) — Inside Brave Leo's local store — the single AIChat SQLite database, its schema for conversations/pages/search sources, why its at-rest OSCrypt encryption falls back to a hardcoded key without a keyring, what that structured local data could be used for, and why harvesting it team-wide is not worth it
- "Unix Is Art" (Oct 2026) — A personal essay on the Unix philosophy as an aesthetic — its history from 1974 to 2004 (Thompson and Ritchie, McIlroy, Kernighan and Pike, Raymond), the ideas behind it and the critics of it, a remembrance of Dennis Ritchie, and what Unix made me
- "Keeping secrets out of Git" (Oct 2026) — A short checklist for keeping secrets out of git — why a committed secret is already compromised, the .gitignore patterns to add, where to state the policy (README, AGENTS.md), and three commands to verify nothing is hiding; with a visual summary infographic
👉 See all 51 articles at ai-thoughts/docs
git clone https://github.com/negtivspace/ai-custom-skills
cd ai-custom-skills
# Follow README for your specific platform (Claude Code / Hermes / OpenClaw)# Chrome extensions monorepo (twitter2md, sum2chn, twitter-bookmark-summarizer)
git clone https://github.com/negtivspace/chrome-extensions
cd chrome-extensions/twitter2md
npm install
npm run build # or load the extension manually in Chromegit clone https://github.com/negtivspace/ai-thoughts
cd docs
# 51 articles: AI platforms, privacy, solo entrepreneurship, technical deep-divesMost repos are MIT License — see individual repos for details.
Last Updated: October 26, 2026 | Tracking: 6 active repos, 51 published articles, 20+ published skills
