skillhelper 0.4.2

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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/bin/lib/atomic-write.mjs +72 -0
  4. package/bin/lib/paths.mjs +65 -0
  5. package/bin/lib/port.mjs +23 -0
  6. package/bin/skillhelper.mjs +720 -0
  7. package/build/build-site.mjs +35 -0
  8. package/build/build-web.mjs +29 -0
  9. package/build/pack-smoke.mjs +195 -0
  10. package/build/prepare-publish.mjs +3 -0
  11. package/build/verify.mjs +157 -0
  12. package/config/sources.example.yaml +126 -0
  13. package/docs/Frontend-Spec.md +1207 -0
  14. package/docs/scan_skills_rules.md +432 -0
  15. package/package.json +95 -0
  16. package/packages/scanner/package.json +15 -0
  17. package/packages/scanner/src/adapters/claude-agents.mjs +134 -0
  18. package/packages/scanner/src/adapters/claude-plugin.mjs +260 -0
  19. package/packages/scanner/src/adapters/codex-plugin.mjs +330 -0
  20. package/packages/scanner/src/adapters/directory-skill.mjs +239 -0
  21. package/packages/scanner/src/adapters/file-docs.mjs +158 -0
  22. package/packages/scanner/src/adapters/hermes-plugin.mjs +149 -0
  23. package/packages/scanner/src/adapters/markdown-skill.mjs +229 -0
  24. package/packages/scanner/src/adapters/mcp-config.mjs +190 -0
  25. package/packages/scanner/src/adapters/scan-tier.mjs +99 -0
  26. package/packages/scanner/src/adapters/skill-adapter.mjs +345 -0
  27. package/packages/scanner/src/adapters/tier1-editor-skills.mjs +278 -0
  28. package/packages/scanner/src/adapters/tier2-user-skills.mjs +218 -0
  29. package/packages/scanner/src/adapters/tier3-other-skills.mjs +225 -0
  30. package/packages/scanner/src/config/editor-tiers.mjs +191 -0
  31. package/packages/scanner/src/core/atomic-write.mjs +11 -0
  32. package/packages/scanner/src/core/descriptor.mjs +143 -0
  33. package/packages/scanner/src/core/path-hash.mjs +89 -0
  34. package/packages/scanner/src/core/registry.mjs +128 -0
  35. package/packages/scanner/src/hash/path-hash.mjs +8 -0
  36. package/packages/scanner/src/icon/brand-map.mjs +268 -0
  37. package/packages/scanner/src/icon/icon-extractor.mjs +466 -0
  38. package/packages/scanner/src/index.mjs +450 -0
  39. package/packages/scanner/src/types.d.ts +144 -0
  40. package/packages/scanner/src/utils.mjs +194 -0
  41. package/packages/server/package.json +15 -0
  42. package/packages/server/src/index.mjs +1071 -0
  43. package/packages/server/src/labels.mjs +64 -0
  44. package/packages/server/src/langdetect.mjs +34 -0
  45. package/packages/server/src/llm-client.mjs +42 -0
  46. package/packages/server/src/translate-cache.mjs +132 -0
  47. package/packages/server/src/translator.mjs +53 -0
  48. package/packages/web/README.md +36 -0
  49. package/packages/web/dist/assets/index-CGt04vt0.js +304 -0
  50. package/packages/web/dist/assets/index-CLSDoa3H.css +1 -0
  51. package/packages/web/dist/brand-icon.png +0 -0
  52. package/packages/web/dist/brand-logo.png +0 -0
  53. package/packages/web/dist/favicon-16x16.png +0 -0
  54. package/packages/web/dist/favicon-192x192.png +0 -0
  55. package/packages/web/dist/favicon-32x32.png +0 -0
  56. package/packages/web/dist/favicon-512x512.png +0 -0
  57. package/packages/web/dist/favicon-source.svg +5 -0
  58. package/packages/web/dist/favicon.ico +0 -0
  59. package/packages/web/dist/favicon.svg +5 -0
  60. package/packages/web/dist/icons/hermes-128.png +0 -0
  61. package/packages/web/dist/icons/hermes-192.png +0 -0
  62. package/packages/web/dist/icons/hermes-256.png +0 -0
  63. package/packages/web/dist/icons/hermes-32.png +0 -0
  64. package/packages/web/dist/icons/hermes-512.png +0 -0
  65. package/packages/web/dist/icons/hermes-64.png +0 -0
  66. package/packages/web/dist/icons/hermes.png +0 -0
  67. package/packages/web/dist/index.html +37 -0
  68. package/packages/web/dist/robots.txt +3 -0
  69. package/packages/web/dist/site.webmanifest +24 -0
  70. package/packages/web/public/brand-icon.png +0 -0
  71. package/packages/web/public/brand-logo.png +0 -0
  72. package/packages/web/public/favicon-16x16.png +0 -0
  73. package/packages/web/public/favicon-192x192.png +0 -0
  74. package/packages/web/public/favicon-32x32.png +0 -0
  75. package/packages/web/public/favicon-512x512.png +0 -0
  76. package/packages/web/public/favicon-source.svg +5 -0
  77. package/packages/web/public/favicon.ico +0 -0
  78. package/packages/web/public/favicon.svg +5 -0
  79. package/packages/web/public/icons/hermes-128.png +0 -0
  80. package/packages/web/public/icons/hermes-192.png +0 -0
  81. package/packages/web/public/icons/hermes-256.png +0 -0
  82. package/packages/web/public/icons/hermes-32.png +0 -0
  83. package/packages/web/public/icons/hermes-512.png +0 -0
  84. package/packages/web/public/icons/hermes-64.png +0 -0
  85. package/packages/web/public/icons/hermes.png +0 -0
  86. package/packages/web/public/robots.txt +3 -0
  87. package/packages/web/public/site.webmanifest +24 -0
  88. package/scripts/install-and-sync.sh +209 -0
  89. package/scripts/sync-skills.sh +605 -0
@@ -0,0 +1 @@
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:var(--font-sans);font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--font-mono);font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}*{--tw-border-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-border-opacity, 1))}html,body,#app{height:100%}body{--tw-bg-opacity: 1;background-color:hsl(var(--color-background) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:hsl(var(--color-foreground) / var(--tw-text-opacity, 1));font-family:var(--font-sans);-webkit-font-smoothing:antialiased}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.app-shell{display:grid;height:100%;grid-template-columns:240px 1fr;grid-template-rows:56px 1fr;grid-template-areas:"topbar topbar" "sidebar main"}.topbar{grid-area:topbar;display:flex;align-items:center;gap:1rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:hsl(var(--color-card) / var(--tw-bg-opacity, 1));padding-left:1rem;padding-right:1rem}.sidebar{grid-area:sidebar;display:flex;flex-direction:column;gap:.25rem;overflow-y:auto;border-right-width:1px;--tw-border-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-border-opacity, 1));padding:.75rem;background-color:hsl(var(--color-sidebar))}.main-pane{grid-area:main;overflow-y:auto;padding:1.5rem}.\!detail,.detail{border-radius:12px;border-width:1px;--tw-border-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:hsl(var(--color-card) / var(--tw-bg-opacity, 1));padding:1.5rem;--tw-text-opacity: 1;color:hsl(var(--color-card-foreground) / var(--tw-text-opacity, 1))}@media(max-width:900px){.app-shell{grid-template-columns:1fr;grid-template-rows:auto auto minmax(0,1fr);grid-template-areas:"topbar" "sidebar" "main"}.topbar{min-height:3.5rem;flex-wrap:wrap;gap:.5rem;padding:.5rem .75rem}.sidebar{flex-direction:row;gap:.25rem;overflow-x:auto;overflow-y:hidden;border-bottom-width:1px;border-right-width:0px;padding:.5rem}.sidebar>p{display:none}.sidebar>button{flex-shrink:0}.main-pane,.detail,.\!detail{padding:1rem}}.markdown-body{font-size:14px;line-height:20px;font-weight:400;line-height:1.625;--tw-text-opacity: 1;color:hsl(var(--color-card-foreground) / var(--tw-text-opacity, 1))}.markdown-body h1{margin-bottom:.5rem;margin-top:1.25rem;font-size:20px;line-height:28px;font-weight:600}.markdown-body h2{margin-bottom:.5rem;margin-top:1.25rem;font-size:16px;line-height:24px;font-weight:600}.markdown-body h3,.markdown-body h4{margin-bottom:.25rem;margin-top:1rem;font-size:14px;line-height:20px;font-weight:600}.markdown-body p{margin-top:.5rem;margin-bottom:.5rem}.markdown-body ul{margin-top:.5rem;margin-bottom:.5rem;list-style-type:disc;padding-left:1.25rem}.markdown-body ol{margin-top:.5rem;margin-bottom:.5rem;list-style-type:decimal;padding-left:1.25rem}.markdown-body li{margin-top:.25rem;margin-bottom:.25rem}.markdown-body a{--tw-text-opacity: 1;color:hsl(var(--color-primary) / var(--tw-text-opacity, 1));text-decoration-line:underline}.markdown-body code{border-radius:4px;--tw-bg-opacity: 1;background-color:hsl(var(--color-muted) / var(--tw-bg-opacity, 1));padding:.125rem .25rem;font-family:var(--font-mono);font-size:12px;line-height:18px;font-weight:400}.markdown-body pre{margin-top:.75rem;margin-bottom:.75rem;overflow-x:auto;border-radius:8px;--tw-bg-opacity: 1;background-color:hsl(var(--color-muted) / var(--tw-bg-opacity, 1));padding:.75rem}.markdown-body pre code{background-color:transparent;padding:0;font-size:12px;line-height:18px;font-weight:400}.markdown-body blockquote{margin-top:.5rem;margin-bottom:.5rem;border-left-width:2px;--tw-border-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-border-opacity, 1));padding-left:.75rem;--tw-text-opacity: 1;color:hsl(var(--color-muted-foreground) / var(--tw-text-opacity, 1))}.markdown-body hr{margin-top:1rem;margin-bottom:1rem;--tw-border-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-border-opacity, 1))}.markdown-body table{margin-top:.75rem;margin-bottom:.75rem;width:100%;border-collapse:collapse;font-size:12px;line-height:18px;font-weight:400}.markdown-body th,.markdown-body td{border-width:1px;--tw-border-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-border-opacity, 1));padding:.25rem .5rem;text-align:left}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.left-2\.5{left:.625rem}.left-3{left:.75rem}.top-0{top:0}.top-0\.5{top:.125rem}.top-1\/2{top:50%}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.mt-6{margin-top:1.5rem}.mt-auto{margin-top:auto}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.\!block{display:block!important}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-full{height:100%}.max-h-80{max-height:20rem}.max-h-\[32rem\]{max-height:32rem}.max-h-full{max-height:100%}.min-h-0{min-height:0px}.min-h-48{min-height:12rem}.min-h-full{min-height:100%}.w-1\.5{width:.375rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-5{width:1.25rem}.w-64{width:16rem}.w-9{width:2.25rem}.w-\[8\.25rem\]{width:8.25rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[12rem\]{min-width:12rem}.max-w-3xl{max-width:48rem}.max-w-\[1440px\]{max-width:1440px}.max-w-lg{max-width:32rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0\.5{--tw-translate-x: .125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-5{--tw-translate-x: 1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-border>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-\[4px\]{border-radius:4px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:12px}.rounded-md{border-radius:8px}.rounded-sm{border-radius:4px}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-500\/25{border-color:#f59e0b40}.border-border{--tw-border-opacity: 1;border-color:hsl(var(--color-border) / var(--tw-border-opacity, 1))}.border-destructive{--tw-border-opacity: 1;border-color:hsl(var(--color-destructive) / var(--tw-border-opacity, 1))}.border-destructive\/25{border-color:hsl(var(--color-destructive) / .25)}.border-destructive\/30{border-color:hsl(var(--color-destructive) / .3)}.border-emerald-500\/25{border-color:#10b98140}.border-input{--tw-border-opacity: 1;border-color:hsl(var(--color-input) / var(--tw-border-opacity, 1))}.border-primary{--tw-border-opacity: 1;border-color:hsl(var(--color-primary) / var(--tw-border-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-background{--tw-bg-opacity: 1;background-color:hsl(var(--color-background) / var(--tw-bg-opacity, 1))}.bg-background\/60{background-color:hsl(var(--color-background) / .6)}.bg-card{--tw-bg-opacity: 1;background-color:hsl(var(--color-card) / var(--tw-bg-opacity, 1))}.bg-card\/60{background-color:hsl(var(--color-card) / .6)}.bg-destructive{--tw-bg-opacity: 1;background-color:hsl(var(--color-destructive) / var(--tw-bg-opacity, 1))}.bg-destructive\/10{background-color:hsl(var(--color-destructive) / .1)}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-500\/10{background-color:#10b9811a}.bg-input{--tw-bg-opacity: 1;background-color:hsl(var(--color-input) / var(--tw-bg-opacity, 1))}.bg-muted{--tw-bg-opacity: 1;background-color:hsl(var(--color-muted) / var(--tw-bg-opacity, 1))}.bg-muted-foreground\/10{background-color:hsl(var(--color-muted-foreground) / .1)}.bg-muted-foreground\/50{background-color:hsl(var(--color-muted-foreground) / .5)}.bg-muted\/20{background-color:hsl(var(--color-muted) / .2)}.bg-muted\/60{background-color:hsl(var(--color-muted) / .6)}.bg-primary{--tw-bg-opacity: 1;background-color:hsl(var(--color-primary) / var(--tw-bg-opacity, 1))}.bg-primary-soft{--tw-bg-opacity: 1;background-color:hsl(var(--color-primary-soft) / var(--tw-bg-opacity, 1))}.bg-secondary{--tw-bg-opacity: 1;background-color:hsl(var(--color-secondary) / var(--tw-bg-opacity, 1))}.bg-sidebar{--tw-bg-opacity: 1;background-color:hsl(var(--color-sidebar) / var(--tw-bg-opacity, 1))}.bg-sky-500\/10{background-color:#0ea5e91a}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-1{padding-bottom:.25rem}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pb-5{padding-bottom:1.25rem}.pl-12{padding-left:3rem}.pl-6{padding-left:1.5rem}.pl-8{padding-left:2rem}.pl-9{padding-left:2.25rem}.pr-2{padding-right:.5rem}.pr-3{padding-right:.75rem}.pt-0{padding-top:0}.pt-3{padding-top:.75rem}.pt-5{padding-top:1.25rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:var(--font-mono)}.text-\[11px\]{font-size:11px}.text-body{font-size:16px;line-height:24px;font-weight:400}.text-body-sm{font-size:14px;line-height:20px;font-weight:400}.text-caption{font-size:12px;line-height:18px;font-weight:400}.text-h3{font-size:24px;line-height:32px;font-weight:600}.text-h4{font-size:20px;line-height:28px;font-weight:600}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-\[0\.08em\]{letter-spacing:.08em}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-card-foreground{--tw-text-opacity: 1;color:hsl(var(--color-card-foreground) / var(--tw-text-opacity, 1))}.text-destructive{--tw-text-opacity: 1;color:hsl(var(--color-destructive) / var(--tw-text-opacity, 1))}.text-destructive-foreground{--tw-text-opacity: 1;color:hsl(var(--color-destructive-foreground) / var(--tw-text-opacity, 1))}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-foreground{--tw-text-opacity: 1;color:hsl(var(--color-foreground) / var(--tw-text-opacity, 1))}.text-muted{--tw-text-opacity: 1;color:hsl(var(--color-muted) / var(--tw-text-opacity, 1))}.text-muted-foreground{--tw-text-opacity: 1;color:hsl(var(--color-muted-foreground) / var(--tw-text-opacity, 1))}.text-muted-foreground\/70{color:hsl(var(--color-muted-foreground) / .7)}.text-primary{--tw-text-opacity: 1;color:hsl(var(--color-primary) / var(--tw-text-opacity, 1))}.text-primary-foreground{--tw-text-opacity: 1;color:hsl(var(--color-primary-foreground) / var(--tw-text-opacity, 1))}.text-primary-foreground\/80{color:hsl(var(--color-primary-foreground) / .8)}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-secondary-foreground{--tw-text-opacity: 1;color:hsl(var(--color-secondary-foreground) / var(--tw-text-opacity, 1))}.text-sky-700{--tw-text-opacity: 1;color:rgb(3 105 161 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.underline-offset-2{text-underline-offset:2px}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-border\/30{--tw-shadow-color: hsl(var(--color-border) / .3);--tw-shadow: var(--tw-shadow-colored)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.line-clamp-2{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}:root{--color-background: 220 20% 98%;--color-foreground: 220 9% 12%;--color-card: 0 0% 100%;--color-card-foreground: 220 9% 12%;--color-sidebar: 210 20% 99%;--color-border: 220 16% 94%;--color-input: 220 13% 96%;--color-ring: 215 100% 46%;--color-primary: 215 100% 46%;--color-primary-foreground: 0 0% 100%;--color-primary-soft: 215 100% 96%;--color-secondary: 217 33% 17%;--color-secondary-foreground: 210 40% 96%;--color-destructive: 0 84% 60%;--color-destructive-foreground: 0 0% 100%;--color-muted: 220 13% 95%;--color-muted-foreground: 217 11% 45%;--color-accent: 38 92% 50%;--color-accent-foreground: 220 9% 12%;--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--font-mono: "SF Mono", "JetBrains Mono", "Fira Code", Menlo, Consolas, monospace}.dark{--color-background: 222 47% 11%;--color-foreground: 210 40% 96%;--color-card: 217 33% 14%;--color-card-foreground: 210 40% 96%;--color-sidebar: 222 33% 13%;--color-border: 217 33% 20%;--color-input: 217 33% 17%;--color-ring: 215 100% 46%;--color-primary: 215 100% 46%;--color-primary-foreground: 0 0% 100%;--color-primary-soft: 217 40% 20%;--color-secondary: 210 40% 96%;--color-secondary-foreground: 217 33% 17%;--color-destructive: 0 84% 60%;--color-destructive-foreground: 0 0% 100%;--color-muted: 217 33% 17%;--color-muted-foreground: 215 14% 65%;--color-accent: 38 92% 50%;--color-accent-foreground: 220 9% 12%}.placeholder\:text-muted-foreground::-moz-placeholder{--tw-text-opacity: 1;color:hsl(var(--color-muted-foreground) / var(--tw-text-opacity, 1))}.placeholder\:text-muted-foreground::placeholder{--tw-text-opacity: 1;color:hsl(var(--color-muted-foreground) / var(--tw-text-opacity, 1))}.last\:border-b-0:last-child{border-bottom-width:0px}.hover\:border-primary:hover{--tw-border-opacity: 1;border-color:hsl(var(--color-primary) / var(--tw-border-opacity, 1))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--color-destructive) / .9)}.hover\:bg-muted:hover{--tw-bg-opacity: 1;background-color:hsl(var(--color-muted) / var(--tw-bg-opacity, 1))}.hover\:bg-muted\/40:hover{background-color:hsl(var(--color-muted) / .4)}.hover\:bg-muted\/60:hover{background-color:hsl(var(--color-muted) / .6)}.hover\:bg-muted\/70:hover{background-color:hsl(var(--color-muted) / .7)}.hover\:bg-primary-soft:hover{--tw-bg-opacity: 1;background-color:hsl(var(--color-primary-soft) / var(--tw-bg-opacity, 1))}.hover\:bg-primary-soft\/40:hover{background-color:hsl(var(--color-primary-soft) / .4)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--color-primary) / .9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--color-secondary) / .8)}.hover\:text-foreground:hover{--tw-text-opacity: 1;color:hsl(var(--color-foreground) / var(--tw-text-opacity, 1))}.hover\:text-primary:hover{--tw-text-opacity: 1;color:hsl(var(--color-primary) / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-primary\/50:focus{--tw-ring-color: hsl(var(--color-primary) / .5)}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: hsl(var(--color-ring) / var(--tw-ring-opacity, 1))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.group:hover .group-hover\:translate-x-1{--tw-translate-x: .25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.dark\:text-amber-300:is(.dark *){--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.dark\:text-emerald-300:is(.dark *){--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.dark\:text-sky-300:is(.dark *){--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity, 1))}@media(min-width:640px){.sm\:flex{display:flex}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-start{align-items:flex-start}.sm\:justify-between{justify-content:space-between}}@media(min-width:768px){.md\:block{display:block}.md\:inline-flex{display:inline-flex}.md\:w-64{width:16rem}.md\:w-72{width:18rem}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-\[1fr_auto\]{grid-template-columns:1fr auto}.md\:flex-row{flex-direction:row}.md\:items-start{align-items:flex-start}.md\:items-center{align-items:center}.md\:justify-between{justify-content:space-between}}@media(min-width:1024px){.lg\:flex{display:flex}.lg\:w-80{width:20rem}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-\[320px_minmax\(0\,1fr\)\]{grid-template-columns:320px minmax(0,1fr)}.lg\:grid-cols-\[minmax\(160px\,0\.8fr\)_minmax\(0\,1\.4fr\)\]{grid-template-columns:minmax(160px,.8fr) minmax(0,1.4fr)}.lg\:grid-cols-\[minmax\(180px\,0\.9fr\)_minmax\(0\,1\.4fr\)\]{grid-template-columns:minmax(180px,.9fr) minmax(0,1.4fr)}.lg\:grid-cols-\[minmax\(240px\,1\.4fr\)_minmax\(160px\,0\.7fr\)_minmax\(140px\,0\.6fr\)\]{grid-template-columns:minmax(240px,1.4fr) minmax(160px,.7fr) minmax(140px,.6fr)}.lg\:flex-row{flex-direction:row}.lg\:items-end{align-items:flex-end}.lg\:justify-between{justify-content:space-between}}@media(min-width:1280px){.xl\:block{display:block}.xl\:w-\[420px\]{width:420px}.xl\:w-\[9rem\]{width:9rem}.xl\:min-w-\[620px\]{min-width:620px}.xl\:max-w-xl{max-width:36rem}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-\[minmax\(0\,1\.15fr\)_minmax\(320px\,0\.85fr\)\]{grid-template-columns:minmax(0,1.15fr) minmax(320px,.85fr)}.xl\:grid-cols-\[minmax\(0\,1fr\)_300px\]{grid-template-columns:minmax(0,1fr) 300px}.xl\:grid-cols-\[minmax\(0\,1fr\)_360px\]{grid-template-columns:minmax(0,1fr) 360px}.xl\:grid-cols-\[minmax\(220px\,0\.9fr\)_minmax\(260px\,1fr\)_minmax\(280px\,1\.1fr\)\]{grid-template-columns:minmax(220px,.9fr) minmax(260px,1fr) minmax(280px,1.1fr)}.xl\:flex-row{flex-direction:row}.xl\:items-start{align-items:flex-start}.xl\:items-center{align-items:center}.xl\:justify-between{justify-content:space-between}}@media(min-width:1536px){.\32xl\:block{display:block}.\32xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.\32xl\:grid-cols-\[340px_minmax\(0\,1fr\)\]{grid-template-columns:340px minmax(0,1fr)}.\32xl\:grid-cols-\[340px_minmax\(0\,1fr\)_300px\]{grid-template-columns:340px minmax(0,1fr) 300px}}
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="192" height="192" viewBox="0 0 192 192" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <rect width="192" height="192" rx="48" fill="#7c3aed"/>
4
+ <text x="96" y="120" font-size="100" font-weight="bold" fill="white" text-anchor="middle" font-family="system-ui">🛠</text>
5
+ </svg>
Binary file
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="呼哈哈-技能助手">
2
+ <rect x="3" y="3" width="26" height="26" rx="7" fill="#202326"/>
3
+ <path d="M10 12v7.2a6 6 0 0 0 12 0V12" fill="none" stroke="#f6b51d" stroke-width="4.2" stroke-linecap="round"/>
4
+ <path d="M10 12v4.2M22 12v4.2" fill="none" stroke="#fff" stroke-width="4.2" stroke-linecap="round"/>
5
+ </svg>
@@ -0,0 +1,37 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>呼哈哈-技能助手</title>
7
+
8
+ <!-- Favicon -->
9
+ <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
10
+ <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
11
+ <link rel="apple-touch-icon" href="/favicon-192x192.png" />
12
+ <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
13
+
14
+ <!-- PWA -->
15
+ <link rel="manifest" href="/site.webmanifest" />
16
+ <meta name="theme-color" content="#3B82F6" />
17
+ <meta name="description" content="呼哈哈-技能助手:本地技能 / 插件 / MCP 聚合中心" />
18
+
19
+ <!-- 防止暗色模式首屏闪烁:渲染前读取偏好并应用 .dark -->
20
+ <script>
21
+ (function () {
22
+ try {
23
+ var t = localStorage.getItem('skillhelper-theme');
24
+ var dark =
25
+ t === 'dark' ||
26
+ (!t && window.matchMedia('(prefers-color-scheme: dark)').matches);
27
+ if (dark) document.documentElement.classList.add('dark');
28
+ } catch (e) {}
29
+ })();
30
+ </script>
31
+ <script type="module" crossorigin src="/assets/index-CGt04vt0.js"></script>
32
+ <link rel="stylesheet" crossorigin href="/assets/index-CLSDoa3H.css">
33
+ </head>
34
+ <body>
35
+ <div id="app"></div>
36
+ </body>
37
+ </html>
@@ -0,0 +1,3 @@
1
+ User-agent: *
2
+ Allow: /
3
+ Disallow: /api
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "呼哈哈-技能助手",
3
+ "short_name": "呼哈哈",
4
+ "description": "呼哈哈-技能助手:本地技能 / 插件 / MCP 聚合中心",
5
+ "start_url": "/",
6
+ "display": "standalone",
7
+ "background_color": "#ffffff",
8
+ "theme_color": "#3B82F6",
9
+ "orientation": "portrait-primary",
10
+ "icons": [
11
+ {
12
+ "src": "/favicon-192x192.png",
13
+ "sizes": "192x192",
14
+ "type": "image/png",
15
+ "purpose": "any"
16
+ },
17
+ {
18
+ "src": "/favicon-512x512.png",
19
+ "sizes": "512x512",
20
+ "type": "image/png",
21
+ "purpose": "any"
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="192" height="192" viewBox="0 0 192 192" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <rect width="192" height="192" rx="48" fill="#7c3aed"/>
4
+ <text x="96" y="120" font-size="100" font-weight="bold" fill="white" text-anchor="middle" font-family="system-ui">🛠</text>
5
+ </svg>
Binary file
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="呼哈哈-技能助手">
2
+ <rect x="3" y="3" width="26" height="26" rx="7" fill="#202326"/>
3
+ <path d="M10 12v7.2a6 6 0 0 0 12 0V12" fill="none" stroke="#f6b51d" stroke-width="4.2" stroke-linecap="round"/>
4
+ <path d="M10 12v4.2M22 12v4.2" fill="none" stroke="#fff" stroke-width="4.2" stroke-linecap="round"/>
5
+ </svg>
@@ -0,0 +1,3 @@
1
+ User-agent: *
2
+ Allow: /
3
+ Disallow: /api
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "呼哈哈-技能助手",
3
+ "short_name": "呼哈哈",
4
+ "description": "呼哈哈-技能助手:本地技能 / 插件 / MCP 聚合中心",
5
+ "start_url": "/",
6
+ "display": "standalone",
7
+ "background_color": "#ffffff",
8
+ "theme_color": "#3B82F6",
9
+ "orientation": "portrait-primary",
10
+ "icons": [
11
+ {
12
+ "src": "/favicon-192x192.png",
13
+ "sizes": "192x192",
14
+ "type": "image/png",
15
+ "purpose": "any"
16
+ },
17
+ {
18
+ "src": "/favicon-512x512.png",
19
+ "sizes": "512x512",
20
+ "type": "image/png",
21
+ "purpose": "any"
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,209 @@
1
+ #!/bin/bash
2
+
3
+ ###############################################################################
4
+ # 呼哈哈-技能助手远程安装与技能同步入口 (v0.1.5)
5
+ #
6
+ # 用法:
7
+ # curl -fsSL https://raw.githubusercontent.com/aquarkgn/SkillsHelper/main/install-and-sync.sh | bash
8
+ # 或
9
+ # curl -fsSL https://raw.githubusercontent.com/aquarkgn/SkillsHelper/main/install-and-sync.sh | bash -s -- --sync-only
10
+ #
11
+ # 参数:
12
+ # --sync-only 只执行同步,不安装
13
+ # --local PATH 使用本地项目路径
14
+ # --branch NAME 指定分支(默认 main)
15
+ #
16
+ ###############################################################################
17
+
18
+ set -euo pipefail
19
+
20
+ # 配置
21
+ REPO_URL="https://github.com/aquarkgn/SkillsHelper.git"
22
+ REPO_RAW="https://raw.githubusercontent.com/aquarkgn/SkillsHelper"
23
+ BRANCH="main"
24
+ SYNC_ONLY=false
25
+ LOCAL_PATH=""
26
+
27
+ # 颜色定义
28
+ readonly BLUE='\033[0;34m'
29
+ readonly GREEN='\033[0;32m'
30
+ readonly YELLOW='\033[1;33m'
31
+ readonly RED='\033[0;31m'
32
+ readonly CYAN='\033[0;36m'
33
+ readonly NC='\033[0m'
34
+
35
+ # 日志函数
36
+ log_info() { echo -e "${BLUE}ℹ${NC} $*"; }
37
+ log_success() { echo -e "${GREEN}✓${NC} $*"; }
38
+ log_warn() { echo -e "${YELLOW}⚠${NC} $*"; }
39
+ log_error() { echo -e "${RED}✗${NC} $*" >&2; }
40
+
41
+ # 解析命令行参数
42
+ parse_args() {
43
+ while [[ $# -gt 0 ]]; do
44
+ case "$1" in
45
+ --sync-only)
46
+ SYNC_ONLY=true
47
+ shift
48
+ ;;
49
+ --local)
50
+ LOCAL_PATH="$2"
51
+ SYNC_ONLY=true
52
+ shift 2
53
+ ;;
54
+ --branch)
55
+ BRANCH="$2"
56
+ shift 2
57
+ ;;
58
+ *)
59
+ log_error "未知参数: $1"
60
+ exit 1
61
+ ;;
62
+ esac
63
+ done
64
+ }
65
+
66
+ # 获取临时目录
67
+ get_temp_dir() {
68
+ if command -v mktemp &>/dev/null; then
69
+ mktemp -d
70
+ else
71
+ local tmpdir="/tmp/skillhelper-$$"
72
+ mkdir -p "$tmpdir"
73
+ echo "$tmpdir"
74
+ fi
75
+ }
76
+
77
+ # 检查依赖
78
+ check_deps() {
79
+ if ! command -v curl &>/dev/null; then
80
+ log_error "需要 curl,请先安装"
81
+ exit 1
82
+ fi
83
+
84
+ if ! $SYNC_ONLY && ! command -v git &>/dev/null; then
85
+ log_error "需要 git,请先安装"
86
+ exit 1
87
+ fi
88
+ }
89
+
90
+ # 下载并执行同步脚本
91
+ download_and_sync() {
92
+ local sync_script_url="$REPO_RAW/$BRANCH/scripts/sync-skills.sh"
93
+
94
+ log_info "下载同步脚本..."
95
+
96
+ local temp_script
97
+ temp_script=$(mktemp)
98
+ trap "rm -f '$temp_script'" EXIT
99
+
100
+ if ! curl -fsSL "$sync_script_url" -o "$temp_script"; then
101
+ log_error "下载失败: $sync_script_url"
102
+ return 1
103
+ fi
104
+
105
+ if [[ -n "$LOCAL_PATH" ]]; then
106
+ export SKILLHELPER_LOCAL_PATH="$LOCAL_PATH"
107
+ fi
108
+
109
+ log_success "同步脚本已下载"
110
+
111
+ # 执行同步脚本
112
+ bash "$temp_script"
113
+ }
114
+
115
+ # 本地安装(git clone)
116
+ local_install() {
117
+ local temp_dir
118
+ temp_dir=$(get_temp_dir)
119
+ trap "rm -rf '$temp_dir'" EXIT
120
+
121
+ log_info "克隆项目仓库..."
122
+
123
+ if ! git clone --depth 1 --branch "$BRANCH" "$REPO_URL" "$temp_dir"; then
124
+ log_error "克隆失败"
125
+ return 1
126
+ fi
127
+
128
+ local_path="$temp_dir"
129
+ log_success "项目已克隆到临时目录"
130
+
131
+ # 执行同步
132
+ export SKILLHELPER_LOCAL_PATH="$local_path"
133
+ download_and_sync
134
+ }
135
+
136
+ # 检查 npm 全局安装
137
+ npm_install() {
138
+ if ! command -v npm &>/dev/null; then
139
+ log_warn "未安装 npm,跳过全局安装"
140
+ return 0
141
+ fi
142
+
143
+ log_info "正在进行 npm 全局安装..."
144
+
145
+ if npm install -g "github:aquarkgn/SkillsHelper#$BRANCH"; then
146
+ log_success "npm 全局安装完成"
147
+
148
+ # 获取安装位置
149
+ local npm_prefix
150
+ npm_prefix=$(npm prefix -g)
151
+ export SKILLHELPER_LOCAL_PATH="$npm_prefix/node_modules/skillhelper"
152
+
153
+ return 0
154
+ else
155
+ log_warn "npm 全局安装失败,将使用远程脚本"
156
+ return 1
157
+ fi
158
+ }
159
+
160
+ # 主函数
161
+ main() {
162
+ echo -e "\n${CYAN}╔════════════════════════════════════════════════════════╗${NC}"
163
+ echo -e "${CYAN}║ 呼哈哈-技能助手 v0.1.5 - 编辑器技能自动同步 ║${NC}"
164
+ echo -e "${CYAN}╚════════════════════════════════════════════════════════╝${NC}\n"
165
+
166
+ parse_args "$@"
167
+ check_deps
168
+
169
+ if $SYNC_ONLY; then
170
+ log_info "执行同步模式"
171
+ if [[ -z "$LOCAL_PATH" ]]; then
172
+ # 只下载并执行远程脚本
173
+ download_and_sync
174
+ else
175
+ # 使用本地路径
176
+ if [[ ! -d "$LOCAL_PATH" ]]; then
177
+ log_error "本地路径不存在: $LOCAL_PATH"
178
+ exit 1
179
+ fi
180
+ export SKILLHELPER_LOCAL_PATH="$LOCAL_PATH"
181
+ download_and_sync
182
+ fi
183
+ else
184
+ log_info "执行完整安装 + 同步流程"
185
+
186
+ # 尝试 npm 全局安装
187
+ if ! npm_install; then
188
+ # 如果 npm 安装失败,使用 git clone
189
+ log_info "使用 git clone 方式安装"
190
+ local_install
191
+ else
192
+ # npm 安装成功,执行同步
193
+ download_and_sync
194
+ fi
195
+ fi
196
+
197
+ echo -e "\n${GREEN}╔════════════════════════════════════════════════════════╗${NC}"
198
+ echo -e "${GREEN}║ ✨ 同步完成! ✨ ║${NC}"
199
+ echo -e "${GREEN}╚════════════════════════════════════════════════════════╝${NC}\n"
200
+
201
+ log_info "后续步骤:"
202
+ echo " 1. 启动 SkillHelper: npm start"
203
+ echo " 2. 查看技能中心: http://localhost:11520"
204
+ echo " 3. 在编辑器中使用你的技能"
205
+ echo -e "\n更多信息: https://github.com/aquarkgn/SkillsHelper\n"
206
+ }
207
+
208
+ # 执行主程序
209
+ main "$@"