botschat 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 (88) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +213 -0
  3. package/migrations/0001_initial.sql +88 -0
  4. package/migrations/0002_rename_projects_to_channels.sql +53 -0
  5. package/migrations/0003_messages.sql +14 -0
  6. package/migrations/0004_jobs.sql +15 -0
  7. package/migrations/0005_deleted_cron_jobs.sql +6 -0
  8. package/migrations/0006_tasks_add_model.sql +2 -0
  9. package/migrations/0007_sessions.sql +25 -0
  10. package/migrations/0008_remove_openclaw_fields.sql +8 -0
  11. package/package.json +53 -0
  12. package/packages/api/package.json +17 -0
  13. package/packages/api/src/do/connection-do.ts +929 -0
  14. package/packages/api/src/env.ts +8 -0
  15. package/packages/api/src/index.ts +297 -0
  16. package/packages/api/src/routes/agents.ts +68 -0
  17. package/packages/api/src/routes/auth.ts +105 -0
  18. package/packages/api/src/routes/channels.ts +185 -0
  19. package/packages/api/src/routes/jobs.ts +65 -0
  20. package/packages/api/src/routes/models.ts +22 -0
  21. package/packages/api/src/routes/pairing.ts +76 -0
  22. package/packages/api/src/routes/projects.ts +177 -0
  23. package/packages/api/src/routes/sessions.ts +171 -0
  24. package/packages/api/src/routes/tasks.ts +375 -0
  25. package/packages/api/src/routes/upload.ts +52 -0
  26. package/packages/api/src/utils/auth.ts +101 -0
  27. package/packages/api/src/utils/id.ts +19 -0
  28. package/packages/api/tsconfig.json +18 -0
  29. package/packages/plugin/dist/index.d.ts +19 -0
  30. package/packages/plugin/dist/index.d.ts.map +1 -0
  31. package/packages/plugin/dist/index.js +17 -0
  32. package/packages/plugin/dist/index.js.map +1 -0
  33. package/packages/plugin/dist/src/accounts.d.ts +12 -0
  34. package/packages/plugin/dist/src/accounts.d.ts.map +1 -0
  35. package/packages/plugin/dist/src/accounts.js +103 -0
  36. package/packages/plugin/dist/src/accounts.js.map +1 -0
  37. package/packages/plugin/dist/src/channel.d.ts +206 -0
  38. package/packages/plugin/dist/src/channel.d.ts.map +1 -0
  39. package/packages/plugin/dist/src/channel.js +1248 -0
  40. package/packages/plugin/dist/src/channel.js.map +1 -0
  41. package/packages/plugin/dist/src/runtime.d.ts +3 -0
  42. package/packages/plugin/dist/src/runtime.d.ts.map +1 -0
  43. package/packages/plugin/dist/src/runtime.js +18 -0
  44. package/packages/plugin/dist/src/runtime.js.map +1 -0
  45. package/packages/plugin/dist/src/types.d.ts +179 -0
  46. package/packages/plugin/dist/src/types.d.ts.map +1 -0
  47. package/packages/plugin/dist/src/types.js +6 -0
  48. package/packages/plugin/dist/src/types.js.map +1 -0
  49. package/packages/plugin/dist/src/ws-client.d.ts +51 -0
  50. package/packages/plugin/dist/src/ws-client.d.ts.map +1 -0
  51. package/packages/plugin/dist/src/ws-client.js +170 -0
  52. package/packages/plugin/dist/src/ws-client.js.map +1 -0
  53. package/packages/plugin/openclaw.plugin.json +11 -0
  54. package/packages/plugin/package.json +39 -0
  55. package/packages/plugin/tsconfig.json +20 -0
  56. package/packages/web/dist/assets/index-C-wI8eHy.css +1 -0
  57. package/packages/web/dist/assets/index-CbPEKHLG.js +93 -0
  58. package/packages/web/dist/index.html +17 -0
  59. package/packages/web/index.html +16 -0
  60. package/packages/web/package.json +29 -0
  61. package/packages/web/postcss.config.js +6 -0
  62. package/packages/web/src/App.tsx +827 -0
  63. package/packages/web/src/api.ts +242 -0
  64. package/packages/web/src/components/ChatWindow.tsx +864 -0
  65. package/packages/web/src/components/CronDetail.tsx +943 -0
  66. package/packages/web/src/components/CronSidebar.tsx +123 -0
  67. package/packages/web/src/components/DebugLogPanel.tsx +258 -0
  68. package/packages/web/src/components/IconRail.tsx +163 -0
  69. package/packages/web/src/components/JobList.tsx +120 -0
  70. package/packages/web/src/components/LoginPage.tsx +178 -0
  71. package/packages/web/src/components/MessageContent.tsx +1082 -0
  72. package/packages/web/src/components/ModelSelect.tsx +87 -0
  73. package/packages/web/src/components/ScheduleEditor.tsx +403 -0
  74. package/packages/web/src/components/SessionTabs.tsx +246 -0
  75. package/packages/web/src/components/Sidebar.tsx +331 -0
  76. package/packages/web/src/components/TaskBar.tsx +413 -0
  77. package/packages/web/src/components/ThreadPanel.tsx +212 -0
  78. package/packages/web/src/debug-log.ts +58 -0
  79. package/packages/web/src/index.css +170 -0
  80. package/packages/web/src/main.tsx +10 -0
  81. package/packages/web/src/store.ts +492 -0
  82. package/packages/web/src/ws.ts +99 -0
  83. package/packages/web/tailwind.config.js +65 -0
  84. package/packages/web/tsconfig.json +18 -0
  85. package/packages/web/vite.config.ts +20 -0
  86. package/scripts/dev.sh +122 -0
  87. package/tsconfig.json +18 -0
  88. package/wrangler.toml +40 -0
@@ -0,0 +1,178 @@
1
+ import React, { useState } from "react";
2
+ import { authApi, setToken } from "../api";
3
+ import { useAppDispatch } from "../store";
4
+ import { dlog } from "../debug-log";
5
+
6
+ export function LoginPage() {
7
+ const dispatch = useAppDispatch();
8
+ const [isRegister, setIsRegister] = useState(false);
9
+ const [email, setEmail] = useState("");
10
+ const [password, setPassword] = useState("");
11
+ const [displayName, setDisplayName] = useState("");
12
+ const [error, setError] = useState("");
13
+ const [loading, setLoading] = useState(false);
14
+
15
+ const handleSubmit = async (e: React.FormEvent) => {
16
+ e.preventDefault();
17
+ setError("");
18
+ setLoading(true);
19
+
20
+ try {
21
+ let res;
22
+ if (isRegister) {
23
+ dlog.info("Auth", `Registering new account: ${email}`);
24
+ res = await authApi.register(email, password, displayName || undefined);
25
+ } else {
26
+ dlog.info("Auth", `Logging in: ${email}`);
27
+ res = await authApi.login(email, password);
28
+ }
29
+ dlog.info("Auth", `${isRegister ? "Register" : "Login"} success — user ${res.id} (${res.email})`);
30
+ setToken(res.token);
31
+ dispatch({
32
+ type: "SET_USER",
33
+ user: { id: res.id, email: res.email, displayName: res.displayName },
34
+ });
35
+ } catch (err) {
36
+ const message = err instanceof Error ? err.message : "Something went wrong";
37
+ dlog.error("Auth", `${isRegister ? "Register" : "Login"} failed: ${message}`);
38
+ setError(message);
39
+ } finally {
40
+ setLoading(false);
41
+ }
42
+ };
43
+
44
+ return (
45
+ <div
46
+ className="min-h-screen flex items-center justify-center"
47
+ style={{ background: "var(--bg-secondary)" }}
48
+ >
49
+ <div className="w-full max-w-md">
50
+ {/* Header */}
51
+ <div className="text-center mb-8">
52
+ <div
53
+ className="inline-flex items-center justify-center w-16 h-16 rounded-xl text-white text-2xl font-bold mb-4"
54
+ style={{ background: "#1264A3" }}
55
+ >
56
+ BC
57
+ </div>
58
+ <h1 className="text-3xl font-bold" style={{ color: "var(--text-primary)" }}>
59
+ BotsChat
60
+ </h1>
61
+ <p className="mt-2" style={{ color: "var(--text-secondary)" }}>
62
+ Multi-channel AI chat powered by OpenClaw
63
+ </p>
64
+ </div>
65
+
66
+ {/* Form card */}
67
+ <div
68
+ className="rounded-md p-8"
69
+ style={{
70
+ background: "var(--bg-surface)",
71
+ boxShadow: "var(--shadow-lg)",
72
+ }}
73
+ >
74
+ <h2 className="text-h1 mb-6" style={{ color: "var(--text-primary)" }}>
75
+ {isRegister ? "Create account" : "Sign in"}
76
+ </h2>
77
+
78
+ <form onSubmit={handleSubmit} className="space-y-4">
79
+ {isRegister && (
80
+ <div>
81
+ <label className="block text-caption font-bold mb-1" style={{ color: "var(--text-secondary)" }}>
82
+ Display Name
83
+ </label>
84
+ <input
85
+ type="text"
86
+ value={displayName}
87
+ onChange={(e) => setDisplayName(e.target.value)}
88
+ className="w-full px-3 py-2.5 text-body rounded-sm focus:outline-none placeholder:text-[--text-muted]"
89
+ style={{
90
+ background: "var(--bg-surface)",
91
+ color: "var(--text-primary)",
92
+ border: "1px solid var(--border)",
93
+ }}
94
+ placeholder="Your name"
95
+ />
96
+ </div>
97
+ )}
98
+
99
+ <div>
100
+ <label className="block text-caption font-bold mb-1" style={{ color: "var(--text-secondary)" }}>
101
+ Email
102
+ </label>
103
+ <input
104
+ type="email"
105
+ value={email}
106
+ onChange={(e) => setEmail(e.target.value)}
107
+ required
108
+ className="w-full px-3 py-2.5 text-body rounded-sm focus:outline-none placeholder:text-[--text-muted]"
109
+ style={{
110
+ background: "var(--bg-surface)",
111
+ color: "var(--text-primary)",
112
+ border: "1px solid var(--border)",
113
+ }}
114
+ placeholder="you@example.com"
115
+ />
116
+ </div>
117
+
118
+ <div>
119
+ <label className="block text-caption font-bold mb-1" style={{ color: "var(--text-secondary)" }}>
120
+ Password
121
+ </label>
122
+ <input
123
+ type="password"
124
+ value={password}
125
+ onChange={(e) => setPassword(e.target.value)}
126
+ required
127
+ className="w-full px-3 py-2.5 text-body rounded-sm focus:outline-none placeholder:text-[--text-muted]"
128
+ style={{
129
+ background: "var(--bg-surface)",
130
+ color: "var(--text-primary)",
131
+ border: "1px solid var(--border)",
132
+ }}
133
+ placeholder="Enter password"
134
+ />
135
+ </div>
136
+
137
+ {error && (
138
+ <div
139
+ className="text-caption px-3 py-2 rounded-sm"
140
+ style={{ background: "rgba(224,30,90,0.1)", color: "var(--accent-red)" }}
141
+ >
142
+ {error}
143
+ </div>
144
+ )}
145
+
146
+ <button
147
+ type="submit"
148
+ disabled={loading}
149
+ className="w-full py-2.5 font-bold text-body text-white rounded-sm disabled:opacity-50 transition-colors hover:brightness-110"
150
+ style={{ background: "var(--bg-active)" }}
151
+ >
152
+ {loading
153
+ ? "..."
154
+ : isRegister
155
+ ? "Create account"
156
+ : "Sign in"}
157
+ </button>
158
+ </form>
159
+
160
+ <div className="mt-6 text-center">
161
+ <button
162
+ onClick={() => {
163
+ setIsRegister(!isRegister);
164
+ setError("");
165
+ }}
166
+ className="text-caption hover:underline"
167
+ style={{ color: "var(--text-link)" }}
168
+ >
169
+ {isRegister
170
+ ? "Already have an account? Sign in"
171
+ : "Don't have an account? Register"}
172
+ </button>
173
+ </div>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ );
178
+ }