zubo 0.1.16 → 0.1.18

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 (48) hide show
  1. package/.dockerignore +0 -1
  2. package/Dockerfile.registry +17 -0
  3. package/migrations/019_conversations.sql +14 -0
  4. package/migrations/020_email_digests.sql +13 -0
  5. package/migrations/021_webhooks_enhance.sql +3 -0
  6. package/migrations/022_visual_workflows.sql +14 -0
  7. package/migrations/023_skill_registry.sql +96 -0
  8. package/package.json +1 -1
  9. package/site/404.html +22 -22
  10. package/site/admin.html +1379 -0
  11. package/site/docs/agents.html +28 -28
  12. package/site/docs/api.html +627 -33
  13. package/site/docs/channels.html +28 -28
  14. package/site/docs/cli.html +27 -27
  15. package/site/docs/config.html +112 -27
  16. package/site/docs/conversations.html +296 -0
  17. package/site/docs/index.html +48 -35
  18. package/site/docs/integrations.html +30 -30
  19. package/site/docs/marketplace.html +299 -0
  20. package/site/docs/memory.html +27 -27
  21. package/site/docs/security.html +29 -29
  22. package/site/docs/skills.html +59 -34
  23. package/site/docs/webhooks.html +362 -0
  24. package/site/docs/workflows.html +406 -0
  25. package/site/index.html +4 -4
  26. package/site/skills.html +708 -164
  27. package/site/style.css +518 -0
  28. package/src/agent/history.ts +122 -0
  29. package/src/agent/prompts.ts +7 -6
  30. package/src/agent/session.ts +15 -0
  31. package/src/channels/dashboard.html.ts +1338 -19
  32. package/src/channels/webchat.ts +555 -7
  33. package/src/registry/cli.ts +98 -8
  34. package/src/registry/client.ts +65 -16
  35. package/src/registry/installer.ts +23 -15
  36. package/src/registry/server.ts +864 -0
  37. package/src/registry/skill-registry.ts +550 -0
  38. package/src/scheduler/digest.ts +638 -0
  39. package/src/scheduler/visual-workflows.ts +502 -0
  40. package/src/start.ts +18 -0
  41. package/src/tools/builtin/skill-registry.ts +79 -3
  42. package/src/tools/mcp-registry.ts +229 -0
  43. package/tests/digest.test.ts +261 -0
  44. package/tests/history.test.ts +254 -0
  45. package/tests/mcp-registry.test.ts +344 -0
  46. package/tests/skill-registry.test.ts +631 -0
  47. package/tests/visual-workflows.test.ts +575 -0
  48. package/tests/webhooks-enhanced.test.ts +340 -0
package/.dockerignore CHANGED
@@ -1,7 +1,6 @@
1
1
  node_modules
2
2
  dist
3
3
  desktop
4
- site
5
4
  .env
6
5
  .env.*
7
6
  .zubo
@@ -0,0 +1,17 @@
1
+ FROM oven/bun:1
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package.json bun.lock* ./
6
+ RUN bun install --production
7
+
8
+ COPY . .
9
+
10
+ VOLUME /data
11
+
12
+ ENV REGISTRY_DB_PATH=/data/registry.db
13
+ ENV REGISTRY_PORT=3000
14
+
15
+ EXPOSE 3000
16
+
17
+ CMD ["bun", "run", "src/registry/server.ts"]
@@ -0,0 +1,14 @@
1
+ CREATE TABLE IF NOT EXISTS conversation_messages (
2
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
3
+ thread_id TEXT NOT NULL,
4
+ role TEXT NOT NULL,
5
+ content TEXT NOT NULL,
6
+ channel TEXT,
7
+ timestamp TEXT NOT NULL DEFAULT (datetime('now'))
8
+ );
9
+ CREATE INDEX idx_conv_msg_thread ON conversation_messages(thread_id);
10
+ CREATE INDEX idx_conv_msg_ts ON conversation_messages(timestamp DESC);
11
+ CREATE VIRTUAL TABLE IF NOT EXISTS conversation_search USING fts5(content, thread_id UNINDEXED, role UNINDEXED);
12
+ ALTER TABLE threads ADD COLUMN channel TEXT DEFAULT 'webchat';
13
+ ALTER TABLE threads ADD COLUMN message_count INTEGER DEFAULT 0;
14
+ ALTER TABLE threads ADD COLUMN summary TEXT;
@@ -0,0 +1,13 @@
1
+ CREATE TABLE IF NOT EXISTS email_digest_config (
2
+ id INTEGER PRIMARY KEY CHECK (id = 1),
3
+ enabled INTEGER NOT NULL DEFAULT 0,
4
+ frequency TEXT NOT NULL DEFAULT 'daily',
5
+ send_time TEXT NOT NULL DEFAULT '09:00',
6
+ email_to TEXT,
7
+ include_conversations INTEGER NOT NULL DEFAULT 1,
8
+ include_tool_usage INTEGER NOT NULL DEFAULT 1,
9
+ include_errors INTEGER NOT NULL DEFAULT 1,
10
+ include_scheduled_tasks INTEGER NOT NULL DEFAULT 1,
11
+ last_sent_at TEXT
12
+ );
13
+ INSERT OR IGNORE INTO email_digest_config (id) VALUES (1);
@@ -0,0 +1,3 @@
1
+ ALTER TABLE webhooks ADD COLUMN prompt_template TEXT;
2
+ ALTER TABLE webhooks ADD COLUMN last_triggered_at TEXT;
3
+ ALTER TABLE webhooks ADD COLUMN trigger_count INTEGER NOT NULL DEFAULT 0;
@@ -0,0 +1,14 @@
1
+ CREATE TABLE IF NOT EXISTS visual_workflows (
2
+ id TEXT PRIMARY KEY,
3
+ name TEXT NOT NULL,
4
+ description TEXT,
5
+ trigger_type TEXT NOT NULL,
6
+ trigger_config TEXT NOT NULL,
7
+ steps TEXT NOT NULL,
8
+ canvas_data TEXT,
9
+ enabled INTEGER NOT NULL DEFAULT 1,
10
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
11
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
12
+ last_run_at TEXT,
13
+ run_count INTEGER NOT NULL DEFAULT 0
14
+ );
@@ -0,0 +1,96 @@
1
+ -- Skill Registry: Community skill marketplace tables
2
+
3
+ CREATE TABLE IF NOT EXISTS registry_profiles (
4
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
5
+ github_id INTEGER UNIQUE NOT NULL,
6
+ username TEXT UNIQUE NOT NULL,
7
+ display_name TEXT,
8
+ bio TEXT,
9
+ website TEXT,
10
+ github_url TEXT,
11
+ avatar_url TEXT,
12
+ email TEXT,
13
+ session_token TEXT,
14
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
15
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
16
+ );
17
+
18
+ CREATE TABLE IF NOT EXISTS registry_skills (
19
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
20
+ name TEXT UNIQUE NOT NULL,
21
+ description TEXT NOT NULL,
22
+ author_id INTEGER NOT NULL REFERENCES registry_profiles(id),
23
+ version TEXT NOT NULL DEFAULT '1.0.0',
24
+ tags TEXT NOT NULL DEFAULT '[]',
25
+ secrets TEXT NOT NULL DEFAULT '[]',
26
+ handler_code TEXT NOT NULL,
27
+ skill_md TEXT,
28
+ repo_url TEXT,
29
+ status TEXT NOT NULL DEFAULT 'approved' CHECK(status IN ('approved', 'flagged', 'rejected')),
30
+ review_notes TEXT NOT NULL DEFAULT '[]',
31
+ risk_level TEXT NOT NULL DEFAULT 'low' CHECK(risk_level IN ('low', 'medium', 'high')),
32
+ stars_count INTEGER NOT NULL DEFAULT 0,
33
+ install_count INTEGER NOT NULL DEFAULT 0,
34
+ report_count INTEGER NOT NULL DEFAULT 0,
35
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
36
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
37
+ );
38
+
39
+ CREATE VIRTUAL TABLE IF NOT EXISTS registry_skills_fts USING fts5(
40
+ name,
41
+ description,
42
+ tags,
43
+ content='registry_skills',
44
+ content_rowid='id'
45
+ );
46
+
47
+ -- Triggers to keep FTS in sync
48
+ CREATE TRIGGER IF NOT EXISTS registry_skills_ai AFTER INSERT ON registry_skills BEGIN
49
+ INSERT INTO registry_skills_fts(rowid, name, description, tags)
50
+ VALUES (new.id, new.name, new.description, new.tags);
51
+ END;
52
+
53
+ CREATE TRIGGER IF NOT EXISTS registry_skills_ad AFTER DELETE ON registry_skills BEGIN
54
+ INSERT INTO registry_skills_fts(registry_skills_fts, rowid, name, description, tags)
55
+ VALUES ('delete', old.id, old.name, old.description, old.tags);
56
+ END;
57
+
58
+ CREATE TRIGGER IF NOT EXISTS registry_skills_au AFTER UPDATE ON registry_skills BEGIN
59
+ INSERT INTO registry_skills_fts(registry_skills_fts, rowid, name, description, tags)
60
+ VALUES ('delete', old.id, old.name, old.description, old.tags);
61
+ INSERT INTO registry_skills_fts(rowid, name, description, tags)
62
+ VALUES (new.id, new.name, new.description, new.tags);
63
+ END;
64
+
65
+ CREATE TABLE IF NOT EXISTS registry_stars (
66
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
67
+ skill_id INTEGER NOT NULL REFERENCES registry_skills(id) ON DELETE CASCADE,
68
+ profile_id INTEGER NOT NULL REFERENCES registry_profiles(id) ON DELETE CASCADE,
69
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
70
+ UNIQUE(skill_id, profile_id)
71
+ );
72
+
73
+ CREATE TABLE IF NOT EXISTS registry_installs (
74
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
75
+ skill_id INTEGER NOT NULL REFERENCES registry_skills(id) ON DELETE CASCADE,
76
+ user_fingerprint TEXT,
77
+ installed_at TEXT NOT NULL DEFAULT (datetime('now'))
78
+ );
79
+
80
+ CREATE TABLE IF NOT EXISTS registry_reports (
81
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
82
+ skill_id INTEGER NOT NULL REFERENCES registry_skills(id) ON DELETE CASCADE,
83
+ reporter_email TEXT NOT NULL,
84
+ reason TEXT NOT NULL,
85
+ details TEXT,
86
+ status TEXT NOT NULL DEFAULT 'open' CHECK(status IN ('open', 'resolved', 'dismissed')),
87
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
88
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
89
+ );
90
+
91
+ CREATE INDEX IF NOT EXISTS idx_registry_skills_status ON registry_skills(status);
92
+ CREATE INDEX IF NOT EXISTS idx_registry_skills_author ON registry_skills(author_id);
93
+ CREATE INDEX IF NOT EXISTS idx_registry_installs_skill ON registry_installs(skill_id);
94
+ CREATE INDEX IF NOT EXISTS idx_registry_installs_date ON registry_installs(installed_at);
95
+ CREATE INDEX IF NOT EXISTS idx_registry_reports_status ON registry_reports(status);
96
+ CREATE INDEX IF NOT EXISTS idx_registry_stars_skill ON registry_stars(skill_id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zubo",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Your AI agent that never forgets. Persistent memory, 25+ tools, 7 channels, 11+ LLM providers — runs entirely on your machine.",
5
5
  "license": "MIT",
6
6
  "author": "thomaskanze",
package/site/404.html CHANGED
@@ -3,19 +3,19 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>404 — Page Not Found | Zubo</title>
7
- <meta name="description" content="The page you're looking for doesn't exist. Head back to Zubo's home page.">
6
+ <title>404 — Page Not Found Zubo Docs</title>
7
+ <meta name="description" content="The page you are looking for does not exist or has been moved. Return to the Zubo documentation home page to find what you need.">
8
8
  <meta name="theme-color" content="#060608">
9
- <link rel="canonical" href="https://zubo.bot/404.html">
10
- <meta property="og:title" content="404 — Page Not Found | Zubo">
11
- <meta property="og:description" content="The page you're looking for doesn't exist. Head back to Zubo's home page.">
9
+ <link rel="canonical" href="https://zubo.bot/404">
10
+ <meta property="og:title" content="404 — Page Not Found Zubo Docs">
11
+ <meta property="og:description" content="The page you are looking for does not exist or has been moved. Return to the Zubo documentation home page to find what you need.">
12
12
  <meta property="og:type" content="website">
13
- <meta property="og:url" content="https://zubo.bot/404.html">
13
+ <meta property="og:url" content="https://zubo.bot/404">
14
14
  <meta property="og:image" content="https://zubo.bot/og-image.png">
15
15
  <meta property="og:site_name" content="Zubo">
16
16
  <meta name="twitter:card" content="summary_large_image">
17
- <meta name="twitter:title" content="404 — Page Not Found | Zubo">
18
- <meta name="twitter:description" content="The page you're looking for doesn't exist. Head back to Zubo's home page.">
17
+ <meta name="twitter:title" content="404 — Page Not Found Zubo Docs">
18
+ <meta name="twitter:description" content="The page you are looking for does not exist or has been moved. Return to the Zubo documentation home page to find what you need.">
19
19
  <meta name="twitter:image" content="https://zubo.bot/og-image.png">
20
20
  <meta name="twitter:creator" content="@thomaskanze">
21
21
  <meta name="robots" content="noindex, follow">
@@ -77,20 +77,20 @@
77
77
  <!-- ========== NAVIGATION ========== -->
78
78
  <header class="nav" id="nav">
79
79
  <div class="nav-inner">
80
- <a href="index.html" class="nav-logo">
80
+ <a href="/" class="nav-logo">
81
81
  <span class="logo-wordmark">zubo</span>
82
82
  </a>
83
83
  <nav class="nav-links" id="nav-links">
84
- <a href="index.html#features">Features</a>
85
- <a href="docs/index.html">Docs</a>
86
- <a href="skills.html">Skills</a>
87
- <a href="index.html#get-started">Get Started</a>
84
+ <a href="/#features">Features</a>
85
+ <a href="/docs/">Docs</a>
86
+ <a href="/skills">Skills</a>
87
+ <a href="/#get-started">Get Started</a>
88
88
  </nav>
89
89
  <div class="nav-right">
90
90
  <a href="https://github.com/apwn/zubo" class="nav-github" aria-label="GitHub">
91
91
  <svg width="20" height="20" 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.23.957-.266 1.983-.399 3.003-.404 1.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.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
92
92
  </a>
93
- <a href="index.html#get-started" class="btn btn-primary btn-nav">Get Started</a>
93
+ <a href="/#get-started" class="btn btn-primary btn-nav">Get Started</a>
94
94
  <button class="nav-toggle" id="nav-toggle" aria-label="Toggle menu">
95
95
  <span></span><span></span><span></span>
96
96
  </button>
@@ -104,7 +104,7 @@
104
104
  <div class="error-code">404</div>
105
105
  <h1 class="error-subtitle">Page not found</h1>
106
106
  <p class="error-description">The page you're looking for doesn't exist or has been moved. Let's get you back on track.</p>
107
- <a href="index.html" class="btn btn-primary btn-lg">
107
+ <a href="/" class="btn btn-primary btn-lg">
108
108
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5"/><polyline points="12 19 5 12 12 5"/></svg>
109
109
  Back to Home
110
110
  </a>
@@ -116,7 +116,7 @@
116
116
  <div class="container">
117
117
  <div class="footer-inner">
118
118
  <div class="footer-brand">
119
- <a href="index.html" class="nav-logo">
119
+ <a href="/" class="nav-logo">
120
120
  <span class="logo-wordmark">zubo</span>
121
121
  </a>
122
122
  <p>Your AI agent that never forgets.</p>
@@ -124,15 +124,15 @@
124
124
  <div class="footer-links">
125
125
  <div class="footer-col">
126
126
  <h5>Product</h5>
127
- <a href="index.html#features">Features</a>
128
- <a href="index.html#integrations">Integrations</a>
129
- <a href="index.html#channels">Channels</a>
130
- <a href="index.html#get-started">Get Started</a>
127
+ <a href="/#features">Features</a>
128
+ <a href="/#integrations">Integrations</a>
129
+ <a href="/#channels">Channels</a>
130
+ <a href="/#get-started">Get Started</a>
131
131
  </div>
132
132
  <div class="footer-col">
133
133
  <h5>Resources</h5>
134
- <a href="docs/index.html">Documentation</a>
135
- <a href="skills.html">Community Skills</a>
134
+ <a href="/docs/">Documentation</a>
135
+ <a href="/skills">Community Skills</a>
136
136
  <a href="https://github.com/apwn/zubo">GitHub</a>
137
137
  <a href="https://github.com/apwn/zubo/issues">Issues</a>
138
138
  </div>