[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6JYPZASGYJB88GJS7Y526XG":3,"skill-same:01M6JYPZASGYJB88GJS7Y526XG":185},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":24,"publishedAt":46,"linkOnly":47,"markdownContent":48,"markdownBody":49,"frontMatter":50,"refName":53,"commitSha":54,"skillDirectory":55,"forksCount":56,"repositoryHtmlUrl":57,"repositoryHomepageUrl":6,"ownerHtmlUrl":58,"ownerBlogUrl":59,"ownerDescription":60,"updatedAt":61,"install":62,"resources":75},"01M6JYPZASGYJB88GJS7Y526XG","agents-best-practices",null,"Use when designing, auditing, refactoring, or explaining an agentic harness for any domain, especially when work must continue from a measured gap to verified completion. Covers provider-neutral loops, tools, permissions, environment adaptation, planning, durable workflow state, context, skills, observability, evals, and safety for OpenAI, Anthropic, and compatible APIs. Not for implementing an ordinary app feature or reviewing one concrete diff.","AnastasiyaW\u002Fcodex-claude-code-config","AnastasiyaW","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F92753226?v=4","01M6JYPD9X5RRF8G7AH91NYD3R","Anastasiia Butova","01M6JYPDFBGM5EV8G8BABQ3GDY",214,"MIT","https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002FLICENSE-upstream","https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002FSKILL.md",[19],{"categoryNo":20,"categoryName":21,"taxonomyType":22,"taxonomyTypeDesc":23},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],"best practices","agents best practices","work","when","implementing","verified","loops","app","adaptation","domain","evals","context","agentic","refactoring","Safety","Tools","observability","harness","openai","permissions","workflow","2026-11-10 10:12:30",false,"---\nname: portable-tools\ndescription: Build cross-device tools without hardcoding paths or account names\n---\n\n# Portable Tools - Cross-Device Development Methodology\n\nMethodology for building tools that work across different devices, naming schemes, and configurations. Based on lessons from OAuth refresher debugging session (2026-01-23).\n\n## Core Principle\n\n**Never assume your device is the only device.**\n\nYour local setup is just one of many possible configurations. Build for the general case, not the specific instance.\n\n---\n\n## The Three Questions (Before Writing Code)\n\n### 1. \"What varies between devices?\"\n\nBefore writing any code that reads configuration, data, or credentials:\n\n**Ask:**\n- File paths? (macOS vs Linux, different home dirs)\n- Account names? (user123 vs default vs oauth)\n- Service names? (slight variations in spelling\u002Fcapitalization)\n- Data structure? (different versions, different formats)\n- Environment? (different shells, different tools available)\n\n**Example from OAuth refresher:**\n- ❌ Assumed: Account is always \"claude\"\n- ✅ Reality: Could be \"claude\", \"Claude Code\", \"default\", etc.\n\n**Action:** List variables, make them configurable or auto-discoverable\n\n---\n\n### 2. \"How do I prove this works?\"\n\nBefore claiming success:\n\n**Require:**\n- Concrete BEFORE state (exact values)\n- Concrete AFTER state (exact values)\n- Proof they're different (side-by-side comparison)\n\n**Example from OAuth refresher:**\n```\nBEFORE:\n- Access Token: POp5z1fi...eSN9VAAA\n- Expires: 1769189639000\n\nAFTER:\n- Access Token: 01v0RrFG...eOE9QAA ✅ Different\n- Expires: 1769190268000 ✅ Extended\n```\n\n**Action:** Always show data transformation with real values\n\n---\n\n### 3. \"What happens when it breaks?\"\n\nBefore pushing to production:\n\n**Test:**\n- Wrong configuration (intentionally break config)\n- Missing data (remove expected fields)\n- Multiple entries (ambiguous case)\n- Edge cases (empty values, special characters)\n\n**Example from OAuth refresher:**\n- Test with `keychain_account: \"wrong-name\"` → Fallback should work\n- Test with incomplete keychain data → Should fail gracefully with helpful error\n\n**Action:** Test failure modes, not just happy path\n\n---\n\n## Mandatory Patterns\n\n### Pattern 1: Explicit Over Implicit\n\n**❌ Wrong:**\n```bash\n# Ambiguous - returns first match\nsecurity find-generic-password -s \"Service\" -w\n```\n\n**✅ Correct:**\n```bash\n# Explicit - returns specific entry\nsecurity find-generic-password -s \"Service\" -a \"account\" -w\n```\n\n**Rule:** If a command can be ambiguous, make it explicit.\n\n---\n\n### Pattern 2: Validate Before Use\n\n**❌ Wrong:**\n```bash\nDATA=$(read_config)\nUSE_VALUE=\"$DATA\"  # Hope it's valid\n```\n\n**✅ Correct:**\n```bash\nDATA=$(read_config)\nif ! validate_structure \"$DATA\"; then\n    error \"Invalid data structure\"\nfi\nUSE_VALUE=\"$DATA\"\n```\n\n**Rule:** Never assume data has expected structure.\n\n---\n\n### Pattern 3: Fallback Chains\n\n**❌ Wrong:**\n```bash\nACCOUNT=\"claude\"  # Hardcoded\n```\n\n**✅ Correct:**\n```bash\n# Try configured → Try common → Error with help\nACCOUNT=\"${CONFIG_ACCOUNT}\"\nif ! has_data \"$ACCOUNT\"; then\n    for fallback in \"claude\" \"default\" \"oauth\"; do\n        if has_data \"$fallback\"; then\n            ACCOUNT=\"$fallback\"\n            break\n        fi\n    done\nfi\n[[ -z \"$ACCOUNT\" ]] && error \"No account found. Tried: ...\"\n```\n\n**Rule:** Provide automatic fallbacks for common variations.\n\n---\n\n### Pattern 4: Helpful Errors\n\n**❌ Wrong:**\n```bash\n[[ -z \"$TOKEN\" ]] && error \"No token\"\n```\n\n**✅ Correct:**\n```bash\n[[ -z \"$TOKEN\" ]] && error \"No token found\n\nChecked:\n- Config: $CONFIG_FILE\n- Field: $FIELD_NAME\n- Expected: { \\\"tokens\\\": { \\\"refresh\\\": \\\"...\\\" } }\n\nVerify with:\n  cat $CONFIG_FILE | jq '.tokens'\n\"\n```\n\n**Rule:** Error messages should help user diagnose and fix.\n\n---\n\n## Debugging Methodology (Patrick's Approach)\n\n### Step 1: Get Exact Data\n\n**Don't ask:** \"Is it broken?\"  \n**Ask:** \"What exact values do you see? How many entries exist? Which one has the data?\"\n\n**Example:**\n```bash\n# Vague\n\"Check keychain\"\n\n# Specific\n\"Run: security find-generic-password -l 'Service' | grep 'acct'\"\n\"Tell me: 1. How many entries 2. Which has tokens 3. Last modified\"\n```\n\n---\n\n### Step 2: Prove With Concrete Examples\n\n**Don't say:** \"It should work now\"  \n**Show:** \"Here's the BEFORE token (POp5z...), here's AFTER (01v0R...), they're different\"\n\n**Template:**\n```\nBEFORE:\n- Field1: \u003Cexact_value>\n- Field2: \u003Cexact_value>\n\nAFTER:\n- Field1: \u003Cnew_value> ✅ Changed\n- Field2: \u003Cnew_value> ✅ Changed\n\nPROOF: Values are different\n```\n\n---\n\n### Step 3: Think Cross-Device Immediately\n\n**Don't think:** \"Works on my machine\"  \n**Think:** \"What if their setup differs in [X]?\"\n\n**Checklist:**\n- [ ] Different account names?\n- [ ] Different file paths?\n- [ ] Different tools\u002Fversions?\n- [ ] Different permissions?\n- [ ] Different data formats?\n\n---\n\n## Pre-Flight Checklist (Before Publishing)\n\n### Discovery Phase\n- [ ] List all external dependencies (files, commands, services)\n- [ ] Document what each dependency provides\n- [ ] Identify which parts could vary between devices\n\n### Implementation Phase\n- [ ] Make variations configurable (with sensible defaults)\n- [ ] Add validation for each input\n- [ ] Build fallback chains for common variations\n- [ ] Add `--dry-run` or `--test` mode\n\n### Testing Phase\n- [ ] Test with correct config → Should work\n- [ ] Test with wrong config → Should fallback or fail gracefully\n- [ ] Test with missing data → Should give helpful error\n- [ ] Test with multiple entries → Should handle ambiguity\n\n### Documentation Phase\n- [ ] Document default assumptions\n- [ ] Document how to verify local setup\n- [ ] Document common variations and how to handle them\n- [ ] Include data flow diagram\n- [ ] Add troubleshooting section\n\n---\n\n## Real-World Example: OAuth Refresher\n\n### Original (Broken)\n```bash\n# Assumes single entry, no validation, no fallback\nKEYCHAIN_DATA=$(security find-generic-password -s \"Service\" -w)\nREFRESH_TOKEN=$(echo \"$KEYCHAIN_DATA\" | jq -r '.refreshToken')\n# Use token (hope it's valid)\n```\n\n**Problems:**\n- Returns first alphabetical match (wrong entry)\n- No validation (could be empty\u002Fmalformed)\n- No fallback (fails if account name differs)\n\n---\n\n### Fixed (Portable)\n```bash\n# Explicit account with validation and fallback\nvalidate_data() {\n    echo \"$1\" | jq -e '.claudeAiOauth.refreshToken' > \u002Fdev\u002Fnull 2>&1\n}\n\n# Try configured account\nDATA=$(security find-generic-password -s \"$SERVICE\" -a \"$ACCOUNT\" -w 2>&1)\nif validate_data \"$DATA\"; then\n    log \"✓ Using account: $ACCOUNT\"\nelse\n    log \"⚠ Trying fallback accounts...\"\n    for fallback in \"claude\" \"Claude Code\" \"default\"; do\n        DATA=$(security find-generic-password -s \"$SERVICE\" -a \"$fallback\" -w 2>&1)\n        if validate_data \"$DATA\"; then\n            ACCOUNT=\"$fallback\"\n            log \"✓ Found data in: $fallback\"\n            break\n        fi\n    done\nfi\n\n[[ -z \"$DATA\" ]] || ! validate_data \"$DATA\" && error \"No valid data found\nTried accounts: $ACCOUNT, claude, Claude Code, default\nVerify with: security find-generic-password -l '$SERVICE'\"\n\nREFRESH_TOKEN=$(echo \"$DATA\" | jq -r '.claudeAiOauth.refreshToken')\n```\n\n**Improvements:**\n- ✅ Explicit account parameter\n- ✅ Validates data structure\n- ✅ Automatic fallback to common names\n- ✅ Helpful error with verification command\n\n---\n\n## Common Anti-Patterns\n\n### Anti-Pattern 1: \"Works On My Machine\"\n```bash\nFILE=\"\u002FUsers\u002Fpatrick\u002F.config\u002Fapp.json\"  # Hardcoded path\n```\n\n**Fix:** Use `$HOME`, detect OS, or make configurable\n\n---\n\n### Anti-Pattern 2: \"Hope It's There\"\n```bash\nTOKEN=$(cat config.json | jq -r '.token')\n# What if .token doesn't exist? Script continues with empty value\n```\n\n**Fix:** Validate before using\n```bash\nTOKEN=$(cat config.json | jq -r '.token \u002F\u002F empty')\n[[ -z \"$TOKEN\" ]] && error \"No token in config\"\n```\n\n---\n\n### Anti-Pattern 3: \"First Match Is Right\"\n```bash\n# If multiple entries exist, which one?\nENTRY=$(find_entry \"service\")\n```\n\n**Fix:** Be explicit or enumerate all\n```bash\nENTRY=$(find_entry \"service\" \"account\")  # Specific\n# OR\nALL=$(find_all_entries \"service\")\nfor entry in $ALL; do\n    validate_and_use \"$entry\"\ndone\n```\n\n---\n\n### Anti-Pattern 4: \"Silent Failures\"\n```bash\nprocess_data || true  # Ignore errors\n```\n\n**Fix:** Fail loudly with context\n```bash\nprocess_data || error \"Failed to process\nData: $DATA\nExpected: { ... }\nCheck: command_to_verify\"\n```\n\n---\n\n## Integration With Existing Workflows\n\n### With sprint-plan.md\nAdd to testing section:\n```markdown\n## Cross-Device Testing\n- [ ] Test with different account names\n- [ ] Test with wrong config values\n- [ ] Test with missing data\n- [ ] Document fallback behavior\n```\n\n### With PRIVACY-CHECKLIST.md\nAdd before publishing:\n```markdown\n## Portability Check\n- [ ] No hardcoded paths (use $HOME, detect OS)\n- [ ] No hardcoded names (use config or fallback)\n- [ ] Validation on all inputs\n- [ ] Helpful errors for common issues\n```\n\n### With skill-creator\nWhen building new skills:\n1. List what varies between devices\n2. Make it configurable or auto-discoverable\n3. Test with wrong config\n4. Document troubleshooting\n\n---\n\n## Quick Reference Card\n\n**Before writing code:**\n1. What varies between devices?\n2. How do I prove this works?\n3. What happens when it breaks?\n\n**Mandatory patterns:**\n- Explicit over implicit\n- Validate before use\n- Fallback chains\n- Helpful errors\n\n**Testing:**\n- Correct config → Works\n- Wrong config → Fallback or helpful error\n- Missing data → Clear diagnostic\n\n**Documentation:**\n- Data flow diagram\n- Common variations\n- Troubleshooting guide\n\n---\n\n## Success Criteria\n\nA tool is **portable** when:\n\n1. ✅ Works on different devices without modification\n2. ✅ Auto-discovers common variations in setup\n3. ✅ Fails gracefully with actionable error messages\n4. ✅ Can be debugged by reading the error output\n5. ✅ Documentation covers \"what if my setup differs\"\n\n**Test:** Give it to someone with a different setup. If they need to ask you questions, the tool isn't portable yet.\n\n---\n\n## Origin Story\n\nThis methodology emerged from debugging the OAuth refresher (2026-01-23):\n- Script read wrong keychain entry (didn't specify account)\n- Assumed single entry existed (multiple did)\n- No validation (used empty data)\n- No fallback (failed on different account names)\n\nPatrick's approach:\n1. Asked for exact data (how many entries, which has tokens)\n2. Demanded proof (show BEFORE\u002FAFTER tokens)\n3. Thought cross-device (what if naming differs?)\n\nResult: Tool went from single-device\u002Fbroken to universal\u002Fproduction-ready.\n\n**Key insight:** The bugs weren't in the logic - they were in the assumptions.\n\n---\n\n## When To Use This Skill\n\n**Use when:**\n- Building tools that read system configuration\n- Working with keychains, credentials, environment variables\n- Creating scripts that run on multiple machines\n- Publishing skills to ClawdHub (others will use them)\n\n**Apply:**\n1. Before implementing: Answer the three questions\n2. During implementation: Use mandatory patterns\n3. Before testing: Run pre-flight checklist\n4. After testing: Document variations and troubleshooting\n\n**Remember:** Your device is just one case. Build for the general case.\n","# Portable Tools - Cross-Device Development Methodology\n\nMethodology for building tools that work across different devices, naming schemes, and configurations. Based on lessons from OAuth refresher debugging session (2026-01-23).\n\n## Core Principle\n\n**Never assume your device is the only device.**\n\nYour local setup is just one of many possible configurations. Build for the general case, not the specific instance.\n\n---\n\n## The Three Questions (Before Writing Code)\n\n### 1. \"What varies between devices?\"\n\nBefore writing any code that reads configuration, data, or credentials:\n\n**Ask:**\n- File paths? (macOS vs Linux, different home dirs)\n- Account names? (user123 vs default vs oauth)\n- Service names? (slight variations in spelling\u002Fcapitalization)\n- Data structure? (different versions, different formats)\n- Environment? (different shells, different tools available)\n\n**Example from OAuth refresher:**\n- ❌ Assumed: Account is always \"claude\"\n- ✅ Reality: Could be \"claude\", \"Claude Code\", \"default\", etc.\n\n**Action:** List variables, make them configurable or auto-discoverable\n\n---\n\n### 2. \"How do I prove this works?\"\n\nBefore claiming success:\n\n**Require:**\n- Concrete BEFORE state (exact values)\n- Concrete AFTER state (exact values)\n- Proof they're different (side-by-side comparison)\n\n**Example from OAuth refresher:**\n```\nBEFORE:\n- Access Token: POp5z1fi...eSN9VAAA\n- Expires: 1769189639000\n\nAFTER:\n- Access Token: 01v0RrFG...eOE9QAA ✅ Different\n- Expires: 1769190268000 ✅ Extended\n```\n\n**Action:** Always show data transformation with real values\n\n---\n\n### 3. \"What happens when it breaks?\"\n\nBefore pushing to production:\n\n**Test:**\n- Wrong configuration (intentionally break config)\n- Missing data (remove expected fields)\n- Multiple entries (ambiguous case)\n- Edge cases (empty values, special characters)\n\n**Example from OAuth refresher:**\n- Test with `keychain_account: \"wrong-name\"` → Fallback should work\n- Test with incomplete keychain data → Should fail gracefully with helpful error\n\n**Action:** Test failure modes, not just happy path\n\n---\n\n## Mandatory Patterns\n\n### Pattern 1: Explicit Over Implicit\n\n**❌ Wrong:**\n```bash\n# Ambiguous - returns first match\nsecurity find-generic-password -s \"Service\" -w\n```\n\n**✅ Correct:**\n```bash\n# Explicit - returns specific entry\nsecurity find-generic-password -s \"Service\" -a \"account\" -w\n```\n\n**Rule:** If a command can be ambiguous, make it explicit.\n\n---\n\n### Pattern 2: Validate Before Use\n\n**❌ Wrong:**\n```bash\nDATA=$(read_config)\nUSE_VALUE=\"$DATA\"  # Hope it's valid\n```\n\n**✅ Correct:**\n```bash\nDATA=$(read_config)\nif ! validate_structure \"$DATA\"; then\n    error \"Invalid data structure\"\nfi\nUSE_VALUE=\"$DATA\"\n```\n\n**Rule:** Never assume data has expected structure.\n\n---\n\n### Pattern 3: Fallback Chains\n\n**❌ Wrong:**\n```bash\nACCOUNT=\"claude\"  # Hardcoded\n```\n\n**✅ Correct:**\n```bash\n# Try configured → Try common → Error with help\nACCOUNT=\"${CONFIG_ACCOUNT}\"\nif ! has_data \"$ACCOUNT\"; then\n    for fallback in \"claude\" \"default\" \"oauth\"; do\n        if has_data \"$fallback\"; then\n            ACCOUNT=\"$fallback\"\n            break\n        fi\n    done\nfi\n[[ -z \"$ACCOUNT\" ]] && error \"No account found. Tried: ...\"\n```\n\n**Rule:** Provide automatic fallbacks for common variations.\n\n---\n\n### Pattern 4: Helpful Errors\n\n**❌ Wrong:**\n```bash\n[[ -z \"$TOKEN\" ]] && error \"No token\"\n```\n\n**✅ Correct:**\n```bash\n[[ -z \"$TOKEN\" ]] && error \"No token found\n\nChecked:\n- Config: $CONFIG_FILE\n- Field: $FIELD_NAME\n- Expected: { \\\"tokens\\\": { \\\"refresh\\\": \\\"...\\\" } }\n\nVerify with:\n  cat $CONFIG_FILE | jq '.tokens'\n\"\n```\n\n**Rule:** Error messages should help user diagnose and fix.\n\n---\n\n## Debugging Methodology (Patrick's Approach)\n\n### Step 1: Get Exact Data\n\n**Don't ask:** \"Is it broken?\"  \n**Ask:** \"What exact values do you see? How many entries exist? Which one has the data?\"\n\n**Example:**\n```bash\n# Vague\n\"Check keychain\"\n\n# Specific\n\"Run: security find-generic-password -l 'Service' | grep 'acct'\"\n\"Tell me: 1. How many entries 2. Which has tokens 3. Last modified\"\n```\n\n---\n\n### Step 2: Prove With Concrete Examples\n\n**Don't say:** \"It should work now\"  \n**Show:** \"Here's the BEFORE token (POp5z...), here's AFTER (01v0R...), they're different\"\n\n**Template:**\n```\nBEFORE:\n- Field1: \u003Cexact_value>\n- Field2: \u003Cexact_value>\n\nAFTER:\n- Field1: \u003Cnew_value> ✅ Changed\n- Field2: \u003Cnew_value> ✅ Changed\n\nPROOF: Values are different\n```\n\n---\n\n### Step 3: Think Cross-Device Immediately\n\n**Don't think:** \"Works on my machine\"  \n**Think:** \"What if their setup differs in [X]?\"\n\n**Checklist:**\n- [ ] Different account names?\n- [ ] Different file paths?\n- [ ] Different tools\u002Fversions?\n- [ ] Different permissions?\n- [ ] Different data formats?\n\n---\n\n## Pre-Flight Checklist (Before Publishing)\n\n### Discovery Phase\n- [ ] List all external dependencies (files, commands, services)\n- [ ] Document what each dependency provides\n- [ ] Identify which parts could vary between devices\n\n### Implementation Phase\n- [ ] Make variations configurable (with sensible defaults)\n- [ ] Add validation for each input\n- [ ] Build fallback chains for common variations\n- [ ] Add `--dry-run` or `--test` mode\n\n### Testing Phase\n- [ ] Test with correct config → Should work\n- [ ] Test with wrong config → Should fallback or fail gracefully\n- [ ] Test with missing data → Should give helpful error\n- [ ] Test with multiple entries → Should handle ambiguity\n\n### Documentation Phase\n- [ ] Document default assumptions\n- [ ] Document how to verify local setup\n- [ ] Document common variations and how to handle them\n- [ ] Include data flow diagram\n- [ ] Add troubleshooting section\n\n---\n\n## Real-World Example: OAuth Refresher\n\n### Original (Broken)\n```bash\n# Assumes single entry, no validation, no fallback\nKEYCHAIN_DATA=$(security find-generic-password -s \"Service\" -w)\nREFRESH_TOKEN=$(echo \"$KEYCHAIN_DATA\" | jq -r '.refreshToken')\n# Use token (hope it's valid)\n```\n\n**Problems:**\n- Returns first alphabetical match (wrong entry)\n- No validation (could be empty\u002Fmalformed)\n- No fallback (fails if account name differs)\n\n---\n\n### Fixed (Portable)\n```bash\n# Explicit account with validation and fallback\nvalidate_data() {\n    echo \"$1\" | jq -e '.claudeAiOauth.refreshToken' > \u002Fdev\u002Fnull 2>&1\n}\n\n# Try configured account\nDATA=$(security find-generic-password -s \"$SERVICE\" -a \"$ACCOUNT\" -w 2>&1)\nif validate_data \"$DATA\"; then\n    log \"✓ Using account: $ACCOUNT\"\nelse\n    log \"⚠ Trying fallback accounts...\"\n    for fallback in \"claude\" \"Claude Code\" \"default\"; do\n        DATA=$(security find-generic-password -s \"$SERVICE\" -a \"$fallback\" -w 2>&1)\n        if validate_data \"$DATA\"; then\n            ACCOUNT=\"$fallback\"\n            log \"✓ Found data in: $fallback\"\n            break\n        fi\n    done\nfi\n\n[[ -z \"$DATA\" ]] || ! validate_data \"$DATA\" && error \"No valid data found\nTried accounts: $ACCOUNT, claude, Claude Code, default\nVerify with: security find-generic-password -l '$SERVICE'\"\n\nREFRESH_TOKEN=$(echo \"$DATA\" | jq -r '.claudeAiOauth.refreshToken')\n```\n\n**Improvements:**\n- ✅ Explicit account parameter\n- ✅ Validates data structure\n- ✅ Automatic fallback to common names\n- ✅ Helpful error with verification command\n\n---\n\n## Common Anti-Patterns\n\n### Anti-Pattern 1: \"Works On My Machine\"\n```bash\nFILE=\"\u002FUsers\u002Fpatrick\u002F.config\u002Fapp.json\"  # Hardcoded path\n```\n\n**Fix:** Use `$HOME`, detect OS, or make configurable\n\n---\n\n### Anti-Pattern 2: \"Hope It's There\"\n```bash\nTOKEN=$(cat config.json | jq -r '.token')\n# What if .token doesn't exist? Script continues with empty value\n```\n\n**Fix:** Validate before using\n```bash\nTOKEN=$(cat config.json | jq -r '.token \u002F\u002F empty')\n[[ -z \"$TOKEN\" ]] && error \"No token in config\"\n```\n\n---\n\n### Anti-Pattern 3: \"First Match Is Right\"\n```bash\n# If multiple entries exist, which one?\nENTRY=$(find_entry \"service\")\n```\n\n**Fix:** Be explicit or enumerate all\n```bash\nENTRY=$(find_entry \"service\" \"account\")  # Specific\n# OR\nALL=$(find_all_entries \"service\")\nfor entry in $ALL; do\n    validate_and_use \"$entry\"\ndone\n```\n\n---\n\n### Anti-Pattern 4: \"Silent Failures\"\n```bash\nprocess_data || true  # Ignore errors\n```\n\n**Fix:** Fail loudly with context\n```bash\nprocess_data || error \"Failed to process\nData: $DATA\nExpected: { ... }\nCheck: command_to_verify\"\n```\n\n---\n\n## Integration With Existing Workflows\n\n### With sprint-plan.md\nAdd to testing section:\n```markdown\n## Cross-Device Testing\n- [ ] Test with different account names\n- [ ] Test with wrong config values\n- [ ] Test with missing data\n- [ ] Document fallback behavior\n```\n\n### With PRIVACY-CHECKLIST.md\nAdd before publishing:\n```markdown\n## Portability Check\n- [ ] No hardcoded paths (use $HOME, detect OS)\n- [ ] No hardcoded names (use config or fallback)\n- [ ] Validation on all inputs\n- [ ] Helpful errors for common issues\n```\n\n### With skill-creator\nWhen building new skills:\n1. List what varies between devices\n2. Make it configurable or auto-discoverable\n3. Test with wrong config\n4. Document troubleshooting\n\n---\n\n## Quick Reference Card\n\n**Before writing code:**\n1. What varies between devices?\n2. How do I prove this works?\n3. What happens when it breaks?\n\n**Mandatory patterns:**\n- Explicit over implicit\n- Validate before use\n- Fallback chains\n- Helpful errors\n\n**Testing:**\n- Correct config → Works\n- Wrong config → Fallback or helpful error\n- Missing data → Clear diagnostic\n\n**Documentation:**\n- Data flow diagram\n- Common variations\n- Troubleshooting guide\n\n---\n\n## Success Criteria\n\nA tool is **portable** when:\n\n1. ✅ Works on different devices without modification\n2. ✅ Auto-discovers common variations in setup\n3. ✅ Fails gracefully with actionable error messages\n4. ✅ Can be debugged by reading the error output\n5. ✅ Documentation covers \"what if my setup differs\"\n\n**Test:** Give it to someone with a different setup. If they need to ask you questions, the tool isn't portable yet.\n\n---\n\n## Origin Story\n\nThis methodology emerged from debugging the OAuth refresher (2026-01-23):\n- Script read wrong keychain entry (didn't specify account)\n- Assumed single entry existed (multiple did)\n- No validation (used empty data)\n- No fallback (failed on different account names)\n\nPatrick's approach:\n1. Asked for exact data (how many entries, which has tokens)\n2. Demanded proof (show BEFORE\u002FAFTER tokens)\n3. Thought cross-device (what if naming differs?)\n\nResult: Tool went from single-device\u002Fbroken to universal\u002Fproduction-ready.\n\n**Key insight:** The bugs weren't in the logic - they were in the assumptions.\n\n---\n\n## When To Use This Skill\n\n**Use when:**\n- Building tools that read system configuration\n- Working with keychains, credentials, environment variables\n- Creating scripts that run on multiple machines\n- Publishing skills to ClawdHub (others will use them)\n\n**Apply:**\n1. Before implementing: Answer the three questions\n2. During implementation: Use mandatory patterns\n3. Before testing: Run pre-flight checklist\n4. After testing: Document variations and troubleshooting\n\n**Remember:** Your device is just one case. Build for the general case.\n",{"name":51,"description":52},"portable-tools","Build cross-device tools without hardcoding paths or account names","main","b80cde2ef85241dd4fd54a1b934f5e22835f78ba","skills\u002Fagents-best-practices",32,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config","https:\u002F\u002Fgithub.com\u002FAnastasiyaW","https:\u002F\u002Fhappyin.work","ComfyUI specialist · turnkey image-processing pipelines · diffusion models, computer vision · Belgrade","2026-11-08 21:56:55",{"source":8,"skillName":51,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add AnastasiyaW\u002Fcodex-claude-code-config --skill portable-tools",{"tool":68,"command":69},"bunx","bunx skills add AnastasiyaW\u002Fcodex-claude-code-config --skill portable-tools",{"tool":71,"command":72},"pnpm","pnpm dlx skills add AnastasiyaW\u002Fcodex-claude-code-config --skill portable-tools","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002FSKILL.md",true,[76,82,87,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181],{"path":77,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":80,"sourceHtmlUrl":81},"ATTRIBUTION.md","REFERENCE","参考文档",844,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002FATTRIBUTION.md",{"path":83,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":86,"sourceHtmlUrl":16},"LICENSE-upstream","LICENSE","许可证",1071,{"path":88,"resourceType":89,"resourceTypeDesc":90,"sizeBytes":91,"sourceHtmlUrl":92},"pre-publish-checklist.sh","SCRIPT","脚本",4657,"https:\u002F\u002Fgithub.com\u002Fsundial-org\u002Fawesome-openclaw-skills\u002Fblob\u002Fmain\u002Fskills\u002Fportable-tools\u002Fpre-publish-checklist.sh",{"path":94,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":95,"sourceHtmlUrl":96},"README.md",4255,"https:\u002F\u002Fgithub.com\u002Fsundial-org\u002Fawesome-openclaw-skills\u002Fblob\u002Fmain\u002Fskills\u002Fportable-tools\u002FREADME.md",{"path":98,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":99,"sourceHtmlUrl":100},"references\u002Fagent-legibility-feedback-loops.md",7773,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fagent-legibility-feedback-loops.md",{"path":102,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":103,"sourceHtmlUrl":104},"references\u002Fagentic-loop.md",6875,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fagentic-loop.md",{"path":106,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":107,"sourceHtmlUrl":108},"references\u002Farchitecture.md",9272,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Farchitecture.md",{"path":110,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":111,"sourceHtmlUrl":112},"references\u002Fchecklists.md",15819,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fchecklists.md",{"path":114,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":115,"sourceHtmlUrl":116},"references\u002Fcoding-agents.md",17505,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fcoding-agents.md",{"path":118,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":119,"sourceHtmlUrl":120},"references\u002Fcompletion-reconciliation.md",7004,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fcompletion-reconciliation.md",{"path":122,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":123,"sourceHtmlUrl":124},"references\u002Fcontext-memory-compaction.md",8027,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fcontext-memory-compaction.md",{"path":126,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":127,"sourceHtmlUrl":128},"references\u002Fcoverage-audit.md",8367,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fcoverage-audit.md",{"path":130,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":131,"sourceHtmlUrl":132},"references\u002Fenvironment-adaptive-tools.md",22372,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fenvironment-adaptive-tools.md",{"path":134,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":135,"sourceHtmlUrl":136},"references\u002Fevals.md",14161,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fevals.md",{"path":138,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":139,"sourceHtmlUrl":140},"references\u002Fmvp-agent-blueprint.md",16502,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fmvp-agent-blueprint.md",{"path":142,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":143,"sourceHtmlUrl":144},"references\u002Fplanning-and-goals.md",7362,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fplanning-and-goals.md",{"path":146,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":147,"sourceHtmlUrl":148},"references\u002Fprompt-caching-and-cost.md",7586,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fprompt-caching-and-cost.md",{"path":150,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":151,"sourceHtmlUrl":152},"references\u002Fprovider-api-patterns.md",7435,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fprovider-api-patterns.md",{"path":154,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":155,"sourceHtmlUrl":156},"references\u002Fsecurity-observability.md",6706,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fsecurity-observability.md",{"path":158,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":159,"sourceHtmlUrl":160},"references\u002Fself-refining-recursive-harnesses.md",26134,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fself-refining-recursive-harnesses.md",{"path":162,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":163,"sourceHtmlUrl":164},"references\u002Fskills-and-connectors.md",8849,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fskills-and-connectors.md",{"path":166,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":167,"sourceHtmlUrl":168},"references\u002Fsource-links.md",7681,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fsource-links.md",{"path":170,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":171,"sourceHtmlUrl":172},"references\u002Fspeculative-tool-execution.md",18409,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fspeculative-tool-execution.md",{"path":174,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":175,"sourceHtmlUrl":176},"references\u002Fsystem-prompts-instructions.md",4430,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fsystem-prompts-instructions.md",{"path":178,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":179,"sourceHtmlUrl":180},"references\u002Ftools-and-permissions.md",8360,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Ftools-and-permissions.md",{"path":182,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":183,"sourceHtmlUrl":184},"references\u002Fworkflow-orchestration.md",13486,"https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fagents-best-practices\u002Freferences\u002Fworkflow-orchestration.md",[186,195,211,237,265,283],{"skillNo":187,"name":188,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":189,"categories":190,"keywords":192,"publishedAt":46},"01M6JZ2SNGKFN8NK3HZBMVGQP1","owner-voice","https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fwriting\u002Fowner-voice\u002FSKILL.md",[191],{"categoryNo":20,"categoryName":21,"taxonomyType":22,"taxonomyTypeDesc":23},[193,194],"owner voice","voice",{"skillNo":196,"name":197,"nameZh":6,"description":198,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":199,"categories":200,"keywords":202,"publishedAt":46},"01M6JZ2N0C2WFCAK6T8N3RMBVS","humanize-russian","Редактировать русский текст для ясности и естественного звучания, сохраняя факты,\nтермины, источники и жанр. Использовать когда: убрать канцелярит, сделать текст\nживее, отредактировать русский черновик или статью перед публикацией.\nНе определяет авторство и не обещает обход детекторов. Для английского —\nhumanize-english; для структуры и доказательств — article-structure-review.","https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fwriting\u002Fhumanize-russian\u002FSKILL.md",[201],{"categoryNo":20,"categoryName":21,"taxonomyType":22,"taxonomyTypeDesc":23},[203,204,205,206,207,208,209,210],"russian","humanize","humanize russian","english","review","structure","article","2026",{"skillNo":212,"name":213,"nameZh":6,"description":214,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":215,"categories":216,"keywords":217,"publishedAt":46},"01M6JZ2GN264R6GKBQ5QVZE0ZS","humanize-english","Edit English drafts for clear, natural language while preserving facts, uncertainty,\ntechnical meaning, citations and genre. Use when: humanize this text, remove AI-style\nfiller, improve English prose, or edit an English article before publication.\nNot an authorship detector or a promise to bypass one. For Russian use\nhumanize-russian; for thesis\u002Fevidence and structure use article-structure-review.","https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fwriting\u002Fhumanize-english\u002FSKILL.md",[],[204,206,218,219,203,220,221,222,223,208,224,225,226,207,227,210,28,228,229,230,231,232,233,234,209,235,236],"humanize english","technical","evidence","use","remove","edit","text","improve","Citations","Publication","for","facts","natural language","drafts","meaning","uncertainty","style","thesis","promise",{"skillNo":238,"name":239,"nameZh":6,"description":240,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":241,"categories":242,"keywords":243,"publishedAt":46},"01M6JZ2BM31D5Y609DQJJJM6MM","caveman","Ultra-compressed reply mode. Cuts output tokens ~65-75% by answering in terse \"caveman\" style while keeping full technical accuracy, and shapes what survives: action first, state restated every turn, concrete time estimates, visible wins. Intensity levels: lite, full (default), ultra, wenyan-lite, wenyan-full, wenyan-ultra. Use when user says \"caveman\", \"talk like caveman\", \"use caveman\", \"less tokens\", \"be brief\", or Russian \"пещерный режим\", \"говори как пещерный\", \"кратко\", \"меньше токенов\", \"экономь токены\" — or invokes \u002Fcaveman. Preserves the user's language (Russian in → Russian caveman out). Off only: \"stop caveman\" \u002F \"normal mode\" \u002F \"обычный режим\". Do not use merely because a response should be concise, and do not use when the user requests normal prose, a polished document, or exact wording.","https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fwriting\u002Fcaveman\u002FSKILL.md",[],[239,234,28,244,245,246,247,248,249,250,251,252,253,254,255,256,257,203,258,259,260,261,221,219,262,263,264],"normal","terse","accuracy","ultra","mode","document","requests","concise","output","intensity","tokens","full","time","do","action","default","stop","only","first","brief","state",{"skillNo":266,"name":267,"nameZh":6,"description":268,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":269,"categories":270,"keywords":280,"publishedAt":46},"01M6JZ25Y5GJXFKXNR6TRQX237","article-structure-review","Проверить структуру технической статьи после черновика: задача читателя, жанр,\nопора значимых утверждений на доказательства и честные ограничения.\nUse after the first draft, before publication. Исправлять структуру, когда это\nвходит в запрос; не создавать обязательный конвейер из других навыков.\nДля локальной языковой редактуры — humanize-english или humanize-russian.","https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fwriting\u002Farticle-structure-review\u002FSKILL.md",[271,274,275],{"categoryNo":272,"categoryName":273,"taxonomyType":22,"taxonomyTypeDesc":23},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":20,"categoryName":21,"taxonomyType":22,"taxonomyTypeDesc":23},{"categoryNo":276,"categoryName":277,"taxonomyType":278,"taxonomyTypeDesc":279},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[281,209,208,207,282,204,203,221,262,206,227,210],"article structure review","draft",{"skillNo":284,"name":285,"nameZh":6,"description":286,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":287,"categories":288,"keywords":292,"publishedAt":46},"01M6JZ1XN7WQQCWCHHMTTD8K28","video-post-production","Video post-production rules: audio mastering, color, captions, platform export. Use when: 'add music', 'add voiceover', 'export for tiktok', 'add captions', 'color grade', 'audio levels', 'master audio', 'export settings', 'platform requirements'. Covers FFmpeg patterns, audio chain, subtitle standards, and platform-specific export configs. Do NOT use to generate or animate the video frames\u002Fscenes in code (use remotion-production-guide), to write the script (use video-narrative-arc), or to evaluate script quality (use script-evaluator); this is the finishing stage applied to an already-rendered video.","https:\u002F\u002Fgithub.com\u002FAnastasiyaW\u002Fcodex-claude-code-config\u002Fblob\u002Fmain\u002Fskills\u002Fvideo-production\u002Fvideo-post-production\u002FSKILL.md",[289],{"categoryNo":290,"categoryName":291,"taxonomyType":22,"taxonomyTypeDesc":23},"01JBSEEDCAT000000000000016","图像与多媒体",[293,294,295,296,297,28,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312],"video post production","post","Production","Video","patterns","post-production","narrative","add","chain","tiktok","voiceover","master","export","write","music","Captions","Audio","Remotion","code","generate"]