{"_id":"@caesarloo/dsh-config-git-backup","_rev":"8-03289c34ec844667c7155cecf1ca12be","name":"@caesarloo/dsh-config-git-backup","dist-tags":{"latest":"0.2.6"},"versions":{"0.1.0":{"name":"@caesarloo/dsh-config-git-backup","version":"0.1.0","keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"license":"MIT","_id":"@caesarloo/dsh-config-git-backup@0.1.0","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"15ea656da29fd72e512845431fd7f32b614d6a2e","tarball":"https://registry.npmjs.org/@caesarloo/dsh-config-git-backup/-/dsh-config-git-backup-0.1.0.tgz","fileCount":5,"integrity":"sha512-iYOzqecfDATGtwQElLlsvPdg+5l1CTuedWZneEF6TzOY7ftqzgVUPyQRahvjC89CpebQZF/VfqGPUy558PH4kg==","signatures":[{"sig":"MEUCIEdZpF+kOeAaFHDQDjtsfkRlJRWpZOZZXmbVeqBzP0IOAiEArynlT3MvOCK65br7ERYZAtp/O448B4ly1u8SwxySMqE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15305},"main":"./dist/index.js","type":"module","exports":{".":"./dist/index.js"},"gitHead":"554257600a5ea12aef33daacbf82e8add0a4f2a5","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"_npmVersion":"11.16.0","description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@deepseek-ai/dsh-tools":"0.1.0-rc.6","@deepseek-ai/dsh-subprocess":"0.1.0-rc.6"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.10.0","@deepseek-ai/cordis":"^4.0.1"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1"},"_npmOperationalInternal":{"tmp":"tmp/dsh-config-git-backup_0.1.0_1788707290490_0.22710346812623872","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@caesarloo/dsh-config-git-backup","version":"0.2.0","keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"license":"MIT","_id":"@caesarloo/dsh-config-git-backup@0.2.0","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"0f846f06e1e2e4b22650ebce949f4edee3444765","tarball":"https://registry.npmjs.org/@caesarloo/dsh-config-git-backup/-/dsh-config-git-backup-0.2.0.tgz","fileCount":5,"integrity":"sha512-EYHiolpePHP9Pkqegqg2xq3He8ajlqfX2AvUyMIm3veV9bDWFjNMA/llpcHxW+FrL3EoAx8TeTRhG1ckewulyg==","signatures":[{"sig":"MEUCIQCoVvWVJOhU9Eq7eJASJjR3EZkmFq7AYz93JYaqCBojWAIgJgPbAh+DxvxDs/RQ3swksCB++Lez/ab4AWcQ11iCiTA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24286},"main":"./dist/index.js","type":"module","exports":{".":"./dist/index.js"},"gitHead":"923310cfad22c694a962a853b2763dbaca531b6e","scripts":{"test":"node test/smoke.mjs","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"_npmVersion":"11.16.0","description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@deepseek-ai/dsh-tools":"0.1.0-rc.6","@deepseek-ai/dsh-subprocess":"0.1.0-rc.6"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.10.0","@deepseek-ai/cordis":"^4.0.1"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1"},"_npmOperationalInternal":{"tmp":"tmp/dsh-config-git-backup_0.2.0_1789262543269_0.03302688938524234","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@caesarloo/dsh-config-git-backup","version":"0.2.1","keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"license":"MIT","_id":"@caesarloo/dsh-config-git-backup@0.2.1","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"8d0c0a7fa8e9fcff620911fb92a1ab421caca348","tarball":"https://registry.npmjs.org/@caesarloo/dsh-config-git-backup/-/dsh-config-git-backup-0.2.1.tgz","fileCount":5,"integrity":"sha512-+H36s6r2eGHgnN94HNFOf+esiPs9noLb6qKBLySOvbNlY0b4IZwvVNY5r6tWR+vIPCaPPtAETF/NHr2PfC9RzA==","signatures":[{"sig":"MEUCIE8K0Mpa12xrXROTcPnFtLsATlEamfLz6t2kwVsMr0O6AiEAursybSpu+lkDPl6u4bNCCretdmePULaXRoGMk6QTN8w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26309},"main":"./dist/index.js","type":"module","exports":{".":"./dist/index.js"},"gitHead":"488cf6819975357ac6dddb1dd9c5fd7a907c8d43","scripts":{"test":"node test/smoke.mjs","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"_npmVersion":"11.16.0","description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.10.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependenciesMeta":{"@deepseek-ai/dsh-tools":{"optional":true},"@deepseek-ai/dsh-subprocess":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dsh-config-git-backup_0.2.1_1789394392960_0.08931360193880256","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@caesarloo/dsh-config-git-backup","version":"0.2.2","keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"license":"MIT","_id":"@caesarloo/dsh-config-git-backup@0.2.2","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"db850b3f9fcc35efcbe03d9d525c18e47eb70d24","tarball":"https://registry.npmjs.org/@caesarloo/dsh-config-git-backup/-/dsh-config-git-backup-0.2.2.tgz","fileCount":5,"integrity":"sha512-z8v3S5iMWP9GwkTPglOlh4oQF+DG9H65bmUvzKlZBeCnuGxKorbbZNDwuY9bRi/A3u05xmzBo6kaZrLsnCg1sg==","signatures":[{"sig":"MEYCIQD37/T/hViEpcTqCrO5DcbBwXiixaAo/MMg5kmy5nC/HAIhAKdg/ec5gClA7L3Int4c8xWLcNNqwxpExGl0tEHRr5Az","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCHVr+JjcSqYvPcITw8R4+vsshH0wWIvGuTRfi9/kFkQQIgAKPLefOdW3i9CbcIdgL8fLubWOdYqXdda6j4ymmFAdo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26314},"main":"./dist/index.js","type":"module","exports":{".":"./dist/index.js"},"gitHead":"98926b0054c4a69d107e2f008cabbabc1bd4dc9c","scripts":{"test":"node test/smoke.mjs","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"_npmVersion":"11.16.0","description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.10.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependenciesMeta":{"@deepseek-ai/dsh-tools":{"optional":true},"@deepseek-ai/dsh-subprocess":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dsh-config-git-backup_0.2.2_1789611871978_0.9842083836221116","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@caesarloo/dsh-config-git-backup","version":"0.2.3","keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"license":"MIT","_id":"@caesarloo/dsh-config-git-backup@0.2.3","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"12ad882e5b6dc4b4f92adb50aacac6b5579125c8","tarball":"https://registry.npmjs.org/@caesarloo/dsh-config-git-backup/-/dsh-config-git-backup-0.2.3.tgz","fileCount":5,"integrity":"sha512-KnQvnEurB9CuvkbYEK034WPI1C7n0srdfN1MA5MPKGa2hTW9ochI2JLdrpTwI4FLd+gM0xIi1TxGeoKu9nCqRA==","signatures":[{"sig":"MEUCIQDy9WX4qRtr3OYLzcLJ3wVMi8LjttuOQInlFL0vHAjcPgIgF/jNTTe0VjSxBwDIasM4gcS4M+ddUrut7C+NmCK2P7k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIFXJozRwxwoIfceobRuKcaIu3Cf1JYPEx36zI95j7O7PAiA8aOG9mrgpiD3Hs/kYbEgogQR41dJCCUVWghQLLVrYXw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31727},"main":"./dist/index.js","type":"module","exports":{".":"./dist/index.js"},"gitHead":"e5224d43155af246d69128ebf5275224875482b5","scripts":{"test":"node test/smoke.mjs","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"_npmVersion":"11.16.0","description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.10.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependenciesMeta":{"@deepseek-ai/dsh-tools":{"optional":true},"@deepseek-ai/dsh-subprocess":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dsh-config-git-backup_0.2.3_1789612119451_0.04744040148450823","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@caesarloo/dsh-config-git-backup","version":"0.2.4","keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"license":"MIT","_id":"@caesarloo/dsh-config-git-backup@0.2.4","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"57ced38a12fd78f376a924fcf2c85020deaf119a","tarball":"https://registry.npmjs.org/@caesarloo/dsh-config-git-backup/-/dsh-config-git-backup-0.2.4.tgz","fileCount":5,"integrity":"sha512-xGZM5sVk+jgoC9DxBP95MDosaiZYDVOZoD0Ks5NXsdU6IoyBlNegNdau/EsSPuxC3/mTwNRKzzdJGLAPH6kajQ==","signatures":[{"sig":"MEQCIGXX4x7qXIb+Hmi9iAl80SiZSD9GgsviZ+EOXo+H46xoAiBhHXinpAThy3C1QCqyv/SXrmpxDRLqTaPmVQNZyW1N9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGFhCKg4YO9zPSZE1fClanGW4xWp3r3kH339ACxSwlsNAiA4kYA+ExJbRIWGyDJxlsqi0TEFKUDGX8SnG9zvxvIBwg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31727},"main":"./dist/index.js","type":"module","exports":{".":"./dist/index.js"},"gitHead":"c57f885900349417e0658b69549345fb73c58f54","scripts":{"test":"node test/smoke.mjs","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"_npmVersion":"11.16.0","description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.10.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependenciesMeta":{"@deepseek-ai/dsh-tools":{"optional":true},"@deepseek-ai/dsh-subprocess":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dsh-config-git-backup_0.2.4_1789626739518_0.8704851163631124","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"@caesarloo/dsh-config-git-backup","version":"0.2.5","keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"license":"MIT","_id":"@caesarloo/dsh-config-git-backup@0.2.5","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"607be87e6ed584aa9d7468bd481ba2719003d426","tarball":"https://registry.npmjs.org/@caesarloo/dsh-config-git-backup/-/dsh-config-git-backup-0.2.5.tgz","fileCount":5,"integrity":"sha512-abTzhfGmmOi80ywtp/+e5l0BPiGATqBEUfBbPKsRby1K6CiaSm1UltrttQUBDsCvy+1hQIsPBqwHzfFvcp+7NQ==","signatures":[{"sig":"MEYCIQDkgjBJp1WopA/1qPt755a0TmhKiUYz6hGsOhG7JXyTcAIhAKnqrtnDmtopJ+Rl0WOfTBPQRD6hH9zRQFIIUxXAWKSS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDWBbceQ3zHAvSAbK5TlMYzpHB/4y4PWwRnHZBUmyZhJgIhAOLhuWEDwvgZEXbguAfakM5DjSSkCvAhnKRqZ8lMj9ZZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31725},"main":"./dist/index.js","type":"module","exports":{".":"./dist/index.js"},"gitHead":"5eb94772ae125673f6a36002486c323f731024b0","scripts":{"test":"node test/smoke.mjs","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"_npmVersion":"11.16.0","description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.10.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.1.5-rc.2","@deepseek-ai/dsh-subprocess":"^0.1.5-rc.2"},"peerDependenciesMeta":{"@deepseek-ai/dsh-tools":{"optional":true},"@deepseek-ai/dsh-subprocess":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/dsh-config-git-backup_0.2.5_1789628524224_0.3579200630629482","host":"s3://npm-registry-packages-npm-production"}},"0.2.6":{"_id":"@caesarloo/dsh-config-git-backup@0.2.6","dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"eabe7172a916ca780986c6ac8b3dffc21c38010d","tarball":"https://registry.npmjs.org/@caesarloo/dsh-config-git-backup/-/dsh-config-git-backup-0.2.6.tgz","fileCount":6,"integrity":"sha512-3lGFBYK2BLAqJax76zG98gGoASYeBCe/CmyZrFKm0rfuBUjj5kxLBht5NqoCZBp/ypDbAga79na39XRgS+RioA==","signatures":[{"sig":"MEUCIENLakku6jc+r68155GBSZoiJqHeVNFQ6Qu2Kca/JJM/AiEAl58v9G5lPK0VYedGWlprzU8wE9IJZCGK5xPCpGdyMkk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDj0QdrViscj4mA9TSt+BLGQ9wFbO65UBZmCOt1FkJf0gIhAIH+BfVQ8yFCQSiAFXoMoBSBy/paPUfqLtdJLUeuKO2G"}],"unpackedSize":32934},"main":"./dist/index.js","name":"@caesarloo/dsh-config-git-backup","type":"module","exports":{".":"./dist/index.js"},"gitHead":"17986ae4741ddaba7d2120865034abfb222c7405","license":"MIT","scripts":{"test":"node test/smoke.mjs","build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"version":"0.2.6","_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"_npmVersion":"11.16.0","description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","directories":{},"maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.10.0","@deepseek-ai/cordis":"~4.0.4","@deepseek-ai/dsh-tools":"^0.2.0-rc.2","@deepseek-ai/dsh-subprocess":"^0.2.0-rc.2"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-tools":"^0.2.0-rc.2","@deepseek-ai/dsh-subprocess":"^0.2.0-rc.2"},"peerDependenciesMeta":{"@deepseek-ai/dsh-tools":{"optional":true},"@deepseek-ai/dsh-subprocess":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-config-git-backup_0.2.6_1790760319720_0.30596712767488476"}}},"time":{"created":"2026-09-06T15:08:10.290Z","modified":"2026-09-30T09:25:20.149Z","0.1.0":"2026-09-06T15:08:10.635Z","0.2.0":"2026-09-13T01:22:23.402Z","0.2.1":"2026-09-14T13:59:53.330Z","0.2.2":"2026-09-17T02:24:32.057Z","0.2.3":"2026-09-17T02:28:39.537Z","0.2.4":"2026-09-17T06:32:19.615Z","0.2.5":"2026-09-17T07:02:04.329Z","0.2.6":"2026-09-30T09:25:19.812Z"},"license":"MIT","keywords":["dsh","deepseek-harness","dsh-plugin","backup","sync","git"],"description":"Backup/restore DSH config, custom skills and plugin sources against a local git repository, callable by the agent as the dsh_config_git_backup tool (backup = sync + git commit; restore = repo back to live sources).","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"readme":"# @caesarloo/dsh-config-git-backup\n\n[English](#english) | [中文](#中文)\n\n---\n\n## English\n\nA DeepSeek Harness tool plugin that versions DSH **sources** — config, custom skills and plugin sources — in a local git repository, and restores them onto a fresh or repaired host. The agent calls it as the `dsh_config_git_backup` tool.\n\n### What it does\n\nRegisters one tool with two modes:\n\n- **`backup`** — copy live sources (your `~/.dsh` config + skills, plus the local plugin source dir) into the configured git repo, then `git add -A && git commit`;\n- **`restore`** — copy the repo content back onto the live sources (reinstall / new machine / multi-host sync). **Destructive**: it overwrites live files, so it is fail-closed — see Safety below.\n\nThe plugin is a thin driver: **the actual sync logic lives in the `sync.ps1` you point it at** (contract: `-Mode backup | restore`, plus the optional `-DryRun` / `-Force` switches; a typical implementation uses `robocopy` with `node_modules` excluded). Paths are never hard-coded in the source — everything comes from config or environment.\n\nThe intended workflow: keep plugin / skill / config **sources** versioned in a git repo (optionally mirrored to a NAS or cloud drive) so any host can reproduce the exact environment. Sensitive data (`.credentials.yaml`, `sessions/`, `storages/`, `.env`) is deliberately **not** synced.\n\n### Safety (since 0.2.0)\n\n`restore` overwrites the live sources, so it is protected in three layers:\n\n1. **Tool-level confirmation gate (fail-closed)** — a `restore` without `confirm: true` writes **nothing**: it first takes a `-DryRun` diff, then fails with the list of items that would be added / overwritten plus the confirmation requirement.\n2. **Script-level gate** — `sync.ps1 -Mode restore` refuses to run without `-Force`; `-DryRun` only previews. Directory sync uses `robocopy /E` rather than `/MIR`, so it **never purges** — files unique to the live sources survive.\n3. **Pre-overwrite snapshot** — before a `-Force` restore, the live sources are snapshotted to `<DSH_HOME>/vet/restore-snapshots/<timestamp>/` (with a `manifest.txt` recording what will be overwritten / kept); the last 10 snapshots are retained.\n\n`backup` adds a **landed-content check**: after syncing it compares every file by SHA256 and **errors out** if anything did not land, so a silent `robocopy` skip (same size + same mtime) can no longer be reported as success.\n\n### Install\n\n```sh\ndsh plugin --profile web add @caesarloo/dsh-config-git-backup\n```\n\nRestart dsh afterwards (bundle-level change, not hot-reloaded). Verify:\n\n```powershell\ndsh --profile web --dump-config | Select-String tool-dsh-config-git-backup\n```\n\n### Dependencies (since 0.2.1)\n\nThe plugin declares **no runtime `dependencies`**. The host (DSH itself) provides `@deepseek-ai/dsh-tools` (`defineTool`) and `@deepseek-ai/dsh-subprocess` (`ctx.subprocess`); both are declared only as `optional: true` peerDependencies.\n\n- **Why**: `dsh-tools` registers its tool runtime with `Symbol('@deepseek-ai/dsh-tools.scheduler')`, and a `Symbol` is **locally unique** (not `Symbol.for`). If the package manager installs a second real copy inside the profile, plugins and the host resolve **two module instances / two symbols** → tool registration no longer matches and every tool call in that turn fails. Declaring them as non-optional peers would reintroduce that second copy, hence `optional: true`.\n- The `devDependencies` copies exist only in a development clone for `tsc` type-checking and the smoke test; they are not part of the published artifact.\n- If a profile was polluted by an older version, upgrade the plugin and move the leftover real directories away; pinning the host instance through `overrides` in `pnpm-workspace.yaml` prevents a repeat.\n\n### Configuration\n\nProvide via the profile patch layer (`cordis.patch.yml`) or environment variables. With neither set, the tool runs **fail-closed** (every call errors).\n\n| Config key | Env var | Meaning |\n|---|---|---|\n| `repoDir` | `DSH_CONFIG_GIT_BACKUP_REPO_DIR` | Target git repository directory |\n| `syncScript` | `DSH_CONFIG_GIT_BACKUP_SYNC_SCRIPT` | Full path of your `sync.ps1` (defaults to `sync.ps1` inside `repoDir`) |\n| `powershell` | — | PowerShell executable (Windows PowerShell on win32, `pwsh` elsewhere) |\n\nExample patch:\n\n```yaml\n- id: tool-dsh-config-git-backup\n  config:\n    repoDir: '<backup repo path>'\n    syncScript: '<backup repo path>\\sync.ps1'\n```\n\n### Usage\n\n```\ndsh_config_git_backup({ mode: 'backup', message: 'update skill my-skill' })         # sync + git commit\ndsh_config_git_backup({ mode: 'backup', dryRun: true })                            # preview what would be written\ndsh_config_git_backup({ mode: 'restore', dryRun: true })                           # preview what would be overwritten\ndsh_config_git_backup({ mode: 'restore', confirm: true })                          # confirm: snapshot, then overwrite\n```\n\n`dryRun` and `confirm` cannot both be `true`. `message` is normalized: control characters flattened, whitespace collapsed to single spaces, truncated to 200 characters; the default is `backup: <timestamp>`.\n\n### Notes & limits\n\n- **`sync.ps1` contract** — implement `-Mode backup` / `-Mode restore` copying between the live sources and the repo, excluding `node_modules/` and anything else you do not want versioned. To get the 0.2.0 protections from a custom script, also accept `-DryRun` (preview, no writes) and `-Force` (acknowledge a destructive restore; snapshot first). The plugin performs the git commit for `backup`, and for `restore` refuses without `confirm` and reports the snapshot path.\n- **Never sync host-private secrets.** The reference `sync.ps1` keeps `profiles/web/cordis.patch.yml` out of its item list (it holds a local relay token and machine-specific absolute paths); only a sanitized `cordis.patch.yml.example` is versioned. A repo-side `.gitignore` additionally excludes `.credentials.yaml`, `sessions/`, `storages/`, `.env`, `node_modules/`, `dist/`.\n- **Platform** — the reference `sync.ps1` uses `robocopy` + Windows PowerShell (and reports UTF-8 output; its SHA256 check uses .NET rather than `Get-FileHash`). On non-Windows you supply your own sync script; the plugin itself is cross-platform (`ctx.subprocess`, `node:path`).\n- **Not a session/memory backup tool** — it versions *sources* (config / skills / plugins), not runtime state.\n- Runs through `ctx.subprocess` (host layer, outside sandbox restrictions).\n- **Tests** — `npm test` drives the built tool against a throwaway sandbox (fake Cordis ctx, real subprocess, path-rewritten `sync.ps1`) and asserts the confirm gate, dry-run, snapshot, message normalization and fail-closed behavior; the suite never reads or overwrites the real `~/.dsh`. The companion `test/sync-protection-tests.ps1` exercises the sync-script contract (preview / refusal / snapshot / landed-content verify) and needs no plugin install.\n\n### License\n\nMIT\n\n---\n\n## 中文\n\n一个 DeepSeek Harness 工具插件：把 DSH 的**源文件**（配置、自定义技能、插件源码）版本化到一个本地 git 仓库，并能把它们还原到新机器或修复后的机器上。Agent 通过 `dsh_config_git_backup` 工具调用它。\n\n### 功能\n\n注册一个工具，两种模式：\n\n- **`backup`** —— 把活跃源（`~/.dsh` 的配置与技能，以及本地插件源码目录）复制进配置的 git 仓库，然后 `git add -A && git commit`；\n- **`restore`** —— 把仓库内容复制回活跃源（重装 / 新机器 / 多机同步）。**破坏性**：会覆盖活跃源文件，因此是 fail-closed（见「安全约定」）。\n\n插件本身只是薄驱动：**真正的同步逻辑在你指定的 `sync.ps1` 里**（契约：`-Mode backup | restore`，外加可选的 `-DryRun` / `-Force`；典型实现用 `robocopy` 并排除 `node_modules`）。源码中不硬编码任何路径——一切都来自配置或环境变量。\n\n适用场景：把插件 / 技能 / 配置的**源文件**放进 git 仓库版本化（可选再镜像到 NAS 或云盘），这样任何一台机器都能复现同样的环境。敏感数据（`.credentials.yaml`、`sessions/`、`storages/`、`.env`）**刻意不同步**。\n\n### 安全约定（0.2.0 起）\n\n`restore` 会用仓库版本覆盖活跃源，未提交的本地改动会丢，因此有三层保护：\n\n1. **工具层确认门（fail-closed）** —— `restore` 不带 `confirm: true` 时**不写入任何东西**：它先以 `-DryRun` 取一份差异，然后把「会被新增 / 覆盖的清单」连同确认要求一起报错返回。\n2. **脚本层闸门** —— `sync.ps1 -Mode restore` 没有 `-Force` 直接拒绝执行，`-DryRun` 只预览。目录同步用 `robocopy /E` 而非 `/MIR`，**不做 purge 删除**——活跃源独有的文件不会被删。\n3. **覆盖前快照** —— `-Force` 执行还原前，先把活跃源快照到 `<DSH_HOME>/vet/restore-snapshots/<时间戳>/`（含 `manifest.txt`，记录将覆盖 / 保留的清单），只保留最近 10 份。\n\n`backup` 另加**落库校验**：同步完成后逐文件比对 SHA256，仍有未落库项即**报错退出**，不再把「同步实际没生效」（如 robocopy 因同尺寸同时间戳静默跳过）记成成功。\n\n### 安装\n\n```sh\ndsh plugin --profile web add @caesarloo/dsh-config-git-backup\n```\n\n装完**重启 dsh**（bundle 层变更，不随热重载生效）。验证：\n\n```powershell\ndsh --profile web --dump-config | Select-String tool-dsh-config-git-backup\n```\n\n### 依赖约定（0.2.1 起）\n\n插件**不声明任何 runtime `dependencies`**。它用到的 `@deepseek-ai/dsh-tools`（`defineTool`）与 `@deepseek-ai/dsh-subprocess`（`ctx.subprocess`）**由宿主（DSH 主包）提供**，二者只以 `optional: true` 的 peerDependencies 声明。\n\n- **原因**：`dsh-tools` 用 `Symbol('@deepseek-ai/dsh-tools.scheduler')` 注册工具运行时，而 `Symbol` 是**局部唯一**的（不是 `Symbol.for`）。若包管理器在 profile 里再装一份真实副本，插件与主包会解析到**两个模块实例、两个 Symbol** → 工具注册与读取不匹配，该轮所有工具调用全线失败。把这两个包写成非 optional 的 peer 会重新引入那份副本，所以必须是 `optional: true`。\n- `devDependencies` 里的同版本包只存在于开发克隆，用于 `tsc` 类型检查与冒烟测试，不随发布产物分发。\n- 若某个 profile 曾被旧版污染，升级本插件后还要把残留的真实目录移走；在 `pnpm-workspace.yaml` 里用 `overrides` 把宿主实例钉住可防复发。\n\n### 配置\n\n通过 profile 的 patch 层（`cordis.patch.yml`）或环境变量提供；两者都缺省时工具 **fail-closed**（每次调用都报错）。\n\n| 配置键 | 环境变量 | 含义 |\n|---|---|---|\n| `repoDir` | `DSH_CONFIG_GIT_BACKUP_REPO_DIR` | 目标 git 仓库目录 |\n| `syncScript` | `DSH_CONFIG_GIT_BACKUP_SYNC_SCRIPT` | 你的 `sync.ps1` 完整路径（缺省为 `repoDir` 下的 `sync.ps1`） |\n| `powershell` | — | PowerShell 可执行文件（win32 缺省 Windows PowerShell，其它平台 `pwsh`） |\n\n配置示例：\n\n```yaml\n- id: tool-dsh-config-git-backup\n  config:\n    repoDir: '<备份仓库路径>'\n    syncScript: '<备份仓库路径>\\sync.ps1'\n```\n\n### 用法示例\n\n```\ndsh_config_git_backup({ mode: 'backup', message: '更新技能 my-skill' })          # 同步 + git commit\ndsh_config_git_backup({ mode: 'backup', dryRun: true })                        # 预览将写入仓库的差异\ndsh_config_git_backup({ mode: 'restore', dryRun: true })                       # 预览将被覆盖的活跃源项\ndsh_config_git_backup({ mode: 'restore', confirm: true })                      # 确认还原（先快照，再覆盖）\n```\n\n`dryRun` 与 `confirm` 不能同时为 `true`。`message` 会被规范化：控制字符压平、空白折叠成单空格、截断到 200 字符，缺省为 `备份: <时间戳>`。\n\n### 说明与限制\n\n- **`sync.ps1` 契约** —— 实现 `-Mode backup` / `-Mode restore`，在活跃源与仓库之间复制，排除 `node_modules/` 以及任何你不想版本化的内容。要用上 0.2.0 的保护，自定义脚本还需接受 `-DryRun`（只预览、不写入）与 `-Force`（确认破坏性还原，先做快照）。`backup` 的 git 提交由插件完成；`restore` 缺 `confirm` 时插件直接拒绝，并报告快照路径。\n- **绝不同步含主机私密信息的文件。** 参考实现的 `sync.ps1` 刻意把 `profiles/web/cordis.patch.yml` 排除在同步项之外（它含本地转发口令与机器专属绝对路径），仓库里只放脱敏模板 `cordis.patch.yml.example`。仓库侧 `.gitignore` 另排除 `.credentials.yaml`、`sessions/`、`storages/`、`.env`、`node_modules/`、`dist/`。\n- **平台** —— 参考实现的 `sync.ps1` 使用 `robocopy` + Windows PowerShell（并输出 UTF-8，其 SHA256 校验用 .NET 而非 `Get-FileHash`）。在非 Windows 上请自备同步脚本；插件本身跨平台（`ctx.subprocess`、`node:path`）。\n- **不是会话 / 记忆备份工具** —— 它版本化的是**源文件**（配置 / 技能 / 插件），不是运行时状态。\n- 通过 `ctx.subprocess`（host 层）执行，不受沙箱限制。\n- **测试** —— `npm test` 用一次性沙箱驱动构建产物（假 Cordis ctx、真实 subprocess、路径重写后的 `sync.ps1`），断言确认门、dry-run、快照、消息规范化与 fail-closed 行为；测试套件绝不读写真实的 `~/.dsh`。配套的 `test/sync-protection-tests.ps1` 覆盖同步脚本契约（预览 / 拒绝 / 快照 / 落库校验），无需安装插件即可运行。\n\n### License\n\nMIT\n","readmeFilename":"README.md"}