linguclaw 0.4.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/LICENSE +21 -0
- package/README.md +161 -0
- package/dist/agent-system.d.ts +196 -0
- package/dist/agent-system.d.ts.map +1 -0
- package/dist/agent-system.js +738 -0
- package/dist/agent-system.js.map +1 -0
- package/dist/alphabeta.d.ts +54 -0
- package/dist/alphabeta.d.ts.map +1 -0
- package/dist/alphabeta.js +193 -0
- package/dist/alphabeta.js.map +1 -0
- package/dist/browser.d.ts +62 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +224 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +565 -0
- package/dist/cli.js.map +1 -0
- package/dist/code-parser.d.ts +39 -0
- package/dist/code-parser.d.ts.map +1 -0
- package/dist/code-parser.js +385 -0
- package/dist/code-parser.js.map +1 -0
- package/dist/config.d.ts +66 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +232 -0
- package/dist/config.js.map +1 -0
- package/dist/core/engine.d.ts +359 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +127 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/daemon.d.ts +29 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +212 -0
- package/dist/daemon.js.map +1 -0
- package/dist/email-receiver.d.ts +63 -0
- package/dist/email-receiver.d.ts.map +1 -0
- package/dist/email-receiver.js +553 -0
- package/dist/email-receiver.js.map +1 -0
- package/dist/git-integration.d.ts +180 -0
- package/dist/git-integration.d.ts.map +1 -0
- package/dist/git-integration.js +850 -0
- package/dist/git-integration.js.map +1 -0
- package/dist/inbox.d.ts +84 -0
- package/dist/inbox.d.ts.map +1 -0
- package/dist/inbox.js +198 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/languages/cpp.d.ts +51 -0
- package/dist/languages/cpp.d.ts.map +1 -0
- package/dist/languages/cpp.js +930 -0
- package/dist/languages/cpp.js.map +1 -0
- package/dist/languages/csharp.d.ts +79 -0
- package/dist/languages/csharp.d.ts.map +1 -0
- package/dist/languages/csharp.js +1776 -0
- package/dist/languages/csharp.js.map +1 -0
- package/dist/languages/go.d.ts +50 -0
- package/dist/languages/go.d.ts.map +1 -0
- package/dist/languages/go.js +882 -0
- package/dist/languages/go.js.map +1 -0
- package/dist/languages/java.d.ts +47 -0
- package/dist/languages/java.d.ts.map +1 -0
- package/dist/languages/java.js +649 -0
- package/dist/languages/java.js.map +1 -0
- package/dist/languages/python.d.ts +47 -0
- package/dist/languages/python.d.ts.map +1 -0
- package/dist/languages/python.js +655 -0
- package/dist/languages/python.js.map +1 -0
- package/dist/languages/rust.d.ts +61 -0
- package/dist/languages/rust.d.ts.map +1 -0
- package/dist/languages/rust.js +1064 -0
- package/dist/languages/rust.js.map +1 -0
- package/dist/logger.d.ts +20 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +133 -0
- package/dist/logger.js.map +1 -0
- package/dist/longterm-memory.d.ts +47 -0
- package/dist/longterm-memory.d.ts.map +1 -0
- package/dist/longterm-memory.js +300 -0
- package/dist/longterm-memory.js.map +1 -0
- package/dist/memory.d.ts +42 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +274 -0
- package/dist/memory.js.map +1 -0
- package/dist/messaging.d.ts +103 -0
- package/dist/messaging.d.ts.map +1 -0
- package/dist/messaging.js +645 -0
- package/dist/messaging.js.map +1 -0
- package/dist/multi-provider.d.ts +69 -0
- package/dist/multi-provider.d.ts.map +1 -0
- package/dist/multi-provider.js +484 -0
- package/dist/multi-provider.js.map +1 -0
- package/dist/orchestrator.d.ts +65 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +441 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/plugins.d.ts +52 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +215 -0
- package/dist/plugins.js.map +1 -0
- package/dist/prism-orchestrator.d.ts +26 -0
- package/dist/prism-orchestrator.d.ts.map +1 -0
- package/dist/prism-orchestrator.js +191 -0
- package/dist/prism-orchestrator.js.map +1 -0
- package/dist/prism.d.ts +46 -0
- package/dist/prism.d.ts.map +1 -0
- package/dist/prism.js +188 -0
- package/dist/prism.js.map +1 -0
- package/dist/privacy.d.ts +23 -0
- package/dist/privacy.d.ts.map +1 -0
- package/dist/privacy.js +220 -0
- package/dist/privacy.js.map +1 -0
- package/dist/proactive.d.ts +30 -0
- package/dist/proactive.d.ts.map +1 -0
- package/dist/proactive.js +260 -0
- package/dist/proactive.js.map +1 -0
- package/dist/refactoring-engine.d.ts +100 -0
- package/dist/refactoring-engine.d.ts.map +1 -0
- package/dist/refactoring-engine.js +717 -0
- package/dist/refactoring-engine.js.map +1 -0
- package/dist/resilience.d.ts +43 -0
- package/dist/resilience.d.ts.map +1 -0
- package/dist/resilience.js +200 -0
- package/dist/resilience.js.map +1 -0
- package/dist/safety.d.ts +40 -0
- package/dist/safety.d.ts.map +1 -0
- package/dist/safety.js +133 -0
- package/dist/safety.js.map +1 -0
- package/dist/sandbox.d.ts +33 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +173 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/scheduler.d.ts +72 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +374 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/semantic-memory.d.ts +70 -0
- package/dist/semantic-memory.d.ts.map +1 -0
- package/dist/semantic-memory.js +430 -0
- package/dist/semantic-memory.js.map +1 -0
- package/dist/skills.d.ts +97 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +575 -0
- package/dist/skills.js.map +1 -0
- package/dist/static/dashboard.html +853 -0
- package/dist/static/hub.html +772 -0
- package/dist/static/index.html +818 -0
- package/dist/static/logo.svg +24 -0
- package/dist/static/workflow-editor.html +913 -0
- package/dist/tools.d.ts +67 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +303 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +295 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +90 -0
- package/dist/types.js.map +1 -0
- package/dist/web.d.ts +76 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +2139 -0
- package/dist/web.js.map +1 -0
- package/dist/workflow-engine.d.ts +114 -0
- package/dist/workflow-engine.d.ts.map +1 -0
- package/dist/workflow-engine.js +855 -0
- package/dist/workflow-engine.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,772 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>ClawLing Hub — Community Skills Marketplace</title>
|
|
7
|
+
<meta name="description" content="Discover, share, and install community-built skills for LinguClaw. Browse automation, AI, data, and messaging skills.">
|
|
8
|
+
<meta property="og:title" content="ClawLing Hub — Community Skills Marketplace">
|
|
9
|
+
<meta property="og:description" content="Browse, create, and share AI skills for the LinguClaw multi-agent system.">
|
|
10
|
+
<link rel="icon" type="image/svg+xml" href="logo.svg">
|
|
11
|
+
<style>
|
|
12
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap');
|
|
13
|
+
:root{--bg:#06060a;--bg1:#0c0c12;--bg2:#12121a;--bg3:#1a1a24;--border:#1e1e2a;--accent:#6c5ce7;--accent2:#a29bfe;--accent3:#5b4cdb;--glow:rgba(108,92,231,.18);--glow2:rgba(108,92,231,.06);--green:#00e676;--cyan:#18ffff;--pink:#ff6b9d;--orange:#ffa726;--yellow:#ffee58;--text:#eeeef0;--dim:#9e9eb0;--muted:#5e5e72;--r:12px;--r2:20px;--r3:28px}
|
|
14
|
+
*{box-sizing:border-box;margin:0;padding:0}
|
|
15
|
+
html{scroll-behavior:smooth;overflow-x:hidden}
|
|
16
|
+
body{font-family:'Inter',system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.6;-webkit-font-smoothing:antialiased}
|
|
17
|
+
::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}
|
|
18
|
+
::selection{background:var(--accent);color:#fff}
|
|
19
|
+
a{color:inherit;text-decoration:none;transition:color .2s}
|
|
20
|
+
code,pre{font-family:'JetBrains Mono',monospace}
|
|
21
|
+
|
|
22
|
+
/* animations */
|
|
23
|
+
@keyframes gradient-shift{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}
|
|
24
|
+
@keyframes slide-up{from{opacity:0;transform:translateY(40px)}to{opacity:1;transform:translateY(0)}}
|
|
25
|
+
@keyframes morph{0%,100%{border-radius:60% 40% 30% 70%/60% 30% 70% 40%}50%{border-radius:30% 60% 70% 40%/50% 60% 30% 60%}}
|
|
26
|
+
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
|
|
27
|
+
.reveal{opacity:0;transform:translateY(30px);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1)}.reveal.visible{opacity:1;transform:translateY(0)}
|
|
28
|
+
.reveal-left{opacity:0;transform:translateX(-40px);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1)}.reveal-left.visible{opacity:1;transform:translateX(0)}
|
|
29
|
+
.reveal-right{opacity:0;transform:translateX(40px);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1)}.reveal-right.visible{opacity:1;transform:translateX(0)}
|
|
30
|
+
.d1{transition-delay:.1s}.d2{transition-delay:.2s}.d3{transition-delay:.3s}.d4{transition-delay:.4s}.d5{transition-delay:.5s}.d6{transition-delay:.6s}
|
|
31
|
+
|
|
32
|
+
.container{max-width:1200px;margin:0 auto;padding:0 24px}
|
|
33
|
+
section{padding:120px 0;position:relative;overflow:hidden}
|
|
34
|
+
|
|
35
|
+
/* navbar */
|
|
36
|
+
.navbar{position:fixed;top:0;left:0;right:0;z-index:1000;padding:14px 0;transition:all .35s ease}
|
|
37
|
+
.navbar.scrolled{background:rgba(6,6,10,.88);backdrop-filter:blur(20px) saturate(1.4);border-bottom:1px solid var(--border);padding:10px 0}
|
|
38
|
+
.nav-inner{display:flex;align-items:center;justify-content:space-between}
|
|
39
|
+
.nav-brand{display:flex;align-items:center;gap:10px;font-weight:800;font-size:20px}
|
|
40
|
+
.nav-logo{width:34px;height:34px;border-radius:10px;background:linear-gradient(135deg,#0ea5e9,#2563eb);display:flex;align-items:center;justify-content:center;padding:4px;box-shadow:0 2px 12px rgba(14,165,233,.3)}
|
|
41
|
+
.nav-logo img{width:100%;height:100%;filter:brightness(10)}
|
|
42
|
+
.nav-brand-text{background:linear-gradient(135deg,var(--accent2),var(--cyan));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
43
|
+
.nav-links{display:flex;align-items:center;gap:4px}
|
|
44
|
+
.nav-link{padding:8px 16px;border-radius:8px;font-size:13.5px;font-weight:500;color:var(--dim);transition:all .2s}
|
|
45
|
+
.nav-link:hover{color:var(--text);background:rgba(255,255,255,.04)}
|
|
46
|
+
.nav-link.active{color:var(--accent2)}
|
|
47
|
+
.nav-cta{padding:9px 22px;border-radius:10px;font-size:13.5px;font-weight:700;background:var(--accent);color:#fff;border:none;cursor:pointer;transition:all .3s;margin-left:8px}
|
|
48
|
+
.nav-cta:hover{background:var(--accent3);transform:translateY(-1px);box-shadow:0 6px 24px var(--glow)}
|
|
49
|
+
.nav-auth{display:inline-flex;align-items:center;gap:6px;padding:9px 18px;border-radius:10px;font-size:13.5px;font-weight:700;background:transparent;color:var(--dim);border:1.5px solid rgba(255,255,255,.12);cursor:pointer;transition:all .3s;margin-left:8px;font-family:inherit}
|
|
50
|
+
.nav-auth:hover{border-color:var(--accent);color:#fff;box-shadow:0 4px 16px var(--glow)}
|
|
51
|
+
.nav-auth.signed-in{border-color:var(--green);color:var(--green)}
|
|
52
|
+
.nav-auth .auth-avatar{width:22px;height:22px;border-radius:50%;margin-right:2px}
|
|
53
|
+
.hamburger{display:none;background:none;border:none;color:var(--dim);padding:8px;cursor:pointer}
|
|
54
|
+
.hamburger svg{width:24px;height:24px}
|
|
55
|
+
|
|
56
|
+
/* hero */
|
|
57
|
+
.hub-hero{padding:160px 0 100px;position:relative;text-align:center}
|
|
58
|
+
.hub-hero-bg{position:absolute;inset:0;overflow:hidden;pointer-events:none}
|
|
59
|
+
.hub-hero-orb{position:absolute;border-radius:50%;filter:blur(120px);opacity:.2;animation:morph 20s ease-in-out infinite}
|
|
60
|
+
.hub-hero-orb.a{width:500px;height:500px;background:var(--cyan);top:-20%;left:20%}
|
|
61
|
+
.hub-hero-orb.b{width:400px;height:400px;background:var(--accent);bottom:-10%;right:10%;animation-delay:-8s}
|
|
62
|
+
.hub-hero-content{position:relative;z-index:2;max-width:700px;margin:0 auto}
|
|
63
|
+
.hub-hero-badge{display:inline-flex;align-items:center;gap:8px;padding:6px 16px 6px 8px;border-radius:100px;font-size:12px;font-weight:600;background:rgba(24,255,255,.08);border:1px solid rgba(24,255,255,.2);color:var(--cyan);margin-bottom:24px;animation:slide-up .7s ease both}
|
|
64
|
+
.hub-hero-badge .tag{padding:3px 10px;border-radius:100px;background:rgba(24,255,255,.15);font-weight:700;font-size:11px}
|
|
65
|
+
.hub-hero h1{font-size:clamp(40px,7vw,72px);font-weight:900;letter-spacing:-2.5px;line-height:1.05;margin-bottom:20px;animation:slide-up .7s ease .08s both}
|
|
66
|
+
.hub-hero h1 .grad{background:linear-gradient(135deg,var(--cyan) 0%,var(--accent2) 50%,var(--cyan) 100%);background-size:200% 200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:gradient-shift 5s ease infinite}
|
|
67
|
+
.hub-hero .sub{font-size:clamp(15px,2.2vw,18px);color:var(--dim);max-width:520px;margin:0 auto 36px;animation:slide-up .7s ease .15s both;line-height:1.75}
|
|
68
|
+
.btn-h{padding:14px 30px;border-radius:var(--r);font-size:15px;font-weight:700;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:9px;transition:all .3s ease;text-decoration:none}
|
|
69
|
+
.btn-h svg{width:18px;height:18px}
|
|
70
|
+
.btn-h.primary{background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;box-shadow:0 4px 24px var(--glow)}
|
|
71
|
+
.btn-h.primary:hover{transform:translateY(-2px);box-shadow:0 8px 36px rgba(108,92,231,.35)}
|
|
72
|
+
.btn-h.secondary{background:var(--bg2);color:var(--text);border:1px solid var(--border)}
|
|
73
|
+
.btn-h.secondary:hover{border-color:var(--accent);background:var(--bg3);transform:translateY(-2px)}
|
|
74
|
+
.hub-hero-stats{display:flex;gap:40px;justify-content:center;margin-top:56px;animation:slide-up .7s ease .3s both}
|
|
75
|
+
.hs{text-align:center}
|
|
76
|
+
.hs .val{font-size:32px;font-weight:800;letter-spacing:-1px;background:linear-gradient(135deg,var(--text),var(--dim));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
77
|
+
.hs .lbl{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-top:2px}
|
|
78
|
+
|
|
79
|
+
/* section header */
|
|
80
|
+
.sh{text-align:center;max-width:620px;margin:0 auto 64px}
|
|
81
|
+
.sh-badge{display:inline-flex;align-items:center;gap:6px;padding:5px 14px;border-radius:100px;font-size:11px;font-weight:700;letter-spacing:.8px;text-transform:uppercase;background:var(--bg2);border:1px solid var(--border);color:var(--accent2);margin-bottom:18px}
|
|
82
|
+
.sh h2{font-size:clamp(30px,4.5vw,46px);font-weight:800;letter-spacing:-1.5px;margin-bottom:14px}
|
|
83
|
+
.sh p{color:var(--dim);font-size:15.5px;line-height:1.7}
|
|
84
|
+
|
|
85
|
+
/* how publishing works */
|
|
86
|
+
.how-pub{background:linear-gradient(180deg,var(--bg),var(--bg1))}
|
|
87
|
+
.how-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
|
|
88
|
+
.how-card{text-align:center;padding:36px 24px;border-radius:var(--r2);background:var(--bg2);border:1px solid var(--border);transition:all .3s}
|
|
89
|
+
.how-card:hover{border-color:rgba(108,92,231,.3);transform:translateY(-4px)}
|
|
90
|
+
.how-card .step{width:48px;height:48px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;font-weight:800;font-size:18px;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;box-shadow:0 4px 16px var(--glow)}
|
|
91
|
+
.how-card h3{font-size:15px;font-weight:700;margin-bottom:8px}
|
|
92
|
+
.how-card p{font-size:12.5px;color:var(--dim);line-height:1.7}
|
|
93
|
+
|
|
94
|
+
/* skill code example */
|
|
95
|
+
.code-show{background:var(--bg1)}
|
|
96
|
+
.code-grid{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center}
|
|
97
|
+
.code-text h3{font-size:clamp(24px,3.5vw,36px);font-weight:800;letter-spacing:-1px;margin-bottom:16px}
|
|
98
|
+
.code-text p{font-size:14.5px;color:var(--dim);line-height:1.8;margin-bottom:20px}
|
|
99
|
+
.code-features{list-style:none}
|
|
100
|
+
.code-features li{display:flex;align-items:center;gap:10px;padding:8px 0;font-size:13.5px;color:var(--dim)}
|
|
101
|
+
.code-features li::before{content:'✓';width:22px;height:22px;border-radius:50%;background:rgba(0,230,118,.1);color:var(--green);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;flex-shrink:0}
|
|
102
|
+
.code-block{border-radius:var(--r2);overflow:hidden;border:1px solid var(--border);background:var(--bg);box-shadow:0 16px 48px rgba(0,0,0,.3)}
|
|
103
|
+
.code-block-bar{padding:10px 14px;background:var(--bg2);border-bottom:1px solid var(--border);font-size:11px;color:var(--muted);font-family:'JetBrains Mono',monospace;display:flex;align-items:center;gap:8px}
|
|
104
|
+
.code-block-bar .dot{width:8px;height:8px;border-radius:50%;background:var(--cyan)}
|
|
105
|
+
.code-block pre{padding:20px;font-size:12.5px;line-height:1.9;color:var(--dim);overflow-x:auto;margin:0;white-space:pre}
|
|
106
|
+
.code-block .kw{color:var(--accent2)}.code-block .fn{color:var(--cyan)}.code-block .str{color:var(--green)}.code-block .cm{color:var(--muted);font-style:italic}.code-block .tp{color:var(--orange)}
|
|
107
|
+
|
|
108
|
+
/* featured skills */
|
|
109
|
+
.featured{background:linear-gradient(180deg,var(--bg1),var(--bg))}
|
|
110
|
+
.skills-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}
|
|
111
|
+
.skill-card{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r2);overflow:hidden;transition:all .4s cubic-bezier(.16,1,.3,1)}
|
|
112
|
+
.skill-card:hover{border-color:rgba(108,92,231,.35);transform:translateY(-4px);box-shadow:0 12px 40px rgba(0,0,0,.25)}
|
|
113
|
+
.sk-head{padding:18px 18px 0;display:flex;align-items:center;gap:12px}
|
|
114
|
+
.sk-ico{width:42px;height:42px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:20px;background:linear-gradient(135deg,var(--glow),var(--glow2));border:1px solid rgba(108,92,231,.15);flex-shrink:0}
|
|
115
|
+
.sk-meta{flex:1;min-width:0}
|
|
116
|
+
.sk-meta h4{font-size:14px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
117
|
+
.sk-meta .author{font-size:11px;color:var(--muted)}
|
|
118
|
+
.sk-ver{font-size:10px;color:var(--muted);padding:2px 8px;border-radius:6px;background:var(--bg3);flex-shrink:0}
|
|
119
|
+
.sk-body{padding:12px 18px}
|
|
120
|
+
.sk-body p{font-size:12.5px;color:var(--dim);line-height:1.7;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
|
|
121
|
+
.sk-foot{padding:8px 18px 14px;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
|
|
122
|
+
.sk-tag{padding:2px 8px;border-radius:6px;font-size:10px;font-weight:600;background:var(--bg3);color:var(--muted)}
|
|
123
|
+
.sk-tag.lang{color:var(--cyan);border:1px solid rgba(24,255,255,.12);background:rgba(24,255,255,.04)}
|
|
124
|
+
.sk-stats{margin-left:auto;display:flex;gap:10px;font-size:11px;color:var(--muted);align-items:center}
|
|
125
|
+
.sk-stats span{display:flex;align-items:center;gap:3px}
|
|
126
|
+
.sk-stats svg{width:12px;height:12px}
|
|
127
|
+
.install-btn{padding:3px 10px;border-radius:6px;font-size:10px;font-weight:700;background:var(--green);color:#000;border:none;cursor:pointer;transition:all .2s;letter-spacing:.3px}
|
|
128
|
+
.install-btn:hover{transform:translateY(-1px);box-shadow:0 3px 12px rgba(0,230,118,.3)}
|
|
129
|
+
|
|
130
|
+
/* categories */
|
|
131
|
+
.categories{background:var(--bg)}
|
|
132
|
+
.cat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:14px}
|
|
133
|
+
.cat-card{padding:28px 20px;border-radius:var(--r2);background:var(--bg2);border:1px solid var(--border);text-align:center;transition:all .3s;cursor:default}
|
|
134
|
+
.cat-card:hover{border-color:rgba(108,92,231,.3);transform:translateY(-3px);box-shadow:0 8px 28px rgba(0,0,0,.2)}
|
|
135
|
+
.cat-card .cat-ico{font-size:32px;margin-bottom:12px;display:block}
|
|
136
|
+
.cat-card .cat-name{font-size:14px;font-weight:700;margin-bottom:4px}
|
|
137
|
+
.cat-card .cat-count{font-size:11px;color:var(--muted)}
|
|
138
|
+
|
|
139
|
+
/* cta */
|
|
140
|
+
.cta{text-align:center;padding:100px 0 120px;position:relative}
|
|
141
|
+
.cta::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at center,rgba(24,255,255,.04),transparent 70%);pointer-events:none}
|
|
142
|
+
.cta h2{font-size:clamp(28px,4vw,42px);font-weight:900;letter-spacing:-1.5px;margin-bottom:14px}
|
|
143
|
+
.cta p{color:var(--dim);font-size:15px;margin-bottom:36px;max-width:480px;margin-left:auto;margin-right:auto;line-height:1.7}
|
|
144
|
+
|
|
145
|
+
/* filter buttons */
|
|
146
|
+
.sk-filter{padding:6px 16px;border-radius:100px;font-size:12px;font-weight:600;background:var(--bg2);border:1px solid var(--border);color:var(--muted);cursor:pointer;transition:all .2s}
|
|
147
|
+
.sk-filter:hover{border-color:var(--accent);color:var(--text)}
|
|
148
|
+
.sk-filter.active{background:var(--accent);border-color:var(--accent);color:#fff}
|
|
149
|
+
|
|
150
|
+
/* publish section */
|
|
151
|
+
.publish-sec{background:linear-gradient(180deg,var(--bg),var(--bg1));position:relative}
|
|
152
|
+
.publish-grid{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
|
|
153
|
+
.publish-form{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r2);padding:32px;display:flex;flex-direction:column;gap:16px}
|
|
154
|
+
.publish-form label{font-size:12px;font-weight:600;color:var(--dim);text-transform:uppercase;letter-spacing:.5px}
|
|
155
|
+
.publish-form input,.publish-form textarea,.publish-form select{width:100%;padding:10px 14px;border-radius:var(--r);background:var(--bg);border:1px solid var(--border);color:var(--text);font-size:14px;outline:none;transition:border-color .2s;font-family:inherit}
|
|
156
|
+
.publish-form input:focus,.publish-form textarea:focus,.publish-form select:focus{border-color:var(--accent)}
|
|
157
|
+
.publish-form textarea{resize:vertical;min-height:100px;font-family:'JetBrains Mono',monospace;font-size:12px}
|
|
158
|
+
.publish-form .file-drop{border:2px dashed var(--border);border-radius:var(--r);padding:32px;text-align:center;color:var(--muted);cursor:pointer;transition:all .2s}
|
|
159
|
+
.publish-form .file-drop:hover{border-color:var(--accent);color:var(--dim)}
|
|
160
|
+
.publish-form .file-drop.dragover{border-color:var(--cyan);background:rgba(24,255,255,.03)}
|
|
161
|
+
.publish-btn{padding:12px 28px;border-radius:var(--r);background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;font-size:14px;font-weight:700;border:none;cursor:pointer;transition:all .3s}
|
|
162
|
+
.publish-btn:hover{transform:translateY(-2px);box-shadow:0 8px 24px var(--glow)}
|
|
163
|
+
.toast{position:fixed;bottom:32px;right:32px;padding:14px 24px;border-radius:var(--r);background:var(--green);color:#000;font-weight:600;font-size:13px;z-index:9999;transform:translateY(100px);opacity:0;transition:all .4s cubic-bezier(.16,1,.3,1)}
|
|
164
|
+
.toast.show{transform:translateY(0);opacity:1}
|
|
165
|
+
|
|
166
|
+
@media(max-width:768px){.publish-grid{grid-template-columns:1fr}}
|
|
167
|
+
|
|
168
|
+
/* footer */
|
|
169
|
+
.footer{border-top:1px solid var(--border);padding:48px 0 32px;background:var(--bg)}
|
|
170
|
+
.footer-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:40px;margin-bottom:32px}
|
|
171
|
+
.footer-brand{display:flex;align-items:center;gap:8px;font-weight:800;font-size:17px;margin-bottom:12px}
|
|
172
|
+
.footer-brand .fl{width:28px;height:28px;border-radius:8px;background:linear-gradient(135deg,var(--accent),var(--accent3));display:flex;align-items:center;justify-content:center;font-size:14px}
|
|
173
|
+
.footer-brand-text{background:linear-gradient(135deg,var(--accent2),var(--cyan));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
|
174
|
+
.footer-desc{font-size:13px;color:var(--muted);line-height:1.7;max-width:280px}
|
|
175
|
+
.footer-col h4{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:var(--dim);margin-bottom:14px}
|
|
176
|
+
.footer-col a{display:block;font-size:13px;color:var(--muted);padding:4px 0;transition:color .2s}
|
|
177
|
+
.footer-col a:hover{color:var(--accent2)}
|
|
178
|
+
.footer-bottom{display:flex;justify-content:space-between;align-items:center;padding-top:24px;border-top:1px solid var(--border);font-size:12px;color:var(--muted)}
|
|
179
|
+
.footer-social{display:flex;gap:12px}
|
|
180
|
+
.footer-social a{width:32px;height:32px;border-radius:8px;background:var(--bg2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;color:var(--muted);transition:all .2s}
|
|
181
|
+
.footer-social a:hover{border-color:var(--accent);color:var(--accent2)}
|
|
182
|
+
.footer-social a svg{width:15px;height:15px}
|
|
183
|
+
|
|
184
|
+
@media(max-width:1024px){.code-grid{grid-template-columns:1fr}.footer-grid{grid-template-columns:1fr 1fr}}
|
|
185
|
+
@media(max-width:768px){
|
|
186
|
+
.how-grid,.skills-grid{grid-template-columns:1fr}
|
|
187
|
+
.code-grid{grid-template-columns:1fr}
|
|
188
|
+
.cat-grid{grid-template-columns:repeat(2,1fr)}
|
|
189
|
+
.nav-links{display:none}.hamburger{display:block}
|
|
190
|
+
.footer-grid{grid-template-columns:1fr}
|
|
191
|
+
.hub-hero-stats{gap:20px;flex-wrap:wrap}
|
|
192
|
+
section{padding:80px 0}
|
|
193
|
+
}
|
|
194
|
+
</style>
|
|
195
|
+
</head>
|
|
196
|
+
<body>
|
|
197
|
+
|
|
198
|
+
<!-- NAVBAR -->
|
|
199
|
+
<nav class="navbar" id="navbar">
|
|
200
|
+
<div class="container nav-inner">
|
|
201
|
+
<a href="index.html" class="nav-brand">
|
|
202
|
+
<div class="nav-logo"><img src="logo.svg" alt="LinguClaw"></div>
|
|
203
|
+
<span class="nav-brand-text">LinguClaw</span>
|
|
204
|
+
</a>
|
|
205
|
+
<div class="nav-links" id="navLinks">
|
|
206
|
+
<a href="index.html" class="nav-link">Home</a>
|
|
207
|
+
<a href="index.html#features" class="nav-link">Features</a>
|
|
208
|
+
<a href="#" class="nav-link active">ClawLing Hub</a>
|
|
209
|
+
<a href="#skills" class="nav-link">Skills</a>
|
|
210
|
+
<a href="https://github.com/LinguDeep/LinguClaw" target="_blank" class="nav-cta">
|
|
211
|
+
<svg viewBox="0 0 24 24" fill="currentColor" style="width:16px;height:16px"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg>
|
|
212
|
+
GitHub
|
|
213
|
+
</a>
|
|
214
|
+
<button class="nav-auth" id="authBtn" onclick="handleAuth()">
|
|
215
|
+
<svg viewBox="0 0 24 24" fill="currentColor" style="width:16px;height:16px"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg>
|
|
216
|
+
<span id="authLabel">Sign in</span>
|
|
217
|
+
</button>
|
|
218
|
+
</div>
|
|
219
|
+
<button class="hamburger" id="hamburger" aria-label="Menu"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg></button>
|
|
220
|
+
</div>
|
|
221
|
+
</nav>
|
|
222
|
+
|
|
223
|
+
<!-- HERO -->
|
|
224
|
+
<section class="hub-hero">
|
|
225
|
+
<div class="hub-hero-bg">
|
|
226
|
+
<div class="hub-hero-orb a"></div>
|
|
227
|
+
<div class="hub-hero-orb b"></div>
|
|
228
|
+
</div>
|
|
229
|
+
<div class="container hub-hero-content">
|
|
230
|
+
<div class="hub-hero-badge">
|
|
231
|
+
<span class="tag">Open Source</span>
|
|
232
|
+
Community Skills Marketplace
|
|
233
|
+
</div>
|
|
234
|
+
<h1><span class="grad">ClawLing Hub</span></h1>
|
|
235
|
+
<p class="sub">Discover and install powerful integrations — from Telegram bots to AI providers, smart home control to 1Password secrets. All open source.</p>
|
|
236
|
+
<div style="display:flex;gap:14px;justify-content:center;flex-wrap:wrap;animation:slide-up .7s ease .22s both">
|
|
237
|
+
<a href="#skills" class="btn-h primary">
|
|
238
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
|
239
|
+
Browse All Modules
|
|
240
|
+
</a>
|
|
241
|
+
<a href="#publish" class="btn-h secondary">
|
|
242
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
243
|
+
Publish Your Skill
|
|
244
|
+
</a>
|
|
245
|
+
</div>
|
|
246
|
+
<div class="hub-hero-stats">
|
|
247
|
+
<div class="hs"><div class="val" data-count="49">0</div><div class="lbl">Modules</div></div>
|
|
248
|
+
<div class="hs"><div class="val" data-count="8">0</div><div class="lbl">Categories</div></div>
|
|
249
|
+
<div class="hs"><div class="val" data-count="22">0</div><div class="lbl">Workflow Nodes</div></div>
|
|
250
|
+
<div class="hs"><div class="val" data-count="6">0</div><div class="lbl">Languages</div></div>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
</section>
|
|
254
|
+
|
|
255
|
+
<!-- CATEGORIES -->
|
|
256
|
+
<section class="categories">
|
|
257
|
+
<div class="container">
|
|
258
|
+
<div class="sh reveal">
|
|
259
|
+
<div class="sh-badge">📂 Categories</div>
|
|
260
|
+
<h2>Skills for every use case</h2>
|
|
261
|
+
<p>Browse skills by category or search for exactly what you need.</p>
|
|
262
|
+
</div>
|
|
263
|
+
<div class="cat-grid">
|
|
264
|
+
<div class="cat-card reveal d1"><span class="cat-ico">🖥️</span><div class="cat-name">System</div><div class="cat-count">Shell, Filesystem, Browser, Scheduler, Memory, Inbox</div></div>
|
|
265
|
+
<div class="cat-card reveal d2"><span class="cat-ico">💬</span><div class="cat-name">Messaging</div><div class="cat-count">Telegram, Discord, Slack, WhatsApp, Signal +6</div></div>
|
|
266
|
+
<div class="cat-card reveal d3"><span class="cat-ico">🧠</span><div class="cat-name">AI Providers</div><div class="cat-count">OpenAI, Anthropic, Google, Mistral, DeepSeek +4</div></div>
|
|
267
|
+
<div class="cat-card reveal d4"><span class="cat-ico">📋</span><div class="cat-name">Productivity</div><div class="cat-count">Notion, Trello, GitHub, Obsidian, Apple Notes</div></div>
|
|
268
|
+
<div class="cat-card reveal d5"><span class="cat-ico">🏠</span><div class="cat-name">Smart Home</div><div class="cat-count">Home Assistant, Hue, Spotify, Sonos</div></div>
|
|
269
|
+
<div class="cat-card reveal d6"><span class="cat-ico">🔧</span><div class="cat-name">Utility</div><div class="cat-count">Weather, Webhooks, Image Gen, 1Password, Gmail</div></div>
|
|
270
|
+
<div class="cat-card reveal d1"><span class="cat-ico">🌐</span><div class="cat-name">Languages</div><div class="cat-count">C++, C#, Go, Java, Python, Rust</div></div>
|
|
271
|
+
<div class="cat-card reveal d2"><span class="cat-ico">🔌</span><div class="cat-name">Plugins</div><div class="cat-count">Weather, Notes, System Info</div></div>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
</section>
|
|
275
|
+
|
|
276
|
+
<!-- FEATURED SKILLS -->
|
|
277
|
+
<section class="featured" id="skills">
|
|
278
|
+
<div class="container">
|
|
279
|
+
<div class="sh reveal">
|
|
280
|
+
<div class="sh-badge">🧩 All Modules</div>
|
|
281
|
+
<h2>Browse <span style="color:var(--accent2)">49</span> integrations</h2>
|
|
282
|
+
<p>Filter by category, search by name — every module is built-in and ready to use.</p>
|
|
283
|
+
</div>
|
|
284
|
+
<div style="max-width:480px;margin:0 auto 32px;position:relative" class="reveal">
|
|
285
|
+
<input type="text" id="skillSearch" placeholder="Search modules..." style="width:100%;padding:12px 16px 12px 42px;border-radius:var(--r);background:var(--bg2);border:1px solid var(--border);color:var(--text);font-size:14px;outline:none;transition:border-color .2s">
|
|
286
|
+
<svg style="position:absolute;left:14px;top:50%;transform:translateY(-50%);width:16px;height:16px;color:var(--muted)" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
|
287
|
+
</div>
|
|
288
|
+
<div style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-bottom:28px" class="reveal" id="filterBtns">
|
|
289
|
+
<button class="sk-filter active" data-cat="all">All</button>
|
|
290
|
+
<button class="sk-filter" data-cat="system">System</button>
|
|
291
|
+
<button class="sk-filter" data-cat="messaging">Messaging</button>
|
|
292
|
+
<button class="sk-filter" data-cat="ai">AI Providers</button>
|
|
293
|
+
<button class="sk-filter" data-cat="productivity">Productivity</button>
|
|
294
|
+
<button class="sk-filter" data-cat="smart-home">Smart Home</button>
|
|
295
|
+
<button class="sk-filter" data-cat="utility">Utility</button>
|
|
296
|
+
<button class="sk-filter" data-cat="language">Languages</button>
|
|
297
|
+
<button class="sk-filter" data-cat="plugin">Plugins</button>
|
|
298
|
+
</div>
|
|
299
|
+
<div class="skills-grid" id="skillsGrid"></div>
|
|
300
|
+
</div>
|
|
301
|
+
</section>
|
|
302
|
+
|
|
303
|
+
<!-- HOW IT WORKS -->
|
|
304
|
+
<section class="how-pub" id="howto">
|
|
305
|
+
<div class="container">
|
|
306
|
+
<div class="sh reveal">
|
|
307
|
+
<div class="sh-badge">🔌 Easy Integration</div>
|
|
308
|
+
<h2>Add a skill in 3 steps</h2>
|
|
309
|
+
<p>Extend LinguClaw with your own logic — zero config, hot-reloadable.</p>
|
|
310
|
+
</div>
|
|
311
|
+
<div class="how-grid">
|
|
312
|
+
<div class="how-card reveal d1">
|
|
313
|
+
<div class="step">1</div>
|
|
314
|
+
<h3>Extend BaseSkill</h3>
|
|
315
|
+
<p>Create a TypeScript class with NAME, DESCRIPTION, VERSION, and an execute() method. That's it.</p>
|
|
316
|
+
</div>
|
|
317
|
+
<div class="how-card reveal d2">
|
|
318
|
+
<div class="step">2</div>
|
|
319
|
+
<h3>Drop in plugins/</h3>
|
|
320
|
+
<p>Place your file in the plugins directory or ~/.linguclaw/plugins/. Auto-discovered on startup.</p>
|
|
321
|
+
</div>
|
|
322
|
+
<div class="how-card reveal d3">
|
|
323
|
+
<div class="step">3</div>
|
|
324
|
+
<h3>Use Immediately</h3>
|
|
325
|
+
<p>Your skill is available to all agents instantly. Hot-reload means no restart needed during dev.</p>
|
|
326
|
+
</div>
|
|
327
|
+
</div>
|
|
328
|
+
</div>
|
|
329
|
+
</section>
|
|
330
|
+
|
|
331
|
+
<!-- CODE EXAMPLE -->
|
|
332
|
+
<section class="code-show">
|
|
333
|
+
<div class="container">
|
|
334
|
+
<div class="code-grid">
|
|
335
|
+
<div class="code-text reveal-left">
|
|
336
|
+
<h3>Simple, powerful<br>skill API</h3>
|
|
337
|
+
<p>Every skill follows the same pattern: define metadata, implement execute(), and declare a schema. LinguClaw handles the rest — discovery, validation, sandboxing.</p>
|
|
338
|
+
<ul class="code-features">
|
|
339
|
+
<li>TypeScript-first with full type safety</li>
|
|
340
|
+
<li>Automatic input validation from schema</li>
|
|
341
|
+
<li>Sandboxed execution with resource limits</li>
|
|
342
|
+
<li>Built-in versioning and dependency management</li>
|
|
343
|
+
<li>Hot-reload during development</li>
|
|
344
|
+
</ul>
|
|
345
|
+
</div>
|
|
346
|
+
<div class="code-block reveal-right">
|
|
347
|
+
<div class="code-block-bar"><span class="dot"></span> web-scraper.ts</div>
|
|
348
|
+
<pre><span class="kw">import</span> { BaseSkill, SkillInput, SkillResult } <span class="kw">from</span> <span class="str">'linguclaw'</span>;
|
|
349
|
+
|
|
350
|
+
<span class="kw">export class</span> <span class="fn">WebScraperSkill</span> <span class="kw">extends</span> BaseSkill {
|
|
351
|
+
NAME = <span class="str">'web-scraper'</span>;
|
|
352
|
+
DESCRIPTION = <span class="str">'Scrape websites with CSS selectors'</span>;
|
|
353
|
+
VERSION = <span class="str">'2.1.0'</span>;
|
|
354
|
+
AUTHOR = <span class="str">'LinguClaw'</span>;
|
|
355
|
+
TYPE = <span class="str">'automation'</span> <span class="kw">as const</span>;
|
|
356
|
+
|
|
357
|
+
<span class="kw">async</span> <span class="fn">execute</span>(input: <span class="tp">SkillInput</span>): Promise<<span class="tp">SkillResult</span>> {
|
|
358
|
+
<span class="kw">const</span> { url, selector } = input;
|
|
359
|
+
<span class="kw">const</span> page = <span class="kw">await</span> this.<span class="fn">browser</span>().<span class="fn">goto</span>(url);
|
|
360
|
+
<span class="kw">const</span> data = <span class="kw">await</span> page.<span class="fn">$$eval</span>(selector, <span class="fn">els</span> =>
|
|
361
|
+
els.<span class="fn">map</span>(<span class="fn">el</span> => el.textContent)
|
|
362
|
+
);
|
|
363
|
+
<span class="kw">return</span> { success: <span class="tp">true</span>, data };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
<span class="fn">getSchema</span>() {
|
|
367
|
+
<span class="kw">return</span> {
|
|
368
|
+
input: {
|
|
369
|
+
url: { type: <span class="str">'string'</span>, required: <span class="tp">true</span> },
|
|
370
|
+
selector: { type: <span class="str">'string'</span>, required: <span class="tp">true</span> }
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
}</pre>
|
|
375
|
+
</div>
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
</section>
|
|
379
|
+
|
|
380
|
+
<!-- PUBLISH YOUR SKILL -->
|
|
381
|
+
<section class="publish-sec" id="publish">
|
|
382
|
+
<div class="container">
|
|
383
|
+
<div class="sh reveal">
|
|
384
|
+
<div class="sh-badge">🚀 Publish</div>
|
|
385
|
+
<h2>Share your skill with the world</h2>
|
|
386
|
+
<p>Upload your skill file and it gets added to the Hub instantly. TypeScript or JavaScript — both work.</p>
|
|
387
|
+
</div>
|
|
388
|
+
<div class="publish-grid">
|
|
389
|
+
<div class="reveal-left">
|
|
390
|
+
<h3 style="font-size:22px;font-weight:800;margin-bottom:14px">Why publish?</h3>
|
|
391
|
+
<ul class="code-features">
|
|
392
|
+
<li>Your skill becomes available to all LinguClaw users</li>
|
|
393
|
+
<li>Get credit as the author — your name stays on it</li>
|
|
394
|
+
<li>Community reviews and improves your code</li>
|
|
395
|
+
<li>Helps the ecosystem grow and diversify</li>
|
|
396
|
+
<li>Listed right here on the ClawLing Hub</li>
|
|
397
|
+
</ul>
|
|
398
|
+
<p style="font-size:13px;color:var(--muted);margin-top:18px;line-height:1.7">Skills extend <code style="color:var(--cyan)">BaseSkill</code> and implement <code style="color:var(--cyan)">execute()</code>. Drop a <code style="color:var(--cyan)">.ts</code> or <code style="color:var(--cyan)">.js</code> file and you're live.</p>
|
|
399
|
+
</div>
|
|
400
|
+
<form class="publish-form reveal-right" id="publishForm" onsubmit="return false" style="position:relative">
|
|
401
|
+
<div id="authOverlay" style="position:absolute;inset:0;background:rgba(6,6,10,.92);backdrop-filter:blur(6px);border-radius:18px;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:10;gap:14px">
|
|
402
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="var(--accent2)" stroke-width="2" style="width:40px;height:40px"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0110 0v4"/></svg>
|
|
403
|
+
<span style="color:var(--dim);font-size:15px;font-weight:600">Sign in with GitHub to publish</span>
|
|
404
|
+
<button onclick="handleAuth()" style="padding:10px 24px;border-radius:10px;background:var(--accent);color:#fff;border:none;cursor:pointer;font-weight:700;font-size:14px;font-family:inherit">Sign in with GitHub</button>
|
|
405
|
+
</div>
|
|
406
|
+
<div>
|
|
407
|
+
<label>Skill Name</label>
|
|
408
|
+
<input type="text" id="pubName" placeholder="e.g. My Awesome Skill" required>
|
|
409
|
+
</div>
|
|
410
|
+
<div>
|
|
411
|
+
<label>Author</label>
|
|
412
|
+
<input type="text" id="pubAuthor" placeholder="Your name or handle" required>
|
|
413
|
+
</div>
|
|
414
|
+
<div>
|
|
415
|
+
<label>Category</label>
|
|
416
|
+
<select id="pubCat">
|
|
417
|
+
<option value="communication">Communication</option>
|
|
418
|
+
<option value="file">File & Data</option>
|
|
419
|
+
<option value="web">Web & API</option>
|
|
420
|
+
<option value="system">System & DevOps</option>
|
|
421
|
+
<option value="ai">AI & NLP</option>
|
|
422
|
+
<option value="devtools">Dev Tools</option>
|
|
423
|
+
<option value="analytics">Analytics</option>
|
|
424
|
+
<option value="plugin">Plugin</option>
|
|
425
|
+
</select>
|
|
426
|
+
</div>
|
|
427
|
+
<div>
|
|
428
|
+
<label>Description</label>
|
|
429
|
+
<input type="text" id="pubDesc" placeholder="One-line description of what it does" required>
|
|
430
|
+
</div>
|
|
431
|
+
<div>
|
|
432
|
+
<label>Skill File (.ts or .js)</label>
|
|
433
|
+
<div class="file-drop" id="fileDrop">
|
|
434
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:32px;height:32px;margin-bottom:8px;color:var(--accent2)"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
|
435
|
+
<div id="fileLabel">Drop your .ts/.js file here or <span style="color:var(--accent2);text-decoration:underline">click to browse</span></div>
|
|
436
|
+
<input type="file" id="fileInput" accept=".ts,.js" style="display:none">
|
|
437
|
+
</div>
|
|
438
|
+
</div>
|
|
439
|
+
<button type="submit" class="publish-btn" id="publishBtn">Publish Skill</button>
|
|
440
|
+
</form>
|
|
441
|
+
</div>
|
|
442
|
+
</div>
|
|
443
|
+
</section>
|
|
444
|
+
|
|
445
|
+
<!-- CTA -->
|
|
446
|
+
<section class="cta">
|
|
447
|
+
<div class="container reveal">
|
|
448
|
+
<h2>Ready to extend LinguClaw?</h2>
|
|
449
|
+
<p>Add your own skills in minutes. Fork the repo, create a skill class, and you're live.</p>
|
|
450
|
+
<div style="display:flex;gap:14px;justify-content:center;flex-wrap:wrap">
|
|
451
|
+
<a href="https://github.com/LinguDeep/LinguClaw" target="_blank" class="btn-h primary">
|
|
452
|
+
<svg viewBox="0 0 24 24" fill="currentColor" style="width:18px;height:18px"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg>
|
|
453
|
+
Get Started
|
|
454
|
+
</a>
|
|
455
|
+
<a href="index.html" class="btn-h secondary">
|
|
456
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:18px;height:18px"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
|
457
|
+
Back to LinguClaw
|
|
458
|
+
</a>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
</section>
|
|
462
|
+
|
|
463
|
+
<!-- FOOTER -->
|
|
464
|
+
<footer class="footer">
|
|
465
|
+
<div class="container">
|
|
466
|
+
<div class="footer-grid">
|
|
467
|
+
<div>
|
|
468
|
+
<div class="footer-brand">
|
|
469
|
+
<div class="fl"><img src="logo.svg" alt="" style="width:24px;height:24px;filter:brightness(10)"></div>
|
|
470
|
+
<span class="footer-brand-text">LinguClaw</span>
|
|
471
|
+
</div>
|
|
472
|
+
<p class="footer-desc">Open-source AI multi-agent system with visual workflows, semantic memory, and a community skill marketplace.</p>
|
|
473
|
+
</div>
|
|
474
|
+
<div class="footer-col">
|
|
475
|
+
<h4>Product</h4>
|
|
476
|
+
<a href="index.html#features">Features</a>
|
|
477
|
+
<a href="index.html#workflows">Workflows</a>
|
|
478
|
+
<a href="index.html#architecture">Architecture</a>
|
|
479
|
+
<a href="index.html#getstarted">Get Started</a>
|
|
480
|
+
</div>
|
|
481
|
+
<div class="footer-col">
|
|
482
|
+
<h4>Community</h4>
|
|
483
|
+
<a href="#">ClawLing Hub</a>
|
|
484
|
+
<a href="https://github.com/LinguDeep/LinguClaw/blob/main/CONTRIBUTING.md" target="_blank">Contributing</a>
|
|
485
|
+
<a href="https://github.com/LinguDeep/LinguClaw/blob/main/CHANGELOG.md" target="_blank">Changelog</a>
|
|
486
|
+
</div>
|
|
487
|
+
<div class="footer-col">
|
|
488
|
+
<h4>Resources</h4>
|
|
489
|
+
<a href="https://github.com/LinguDeep/LinguClaw" target="_blank">GitHub</a>
|
|
490
|
+
<a href="https://github.com/LinguDeep/LinguClaw/blob/main/LICENSE" target="_blank">MIT License</a>
|
|
491
|
+
<a href="https://github.com/LinguDeep/LinguClaw/issues" target="_blank">Issues</a>
|
|
492
|
+
</div>
|
|
493
|
+
</div>
|
|
494
|
+
<div class="footer-bottom">
|
|
495
|
+
<span>© 2026 LinguDeep. Open source under MIT.</span>
|
|
496
|
+
<div class="footer-social">
|
|
497
|
+
<a href="https://github.com/LinguDeep/LinguClaw" target="_blank" aria-label="GitHub"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/></svg></a>
|
|
498
|
+
</div>
|
|
499
|
+
</div>
|
|
500
|
+
</div>
|
|
501
|
+
</footer>
|
|
502
|
+
|
|
503
|
+
<script src="https://www.gstatic.com/firebasejs/10.12.0/firebase-app-compat.js"></script>
|
|
504
|
+
<script src="https://www.gstatic.com/firebasejs/10.12.0/firebase-firestore-compat.js"></script>
|
|
505
|
+
<script src="https://www.gstatic.com/firebasejs/10.12.0/firebase-storage-compat.js"></script>
|
|
506
|
+
<script src="https://www.gstatic.com/firebasejs/10.12.0/firebase-auth-compat.js"></script>
|
|
507
|
+
<script>
|
|
508
|
+
firebase.initializeApp({
|
|
509
|
+
apiKey:"AIzaSyB81SRksmveSEEEdsWoIykAm38q_FtvQvo",
|
|
510
|
+
authDomain:"linguclaw.firebaseapp.com",
|
|
511
|
+
projectId:"linguclaw",
|
|
512
|
+
storageBucket:"linguclaw.firebasestorage.app",
|
|
513
|
+
messagingSenderId:"182415196892",
|
|
514
|
+
appId:"1:182415196892:web:cbd3bc9a033653ff7a2a19"
|
|
515
|
+
});
|
|
516
|
+
var db=firebase.firestore();
|
|
517
|
+
var storage=firebase.storage();
|
|
518
|
+
var auth=firebase.auth();
|
|
519
|
+
var currentUser=null;
|
|
520
|
+
|
|
521
|
+
// GitHub Auth
|
|
522
|
+
var githubProvider=new firebase.auth.GithubAuthProvider();
|
|
523
|
+
|
|
524
|
+
function handleAuth(){
|
|
525
|
+
if(currentUser){
|
|
526
|
+
auth.signOut();
|
|
527
|
+
}else{
|
|
528
|
+
auth.signInWithPopup(githubProvider).catch(function(err){
|
|
529
|
+
console.error('Auth error:',err);
|
|
530
|
+
alert('Sign-in failed: '+err.message);
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
auth.onAuthStateChanged(function(user){
|
|
536
|
+
currentUser=user;
|
|
537
|
+
var btn=document.getElementById('authBtn');
|
|
538
|
+
var label=document.getElementById('authLabel');
|
|
539
|
+
var overlay=document.getElementById('authOverlay');
|
|
540
|
+
var authorInput=document.getElementById('pubAuthor');
|
|
541
|
+
if(user){
|
|
542
|
+
btn.classList.add('signed-in');
|
|
543
|
+
var name=user.displayName||user.email||'User';
|
|
544
|
+
var photo=user.photoURL;
|
|
545
|
+
if(photo){
|
|
546
|
+
label.innerHTML='<img class="auth-avatar" src="'+photo+'" alt="">'+name;
|
|
547
|
+
}else{
|
|
548
|
+
label.textContent=name;
|
|
549
|
+
}
|
|
550
|
+
if(overlay)overlay.style.display='none';
|
|
551
|
+
if(authorInput){authorInput.value=name;authorInput.readOnly=true;}
|
|
552
|
+
}else{
|
|
553
|
+
btn.classList.remove('signed-in');
|
|
554
|
+
label.textContent='Sign in';
|
|
555
|
+
if(overlay)overlay.style.display='flex';
|
|
556
|
+
if(authorInput){authorInput.value='';authorInput.readOnly=false;}
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
</script>
|
|
560
|
+
|
|
561
|
+
<script>
|
|
562
|
+
// navbar scroll
|
|
563
|
+
window.addEventListener('scroll',function(){document.getElementById('navbar').classList.toggle('scrolled',window.scrollY>40)});
|
|
564
|
+
|
|
565
|
+
// mobile menu
|
|
566
|
+
document.getElementById('hamburger').addEventListener('click',function(){
|
|
567
|
+
var l=document.getElementById('navLinks');var o=l.style.display==='flex';
|
|
568
|
+
l.style.display=o?'none':'flex';l.style.position='fixed';l.style.top='60px';l.style.left='0';l.style.right='0';
|
|
569
|
+
l.style.background='rgba(6,6,10,.96)';l.style.flexDirection='column';l.style.padding='16px';
|
|
570
|
+
l.style.borderBottom='1px solid var(--border)';l.style.backdropFilter='blur(20px)';
|
|
571
|
+
if(o)l.removeAttribute('style');
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
// reveal
|
|
575
|
+
var obs=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('visible');obs.unobserve(e.target)}})},{threshold:.08,rootMargin:'0px 0px -30px 0px'});
|
|
576
|
+
document.querySelectorAll('.reveal,.reveal-left,.reveal-right').forEach(function(el){obs.observe(el)});
|
|
577
|
+
|
|
578
|
+
// counters
|
|
579
|
+
var cd={};
|
|
580
|
+
function ac(el){var id=el.parentElement.textContent;if(cd[id])return;cd[id]=true;
|
|
581
|
+
var t=parseInt(el.dataset.count),dur=1400,s=Date.now();
|
|
582
|
+
!function tick(){var p=Math.min((Date.now()-s)/dur,1);el.textContent=Math.round(t*(1-Math.pow(1-p,3))).toLocaleString();if(p<1)requestAnimationFrame(tick)}()}
|
|
583
|
+
var co=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting)ac(e.target)})},{threshold:.5});
|
|
584
|
+
document.querySelectorAll('[data-count]').forEach(function(el){co.observe(el)});
|
|
585
|
+
|
|
586
|
+
// skills data — real integrations from web.ts + codebase modules
|
|
587
|
+
var skills=[
|
|
588
|
+
// System Builtins (6) — web.ts
|
|
589
|
+
{name:'Shell',author:'LinguClaw',icon:'🖥️',desc:'Execute shell commands',tags:['shell','cli'],cat:'system',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
590
|
+
{name:'Filesystem',author:'LinguClaw',icon:'📁',desc:'Read/write files',tags:['files','io'],cat:'system',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
591
|
+
{name:'Browser',author:'LinguClaw',icon:'🌐',desc:'Browse websites & extract data',tags:['web','scraping'],cat:'system',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
592
|
+
{name:'Scheduler',author:'LinguClaw',icon:'⏰',desc:'Schedule background tasks',tags:['cron','tasks'],cat:'system',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
593
|
+
{name:'Memory',author:'LinguClaw',icon:'🧠',desc:'Persistent memory storage',tags:['memory','storage'],cat:'system',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
594
|
+
{name:'Inbox',author:'LinguClaw',icon:'📥',desc:'Track and reply to messages',tags:['inbox','messages'],cat:'system',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
595
|
+
|
|
596
|
+
// Messaging (11) — web.ts
|
|
597
|
+
{name:'Email',author:'LinguClaw',icon:'📧',desc:'Send/receive emails via IMAP',tags:['email','imap'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
598
|
+
{name:'Telegram',author:'LinguClaw',icon:'✈️',desc:'Telegram bot integration',tags:['telegram','bot'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
599
|
+
{name:'Discord',author:'LinguClaw',icon:'🎮',desc:'Discord bot integration',tags:['discord','bot'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
600
|
+
{name:'Slack',author:'LinguClaw',icon:'💬',desc:'Slack bot integration',tags:['slack','bot'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
601
|
+
{name:'WhatsApp',author:'LinguClaw',icon:'📱',desc:'WhatsApp via Twilio',tags:['whatsapp','twilio'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
602
|
+
{name:'Signal',author:'LinguClaw',icon:'🔒',desc:'Signal via signal-cli',tags:['signal','privacy'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
603
|
+
{name:'iMessage',author:'LinguClaw',icon:'🍎',desc:'iMessage via BlueBubbles',tags:['imessage','apple'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
604
|
+
{name:'Teams',author:'LinguClaw',icon:'🏢',desc:'Microsoft Teams integration',tags:['teams','microsoft'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
605
|
+
{name:'Matrix',author:'LinguClaw',icon:'🔗',desc:'Matrix protocol integration',tags:['matrix','decentralized'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
606
|
+
{name:'Nostr',author:'LinguClaw',icon:'🟣',desc:'Nostr NIP-04 messages',tags:['nostr','decentralized'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
607
|
+
{name:'Zalo',author:'LinguClaw',icon:'💙',desc:'Zalo bot integration',tags:['zalo','vietnam'],cat:'messaging',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
608
|
+
|
|
609
|
+
// AI Providers (9) — web.ts
|
|
610
|
+
{name:'OpenAI',author:'LinguClaw',icon:'🤖',desc:'OpenAI GPT-4, o1, GPT-5',tags:['openai','gpt'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
611
|
+
{name:'Anthropic',author:'LinguClaw',icon:'🧠',desc:'Anthropic Claude 3.5/4',tags:['anthropic','claude'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
612
|
+
{name:'Google',author:'LinguClaw',icon:'🔵',desc:'Google Gemini 1.5/2.5',tags:['google','gemini'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
613
|
+
{name:'xAI',author:'LinguClaw',icon:'✖️',desc:'xAI Grok',tags:['xai','grok'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
614
|
+
{name:'Mistral',author:'LinguClaw',icon:'🌬️',desc:'Mistral AI models',tags:['mistral'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
615
|
+
{name:'DeepSeek',author:'LinguClaw',icon:'🔍',desc:'DeepSeek V3 & R1',tags:['deepseek'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
616
|
+
{name:'Perplexity',author:'LinguClaw',icon:'🔎',desc:'Perplexity Search-augmented',tags:['perplexity','search'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
617
|
+
{name:'Ollama',author:'LinguClaw',icon:'🦙',desc:'Ollama local models',tags:['ollama','local'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
618
|
+
{name:'LM Studio',author:'LinguClaw',icon:'💻',desc:'LM Studio local models',tags:['lmstudio','local'],cat:'ai',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
619
|
+
|
|
620
|
+
// Productivity (5) — web.ts
|
|
621
|
+
{name:'Notion',author:'LinguClaw',icon:'📓',desc:'Notion pages & databases',tags:['notion','workspace'],cat:'productivity',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
622
|
+
{name:'Trello',author:'LinguClaw',icon:'📋',desc:'Trello boards & cards',tags:['trello','kanban'],cat:'productivity',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
623
|
+
{name:'GitHub',author:'LinguClaw',icon:'🐙',desc:'GitHub repos, issues, PRs',tags:['github','git'],cat:'productivity',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
624
|
+
{name:'Obsidian',author:'LinguClaw',icon:'💎',desc:'Obsidian vault access',tags:['obsidian','notes'],cat:'productivity',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
625
|
+
{name:'Apple Notes',author:'LinguClaw',icon:'🍎',desc:'Apple Notes (macOS)',tags:['apple-notes','macos'],cat:'productivity',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
626
|
+
|
|
627
|
+
// Smart Home & Media (4) — web.ts
|
|
628
|
+
{name:'Home Assistant',author:'LinguClaw',icon:'🏠',desc:'Home Assistant hub',tags:['home-assistant','iot'],cat:'smart-home',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
629
|
+
{name:'Philips Hue',author:'LinguClaw',icon:'💡',desc:'Philips Hue lighting',tags:['hue','lights'],cat:'smart-home',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
630
|
+
{name:'Spotify',author:'LinguClaw',icon:'🎵',desc:'Spotify control',tags:['spotify','music'],cat:'smart-home',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
631
|
+
{name:'Sonos',author:'LinguClaw',icon:'🔊',desc:'Sonos multi-room audio',tags:['sonos','audio'],cat:'smart-home',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
632
|
+
|
|
633
|
+
// Utility (5) — web.ts
|
|
634
|
+
{name:'Weather',author:'LinguClaw',icon:'🌤️',desc:'Weather forecasts',tags:['weather','api'],cat:'utility',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
635
|
+
{name:'Webhooks',author:'LinguClaw',icon:'🔗',desc:'HTTP webhook triggers',tags:['webhooks','http'],cat:'utility',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
636
|
+
{name:'Image Gen',author:'LinguClaw',icon:'🖼️',desc:'AI Image Generation',tags:['image','dalle'],cat:'utility',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
637
|
+
{name:'1Password',author:'LinguClaw',icon:'🔐',desc:'1Password secrets',tags:['1password','secrets'],cat:'utility',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
638
|
+
{name:'Gmail',author:'LinguClaw',icon:'📨',desc:'Gmail Pub/Sub triggers',tags:['gmail','google'],cat:'utility',lang:'TypeScript',ver:'1.0.0',type:'integration'},
|
|
639
|
+
|
|
640
|
+
// Language Analyzers (6) — src/languages/
|
|
641
|
+
{name:'C++ Analyzer',author:'LinguClaw',icon:'⚡',desc:'C++ code analysis, refactoring, and diagnostics',tags:['cpp','analysis'],cat:'language',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
642
|
+
{name:'C# Analyzer',author:'LinguClaw',icon:'🟦',desc:'C# code analysis, refactoring, and diagnostics',tags:['csharp','analysis'],cat:'language',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
643
|
+
{name:'Go Analyzer',author:'LinguClaw',icon:'🐹',desc:'Go code analysis, refactoring, and diagnostics',tags:['go','analysis'],cat:'language',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
644
|
+
{name:'Java Analyzer',author:'LinguClaw',icon:'☕',desc:'Java code analysis, refactoring, and diagnostics',tags:['java','analysis'],cat:'language',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
645
|
+
{name:'Python Analyzer',author:'LinguClaw',icon:'🐍',desc:'Python code analysis, refactoring, and diagnostics',tags:['python','analysis'],cat:'language',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
646
|
+
{name:'Rust Analyzer',author:'LinguClaw',icon:'🦀',desc:'Rust code analysis, refactoring, and diagnostics',tags:['rust','analysis'],cat:'language',lang:'TypeScript',ver:'1.0.0',type:'builtin'},
|
|
647
|
+
|
|
648
|
+
// Plugins (3) — plugins/
|
|
649
|
+
{name:'Weather Plugin',author:'LinguClaw',icon:'🌦️',desc:'Get weather data for any city using the Open-Meteo API. No API key required.',tags:['weather','api'],cat:'plugin',lang:'JavaScript',ver:'1.0.0',type:'plugin'},
|
|
650
|
+
{name:'Notes Plugin',author:'LinguClaw',icon:'🗒️',desc:'Persistent notes management plugin with tags and search. File-based JSON storage.',tags:['notes'],cat:'plugin',lang:'JavaScript',ver:'1.0.0',type:'plugin'},
|
|
651
|
+
{name:'System Info Plugin',author:'LinguClaw',icon:'💻',desc:'Monitor CPU, memory, disk, and OS details. Real-time system resource diagnostics.',tags:['system'],cat:'plugin',lang:'JavaScript',ver:'1.0.0',type:'plugin'},
|
|
652
|
+
];
|
|
653
|
+
|
|
654
|
+
function renderSkills(filter,search){
|
|
655
|
+
var g=document.getElementById('skillsGrid'),h='',filtered=skills;
|
|
656
|
+
if(filter&&filter!=='all')filtered=filtered.filter(function(s){return s.cat===filter});
|
|
657
|
+
if(search){var q=search.toLowerCase();filtered=filtered.filter(function(s){return s.name.toLowerCase().indexOf(q)>-1||s.desc.toLowerCase().indexOf(q)>-1||s.tags.join(' ').indexOf(q)>-1})}
|
|
658
|
+
if(filtered.length===0){g.innerHTML='<div style="grid-column:1/-1;text-align:center;padding:60px 0;color:var(--muted)"><p style="font-size:18px;margin-bottom:8px">No skills found</p><p style="font-size:13px">Try a different search or category.</p></div>';return}
|
|
659
|
+
filtered.forEach(function(s,i){
|
|
660
|
+
h+='<div class="skill-card reveal d'+(i%3+1)+'">'
|
|
661
|
+
+'<div class="sk-head"><div class="sk-ico">'+s.icon+'</div>'
|
|
662
|
+
+'<div class="sk-meta"><h4>'+s.name+'</h4><div class="author">by '+s.author+'</div></div>'
|
|
663
|
+
+'<span class="sk-ver">v'+s.ver+'</span></div>'
|
|
664
|
+
+'<div class="sk-body"><p>'+s.desc+'</p></div>'
|
|
665
|
+
+'<div class="sk-foot">';
|
|
666
|
+
s.tags.forEach(function(t){h+='<span class="sk-tag">'+t+'</span>'});
|
|
667
|
+
h+='<span class="sk-tag lang">'+s.lang+'</span>'
|
|
668
|
+
+'<div class="sk-stats"><span style="color:var(--accent2);font-weight:600">'+s.type+'</span>'
|
|
669
|
+
+(s.type==='community'?'<button class="install-btn" data-name="'+s.name+'" title="Copy install command">Install</button>':'')
|
|
670
|
+
+'</div></div></div>';
|
|
671
|
+
});
|
|
672
|
+
g.innerHTML=h;
|
|
673
|
+
g.querySelectorAll('.install-btn').forEach(function(btn){
|
|
674
|
+
btn.addEventListener('click',function(){
|
|
675
|
+
var cmd='linguclaw hub install '+this.dataset.name;
|
|
676
|
+
navigator.clipboard.writeText(cmd).then(function(){showToast('Copied: '+cmd)}).catch(function(){
|
|
677
|
+
prompt('Run this command:',cmd);
|
|
678
|
+
});
|
|
679
|
+
});
|
|
680
|
+
});
|
|
681
|
+
g.querySelectorAll('.reveal').forEach(function(el){obs.observe(el)});
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// filter buttons
|
|
685
|
+
var activeFilter='all';
|
|
686
|
+
document.getElementById('filterBtns').addEventListener('click',function(e){
|
|
687
|
+
if(!e.target.classList.contains('sk-filter'))return;
|
|
688
|
+
document.querySelectorAll('.sk-filter').forEach(function(b){b.classList.remove('active')});
|
|
689
|
+
e.target.classList.add('active');
|
|
690
|
+
activeFilter=e.target.dataset.cat;
|
|
691
|
+
renderSkills(activeFilter,document.getElementById('skillSearch').value);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
// search
|
|
695
|
+
document.getElementById('skillSearch').addEventListener('input',function(){
|
|
696
|
+
renderSkills(activeFilter,this.value);
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
// initial render (built-in + Firestore community skills)
|
|
700
|
+
renderSkills();
|
|
701
|
+
db.collection('skills').orderBy('createdAt','desc').get().then(function(snap){
|
|
702
|
+
snap.forEach(function(doc){
|
|
703
|
+
var d=doc.data();
|
|
704
|
+
skills.push({name:d.name,author:d.author,icon:'🧩',desc:d.desc,tags:d.tags||[d.cat],cat:d.cat||'plugin',lang:d.lang||'TypeScript',ver:d.ver||'1.0.0',type:'community',downloadUrl:!!d.downloadUrl});
|
|
705
|
+
});
|
|
706
|
+
// update counter
|
|
707
|
+
var countEl=document.querySelector('[data-count]');if(countEl){countEl.dataset.count=skills.length;countEl.textContent=skills.length}
|
|
708
|
+
renderSkills(activeFilter,document.getElementById('skillSearch').value);
|
|
709
|
+
}).catch(function(e){console.warn('Firestore load:',e)});
|
|
710
|
+
|
|
711
|
+
// publish form
|
|
712
|
+
var fileDrop=document.getElementById('fileDrop');
|
|
713
|
+
var fileInput=document.getElementById('fileInput');
|
|
714
|
+
var selectedFile=null;
|
|
715
|
+
fileDrop.addEventListener('click',function(){fileInput.click()});
|
|
716
|
+
fileDrop.addEventListener('dragover',function(e){e.preventDefault();fileDrop.classList.add('dragover')});
|
|
717
|
+
fileDrop.addEventListener('dragleave',function(){fileDrop.classList.remove('dragover')});
|
|
718
|
+
fileDrop.addEventListener('drop',function(e){e.preventDefault();fileDrop.classList.remove('dragover');if(e.dataTransfer.files.length){handleFile(e.dataTransfer.files[0])}});
|
|
719
|
+
fileInput.addEventListener('change',function(){if(this.files.length)handleFile(this.files[0])});
|
|
720
|
+
function handleFile(f){
|
|
721
|
+
if(!f.name.endsWith('.ts')&&!f.name.endsWith('.js')){showToast('Only .ts or .js files allowed');return}
|
|
722
|
+
selectedFile=f;document.getElementById('fileLabel').innerHTML='<span style="color:var(--green)">✓ '+f.name+' ('+Math.round(f.size/1024)+'KB)</span>';
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
document.getElementById('publishBtn').addEventListener('click',function(){
|
|
726
|
+
if(!currentUser){showToast('Please sign in with GitHub first');return}
|
|
727
|
+
var nm=document.getElementById('pubName').value.trim();
|
|
728
|
+
var au=document.getElementById('pubAuthor').value.trim();
|
|
729
|
+
var ct=document.getElementById('pubCat').value;
|
|
730
|
+
var ds=document.getElementById('pubDesc').value.trim();
|
|
731
|
+
if(!nm||!au||!ds){showToast('Please fill in all fields');return}
|
|
732
|
+
if(!selectedFile){showToast('Please upload a skill file');return}
|
|
733
|
+
var btn=this;btn.disabled=true;btn.textContent='Uploading...';
|
|
734
|
+
var lang=selectedFile.name.endsWith('.ts')?'TypeScript':'JavaScript';
|
|
735
|
+
var safeFileName=Date.now()+'_'+selectedFile.name.replace(/[^a-zA-Z0-9._-]/g,'');
|
|
736
|
+
var storageRef=storage.ref('skills/'+safeFileName);
|
|
737
|
+
storageRef.put(selectedFile).then(function(snap){
|
|
738
|
+
btn.textContent='Saving...';
|
|
739
|
+
return snap.ref.getDownloadURL();
|
|
740
|
+
}).then(function(url){
|
|
741
|
+
var skillData={name:nm,author:au,desc:ds,cat:ct,tags:[ct],lang:lang,ver:'1.0.0',fileName:selectedFile.name,downloadUrl:url,createdAt:firebase.firestore.FieldValue.serverTimestamp(),uid:currentUser.uid,authorPhoto:currentUser.photoURL||'',authorGithub:currentUser.providerData[0]&¤tUser.providerData[0].uid||''};
|
|
742
|
+
return db.collection('skills').add(skillData);
|
|
743
|
+
}).then(function(){
|
|
744
|
+
skills.push({name:nm,author:au,icon:'🧩',desc:ds,tags:[ct],cat:ct,lang:lang,ver:'1.0.0',type:'community',downloadUrl:true});
|
|
745
|
+
renderSkills(activeFilter,document.getElementById('skillSearch').value);
|
|
746
|
+
var countEl=document.querySelector('[data-count]');if(countEl){countEl.dataset.count=skills.length;countEl.textContent=skills.length}
|
|
747
|
+
document.getElementById('publishForm').reset();selectedFile=null;
|
|
748
|
+
document.getElementById('fileLabel').innerHTML='Drop your .ts/.js file here or <span style="color:var(--accent2);text-decoration:underline">click to browse</span>';
|
|
749
|
+
showToast('Skill "'+nm+'" published to ClawLing Hub!');
|
|
750
|
+
setTimeout(function(){document.getElementById('skills').scrollIntoView({behavior:'smooth'})},800);
|
|
751
|
+
}).catch(function(e){
|
|
752
|
+
console.error('Publish error:',e);
|
|
753
|
+
showToast('Error publishing — check console');
|
|
754
|
+
}).finally(function(){btn.disabled=false;btn.textContent='Publish Skill'});
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
function showToast(msg){
|
|
758
|
+
var t=document.createElement('div');t.className='toast';t.textContent=msg;document.body.appendChild(t);
|
|
759
|
+
setTimeout(function(){t.classList.add('show')},10);
|
|
760
|
+
setTimeout(function(){t.classList.remove('show');setTimeout(function(){t.remove()},400)},3000);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// smooth scroll
|
|
764
|
+
document.querySelectorAll('a[href^="#"]').forEach(function(a){
|
|
765
|
+
a.addEventListener('click',function(e){
|
|
766
|
+
var t=document.querySelector(this.getAttribute('href'));
|
|
767
|
+
if(t){e.preventDefault();t.scrollIntoView({behavior:'smooth',block:'start'})}
|
|
768
|
+
});
|
|
769
|
+
});
|
|
770
|
+
</script>
|
|
771
|
+
</body>
|
|
772
|
+
</html>
|