agent-skill-manager 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CODE_OF_CONDUCT.md +59 -0
- package/CONTRIBUTING.md +92 -0
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/RELEASE_NOTES.md +31 -0
- package/SECURITY.md +43 -0
- package/bin/skill-manager.ts +46 -0
- package/bun.lock +204 -0
- package/docs/ARCHITECTURE.md +60 -0
- package/docs/CHANGELOG.md +22 -0
- package/docs/DEPLOYMENT.md +52 -0
- package/docs/DEVELOPMENT.md +64 -0
- package/package.json +44 -0
- package/src/config.ts +109 -0
- package/src/index.ts +324 -0
- package/src/scanner.ts +165 -0
- package/src/uninstaller.ts +225 -0
- package/src/utils/colors.ts +16 -0
- package/src/utils/frontmatter.ts +87 -0
- package/src/utils/types.ts +57 -0
- package/src/utils/version.ts +20 -0
- package/src/views/config.ts +147 -0
- package/src/views/confirm.ts +105 -0
- package/src/views/dashboard.ts +252 -0
- package/src/views/help.ts +83 -0
- package/src/views/skill-detail.ts +114 -0
- package/src/views/skill-list.ts +122 -0
package/bun.lock
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "skill-manager",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@opentui/core": "latest",
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"bun-types": "^1.3.10",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
"packages": {
|
|
16
|
+
"@dimforge/rapier2d-simd-compat": ["@dimforge/rapier2d-simd-compat@0.17.3", "", {}, "sha512-bijvwWz6NHsNj5e5i1vtd3dU2pDhthSaTUZSh14DUGGKJfw8eMnlWZsxwHBxB/a3AXVNDjL9abuHw1k9FGR+jg=="],
|
|
17
|
+
|
|
18
|
+
"@jimp/core": ["@jimp/core@1.6.0", "", { "dependencies": { "@jimp/file-ops": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "await-to-js": "^3.0.0", "exif-parser": "^0.1.12", "file-type": "^16.0.0", "mime": "3" } }, "sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w=="],
|
|
19
|
+
|
|
20
|
+
"@jimp/diff": ["@jimp/diff@1.6.0", "", { "dependencies": { "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "pixelmatch": "^5.3.0" } }, "sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw=="],
|
|
21
|
+
|
|
22
|
+
"@jimp/file-ops": ["@jimp/file-ops@1.6.0", "", {}, "sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ=="],
|
|
23
|
+
|
|
24
|
+
"@jimp/js-bmp": ["@jimp/js-bmp@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "bmp-ts": "^1.0.9" } }, "sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw=="],
|
|
25
|
+
|
|
26
|
+
"@jimp/js-gif": ["@jimp/js-gif@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "gifwrap": "^0.10.1", "omggif": "^1.0.10" } }, "sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g=="],
|
|
27
|
+
|
|
28
|
+
"@jimp/js-jpeg": ["@jimp/js-jpeg@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "jpeg-js": "^0.4.4" } }, "sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA=="],
|
|
29
|
+
|
|
30
|
+
"@jimp/js-png": ["@jimp/js-png@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "pngjs": "^7.0.0" } }, "sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg=="],
|
|
31
|
+
|
|
32
|
+
"@jimp/js-tiff": ["@jimp/js-tiff@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "utif2": "^4.1.0" } }, "sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw=="],
|
|
33
|
+
|
|
34
|
+
"@jimp/plugin-blit": ["@jimp/plugin-blit@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA=="],
|
|
35
|
+
|
|
36
|
+
"@jimp/plugin-blur": ["@jimp/plugin-blur@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw=="],
|
|
37
|
+
|
|
38
|
+
"@jimp/plugin-circle": ["@jimp/plugin-circle@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw=="],
|
|
39
|
+
|
|
40
|
+
"@jimp/plugin-color": ["@jimp/plugin-color@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "tinycolor2": "^1.6.0", "zod": "^3.23.8" } }, "sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA=="],
|
|
41
|
+
|
|
42
|
+
"@jimp/plugin-contain": ["@jimp/plugin-contain@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ=="],
|
|
43
|
+
|
|
44
|
+
"@jimp/plugin-cover": ["@jimp/plugin-cover@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA=="],
|
|
45
|
+
|
|
46
|
+
"@jimp/plugin-crop": ["@jimp/plugin-crop@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang=="],
|
|
47
|
+
|
|
48
|
+
"@jimp/plugin-displace": ["@jimp/plugin-displace@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q=="],
|
|
49
|
+
|
|
50
|
+
"@jimp/plugin-dither": ["@jimp/plugin-dither@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0" } }, "sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ=="],
|
|
51
|
+
|
|
52
|
+
"@jimp/plugin-fisheye": ["@jimp/plugin-fisheye@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA=="],
|
|
53
|
+
|
|
54
|
+
"@jimp/plugin-flip": ["@jimp/plugin-flip@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg=="],
|
|
55
|
+
|
|
56
|
+
"@jimp/plugin-hash": ["@jimp/plugin-hash@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "any-base": "^1.1.0" } }, "sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q=="],
|
|
57
|
+
|
|
58
|
+
"@jimp/plugin-mask": ["@jimp/plugin-mask@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA=="],
|
|
59
|
+
|
|
60
|
+
"@jimp/plugin-print": ["@jimp/plugin-print@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/types": "1.6.0", "parse-bmfont-ascii": "^1.0.6", "parse-bmfont-binary": "^1.0.6", "parse-bmfont-xml": "^1.1.6", "simple-xml-to-json": "^1.2.2", "zod": "^3.23.8" } }, "sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A=="],
|
|
61
|
+
|
|
62
|
+
"@jimp/plugin-quantize": ["@jimp/plugin-quantize@1.6.0", "", { "dependencies": { "image-q": "^4.0.0", "zod": "^3.23.8" } }, "sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg=="],
|
|
63
|
+
|
|
64
|
+
"@jimp/plugin-resize": ["@jimp/plugin-resize@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA=="],
|
|
65
|
+
|
|
66
|
+
"@jimp/plugin-rotate": ["@jimp/plugin-rotate@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw=="],
|
|
67
|
+
|
|
68
|
+
"@jimp/plugin-threshold": ["@jimp/plugin-threshold@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w=="],
|
|
69
|
+
|
|
70
|
+
"@jimp/types": ["@jimp/types@1.6.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg=="],
|
|
71
|
+
|
|
72
|
+
"@jimp/utils": ["@jimp/utils@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "tinycolor2": "^1.6.0" } }, "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA=="],
|
|
73
|
+
|
|
74
|
+
"@opentui/core": ["@opentui/core@0.1.87", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "marked": "17.0.1", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.87", "@opentui/core-darwin-x64": "0.1.87", "@opentui/core-linux-arm64": "0.1.87", "@opentui/core-linux-x64": "0.1.87", "@opentui/core-win32-arm64": "0.1.87", "@opentui/core-win32-x64": "0.1.87", "bun-webgpu": "0.1.5", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-dhsmMv0IqKftwG7J/pBrLBj2armsYIg5R3LBvciRQI/6X89GufP4l1u0+QTACAx6iR4SYJJNVNQ2tdX8LM9rMw=="],
|
|
75
|
+
|
|
76
|
+
"@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.87", "", { "os": "darwin", "cpu": "arm64" }, "sha512-G8oq85diOfkU6n0T1CxCle7oDmpKxwhcdhZ9khBMU5IrfLx9ZDuCM3F6MsiRQWdvPPCq2oomNbd64bYkPamYgw=="],
|
|
77
|
+
|
|
78
|
+
"@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.87", "", { "os": "darwin", "cpu": "x64" }, "sha512-MYTFQfOHm6qO7YaY4GHK9u/oJlXY6djaaxl5I+k4p2mk3vvuFIl/AP1ypITwBFjyV5gyp7PRWFp4nGfY9oN8bw=="],
|
|
79
|
+
|
|
80
|
+
"@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.87", "", { "os": "linux", "cpu": "arm64" }, "sha512-he8o1h5M6oskRJ7wE+xKJgmWnv5ZwN6gB3M/Z+SeHtOMPa5cZmi3TefTjG54llEgFfx0F9RcqHof7TJ/GNxRkw=="],
|
|
81
|
+
|
|
82
|
+
"@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.87", "", { "os": "linux", "cpu": "x64" }, "sha512-aiUwjPlH4yDcB8/6YDKSmMkaoGAAltL0Xo0AzXyAtJXWK5tkCSaYjEVwzJ/rYRkr4Magnad+Mjth4AQUWdR2AA=="],
|
|
83
|
+
|
|
84
|
+
"@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.87", "", { "os": "win32", "cpu": "arm64" }, "sha512-cmP0pOyREjWGniHqbDmaMY7U+1AyagrD8VseJbU0cGpNgVpG2/gbrJUGdfdLB0SNb+mzLdx6SOjdxtrElwRCQA=="],
|
|
85
|
+
|
|
86
|
+
"@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.87", "", { "os": "win32", "cpu": "x64" }, "sha512-N2GErAAP8iODf2RPp86pilPaVKiD6G4pkpZL5nLGbKsl0bndrVTpSqZcn8+/nQwFZDPD/AsiRTYNOfWOblhzOw=="],
|
|
87
|
+
|
|
88
|
+
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
|
89
|
+
|
|
90
|
+
"@types/node": ["@types/node@16.9.1", "", {}, "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="],
|
|
91
|
+
|
|
92
|
+
"@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="],
|
|
93
|
+
|
|
94
|
+
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
|
|
95
|
+
|
|
96
|
+
"any-base": ["any-base@1.1.0", "", {}, "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="],
|
|
97
|
+
|
|
98
|
+
"await-to-js": ["await-to-js@3.0.0", "", {}, "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g=="],
|
|
99
|
+
|
|
100
|
+
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
|
101
|
+
|
|
102
|
+
"bmp-ts": ["bmp-ts@1.0.9", "", {}, "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw=="],
|
|
103
|
+
|
|
104
|
+
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
|
|
105
|
+
|
|
106
|
+
"bun-ffi-structs": ["bun-ffi-structs@0.1.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-Lh1oQAYHDcnesJauieA4UNkWGXY9hYck7OA5IaRwE3Bp6K2F2pJSNYqq+hIy7P3uOvo3km3oxS8304g5gDMl/w=="],
|
|
107
|
+
|
|
108
|
+
"bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="],
|
|
109
|
+
|
|
110
|
+
"bun-webgpu": ["bun-webgpu@0.1.5", "", { "dependencies": { "@webgpu/types": "^0.1.60" }, "optionalDependencies": { "bun-webgpu-darwin-arm64": "^0.1.5", "bun-webgpu-darwin-x64": "^0.1.5", "bun-webgpu-linux-x64": "^0.1.5", "bun-webgpu-win32-x64": "^0.1.5" } }, "sha512-91/K6S5whZKX7CWAm9AylhyKrLGRz6BUiiPiM/kXadSnD4rffljCD/q9cNFftm5YXhx4MvLqw33yEilxogJvwA=="],
|
|
111
|
+
|
|
112
|
+
"bun-webgpu-darwin-arm64": ["bun-webgpu-darwin-arm64@0.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-qM7W5IaFpWYGPDcNiQ8DOng3noQ97gxpH2MFH1mGsdKwI0T4oy++egSh5Z7s6AQx8WKgc9GzAsTUM4KZkFdacw=="],
|
|
113
|
+
|
|
114
|
+
"bun-webgpu-darwin-x64": ["bun-webgpu-darwin-x64@0.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-oVoIsme27pcXB68YxnQSAgdNGCa4A3PGWYIBUewOh9VnJaoik4JenGb5Yy+svGE+ETFhQXV9nhHqgMPsDRrO6A=="],
|
|
115
|
+
|
|
116
|
+
"bun-webgpu-linux-x64": ["bun-webgpu-linux-x64@0.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-+SYt09k+xDEl/GfcU7L1zdNgm7IlvAFKV5Xl/auBwuprKG5UwXNhjRlRAWfhTMCUZWN+NDf8E+ZQx0cQi9K2/g=="],
|
|
117
|
+
|
|
118
|
+
"bun-webgpu-win32-x64": ["bun-webgpu-win32-x64@0.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-zvnUl4EAsQbKsmZVu+lEJcH8axQ7MiCfqg2OmnHd6uw1THABmHaX0GbpKiHshdgadNN2Nf+4zDyTJB5YMcAdrA=="],
|
|
119
|
+
|
|
120
|
+
"diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="],
|
|
121
|
+
|
|
122
|
+
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
|
|
123
|
+
|
|
124
|
+
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
|
|
125
|
+
|
|
126
|
+
"exif-parser": ["exif-parser@0.1.12", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="],
|
|
127
|
+
|
|
128
|
+
"file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
|
|
129
|
+
|
|
130
|
+
"gifwrap": ["gifwrap@0.10.1", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="],
|
|
131
|
+
|
|
132
|
+
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
|
133
|
+
|
|
134
|
+
"image-q": ["image-q@4.0.0", "", { "dependencies": { "@types/node": "16.9.1" } }, "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw=="],
|
|
135
|
+
|
|
136
|
+
"jimp": ["jimp@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/diff": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-gif": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-blur": "1.6.0", "@jimp/plugin-circle": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-contain": "1.6.0", "@jimp/plugin-cover": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-displace": "1.6.0", "@jimp/plugin-dither": "1.6.0", "@jimp/plugin-fisheye": "1.6.0", "@jimp/plugin-flip": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/plugin-mask": "1.6.0", "@jimp/plugin-print": "1.6.0", "@jimp/plugin-quantize": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/plugin-rotate": "1.6.0", "@jimp/plugin-threshold": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg=="],
|
|
137
|
+
|
|
138
|
+
"jpeg-js": ["jpeg-js@0.4.4", "", {}, "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="],
|
|
139
|
+
|
|
140
|
+
"marked": ["marked@17.0.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg=="],
|
|
141
|
+
|
|
142
|
+
"mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
|
|
143
|
+
|
|
144
|
+
"omggif": ["omggif@1.0.10", "", {}, "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="],
|
|
145
|
+
|
|
146
|
+
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
|
|
147
|
+
|
|
148
|
+
"parse-bmfont-ascii": ["parse-bmfont-ascii@1.0.6", "", {}, "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA=="],
|
|
149
|
+
|
|
150
|
+
"parse-bmfont-binary": ["parse-bmfont-binary@1.0.6", "", {}, "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA=="],
|
|
151
|
+
|
|
152
|
+
"parse-bmfont-xml": ["parse-bmfont-xml@1.1.6", "", { "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" } }, "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA=="],
|
|
153
|
+
|
|
154
|
+
"peek-readable": ["peek-readable@4.1.0", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="],
|
|
155
|
+
|
|
156
|
+
"pixelmatch": ["pixelmatch@5.3.0", "", { "dependencies": { "pngjs": "^6.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q=="],
|
|
157
|
+
|
|
158
|
+
"planck": ["planck@1.4.3", "", { "peerDependencies": { "stage-js": "^1.0.0-alpha.12" } }, "sha512-B+lHKhRSeg7vZOfEyEzyQVu7nx8JHcX3QgnAcHXrPW0j04XYKX5eXSiUrxH2Z5QR8OoqvjD6zKIaPMdMYAd0uA=="],
|
|
159
|
+
|
|
160
|
+
"pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="],
|
|
161
|
+
|
|
162
|
+
"process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
|
|
163
|
+
|
|
164
|
+
"readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
|
|
165
|
+
|
|
166
|
+
"readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.4", "", { "dependencies": { "readable-stream": "^4.7.0" } }, "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw=="],
|
|
167
|
+
|
|
168
|
+
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
|
169
|
+
|
|
170
|
+
"sax": ["sax@1.5.0", "", {}, "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA=="],
|
|
171
|
+
|
|
172
|
+
"simple-xml-to-json": ["simple-xml-to-json@1.2.3", "", {}, "sha512-kWJDCr9EWtZ+/EYYM5MareWj2cRnZGF93YDNpH4jQiHB+hBIZnfPFSQiVMzZOdk+zXWqTZ/9fTeQNu2DqeiudA=="],
|
|
173
|
+
|
|
174
|
+
"stage-js": ["stage-js@1.0.1", "", {}, "sha512-cz14aPp/wY0s3bkb/B93BPP5ZAEhgBbRmAT3CCDqert8eCAqIpQ0RB2zpK8Ksxf+Pisl5oTzvPHtL4CVzzeHcw=="],
|
|
175
|
+
|
|
176
|
+
"string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
|
|
177
|
+
|
|
178
|
+
"strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="],
|
|
179
|
+
|
|
180
|
+
"three": ["three@0.177.0", "", {}, "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg=="],
|
|
181
|
+
|
|
182
|
+
"tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="],
|
|
183
|
+
|
|
184
|
+
"token-types": ["token-types@4.2.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ=="],
|
|
185
|
+
|
|
186
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
187
|
+
|
|
188
|
+
"utif2": ["utif2@4.1.0", "", { "dependencies": { "pako": "^1.0.11" } }, "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w=="],
|
|
189
|
+
|
|
190
|
+
"web-tree-sitter": ["web-tree-sitter@0.25.10", "", { "peerDependencies": { "@types/emscripten": "^1.40.0" }, "optionalPeers": ["@types/emscripten"] }, "sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA=="],
|
|
191
|
+
|
|
192
|
+
"xml-parse-from-string": ["xml-parse-from-string@1.0.1", "", {}, "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g=="],
|
|
193
|
+
|
|
194
|
+
"xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="],
|
|
195
|
+
|
|
196
|
+
"xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
|
|
197
|
+
|
|
198
|
+
"yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
|
|
199
|
+
|
|
200
|
+
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
|
201
|
+
|
|
202
|
+
"pixelmatch/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="],
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
skill-manager is a terminal UI application that scans, displays, and manages skills installed for various AI coding agents. It follows a simple layered architecture: CLI entry → app bootstrap → core modules → TUI views.
|
|
6
|
+
|
|
7
|
+
## Components
|
|
8
|
+
|
|
9
|
+
### CLI Entry (`bin/skill-manager.ts`)
|
|
10
|
+
|
|
11
|
+
Handles `--help` and `--version` flags, then delegates to the main app entry point.
|
|
12
|
+
|
|
13
|
+
### App Bootstrap (`src/index.ts`)
|
|
14
|
+
|
|
15
|
+
Initializes the OpenTUI renderer, wires up keyboard handlers, and manages view state transitions (dashboard, detail, confirm, config, help).
|
|
16
|
+
|
|
17
|
+
### Core Modules
|
|
18
|
+
|
|
19
|
+
| Module | Responsibility |
|
|
20
|
+
| -------------------- | ----------------------------------------------------------- |
|
|
21
|
+
| `src/config.ts` | Load/save config from `~/.config/skill-manager/config.json` |
|
|
22
|
+
| `src/scanner.ts` | Walk provider directories, parse SKILL.md, filter & sort |
|
|
23
|
+
| `src/uninstaller.ts` | Build removal plans and execute safe deletions |
|
|
24
|
+
|
|
25
|
+
### Views (`src/views/`)
|
|
26
|
+
|
|
27
|
+
Each view is a factory function that creates OpenTUI components:
|
|
28
|
+
|
|
29
|
+
- **dashboard.ts** — Main layout with scope tabs, search input, stats bar
|
|
30
|
+
- **skill-list.ts** — Scrollable, selectable list of discovered skills
|
|
31
|
+
- **skill-detail.ts** — Overlay showing full skill metadata
|
|
32
|
+
- **confirm.ts** — Uninstall confirmation dialog with target list
|
|
33
|
+
- **config.ts** — Provider toggle UI
|
|
34
|
+
- **help.ts** — Keyboard shortcut overlay
|
|
35
|
+
|
|
36
|
+
### Utilities (`src/utils/`)
|
|
37
|
+
|
|
38
|
+
- **types.ts** — Shared TypeScript interfaces (`SkillInfo`, `AppConfig`, `Scope`, etc.)
|
|
39
|
+
- **colors.ts** — Neon green color palette for the TUI
|
|
40
|
+
- **frontmatter.ts** — YAML-like frontmatter parser for SKILL.md files
|
|
41
|
+
|
|
42
|
+
## Data Flow
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Config (disk) → Scanner (walk dirs) → SkillInfo[] → Views (render)
|
|
46
|
+
↕
|
|
47
|
+
Keyboard Events → State Machine → View Transitions
|
|
48
|
+
↓
|
|
49
|
+
Uninstaller → Filesystem Mutations → Rescan
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## State Management
|
|
53
|
+
|
|
54
|
+
Application state is held in module-level variables in `src/index.ts`:
|
|
55
|
+
|
|
56
|
+
- `allSkills` / `filteredSkills` — current skill data
|
|
57
|
+
- `currentScope` / `currentSort` / `searchQuery` — filter state
|
|
58
|
+
- `viewState` — which overlay is active (`dashboard`, `detail`, `confirm`, `config`, `help`)
|
|
59
|
+
|
|
60
|
+
State transitions are driven by keyboard events and propagated to views via update functions.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [1.0.0] - 2025-03-11
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Interactive TUI dashboard with OpenTUI
|
|
12
|
+
- Multi-agent support: Claude Code, Codex, OpenClaw, and generic Agents
|
|
13
|
+
- Configurable providers via `~/.config/skill-manager/config.json`
|
|
14
|
+
- Global and project scope filtering
|
|
15
|
+
- Real-time search and sort (by name, version, location)
|
|
16
|
+
- Detailed skill view with SKILL.md frontmatter metadata
|
|
17
|
+
- Safe uninstall with confirmation dialog
|
|
18
|
+
- In-TUI config editor with provider toggle
|
|
19
|
+
- CLI entry point with `--help` and `--version` flags
|
|
20
|
+
- Pre-commit hooks (Prettier, TypeScript type-checking)
|
|
21
|
+
- GitHub Actions CI pipeline
|
|
22
|
+
- Unit tests for config, scanner, uninstaller, and frontmatter modules
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Deployment
|
|
2
|
+
|
|
3
|
+
## Publishing to npm (via Bun)
|
|
4
|
+
|
|
5
|
+
skill-manager is distributed as a global CLI package.
|
|
6
|
+
|
|
7
|
+
### 1. Bump the version
|
|
8
|
+
|
|
9
|
+
Update the version in both files:
|
|
10
|
+
|
|
11
|
+
- `package.json` → `"version"`
|
|
12
|
+
- `bin/skill-manager.ts` → `VERSION` constant
|
|
13
|
+
|
|
14
|
+
### 2. Build and publish
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm publish
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or if using Bun's npm compatibility:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bunx npm publish
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 3. Install globally
|
|
27
|
+
|
|
28
|
+
Users install with:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bun install -g agent-skill-manager
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Running from Source
|
|
35
|
+
|
|
36
|
+
For development or CI environments:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/luongnv89/skill-manager.git
|
|
40
|
+
cd skill-manager
|
|
41
|
+
bun install
|
|
42
|
+
bun run start
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## CI Pipeline
|
|
46
|
+
|
|
47
|
+
GitHub Actions runs on every push and PR to `main`:
|
|
48
|
+
|
|
49
|
+
- Type-checking (`bun run typecheck`)
|
|
50
|
+
- Tests (`bun test`)
|
|
51
|
+
|
|
52
|
+
See `.github/workflows/ci.yml` for the full pipeline.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- [Bun](https://bun.sh) >= 1.0.0
|
|
6
|
+
- [Git](https://git-scm.com/)
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
git clone https://github.com/luongnv89/skill-manager.git
|
|
12
|
+
cd skill-manager
|
|
13
|
+
bun install
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Running
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun run start # Launch the TUI
|
|
20
|
+
bun run dev # Same as start (alias)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Testing
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bun test # Run all tests
|
|
27
|
+
bun run typecheck # Type-check without emitting
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Test files are co-located with source files using the `*.test.ts` convention:
|
|
31
|
+
|
|
32
|
+
- `src/config.test.ts`
|
|
33
|
+
- `src/scanner.test.ts`
|
|
34
|
+
- `src/uninstaller.test.ts`
|
|
35
|
+
- `src/utils/frontmatter.test.ts`
|
|
36
|
+
|
|
37
|
+
## Pre-commit Hooks
|
|
38
|
+
|
|
39
|
+
The project uses [pre-commit](https://pre-commit.com/) with:
|
|
40
|
+
|
|
41
|
+
- **trailing-whitespace** — removes trailing whitespace
|
|
42
|
+
- **end-of-file-fixer** — ensures files end with a newline
|
|
43
|
+
- **check-yaml / check-json** — validates config files
|
|
44
|
+
- **check-added-large-files** — prevents accidental large file commits
|
|
45
|
+
- **prettier** — auto-formats TS, JS, JSON, CSS, and MD files
|
|
46
|
+
- **typecheck** — runs `tsc --noEmit` on staged TypeScript files
|
|
47
|
+
|
|
48
|
+
Install hooks locally:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pre-commit install
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Debugging
|
|
55
|
+
|
|
56
|
+
Since this is a TUI application, standard `console.log` will interfere with the terminal UI. For debugging:
|
|
57
|
+
|
|
58
|
+
1. Write to a log file: `Bun.write("/tmp/sm-debug.log", JSON.stringify(data))`
|
|
59
|
+
2. Run tests to isolate logic from the TUI layer
|
|
60
|
+
3. Use the `--help` flag to verify CLI plumbing without launching the TUI
|
|
61
|
+
|
|
62
|
+
## Project Layout
|
|
63
|
+
|
|
64
|
+
See [ARCHITECTURE.md](ARCHITECTURE.md) for the full component breakdown.
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-skill-manager",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Interactive TUI for managing installed skills for AI coding agents (Claude Code, Codex, OpenClaw, and more)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"skill-manager": "bin/skill-manager.ts"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "bun run src/index.ts",
|
|
11
|
+
"typecheck": "bun run --bun tsc --noEmit",
|
|
12
|
+
"test": "bun test",
|
|
13
|
+
"dev": "bun run src/index.ts"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@opentui/core": "latest"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"bun": ">=1.0.0"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"skill-manager",
|
|
23
|
+
"tui",
|
|
24
|
+
"cli",
|
|
25
|
+
"ai-agents",
|
|
26
|
+
"claude-code",
|
|
27
|
+
"codex",
|
|
28
|
+
"openclaw",
|
|
29
|
+
"skills"
|
|
30
|
+
],
|
|
31
|
+
"author": "luongnv89",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"homepage": "https://github.com/luongnv89/skill-manager#readme",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/luongnv89/skill-manager.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/luongnv89/skill-manager/issues"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"bun-types": "^1.3.10"
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
2
|
+
import { join, resolve, dirname } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import type { AppConfig, ProviderConfig } from "./utils/types";
|
|
5
|
+
|
|
6
|
+
const HOME = homedir();
|
|
7
|
+
const CONFIG_DIR = join(HOME, ".config", "skill-manager");
|
|
8
|
+
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
9
|
+
|
|
10
|
+
const DEFAULT_PROVIDERS: ProviderConfig[] = [
|
|
11
|
+
{
|
|
12
|
+
name: "claude",
|
|
13
|
+
label: "Claude Code",
|
|
14
|
+
global: "~/.claude/skills",
|
|
15
|
+
project: ".claude/skills",
|
|
16
|
+
enabled: true,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: "codex",
|
|
20
|
+
label: "Codex",
|
|
21
|
+
global: "~/.codex/skills",
|
|
22
|
+
project: ".codex/skills",
|
|
23
|
+
enabled: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "openclaw",
|
|
27
|
+
label: "OpenClaw",
|
|
28
|
+
global: "~/.openclaw/skills",
|
|
29
|
+
project: ".openclaw/skills",
|
|
30
|
+
enabled: true,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "agents",
|
|
34
|
+
label: "Agents",
|
|
35
|
+
global: "~/.agents/skills",
|
|
36
|
+
project: ".agents/skills",
|
|
37
|
+
enabled: true,
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
export function getDefaultConfig(): AppConfig {
|
|
42
|
+
return {
|
|
43
|
+
version: 1,
|
|
44
|
+
providers: DEFAULT_PROVIDERS.map((p) => ({ ...p })),
|
|
45
|
+
customPaths: [],
|
|
46
|
+
preferences: {
|
|
47
|
+
defaultScope: "both",
|
|
48
|
+
defaultSort: "name",
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function getConfigPath(): string {
|
|
54
|
+
return CONFIG_PATH;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function resolveProviderPath(pathTemplate: string): string {
|
|
58
|
+
if (pathTemplate.startsWith("~/")) {
|
|
59
|
+
return join(HOME, pathTemplate.slice(2));
|
|
60
|
+
}
|
|
61
|
+
if (pathTemplate.startsWith("/")) {
|
|
62
|
+
return pathTemplate;
|
|
63
|
+
}
|
|
64
|
+
// Relative path — resolve from cwd (project-level)
|
|
65
|
+
return resolve(pathTemplate);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function mergeWithDefaults(config: Partial<AppConfig>): AppConfig {
|
|
69
|
+
const defaults = getDefaultConfig();
|
|
70
|
+
const providers = config.providers || [];
|
|
71
|
+
|
|
72
|
+
// Add any new default providers that don't exist in the saved config
|
|
73
|
+
const existingNames = new Set(providers.map((p) => p.name));
|
|
74
|
+
for (const defaultProvider of defaults.providers) {
|
|
75
|
+
if (!existingNames.has(defaultProvider.name)) {
|
|
76
|
+
providers.push({ ...defaultProvider });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
version: config.version ?? defaults.version,
|
|
82
|
+
providers,
|
|
83
|
+
customPaths: config.customPaths ?? [],
|
|
84
|
+
preferences: {
|
|
85
|
+
defaultScope:
|
|
86
|
+
config.preferences?.defaultScope ?? defaults.preferences.defaultScope,
|
|
87
|
+
defaultSort:
|
|
88
|
+
config.preferences?.defaultSort ?? defaults.preferences.defaultSort,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function loadConfig(): Promise<AppConfig> {
|
|
94
|
+
try {
|
|
95
|
+
const raw = await readFile(CONFIG_PATH, "utf-8");
|
|
96
|
+
const parsed = JSON.parse(raw);
|
|
97
|
+
return mergeWithDefaults(parsed);
|
|
98
|
+
} catch {
|
|
99
|
+
// Config doesn't exist or is invalid — use defaults
|
|
100
|
+
const config = getDefaultConfig();
|
|
101
|
+
await saveConfig(config);
|
|
102
|
+
return config;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function saveConfig(config: AppConfig): Promise<void> {
|
|
107
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
108
|
+
await writeFile(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
109
|
+
}
|