zubo 0.1.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.
Files changed (222) hide show
  1. package/.github/workflows/ci.yml +35 -0
  2. package/README.md +149 -0
  3. package/bun.lock +216 -0
  4. package/desktop/README.md +57 -0
  5. package/desktop/package.json +12 -0
  6. package/desktop/src-tauri/Cargo.toml +25 -0
  7. package/desktop/src-tauri/build.rs +3 -0
  8. package/desktop/src-tauri/icons/README.md +17 -0
  9. package/desktop/src-tauri/icons/icon.png +0 -0
  10. package/desktop/src-tauri/src/main.rs +189 -0
  11. package/desktop/src-tauri/tauri.conf.json +68 -0
  12. package/docs/ROADMAP.md +490 -0
  13. package/migrations/001_init.sql +9 -0
  14. package/migrations/002_memory.sql +33 -0
  15. package/migrations/003_cron.sql +24 -0
  16. package/migrations/004_usage.sql +12 -0
  17. package/migrations/005_secrets.sql +8 -0
  18. package/migrations/006_agents.sql +1 -0
  19. package/migrations/007_workflows.sql +22 -0
  20. package/migrations/008_proactive.sql +24 -0
  21. package/migrations/009_uploads.sql +9 -0
  22. package/migrations/010_observability.sql +22 -0
  23. package/migrations/011_api_keys.sql +7 -0
  24. package/migrations/012_indexes.sql +5 -0
  25. package/migrations/013_budget.sql +11 -0
  26. package/migrations/014_usage_session_idx.sql +2 -0
  27. package/package.json +39 -0
  28. package/site/404.html +156 -0
  29. package/site/CNAME +1 -0
  30. package/site/docs/agents.html +294 -0
  31. package/site/docs/api.html +446 -0
  32. package/site/docs/channels.html +345 -0
  33. package/site/docs/cli.html +238 -0
  34. package/site/docs/config.html +1034 -0
  35. package/site/docs/index.html +433 -0
  36. package/site/docs/integrations.html +381 -0
  37. package/site/docs/memory.html +254 -0
  38. package/site/docs/security.html +375 -0
  39. package/site/docs/skills.html +322 -0
  40. package/site/docs.css +412 -0
  41. package/site/index.html +638 -0
  42. package/site/install.sh +98 -0
  43. package/site/logo.svg +1 -0
  44. package/site/og-image.png +0 -0
  45. package/site/robots.txt +4 -0
  46. package/site/script.js +361 -0
  47. package/site/sitemap.xml +63 -0
  48. package/site/skills.html +532 -0
  49. package/site/style.css +1686 -0
  50. package/src/agent/agents.ts +159 -0
  51. package/src/agent/compaction.ts +53 -0
  52. package/src/agent/context.ts +18 -0
  53. package/src/agent/delegate.ts +118 -0
  54. package/src/agent/loop.ts +318 -0
  55. package/src/agent/prompts.ts +111 -0
  56. package/src/agent/session.ts +87 -0
  57. package/src/agent/teams.ts +116 -0
  58. package/src/agent/workflow-executor.ts +192 -0
  59. package/src/agent/workflow.ts +175 -0
  60. package/src/channels/adapter.ts +21 -0
  61. package/src/channels/dashboard.html.ts +2969 -0
  62. package/src/channels/discord.ts +137 -0
  63. package/src/channels/optional-deps.d.ts +17 -0
  64. package/src/channels/router.ts +199 -0
  65. package/src/channels/signal.ts +133 -0
  66. package/src/channels/slack.ts +101 -0
  67. package/src/channels/telegram.ts +102 -0
  68. package/src/channels/utils.ts +18 -0
  69. package/src/channels/webchat.ts +1797 -0
  70. package/src/channels/whatsapp.ts +119 -0
  71. package/src/config/loader.ts +22 -0
  72. package/src/config/paths.ts +43 -0
  73. package/src/config/schema.ts +121 -0
  74. package/src/db/connection.ts +20 -0
  75. package/src/db/export.ts +148 -0
  76. package/src/db/migrations.ts +42 -0
  77. package/src/index.ts +261 -0
  78. package/src/llm/claude.ts +193 -0
  79. package/src/llm/factory.ts +115 -0
  80. package/src/llm/failover.ts +101 -0
  81. package/src/llm/openai-compat.ts +409 -0
  82. package/src/llm/provider.ts +83 -0
  83. package/src/llm/smart-router.ts +241 -0
  84. package/src/logs.ts +53 -0
  85. package/src/memory/chunker.ts +58 -0
  86. package/src/memory/document-parser.ts +115 -0
  87. package/src/memory/embedder.ts +235 -0
  88. package/src/memory/engine.ts +170 -0
  89. package/src/memory/fts-index.ts +55 -0
  90. package/src/memory/hybrid-search.ts +72 -0
  91. package/src/memory/store.ts +56 -0
  92. package/src/memory/vector-index.ts +72 -0
  93. package/src/model.ts +118 -0
  94. package/src/registry/cli.ts +43 -0
  95. package/src/registry/client.ts +54 -0
  96. package/src/registry/installer.ts +67 -0
  97. package/src/scheduler/briefing.ts +71 -0
  98. package/src/scheduler/cron.ts +258 -0
  99. package/src/scheduler/heartbeat.ts +58 -0
  100. package/src/scheduler/memory-triggers.ts +100 -0
  101. package/src/scheduler/natural-cron.ts +163 -0
  102. package/src/scheduler/proactive.ts +25 -0
  103. package/src/scheduler/recipes.ts +110 -0
  104. package/src/secrets/store.ts +64 -0
  105. package/src/setup.ts +413 -0
  106. package/src/skills.ts +293 -0
  107. package/src/start.ts +373 -0
  108. package/src/status.ts +165 -0
  109. package/src/tools/builtin/connect-service.ts +205 -0
  110. package/src/tools/builtin/cron.ts +126 -0
  111. package/src/tools/builtin/datetime.ts +36 -0
  112. package/src/tools/builtin/delegate-task.ts +81 -0
  113. package/src/tools/builtin/delegate.ts +42 -0
  114. package/src/tools/builtin/diagnose.ts +41 -0
  115. package/src/tools/builtin/google-oauth.ts +379 -0
  116. package/src/tools/builtin/manage-agents.ts +149 -0
  117. package/src/tools/builtin/manage-skills.ts +294 -0
  118. package/src/tools/builtin/manage-teams.ts +89 -0
  119. package/src/tools/builtin/manage-triggers.ts +94 -0
  120. package/src/tools/builtin/manage-workflows.ts +119 -0
  121. package/src/tools/builtin/memory-search.ts +38 -0
  122. package/src/tools/builtin/memory-write.ts +30 -0
  123. package/src/tools/builtin/run-workflow.ts +36 -0
  124. package/src/tools/builtin/secrets.ts +122 -0
  125. package/src/tools/builtin/skill-registry.ts +75 -0
  126. package/src/tools/builtin-integrations/api-helpers.ts +26 -0
  127. package/src/tools/builtin-integrations/github/github_issues/SKILL.md +56 -0
  128. package/src/tools/builtin-integrations/github/github_issues/handler.ts +108 -0
  129. package/src/tools/builtin-integrations/github/github_prs/SKILL.md +57 -0
  130. package/src/tools/builtin-integrations/github/github_prs/handler.ts +113 -0
  131. package/src/tools/builtin-integrations/github/github_repos/SKILL.md +37 -0
  132. package/src/tools/builtin-integrations/github/github_repos/handler.ts +88 -0
  133. package/src/tools/builtin-integrations/google/gmail/SKILL.md +51 -0
  134. package/src/tools/builtin-integrations/google/gmail/handler.ts +125 -0
  135. package/src/tools/builtin-integrations/google/google_calendar/SKILL.md +35 -0
  136. package/src/tools/builtin-integrations/google/google_calendar/handler.ts +105 -0
  137. package/src/tools/builtin-integrations/google/google_docs/SKILL.md +35 -0
  138. package/src/tools/builtin-integrations/google/google_docs/handler.ts +108 -0
  139. package/src/tools/builtin-integrations/google/google_drive/SKILL.md +39 -0
  140. package/src/tools/builtin-integrations/google/google_drive/handler.ts +106 -0
  141. package/src/tools/builtin-integrations/google/google_sheets/SKILL.md +36 -0
  142. package/src/tools/builtin-integrations/google/google_sheets/handler.ts +116 -0
  143. package/src/tools/builtin-integrations/jira/jira_boards/SKILL.md +21 -0
  144. package/src/tools/builtin-integrations/jira/jira_boards/handler.ts +74 -0
  145. package/src/tools/builtin-integrations/jira/jira_issues/SKILL.md +28 -0
  146. package/src/tools/builtin-integrations/jira/jira_issues/handler.ts +140 -0
  147. package/src/tools/builtin-integrations/linear/linear_issues/SKILL.md +30 -0
  148. package/src/tools/builtin-integrations/linear/linear_issues/handler.ts +75 -0
  149. package/src/tools/builtin-integrations/linear/linear_projects/SKILL.md +21 -0
  150. package/src/tools/builtin-integrations/linear/linear_projects/handler.ts +43 -0
  151. package/src/tools/builtin-integrations/notion/notion_databases/SKILL.md +39 -0
  152. package/src/tools/builtin-integrations/notion/notion_databases/handler.ts +83 -0
  153. package/src/tools/builtin-integrations/notion/notion_pages/SKILL.md +43 -0
  154. package/src/tools/builtin-integrations/notion/notion_pages/handler.ts +130 -0
  155. package/src/tools/builtin-integrations/notion/notion_search/SKILL.md +27 -0
  156. package/src/tools/builtin-integrations/notion/notion_search/handler.ts +69 -0
  157. package/src/tools/builtin-integrations/slack/slack_messages/SKILL.md +42 -0
  158. package/src/tools/builtin-integrations/slack/slack_messages/handler.ts +72 -0
  159. package/src/tools/builtin-integrations/twitter/twitter_posts/SKILL.md +24 -0
  160. package/src/tools/builtin-integrations/twitter/twitter_posts/handler.ts +133 -0
  161. package/src/tools/builtin-skills/file-read/SKILL.md +26 -0
  162. package/src/tools/builtin-skills/file-read/handler.ts +66 -0
  163. package/src/tools/builtin-skills/file-write/SKILL.md +30 -0
  164. package/src/tools/builtin-skills/file-write/handler.ts +64 -0
  165. package/src/tools/builtin-skills/http-request/SKILL.md +34 -0
  166. package/src/tools/builtin-skills/http-request/handler.ts +87 -0
  167. package/src/tools/builtin-skills/shell/SKILL.md +26 -0
  168. package/src/tools/builtin-skills/shell/handler.ts +96 -0
  169. package/src/tools/builtin-skills/url-fetch/SKILL.md +26 -0
  170. package/src/tools/builtin-skills/url-fetch/handler.ts +37 -0
  171. package/src/tools/builtin-skills/web-search/SKILL.md +26 -0
  172. package/src/tools/builtin-skills/web-search/handler.ts +50 -0
  173. package/src/tools/executor.ts +205 -0
  174. package/src/tools/integration-installer.ts +106 -0
  175. package/src/tools/permissions.ts +45 -0
  176. package/src/tools/registry.ts +39 -0
  177. package/src/tools/sandbox-runner.ts +56 -0
  178. package/src/tools/sandbox.ts +82 -0
  179. package/src/tools/skill-installer.ts +52 -0
  180. package/src/tools/skill-loader.ts +259 -0
  181. package/src/types/optional-deps.d.ts +23 -0
  182. package/src/util/auth.ts +121 -0
  183. package/src/util/costs.ts +59 -0
  184. package/src/util/error-buffer.ts +32 -0
  185. package/src/util/google-tokens.ts +180 -0
  186. package/src/util/logger.ts +73 -0
  187. package/src/util/perf-collector.ts +35 -0
  188. package/src/util/rate-limiter.ts +70 -0
  189. package/src/util/tokens.ts +17 -0
  190. package/src/voice/stt.ts +57 -0
  191. package/src/voice/tts.ts +103 -0
  192. package/tests/agent/session.test.ts +109 -0
  193. package/tests/agent-loop.test.ts +54 -0
  194. package/tests/auth.test.ts +89 -0
  195. package/tests/channels.test.ts +67 -0
  196. package/tests/compaction.test.ts +44 -0
  197. package/tests/config.test.ts +51 -0
  198. package/tests/costs.test.ts +19 -0
  199. package/tests/cron.test.ts +55 -0
  200. package/tests/db/export.test.ts +219 -0
  201. package/tests/executor.test.ts +144 -0
  202. package/tests/export.test.ts +137 -0
  203. package/tests/helpers/mock-llm.ts +34 -0
  204. package/tests/helpers/test-db.ts +74 -0
  205. package/tests/integration/chat-flow.test.ts +48 -0
  206. package/tests/integrations.test.ts +97 -0
  207. package/tests/memory/engine.test.ts +114 -0
  208. package/tests/memory-engine.test.ts +57 -0
  209. package/tests/permissions.test.ts +21 -0
  210. package/tests/rate-limiter.test.ts +70 -0
  211. package/tests/registry.test.ts +67 -0
  212. package/tests/router.test.ts +36 -0
  213. package/tests/session.test.ts +58 -0
  214. package/tests/skill-loader.test.ts +44 -0
  215. package/tests/tokens.test.ts +30 -0
  216. package/tests/tools/executor.test.ts +130 -0
  217. package/tests/util/auth.test.ts +75 -0
  218. package/tests/util/rate-limiter.test.ts +73 -0
  219. package/tests/voice.test.ts +60 -0
  220. package/tests/webchat.test.ts +88 -0
  221. package/tests/workflow.test.ts +38 -0
  222. package/tsconfig.json +16 -0
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Zubo Installer
5
+ # Usage: curl -fsSL https://zubo.bot/install.sh | bash
6
+
7
+ BOLD='\033[1m'
8
+ DIM='\033[2m'
9
+ GREEN='\033[32m'
10
+ YELLOW='\033[33m'
11
+ RED='\033[31m'
12
+ CYAN='\033[36m'
13
+ RESET='\033[0m'
14
+
15
+ info() { echo -e "${CYAN}${BOLD}→${RESET} $1"; }
16
+ ok() { echo -e "${GREEN}${BOLD}✓${RESET} $1"; }
17
+ warn() { echo -e "${YELLOW}${BOLD}!${RESET} $1"; }
18
+ fail() { echo -e "${RED}${BOLD}✗${RESET} $1"; exit 1; }
19
+
20
+ echo ""
21
+ echo -e "${BOLD} zubo installer${RESET}"
22
+ echo -e "${DIM} The AI agent that never forgets${RESET}"
23
+ echo ""
24
+
25
+ # --- OS detection ---
26
+ OS="$(uname -s)"
27
+ ARCH="$(uname -m)"
28
+
29
+ case "$OS" in
30
+ Linux*) PLATFORM="linux" ;;
31
+ Darwin*) PLATFORM="darwin" ;;
32
+ *) fail "Unsupported OS: $OS. Zubo supports macOS and Linux." ;;
33
+ esac
34
+
35
+ case "$ARCH" in
36
+ x86_64|amd64) ARCH="x64" ;;
37
+ arm64|aarch64) ARCH="aarch64" ;;
38
+ *) fail "Unsupported architecture: $ARCH" ;;
39
+ esac
40
+
41
+ info "Detected ${PLATFORM}/${ARCH}"
42
+
43
+ # --- Install Bun if missing ---
44
+ if command -v bun &>/dev/null; then
45
+ BUN_VERSION=$(bun --version 2>/dev/null || echo "unknown")
46
+ ok "Bun already installed (v${BUN_VERSION})"
47
+ else
48
+ info "Installing Bun runtime..."
49
+ curl -fsSL https://bun.sh/install | bash
50
+
51
+ # Source the updated profile so bun is on PATH
52
+ export BUN_INSTALL="${HOME}/.bun"
53
+ export PATH="${BUN_INSTALL}/bin:${PATH}"
54
+
55
+ if command -v bun &>/dev/null; then
56
+ ok "Bun installed (v$(bun --version))"
57
+ else
58
+ fail "Bun installation failed. Install manually: https://bun.sh"
59
+ fi
60
+ fi
61
+
62
+ # --- Install Zubo ---
63
+ info "Installing Zubo..."
64
+
65
+ if bun add -g zubo 2>/dev/null; then
66
+ ok "Zubo installed globally"
67
+ else
68
+ warn "Global install failed, trying with sudo..."
69
+ sudo bun add -g zubo || fail "Installation failed. Try: bun add -g zubo"
70
+ ok "Zubo installed globally (with sudo)"
71
+ fi
72
+
73
+ # --- Verify ---
74
+ if command -v zubo &>/dev/null; then
75
+ ZUBO_VERSION=$(zubo --version 2>/dev/null || echo "installed")
76
+ ok "Zubo is ready (${ZUBO_VERSION})"
77
+ else
78
+ # Bun global bin might not be on PATH yet
79
+ ZUBO_BIN="${HOME}/.bun/bin/zubo"
80
+ if [ -f "$ZUBO_BIN" ]; then
81
+ warn "Zubo installed but not on PATH. Add this to your shell profile:"
82
+ echo ""
83
+ echo -e " ${DIM}export PATH=\"\$HOME/.bun/bin:\$PATH\"${RESET}"
84
+ echo ""
85
+ else
86
+ fail "Zubo binary not found after install"
87
+ fi
88
+ fi
89
+
90
+ echo ""
91
+ echo -e "${BOLD} Next steps:${RESET}"
92
+ echo ""
93
+ echo -e " ${CYAN}1.${RESET} Run the setup wizard: ${BOLD}zubo setup${RESET}"
94
+ echo -e " ${CYAN}2.${RESET} Start your agent: ${BOLD}zubo start${RESET}"
95
+ echo -e " ${CYAN}3.${RESET} Open the dashboard: ${BOLD}zubo dashboard${RESET}"
96
+ echo ""
97
+ echo -e " ${DIM}Docs: https://zubo.bot/docs${RESET}"
98
+ echo ""
package/site/logo.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect width="100" height="100" rx="20" fill="#7c3aed"/><path d="M50 15C52 37 63 48 85 50C63 52 52 63 50 85C48 63 37 52 15 50C37 48 48 37 50 15Z" fill="white"/></svg>
Binary file
@@ -0,0 +1,4 @@
1
+ User-agent: *
2
+ Allow: /
3
+
4
+ Sitemap: https://zubo.bot/sitemap.xml
package/site/script.js ADDED
@@ -0,0 +1,361 @@
1
+ /* ============================================
2
+ Zubo Marketing Website — script.js
3
+ Vanilla JS, zero dependencies
4
+ ============================================ */
5
+
6
+ (function () {
7
+ 'use strict';
8
+
9
+ /* ------------------------------------------
10
+ 1. Navigation
11
+ ------------------------------------------ */
12
+ var nav = document.getElementById('nav');
13
+ var navToggle = document.getElementById('nav-toggle');
14
+ var navLinks = document.getElementById('nav-links');
15
+
16
+ function handleScroll() {
17
+ if (window.scrollY > 20) {
18
+ nav.classList.add('scrolled');
19
+ } else {
20
+ nav.classList.remove('scrolled');
21
+ }
22
+ }
23
+
24
+ window.addEventListener('scroll', handleScroll, { passive: true });
25
+ handleScroll();
26
+
27
+ if (navToggle && navLinks) {
28
+ navToggle.addEventListener('click', function () {
29
+ navToggle.classList.toggle('active');
30
+ navLinks.classList.toggle('open');
31
+ });
32
+
33
+ navLinks.querySelectorAll('a').forEach(function (link) {
34
+ link.addEventListener('click', function () {
35
+ navToggle.classList.remove('active');
36
+ navLinks.classList.remove('open');
37
+ });
38
+ });
39
+ }
40
+
41
+ /* ------------------------------------------
42
+ 2. Scroll-triggered reveal animations
43
+ ------------------------------------------ */
44
+ var revealElements = document.querySelectorAll('.reveal');
45
+
46
+ var revealObserver = new IntersectionObserver(
47
+ function (entries) {
48
+ entries.forEach(function (entry) {
49
+ if (entry.isIntersecting) {
50
+ entry.target.classList.add('visible');
51
+ revealObserver.unobserve(entry.target);
52
+ }
53
+ });
54
+ },
55
+ { threshold: 0.1, rootMargin: '0px 0px -40px 0px' }
56
+ );
57
+
58
+ revealElements.forEach(function (el) {
59
+ revealObserver.observe(el);
60
+ });
61
+
62
+ /* ------------------------------------------
63
+ 3. Stat counter animation
64
+ ------------------------------------------ */
65
+ var statNumbers = document.querySelectorAll('.hero-stat-number');
66
+ var statsAnimated = false;
67
+
68
+ function animateCounters() {
69
+ if (statsAnimated) return;
70
+ statsAnimated = true;
71
+
72
+ statNumbers.forEach(function (el) {
73
+ var target = parseInt(el.getAttribute('data-target'), 10);
74
+ var duration = 1500;
75
+ var start = 0;
76
+ var startTime = null;
77
+
78
+ function step(timestamp) {
79
+ if (!startTime) startTime = timestamp;
80
+ var progress = Math.min((timestamp - startTime) / duration, 1);
81
+ // Ease out cubic
82
+ var eased = 1 - Math.pow(1 - progress, 3);
83
+ var current = Math.round(start + (target - start) * eased);
84
+ el.textContent = current;
85
+ if (progress < 1) {
86
+ requestAnimationFrame(step);
87
+ } else {
88
+ el.textContent = target;
89
+ }
90
+ }
91
+
92
+ requestAnimationFrame(step);
93
+ });
94
+ }
95
+
96
+ if (statNumbers.length > 0) {
97
+ var statsSection = statNumbers[0].closest('.hero-stats');
98
+ if (statsSection) {
99
+ var statsObserver = new IntersectionObserver(
100
+ function (entries) {
101
+ if (entries[0].isIntersecting) {
102
+ animateCounters();
103
+ statsObserver.disconnect();
104
+ }
105
+ },
106
+ { threshold: 0.5 }
107
+ );
108
+ statsObserver.observe(statsSection);
109
+ }
110
+ }
111
+
112
+ /* ------------------------------------------
113
+ 4. Terminal typing animation
114
+ ------------------------------------------ */
115
+ var terminalStarted = false;
116
+
117
+ function typeText(element, callback) {
118
+ var text = element.getAttribute('data-text');
119
+ if (!text) { if (callback) callback(); return; }
120
+ var i = 0;
121
+ var speed = 25;
122
+
123
+ function typeChar() {
124
+ if (i < text.length) {
125
+ element.textContent += text.charAt(i);
126
+ i++;
127
+ setTimeout(typeChar, speed + Math.random() * 20);
128
+ } else {
129
+ if (callback) callback();
130
+ }
131
+ }
132
+
133
+ typeChar();
134
+ }
135
+
136
+ function showElement(id) {
137
+ var el = document.getElementById(id);
138
+ if (el) el.style.display = '';
139
+ }
140
+
141
+ function runTerminalDemo() {
142
+ if (terminalStarted) return;
143
+ terminalStarted = true;
144
+
145
+ var cursor = document.getElementById('terminal-cursor');
146
+
147
+ // Step 1: Type first message
148
+ setTimeout(function () {
149
+ typeText(document.getElementById('typed-1'), function () {
150
+ // Step 2: Show first response
151
+ setTimeout(function () {
152
+ showElement('response-1');
153
+ // Step 3: Show and type second prompt
154
+ setTimeout(function () {
155
+ showElement('prompt-2');
156
+ typeText(document.getElementById('typed-2'), function () {
157
+ // Step 4: Show second response
158
+ setTimeout(function () {
159
+ showElement('response-2');
160
+ // Step 5: Show and type third prompt
161
+ setTimeout(function () {
162
+ showElement('prompt-3');
163
+ typeText(document.getElementById('typed-3'), function () {
164
+ // Step 6: Show third response
165
+ setTimeout(function () {
166
+ showElement('response-3');
167
+ if (cursor) cursor.style.display = 'none';
168
+ }, 600);
169
+ });
170
+ }, 800);
171
+ }, 800);
172
+ });
173
+ }, 800);
174
+ }, 700);
175
+ });
176
+ }, 800);
177
+ }
178
+
179
+ var terminalBody = document.getElementById('terminal-body');
180
+ if (terminalBody) {
181
+ var termObserver = new IntersectionObserver(
182
+ function (entries) {
183
+ if (entries[0].isIntersecting) {
184
+ runTerminalDemo();
185
+ termObserver.disconnect();
186
+ }
187
+ },
188
+ { threshold: 0.3 }
189
+ );
190
+ termObserver.observe(terminalBody);
191
+ }
192
+
193
+ /* ------------------------------------------
194
+ 5. Copy-to-clipboard buttons
195
+ ------------------------------------------ */
196
+ function createCheckmarkIcon() {
197
+ var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
198
+ svg.setAttribute('width', '16');
199
+ svg.setAttribute('height', '16');
200
+ svg.setAttribute('viewBox', '0 0 24 24');
201
+ svg.setAttribute('fill', 'none');
202
+ svg.setAttribute('stroke', 'currentColor');
203
+ svg.setAttribute('stroke-width', '2');
204
+ svg.setAttribute('stroke-linecap', 'round');
205
+ svg.setAttribute('stroke-linejoin', 'round');
206
+ var polyline = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');
207
+ polyline.setAttribute('points', '20 6 9 17 4 12');
208
+ svg.appendChild(polyline);
209
+ return svg;
210
+ }
211
+
212
+ document.querySelectorAll('.copy-btn').forEach(function (btn) {
213
+ btn.addEventListener('click', function () {
214
+ var text = btn.getAttribute('data-copy');
215
+ if (!text) return;
216
+
217
+ navigator.clipboard.writeText(text).then(function () {
218
+ btn.classList.add('copied');
219
+ // Save original children and replace with checkmark
220
+ var originalChildren = Array.from(btn.childNodes).map(function (n) { return n.cloneNode(true); });
221
+ while (btn.firstChild) btn.removeChild(btn.firstChild);
222
+ btn.appendChild(createCheckmarkIcon());
223
+
224
+ setTimeout(function () {
225
+ btn.classList.remove('copied');
226
+ while (btn.firstChild) btn.removeChild(btn.firstChild);
227
+ originalChildren.forEach(function (child) { btn.appendChild(child); });
228
+ }, 2000);
229
+ });
230
+ });
231
+ });
232
+
233
+ /* ------------------------------------------
234
+ 6. Quick Start tab switching
235
+ ------------------------------------------ */
236
+ document.querySelectorAll('.qs-tab').forEach(function (tab) {
237
+ tab.addEventListener('click', function () {
238
+ // Deactivate all tabs and panes
239
+ document.querySelectorAll('.qs-tab').forEach(function (t) { t.classList.remove('active'); });
240
+ document.querySelectorAll('.qs-pane').forEach(function (p) { p.classList.remove('active'); });
241
+ // Activate clicked tab and matching pane
242
+ tab.classList.add('active');
243
+ var paneId = 'qs-' + tab.getAttribute('data-tab');
244
+ var pane = document.getElementById(paneId);
245
+ if (pane) pane.classList.add('active');
246
+ });
247
+ });
248
+
249
+ /* ------------------------------------------
250
+ 7. Bento card mouse glow effect
251
+ ------------------------------------------ */
252
+ document.querySelectorAll('.bento-card').forEach(function (card) {
253
+ card.addEventListener('mousemove', function (e) {
254
+ var rect = card.getBoundingClientRect();
255
+ var x = e.clientX - rect.left;
256
+ var y = e.clientY - rect.top;
257
+ card.style.setProperty('--mouse-x', x + 'px');
258
+ card.style.setProperty('--mouse-y', y + 'px');
259
+ });
260
+ });
261
+
262
+ /* ------------------------------------------
263
+ 8. Scroll progress bar
264
+ ------------------------------------------ */
265
+ var progressBar = document.getElementById('scroll-progress');
266
+ if (progressBar) {
267
+ window.addEventListener('scroll', function () {
268
+ var h = document.documentElement;
269
+ var progress = h.scrollTop / (h.scrollHeight - h.clientHeight);
270
+ progressBar.style.setProperty('--progress', Math.min(progress, 1));
271
+ }, { passive: true });
272
+ }
273
+
274
+ /* ------------------------------------------
275
+ 9. Stagger reveal observer
276
+ ------------------------------------------ */
277
+ var staggerElements = document.querySelectorAll('.reveal-stagger');
278
+ var staggerObserver = new IntersectionObserver(function (entries) {
279
+ entries.forEach(function (entry) {
280
+ if (entry.isIntersecting) {
281
+ entry.target.classList.add('visible');
282
+ staggerObserver.unobserve(entry.target);
283
+ }
284
+ });
285
+ }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
286
+ staggerElements.forEach(function (el) {
287
+ staggerObserver.observe(el);
288
+ });
289
+
290
+ /* ------------------------------------------
291
+ 10. Card tilt effect
292
+ ------------------------------------------ */
293
+ document.querySelectorAll('.tilt-card').forEach(function (card) {
294
+ card.addEventListener('mousemove', function (e) {
295
+ var rect = card.getBoundingClientRect();
296
+ var x = e.clientX - rect.left;
297
+ var y = e.clientY - rect.top;
298
+ var centerX = rect.width / 2;
299
+ var centerY = rect.height / 2;
300
+ var tiltX = ((y - centerY) / centerY) * -4;
301
+ var tiltY = ((x - centerX) / centerX) * 4;
302
+ card.style.transform = 'perspective(800px) rotateX(' + tiltX + 'deg) rotateY(' + tiltY + 'deg)';
303
+ });
304
+ card.addEventListener('mouseleave', function () {
305
+ card.style.transform = 'perspective(800px) rotateX(0) rotateY(0)';
306
+ });
307
+ });
308
+
309
+ /* ------------------------------------------
310
+ 11. Animated gradient border angle
311
+ ------------------------------------------ */
312
+ var glowBorders = document.querySelectorAll('.glow-border');
313
+ if (glowBorders.length > 0 && !CSS.supports('animation-timeline', 'auto')) {
314
+ var angle = 0;
315
+ function updateAngle() {
316
+ angle = (angle + 0.5) % 360;
317
+ glowBorders.forEach(function (el) {
318
+ el.style.setProperty('--angle', angle + 'deg');
319
+ });
320
+ requestAnimationFrame(updateAngle);
321
+ }
322
+ requestAnimationFrame(updateAngle);
323
+ }
324
+
325
+ /* ------------------------------------------
326
+ 12. Docs sidebar mobile toggle
327
+ ------------------------------------------ */
328
+ var docsSidebarToggle = document.getElementById('docs-sidebar-toggle');
329
+ var docsSidebar = document.getElementById('docs-sidebar');
330
+ if (docsSidebarToggle && docsSidebar) {
331
+ docsSidebarToggle.addEventListener('click', function () {
332
+ docsSidebar.classList.toggle('open');
333
+ docsSidebarToggle.textContent = docsSidebar.classList.contains('open') ? '\u2715' : '\u2630';
334
+ });
335
+ // Close sidebar when clicking a link
336
+ docsSidebar.querySelectorAll('a').forEach(function (link) {
337
+ link.addEventListener('click', function () {
338
+ docsSidebar.classList.remove('open');
339
+ docsSidebarToggle.textContent = '\u2630';
340
+ });
341
+ });
342
+ }
343
+
344
+ /* ------------------------------------------
345
+ 13. Smooth scroll for anchor links
346
+ ------------------------------------------ */
347
+ document.querySelectorAll('a[href^="#"]').forEach(function (anchor) {
348
+ anchor.addEventListener('click', function (e) {
349
+ var href = anchor.getAttribute('href');
350
+ if (href === '#') return;
351
+ var target = document.querySelector(href);
352
+ if (target) {
353
+ e.preventDefault();
354
+ var offset = 80; // nav height + padding
355
+ var top = target.getBoundingClientRect().top + window.scrollY - offset;
356
+ window.scrollTo({ top: top, behavior: 'smooth' });
357
+ }
358
+ });
359
+ });
360
+
361
+ })();
@@ -0,0 +1,63 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
+ <url>
4
+ <loc>https://zubo.bot/</loc>
5
+ <priority>1.0</priority>
6
+ <changefreq>weekly</changefreq>
7
+ </url>
8
+ <url>
9
+ <loc>https://zubo.bot/skills.html</loc>
10
+ <priority>0.8</priority>
11
+ <changefreq>weekly</changefreq>
12
+ </url>
13
+ <url>
14
+ <loc>https://zubo.bot/docs/</loc>
15
+ <priority>0.9</priority>
16
+ <changefreq>weekly</changefreq>
17
+ </url>
18
+ <url>
19
+ <loc>https://zubo.bot/docs/config.html</loc>
20
+ <priority>0.8</priority>
21
+ <changefreq>weekly</changefreq>
22
+ </url>
23
+ <url>
24
+ <loc>https://zubo.bot/docs/agents.html</loc>
25
+ <priority>0.7</priority>
26
+ <changefreq>monthly</changefreq>
27
+ </url>
28
+ <url>
29
+ <loc>https://zubo.bot/docs/memory.html</loc>
30
+ <priority>0.7</priority>
31
+ <changefreq>monthly</changefreq>
32
+ </url>
33
+ <url>
34
+ <loc>https://zubo.bot/docs/skills.html</loc>
35
+ <priority>0.7</priority>
36
+ <changefreq>monthly</changefreq>
37
+ </url>
38
+ <url>
39
+ <loc>https://zubo.bot/docs/channels.html</loc>
40
+ <priority>0.7</priority>
41
+ <changefreq>monthly</changefreq>
42
+ </url>
43
+ <url>
44
+ <loc>https://zubo.bot/docs/integrations.html</loc>
45
+ <priority>0.7</priority>
46
+ <changefreq>monthly</changefreq>
47
+ </url>
48
+ <url>
49
+ <loc>https://zubo.bot/docs/security.html</loc>
50
+ <priority>0.7</priority>
51
+ <changefreq>monthly</changefreq>
52
+ </url>
53
+ <url>
54
+ <loc>https://zubo.bot/docs/api.html</loc>
55
+ <priority>0.7</priority>
56
+ <changefreq>monthly</changefreq>
57
+ </url>
58
+ <url>
59
+ <loc>https://zubo.bot/docs/cli.html</loc>
60
+ <priority>0.7</priority>
61
+ <changefreq>monthly</changefreq>
62
+ </url>
63
+ </urlset>