{"id":"29d7c25d-677e-495a-a8a1-da8f7a202f8d","shortId":"3nuP5S","kind":"skill","title":"sn-update","tagline":"Update SenseNova Skills (the sn-* bundle) inside an OpenClaw or hermes-agent\ninstall. ALWAYS use this skill when the user says any of: \"update SenseNova\nskills\", \"update SN skills\", \"更新 sensenova skills\", \"更新 sn skills\",\n\"刷新 sn-*\", \"升级 sn-* skills\", or names a specific sn-* skill","description":"# sn-update\n\nRefresh installed `sn-*` skills from upstream\n[SenseNova-Skills](https://github.com/OpenSenseNova/SenseNova-Skills).\n\n---\n\n## Decide the scope\n\n- No list given → every `sn-*` skill upstream.\n- Specific skills named → only those. Don't expand.\n- A named skill missing upstream → surface as error and stop.\n- User said \"force / 强制\" → re-install even when up-to-date.\n\n---\n\n## Decide the target agent\n\nCheck which directories exist:\n\n| `~/.openclaw/skills/` | `~/.hermes/skills/` | Target |\n|---|---|---|\n| exists | absent | openclaw |\n| absent | exists | hermes |\n| exists | exists | **ask the user** — never silently dual-write |\n| absent | absent | no install found, stop |\n\n---\n\n## Sync the upstream repo\n\nPersistent cache at `~/.cache/sn-update/repo/`. Default URL:\n`https://github.com/OpenSenseNova/SenseNova-Skills.git`. User may override\nwith a fork URL.\n\n- **First run**: if you want to actually limit blob download, use partial\n  clone with `--filter=blob:none --no-checkout`, then sparse-checkout only\n  the selected `skills/<name>` paths before copying them. `--filter=blob:none`\n  alone does **not** keep the cache small if the full worktree is checked out;\n  that checkout will still download most or all needed blobs. It still\n  preserves history metadata for SHA queries.\n- **Subsequent runs**: fetch + hard-reset to the upstream default branch, and\n  re-apply sparse-checkout for only the requested `skills/<name>` paths before\n  copying. If updating the whole `sn-*` bundle, expect most/all skill blobs to\n  be downloaded.\n- **URL changed**: if cache's `origin` differs from the requested URL,\n  delete and re-clone.\n\n---\n\n## Compare versions per skill (A → B → C)\n\nFor each skill, pick the highest-precedence signal present on **both**\nsides (installed + upstream); equal → skip, differ → install.\n\nUpstream \"version\" is the per-subtree commit SHA — using repo HEAD would\nmark unrelated skills as stale every time:\n\n```text\ngit -C <cache> log -1 --format=%H -- skills/<skill-name>\n```\n\n- **A — `.sn-version` marker**: one-line file inside the installed skill\n  holding the SHA from its last install.\n- **B — `.sn-release` marker** (fallback): one-line file holding the\n  upstream tag name. Compare against `git describe --tags --abbrev=0`.\n- **C — optional `version:` field in SKILL.md frontmatter**: parse from\n  YAML on both sides, but only for forks or skills that explicitly add this\n  field. If either side lacks it, C does not apply.\n- **Nothing usable** → treat as stale and install.\n\nAlways write `.sn-version` on install so future runs can use A.\n\n---\n\n## Install with backup\n\nFor each skill flagged \"install\":\n\n1. **Move** (not copy) any existing `<agent-skills>/<skill-name>/` into a\n   single timestamped backup bucket shared by all skills in this run:\n   `~/.<agent>/skills_backup/<UTC-timestamp>/<skill-name>/`\n   (e.g. `2026-04-30T15-29-07Z`).\n2. **Copy** `<cache>/skills/<skill-name>/` → `<agent-skills>/<skill-name>/`.\n   **Never symlink** (`ln -s`) from the cache. The cache lives under\n   `~/.cache/` with permissions the agent runtime may not be able to\n   traverse, and some runtimes refuse to load skills resolved through\n   symlinks. Always do a real recursive copy so the installed tree is\n   self-contained and owned by the agent skills dir.\n3. **Write `.sn-version`** with the upstream subtree SHA inside the new copy.\n\nIf the bucket ends up empty (all targets were fresh installs), remove it.\n\nThe backup tree is a **sibling** of `skills/`, never a `.bak` folder\ninside it — most agent runtimes scan the whole `skills/` directory and\nwould pick up stale duplicates.\n\n---\n\n## Enforce backup retention\n\nAfter every run, prune the per-agent backup root to **at most 3** buckets.\nTimestamps sort lexicographically; keep the newest 3, delete the rest.\nRun this even when the current run produced no backup of its own.\n\n---\n\n## Report to the user\n\nGroup by status, keep it short:\n\n```text\nUpdated (3): sn-ppt-standard, sn-image-base, sn-deep-research\nAlready up-to-date (5): sn-ppt-creative, sn-ppt-doctor, ...\nBackup: ~/.openclaw/skills_backup/2026-04-30T15-29-07Z/\n```\n\n- Omit `Backup:` when nothing was backed up.\n- Show SHA pairs (`abc1234 → def5678`) only if the user asks for detail.\n- Errors get their own line — never bury them in a success summary.\n\n---\n\n## Edge cases\n\n- **Asks to delete sn-* skills** — not this skill's job. Decline; point at\n  `~/.<agent>/skills_backup/` if they want to roll back.\n- **User is in the dev repo** and asks to \"update sn skills\" — they mean\n  push to their agent install. Proceed normally; this skill only touches\n  the cache and the agent install dirs, never the dev checkout.\n- **`sn-update` updating itself** — fine; the new copy takes effect on\n  the next invocation.","tags":["update","sensenova","skills","opensensenova","agent","agent-skills","ai-agents","ai-assistant","data-analysis","document-processing","office-automation","presentation-slides"],"capabilities":["skill","source-opensensenova","skill-sn-update","topic-agent","topic-agent-skills","topic-ai-agents","topic-ai-assistant","topic-data-analysis","topic-document-processing","topic-office-automation","topic-presentation-slides"],"categories":["SenseNova-Skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/OpenSenseNova/SenseNova-Skills/sn-update","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add OpenSenseNova/SenseNova-Skills","source_repo":"https://github.com/OpenSenseNova/SenseNova-Skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 1627 github stars · SKILL.md body (4,764 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:53:06.439Z","embedding":null,"createdAt":"2026-05-15T06:53:11.502Z","updatedAt":"2026-05-18T18:53:06.439Z","lastSeenAt":"2026-05-18T18:53:06.439Z","tsv":"'-04':461 '-07':465 '-1':332 '-29':464 '-30':462 '/.cache':481 '/.cache/sn-update/repo':147 '/.hermes/skills':116 '/.openclaw/skills':115 '/.openclaw/skills_backup/2026-04-30t15-29-07z':660 '/opensensenova/sensenova-skills).':65 '/opensensenova/sensenova-skills.git':152 '/skills':469 '/skills_backup':458,707 '0':377 '1':439 '2':467 '2026':460 '3':524,595,603,632 '5':650 'abbrev':376 'abc1234':671 'abl':490 'absent':119,121,134,135 'actual':166 'add':399 'agent':16,110,485,521,566,589,731,743 'alon':195 'alreadi':645 'alway':18,418,503 'appli':241,410 'ask':126,677,694,721 'b':287,356 'back':666,713 'backup':433,449,552,580,590,616,659,662 'bak':561 'base':640 'blob':168,175,193,218,262 'branch':237 'bucket':450,540,596 'bundl':9,258 'buri':686 'c':288,330,378,407 'cach':145,200,269,476,478,740 'case':693 'chang':267 'check':111,207 'checkout':179,183,210,244,749 'clone':172,281 'commit':315 'compar':282,371 'contain':516 'copi':190,252,442,468,508,537,758 'creativ':654 'current':612 'date':106,649 'decid':66,107 'declin':704 'deep':643 'def5678':672 'default':148,236 'delet':277,604,696 'describ':374 'detail':679 'dev':718,748 'differ':272,306 'dir':523,745 'directori':113,572 'doctor':658 'download':169,213,265 'dual':132 'dual-writ':131 'duplic':578 'e.g':459 'edg':692 'effect':760 'either':403 'empti':543 'end':541 'enforc':579 'equal':304 'error':91,680 'even':101,609 'everi':72,326,583 'exist':114,118,122,124,125,444 'expand':83 'expect':259 'explicit':398 'fallback':361 'fetch':229 'field':381,401 'file':344,365 'filter':174,192 'fine':755 'first':160 'flag':437 'folder':562 'forc':96 'fork':158,394 'format':333 'found':138 'fresh':547 'frontmatt':384 'full':204 'futur':426 'get':681 'git':329,373 'github.com':64,151 'github.com/opensensenova/sensenova-skills).':63 'github.com/opensensenova/sensenova-skills.git':150 'given':71 'group':624 'h':334 'hard':231 'hard-reset':230 'head':319 'herm':15,123 'hermes-ag':14 'highest':295 'highest-preced':294 'histori':222 'hold':349,366 'imag':639 'insid':10,345,534,563 'instal':17,55,100,137,302,307,347,355,417,424,431,438,511,548,732,744 'invoc':764 'job':703 'keep':198,600,627 'lack':405 'last':354 'lexicograph':599 'limit':167 'line':343,364,684 'list':70 'live':479 'ln':472 'load':498 'log':331 'mark':321 'marker':340,360 'may':154,487 'mean':727 'metadata':223 'miss':87 'most/all':260 'move':440 'name':46,78,85,370 'need':217 'never':129,470,559,685,746 'new':536,757 'newest':602 'next':763 'no-checkout':177 'none':176,194 'normal':734 'noth':411,664 'omit':661 'one':342,363 'one-lin':341,362 'openclaw':12,120 'option':379 'origin':271 'overrid':155 'own':518 'pair':670 'pars':385 'partial':171 'path':188,250 'per':284,313,588 'per-ag':587 'per-subtre':312 'permiss':483 'persist':144 'pick':292,575 'point':705 'ppt':635,653,657 'preced':296 'present':298 'preserv':221 'proceed':733 'produc':614 'prune':585 'push':728 'queri':226 're':99,240,280 're-appli':239 're-clon':279 're-instal':98 'real':506 'recurs':507 'refresh':54 'refus':496 'releas':359 'remov':549 'repo':143,318,719 'report':620 'request':248,275 'research':644 'reset':232 'resolv':500 'rest':606 'retent':581 'roll':712 'root':591 'run':161,228,427,457,584,607,613 'runtim':486,495,567 'said':95 'say':25 'scan':568 'scope':68 'select':186 'self':515 'self-contain':514 'sensenova':5,29,35,61 'sensenova-skil':60 'sha':225,316,351,533,669 'share':451 'short':629 'show':668 'sibl':556 'side':301,390,404 'signal':297 'silent':130 'singl':447 'skill':6,21,30,33,36,39,44,50,57,62,74,77,86,187,249,261,285,291,323,335,348,396,436,454,499,522,558,571,698,701,725,736 'skill-sn-update' 'skill.md':383 'skip':305 'small':201 'sn':2,8,32,38,41,43,49,52,56,73,257,338,358,421,527,634,638,642,652,656,697,724,751 'sn-deep-research':641 'sn-image-bas':637 'sn-ppt-creativ':651 'sn-ppt-doctor':655 'sn-ppt-standard':633 'sn-releas':357 'sn-updat':1,51,750 'sn-version':337,420,526 'sort':598 'source-opensensenova' 'spars':182,243 'sparse-checkout':181,242 'specif':48,76 'stale':325,415,577 'standard':636 'status':626 'still':212,220 'stop':93,139 'subsequ':227 'subtre':314,532 'success':690 'summari':691 'surfac':89 'symlink':471,502 'sync':140 't15':463 'tag':369,375 'take':759 'target':109,117,545 'text':328,630 'time':327 'timestamp':448,597 'topic-agent' 'topic-agent-skills' 'topic-ai-agents' 'topic-ai-assistant' 'topic-data-analysis' 'topic-document-processing' 'topic-office-automation' 'topic-presentation-slides' 'touch':738 'travers':492 'treat':413 'tree':512,553 'unrel':322 'up-to-d':103,646 'updat':3,4,28,31,53,254,631,723,752,753 'upstream':59,75,88,142,235,303,308,368,531 'url':149,159,266,276 'usabl':412 'use':19,170,317,429 'user':24,94,128,153,623,676,714 'version':283,309,339,380,422,528 'want':164,710 'whole':256,570 'worktre':205 'would':320,574 'write':133,419,525 'yaml':387 'z':466 '刷新':40 '升级':42 '强制':97 '更新':34,37","prices":[{"id":"0419568b-6c75-48a9-86a8-ed67d2bedbae","listingId":"29d7c25d-677e-495a-a8a1-da8f7a202f8d","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"OpenSenseNova","category":"SenseNova-Skills","install_from":"skills.sh"},"createdAt":"2026-05-15T06:53:11.502Z"}],"sources":[{"listingId":"29d7c25d-677e-495a-a8a1-da8f7a202f8d","source":"github","sourceId":"OpenSenseNova/SenseNova-Skills/sn-update","sourceUrl":"https://github.com/OpenSenseNova/SenseNova-Skills/tree/main/skills/sn-update","isPrimary":false,"firstSeenAt":"2026-05-15T06:53:11.502Z","lastSeenAt":"2026-05-18T18:53:06.439Z"}],"details":{"listingId":"29d7c25d-677e-495a-a8a1-da8f7a202f8d","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"OpenSenseNova","slug":"sn-update","github":{"repo":"OpenSenseNova/SenseNova-Skills","stars":1627,"topics":["agent","agent-skills","ai-agents","ai-assistant","data-analysis","document-processing","office-automation","presentation-slides"],"license":"mit","html_url":"https://github.com/OpenSenseNova/SenseNova-Skills","pushed_at":"2026-05-15T04:43:37Z","description":"Modular SenseNova skills for building AI-powered office assistants and productivity workflows","skill_md_sha":"ccbbae1a9c8ef6df00cab8a2880cf628773be2cd","skill_md_path":"skills/sn-update/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/OpenSenseNova/SenseNova-Skills/tree/main/skills/sn-update"},"layout":"multi","source":"github","category":"SenseNova-Skills","frontmatter":{"name":"sn-update","description":"Update SenseNova Skills (the sn-* bundle) inside an OpenClaw or hermes-agent\ninstall. ALWAYS use this skill when the user says any of: \"update SenseNova\nskills\", \"update SN skills\", \"更新 sensenova skills\", \"更新 sn skills\",\n\"刷新 sn-*\", \"升级 sn-* skills\", or names a specific sn-* skill to update\n(e.g. \"更新 sn-ppt-standard\", \"refresh sn-image-base\"). Default scope is the\nwhole sn-* bundle; if the user names specific skills, update ONLY those."},"skills_sh_url":"https://skills.sh/OpenSenseNova/SenseNova-Skills/sn-update"},"updatedAt":"2026-05-18T18:53:06.439Z"}}