thepopebot 1.2.70-beta.9 → 1.2.70
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/README.md +22 -20
- package/lib/ai/agent.js +4 -4
- package/lib/ai/index.js +39 -18
- package/lib/ai/tools.js +36 -2
- package/lib/auth/middleware.js +21 -1
- package/lib/chat/api.js +34 -5
- package/lib/chat/components/app-sidebar.js +1 -1
- package/lib/chat/components/app-sidebar.jsx +1 -1
- package/lib/chat/components/icons.js +25 -3
- package/lib/chat/components/icons.jsx +25 -3
- package/lib/chat/components/message.js +174 -14
- package/lib/chat/components/message.jsx +228 -44
- package/lib/chat/components/notifications-page.js +2 -1
- package/lib/chat/components/notifications-page.jsx +2 -1
- package/lib/chat/components/tool-call.js +85 -0
- package/lib/chat/components/tool-call.jsx +103 -0
- package/lib/paths.js +6 -1
- package/lib/utils/render-md.js +44 -4
- package/package.json +1 -1
- package/setup/setup.mjs +5 -6
- package/templates/.github/workflows/rebuild-event-handler.yml +3 -2
- package/templates/.github/workflows/upgrade-event-handler.yml +3 -2
- package/templates/CLAUDE.md +1 -1
- package/templates/CLAUDE.md.template +514 -56
- package/templates/app/globals.css +1 -0
- package/templates/config/EVENT_HANDLER.md +210 -0
- package/templates/config/PI_SKILL_GUIDE.md +89 -0
- package/templates/config/CHATBOT.md +0 -87
package/README.md
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
# thepopebot
|
|
2
|
-
|
|
3
|
-
## Why thepopebot?
|
|
1
|
+
# Why thepopebot?
|
|
4
2
|
|
|
5
3
|
**The repository IS the agent** — Every action your agent takes is a git commit. You can see exactly what it did, when, and why. If it screws up, revert it. Want to clone your agent? Fork the repo — code, personality, scheduled jobs, full history, all of it goes with your fork.
|
|
6
4
|
|
|
@@ -126,7 +124,26 @@ npm install thepopebot@latest
|
|
|
126
124
|
npx thepopebot init
|
|
127
125
|
```
|
|
128
126
|
|
|
129
|
-
For most people, that's it — `init` handles everything. It updates your project files, runs `npm install`, and updates `THEPOPEBOT_VERSION` in your local `.env`.
|
|
127
|
+
For most people, that's it — `init` handles everything. It updates your project files, runs `npm install`, and updates `THEPOPEBOT_VERSION` in your local `.env`. See [Understanding `init`](#understanding-init) below for details on what this updates and how to handle custom changes.
|
|
128
|
+
|
|
129
|
+
**3. Rebuild for local dev**
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm run build
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**4. Commit and push**
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
git add -A && git commit -m "upgrade thepopebot to vX.X.X"
|
|
139
|
+
git push
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Pushing to `main` triggers the `rebuild-event-handler.yml` workflow on your server. It detects the version change, runs `thepopebot init`, updates `THEPOPEBOT_VERSION` in the server's `.env`, pulls the new Docker image, restarts the container, rebuilds `.next`, and reloads PM2 — no manual `docker compose` needed.
|
|
143
|
+
|
|
144
|
+
> **Upgrade failed?** See [Recovering from a Failed Upgrade](docs/UPGRADE.md#recovering-from-a-failed-upgrade).
|
|
145
|
+
|
|
146
|
+
### Understanding `init`
|
|
130
147
|
|
|
131
148
|
#### How your project is structured
|
|
132
149
|
|
|
@@ -136,7 +153,7 @@ When you ran `thepopebot init` the first time, it scaffolded a project folder wi
|
|
|
136
153
|
|
|
137
154
|
| Files | What they do |
|
|
138
155
|
|-------|-------------|
|
|
139
|
-
| `config/SOUL.md`, `
|
|
156
|
+
| `config/SOUL.md`, `EVENT_HANDLER.md`, `AGENT.md`, etc. | Your agent's personality, behavior, and prompts |
|
|
140
157
|
| `config/CRONS.json`, `TRIGGERS.json` | Your scheduled jobs and webhook triggers |
|
|
141
158
|
| `app/` | Next.js pages and UI components |
|
|
142
159
|
| `docker/job/` | The Dockerfile for your agent's job container |
|
|
@@ -180,21 +197,6 @@ If you've made custom changes to managed files (e.g., added extra steps to a Git
|
|
|
180
197
|
npx thepopebot init --no-managed
|
|
181
198
|
```
|
|
182
199
|
|
|
183
|
-
**3. Rebuild for local dev**
|
|
184
|
-
|
|
185
|
-
```bash
|
|
186
|
-
npm run build
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**4. Commit and push**
|
|
190
|
-
|
|
191
|
-
```bash
|
|
192
|
-
git add -A && git commit -m "upgrade thepopebot to vX.X.X"
|
|
193
|
-
git push
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Pushing to `main` triggers the `rebuild-event-handler.yml` workflow on your server. It detects the version change, runs `thepopebot init`, updates `THEPOPEBOT_VERSION` in the server's `.env`, pulls the new Docker image, restarts the container, rebuilds `.next`, and reloads PM2 — no manual `docker compose` needed.
|
|
197
|
-
|
|
198
200
|
---
|
|
199
201
|
|
|
200
202
|
## CLI Commands
|
package/lib/ai/agent.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createReactAgent } from '@langchain/langgraph/prebuilt';
|
|
2
2
|
import { SystemMessage } from '@langchain/core/messages';
|
|
3
3
|
import { createModel } from './model.js';
|
|
4
|
-
import { createJobTool, getJobStatusTool } from './tools.js';
|
|
4
|
+
import { createJobTool, getJobStatusTool, getSystemTechnicalSpecsTool, getPiSkillCreationGuideTool } from './tools.js';
|
|
5
5
|
import { SqliteSaver } from '@langchain/langgraph-checkpoint-sqlite';
|
|
6
|
-
import {
|
|
6
|
+
import { eventHandlerMd, thepopebotDb } from '../paths.js';
|
|
7
7
|
import { render_md } from '../utils/render-md.js';
|
|
8
8
|
|
|
9
9
|
let _agent = null;
|
|
@@ -16,14 +16,14 @@ let _agent = null;
|
|
|
16
16
|
export async function getAgent() {
|
|
17
17
|
if (!_agent) {
|
|
18
18
|
const model = await createModel();
|
|
19
|
-
const tools = [createJobTool, getJobStatusTool];
|
|
19
|
+
const tools = [createJobTool, getJobStatusTool, getSystemTechnicalSpecsTool, getPiSkillCreationGuideTool];
|
|
20
20
|
const checkpointer = SqliteSaver.fromConnString(thepopebotDb);
|
|
21
21
|
|
|
22
22
|
_agent = createReactAgent({
|
|
23
23
|
llm: model,
|
|
24
24
|
tools,
|
|
25
25
|
checkpointSaver: checkpointer,
|
|
26
|
-
prompt: (state) => [new SystemMessage(render_md(
|
|
26
|
+
prompt: (state) => [new SystemMessage(render_md(eventHandlerMd)), ...state.messages],
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
return _agent;
|
package/lib/ai/index.js
CHANGED
|
@@ -149,24 +149,45 @@ async function* chatStream(threadId, message, attachments = [], options = {}) {
|
|
|
149
149
|
for await (const event of stream) {
|
|
150
150
|
// streamMode: 'messages' yields [message, metadata] tuples
|
|
151
151
|
const msg = Array.isArray(event) ? event[0] : event;
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
152
|
+
const msgType = msg._getType?.();
|
|
153
|
+
|
|
154
|
+
if (msgType === 'ai') {
|
|
155
|
+
// Tool calls — AIMessage.tool_calls is an array of { id, name, args }
|
|
156
|
+
if (msg.tool_calls?.length > 0) {
|
|
157
|
+
for (const tc of msg.tool_calls) {
|
|
158
|
+
yield {
|
|
159
|
+
type: 'tool-call',
|
|
160
|
+
toolCallId: tc.id,
|
|
161
|
+
toolName: tc.name,
|
|
162
|
+
args: tc.args,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Text content (wrapped in structured object)
|
|
168
|
+
let text = '';
|
|
169
|
+
if (typeof msg.content === 'string') {
|
|
170
|
+
text = msg.content;
|
|
171
|
+
} else if (Array.isArray(msg.content)) {
|
|
172
|
+
text = msg.content
|
|
173
|
+
.filter((b) => b.type === 'text' && b.text)
|
|
174
|
+
.map((b) => b.text)
|
|
175
|
+
.join('');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (text) {
|
|
179
|
+
fullText += text;
|
|
180
|
+
yield { type: 'text', text };
|
|
181
|
+
}
|
|
182
|
+
} else if (msgType === 'tool') {
|
|
183
|
+
// Tool result — ToolMessage has tool_call_id and content
|
|
184
|
+
yield {
|
|
185
|
+
type: 'tool-result',
|
|
186
|
+
toolCallId: msg.tool_call_id,
|
|
187
|
+
result: msg.content,
|
|
188
|
+
};
|
|
169
189
|
}
|
|
190
|
+
// Skip other message types (human, system)
|
|
170
191
|
}
|
|
171
192
|
|
|
172
193
|
// Save assistant response to DB
|
|
@@ -192,7 +213,7 @@ async function autoTitle(threadId, firstMessage) {
|
|
|
192
213
|
const chat = getChatById(threadId);
|
|
193
214
|
if (!chat || chat.title !== 'New Chat') return;
|
|
194
215
|
|
|
195
|
-
const model = await createModel();
|
|
216
|
+
const model = await createModel({ maxTokens: 250 });
|
|
196
217
|
const response = await model.invoke([
|
|
197
218
|
['system', 'Generate a short (3-6 word) title for this chat based on the user\'s first message. Return ONLY the title, nothing else.'],
|
|
198
219
|
['human', firstMessage],
|
package/lib/ai/tools.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
1
2
|
import { tool } from '@langchain/core/tools';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { createJob } from '../tools/create-job.js';
|
|
4
5
|
import { getJobStatus } from '../tools/github.js';
|
|
6
|
+
import { claudeMd, skillGuidePath } from '../paths.js';
|
|
5
7
|
|
|
6
8
|
const createJobTool = tool(
|
|
7
9
|
async ({ job_description }) => {
|
|
@@ -15,7 +17,7 @@ const createJobTool = tool(
|
|
|
15
17
|
{
|
|
16
18
|
name: 'create_job',
|
|
17
19
|
description:
|
|
18
|
-
'Create an autonomous job
|
|
20
|
+
'Create an autonomous job that runs a Docker agent in a container. The Docker agent has full filesystem access, web search, browser automation, and other abilities. The job description you provide becomes the Docker agent\'s task prompt. Returns the job ID and branch name.',
|
|
19
21
|
schema: z.object({
|
|
20
22
|
job_description: z
|
|
21
23
|
.string()
|
|
@@ -46,4 +48,36 @@ const getJobStatusTool = tool(
|
|
|
46
48
|
}
|
|
47
49
|
);
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
const getSystemTechnicalSpecsTool = tool(
|
|
52
|
+
async () => {
|
|
53
|
+
try {
|
|
54
|
+
return fs.readFileSync(claudeMd, 'utf8');
|
|
55
|
+
} catch {
|
|
56
|
+
return 'No technical documentation found (CLAUDE.md not present in project root).';
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'get_system_technical_specs',
|
|
61
|
+
description:
|
|
62
|
+
'Read the system architecture and technical documentation (CLAUDE.md). Use this when you need to understand how the system itself works — the event handler, Docker agent, API routes, database, cron/trigger configuration, GitHub Actions, deployment, or file structure. Use this before planning jobs that modify system configuration or infrastructure. NOT for Pi skill creation (use get_pi_skill_creation_guide for that).',
|
|
63
|
+
schema: z.object({}),
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const getPiSkillCreationGuideTool = tool(
|
|
68
|
+
async () => {
|
|
69
|
+
try {
|
|
70
|
+
return fs.readFileSync(skillGuidePath, 'utf8');
|
|
71
|
+
} catch {
|
|
72
|
+
return 'Skill guide not found.';
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'get_pi_skill_creation_guide',
|
|
77
|
+
description:
|
|
78
|
+
'Load the guide for creating, modifying, and understanding Pi agent skills (pi-skills). Use this when the user wants to create a new skill, asks how skills work, wants to modify an existing skill, or when you need to understand the skill format (SKILL.md, {baseDir}, activation, testing). This is about Pi skills specifically — the lightweight bash/Node.js wrappers that extend what the Docker agent can do. NOT for understanding the system architecture (use get_system_technical_specs for that).',
|
|
79
|
+
schema: z.object({}),
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
export { createJobTool, getJobStatusTool, getSystemTechnicalSpecsTool, getPiSkillCreationGuideTool };
|
package/lib/auth/middleware.js
CHANGED
|
@@ -23,7 +23,27 @@ export const middleware = auth((req) => {
|
|
|
23
23
|
|
|
24
24
|
// Everything else requires auth
|
|
25
25
|
if (!req.auth) {
|
|
26
|
-
|
|
26
|
+
const response = NextResponse.redirect(new URL('/login', req.url));
|
|
27
|
+
|
|
28
|
+
// Clear stale session cookies that can't be decrypted (e.g. after AUTH_SECRET rotation
|
|
29
|
+
// or container restart). Auth.js clears these internally in route handlers via
|
|
30
|
+
// sessionStore.clean(), but NOT in middleware — so the bad cookie loops forever.
|
|
31
|
+
// Only session-token cookies are cleared; csrf-token and callback-url are left intact.
|
|
32
|
+
const cookieNames = Object.keys(req.cookies.getAll().reduce((acc, c) => { acc[c.name] = true; return acc; }, {}));
|
|
33
|
+
const staleSessionCookies = cookieNames.filter(name =>
|
|
34
|
+
name === 'authjs.session-token' ||
|
|
35
|
+
name === '__Secure-authjs.session-token' ||
|
|
36
|
+
/^authjs\.session-token\.\d+$/.test(name) ||
|
|
37
|
+
/^__Secure-authjs\.session-token\.\d+$/.test(name)
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (staleSessionCookies.length > 0) {
|
|
41
|
+
for (const name of staleSessionCookies) {
|
|
42
|
+
response.cookies.set(name, '', { maxAge: 0, path: '/' });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return response;
|
|
27
47
|
}
|
|
28
48
|
});
|
|
29
49
|
|
package/lib/chat/api.js
CHANGED
|
@@ -81,17 +81,46 @@ export async function POST(request) {
|
|
|
81
81
|
// Signal start of assistant message
|
|
82
82
|
writer.write({ type: 'start' });
|
|
83
83
|
|
|
84
|
-
const textId = crypto.randomUUID();
|
|
85
84
|
let textStarted = false;
|
|
85
|
+
let textId = crypto.randomUUID();
|
|
86
86
|
|
|
87
87
|
for await (const chunk of chunks) {
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
if (chunk.type === 'text') {
|
|
89
|
+
if (!textStarted) {
|
|
90
|
+
textId = crypto.randomUUID();
|
|
91
|
+
writer.write({ type: 'text-start', id: textId });
|
|
92
|
+
textStarted = true;
|
|
93
|
+
}
|
|
94
|
+
writer.write({ type: 'text-delta', id: textId, delta: chunk.text });
|
|
95
|
+
|
|
96
|
+
} else if (chunk.type === 'tool-call') {
|
|
97
|
+
// Close any open text block before tool events
|
|
98
|
+
if (textStarted) {
|
|
99
|
+
writer.write({ type: 'text-end', id: textId });
|
|
100
|
+
textStarted = false;
|
|
101
|
+
}
|
|
102
|
+
writer.write({
|
|
103
|
+
type: 'tool-input-start',
|
|
104
|
+
toolCallId: chunk.toolCallId,
|
|
105
|
+
toolName: chunk.toolName,
|
|
106
|
+
});
|
|
107
|
+
writer.write({
|
|
108
|
+
type: 'tool-input-available',
|
|
109
|
+
toolCallId: chunk.toolCallId,
|
|
110
|
+
toolName: chunk.toolName,
|
|
111
|
+
input: chunk.args,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
} else if (chunk.type === 'tool-result') {
|
|
115
|
+
writer.write({
|
|
116
|
+
type: 'tool-output-available',
|
|
117
|
+
toolCallId: chunk.toolCallId,
|
|
118
|
+
output: chunk.result,
|
|
119
|
+
});
|
|
91
120
|
}
|
|
92
|
-
writer.write({ type: 'text-delta', id: textId, delta: chunk });
|
|
93
121
|
}
|
|
94
122
|
|
|
123
|
+
// Close final text block if still open
|
|
95
124
|
if (textStarted) {
|
|
96
125
|
writer.write({ type: 'text-end', id: textId });
|
|
97
126
|
}
|
|
@@ -42,7 +42,7 @@ function AppSidebar({ user }) {
|
|
|
42
42
|
/* @__PURE__ */ jsxs(SidebarHeader, { children: [
|
|
43
43
|
/* @__PURE__ */ jsxs("div", { className: collapsed ? "flex justify-center" : "flex items-center justify-between", children: [
|
|
44
44
|
!collapsed && /* @__PURE__ */ jsxs("span", { className: "px-2 font-semibold text-lg", children: [
|
|
45
|
-
"
|
|
45
|
+
"ThePopeBot",
|
|
46
46
|
version && /* @__PURE__ */ jsxs("span", { className: "text-[11px] font-normal text-muted-foreground", children: [
|
|
47
47
|
" v",
|
|
48
48
|
version
|
|
@@ -49,7 +49,7 @@ export function AppSidebar({ user }) {
|
|
|
49
49
|
{/* Top row: brand name + toggle icon (open) or just toggle icon (collapsed) */}
|
|
50
50
|
<div className={collapsed ? 'flex justify-center' : 'flex items-center justify-between'}>
|
|
51
51
|
{!collapsed && (
|
|
52
|
-
<span className="px-2 font-semibold text-lg">
|
|
52
|
+
<span className="px-2 font-semibold text-lg">ThePopeBot{version && <span className="text-[11px] font-normal text-muted-foreground"> v{version}</span>}</span>
|
|
53
53
|
)}
|
|
54
54
|
<Tooltip>
|
|
55
55
|
<TooltipTrigger asChild>
|
|
@@ -209,7 +209,7 @@ function PaperclipIcon({ size = 16 }) {
|
|
|
209
209
|
}
|
|
210
210
|
);
|
|
211
211
|
}
|
|
212
|
-
function XIcon({ size = 16 }) {
|
|
212
|
+
function XIcon({ size = 16, className = "" }) {
|
|
213
213
|
return /* @__PURE__ */ jsxs(
|
|
214
214
|
"svg",
|
|
215
215
|
{
|
|
@@ -222,6 +222,7 @@ function XIcon({ size = 16 }) {
|
|
|
222
222
|
strokeLinejoin: "round",
|
|
223
223
|
width: size,
|
|
224
224
|
height: size,
|
|
225
|
+
className,
|
|
225
226
|
children: [
|
|
226
227
|
/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
|
|
227
228
|
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
@@ -311,7 +312,7 @@ function RefreshIcon({ size = 16 }) {
|
|
|
311
312
|
}
|
|
312
313
|
);
|
|
313
314
|
}
|
|
314
|
-
function ChevronDownIcon({ size = 16 }) {
|
|
315
|
+
function ChevronDownIcon({ size = 16, className = "" }) {
|
|
315
316
|
return /* @__PURE__ */ jsx(
|
|
316
317
|
"svg",
|
|
317
318
|
{
|
|
@@ -324,6 +325,7 @@ function ChevronDownIcon({ size = 16 }) {
|
|
|
324
325
|
strokeLinejoin: "round",
|
|
325
326
|
width: size,
|
|
326
327
|
height: size,
|
|
328
|
+
className,
|
|
327
329
|
children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
|
|
328
330
|
}
|
|
329
331
|
);
|
|
@@ -389,7 +391,7 @@ function CopyIcon({ size = 16 }) {
|
|
|
389
391
|
}
|
|
390
392
|
);
|
|
391
393
|
}
|
|
392
|
-
function CheckIcon({ size = 16 }) {
|
|
394
|
+
function CheckIcon({ size = 16, className = "" }) {
|
|
393
395
|
return /* @__PURE__ */ jsx(
|
|
394
396
|
"svg",
|
|
395
397
|
{
|
|
@@ -402,6 +404,7 @@ function CheckIcon({ size = 16 }) {
|
|
|
402
404
|
strokeLinejoin: "round",
|
|
403
405
|
width: size,
|
|
404
406
|
height: size,
|
|
407
|
+
className,
|
|
405
408
|
children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" })
|
|
406
409
|
}
|
|
407
410
|
);
|
|
@@ -635,6 +638,24 @@ function LifeBuoyIcon({ size = 16 }) {
|
|
|
635
638
|
}
|
|
636
639
|
);
|
|
637
640
|
}
|
|
641
|
+
function WrenchIcon({ size = 16, className = "" }) {
|
|
642
|
+
return /* @__PURE__ */ jsx(
|
|
643
|
+
"svg",
|
|
644
|
+
{
|
|
645
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
646
|
+
viewBox: "0 0 24 24",
|
|
647
|
+
fill: "none",
|
|
648
|
+
stroke: "currentColor",
|
|
649
|
+
strokeWidth: 2,
|
|
650
|
+
strokeLinecap: "round",
|
|
651
|
+
strokeLinejoin: "round",
|
|
652
|
+
width: size,
|
|
653
|
+
height: size,
|
|
654
|
+
className,
|
|
655
|
+
children: /* @__PURE__ */ jsx("path", { d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" })
|
|
656
|
+
}
|
|
657
|
+
);
|
|
658
|
+
}
|
|
638
659
|
function LogOutIcon({ size = 16 }) {
|
|
639
660
|
return /* @__PURE__ */ jsxs(
|
|
640
661
|
"svg",
|
|
@@ -688,6 +709,7 @@ export {
|
|
|
688
709
|
SunIcon,
|
|
689
710
|
SwarmIcon,
|
|
690
711
|
TrashIcon,
|
|
712
|
+
WrenchIcon,
|
|
691
713
|
XIcon,
|
|
692
714
|
ZapIcon
|
|
693
715
|
};
|
|
@@ -205,7 +205,7 @@ export function PaperclipIcon({ size = 16 }) {
|
|
|
205
205
|
);
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
export function XIcon({ size = 16 }) {
|
|
208
|
+
export function XIcon({ size = 16, className = '' }) {
|
|
209
209
|
return (
|
|
210
210
|
<svg
|
|
211
211
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -217,6 +217,7 @@ export function XIcon({ size = 16 }) {
|
|
|
217
217
|
strokeLinejoin="round"
|
|
218
218
|
width={size}
|
|
219
219
|
height={size}
|
|
220
|
+
className={className}
|
|
220
221
|
>
|
|
221
222
|
<path d="M18 6 6 18" />
|
|
222
223
|
<path d="m6 6 12 12" />
|
|
@@ -304,7 +305,7 @@ export function RefreshIcon({ size = 16 }) {
|
|
|
304
305
|
);
|
|
305
306
|
}
|
|
306
307
|
|
|
307
|
-
export function ChevronDownIcon({ size = 16 }) {
|
|
308
|
+
export function ChevronDownIcon({ size = 16, className = '' }) {
|
|
308
309
|
return (
|
|
309
310
|
<svg
|
|
310
311
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -316,6 +317,7 @@ export function ChevronDownIcon({ size = 16 }) {
|
|
|
316
317
|
strokeLinejoin="round"
|
|
317
318
|
width={size}
|
|
318
319
|
height={size}
|
|
320
|
+
className={className}
|
|
319
321
|
>
|
|
320
322
|
<path d="m6 9 6 6 6-6" />
|
|
321
323
|
</svg>
|
|
@@ -380,7 +382,7 @@ export function CopyIcon({ size = 16 }) {
|
|
|
380
382
|
);
|
|
381
383
|
}
|
|
382
384
|
|
|
383
|
-
export function CheckIcon({ size = 16 }) {
|
|
385
|
+
export function CheckIcon({ size = 16, className = '' }) {
|
|
384
386
|
return (
|
|
385
387
|
<svg
|
|
386
388
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -392,6 +394,7 @@ export function CheckIcon({ size = 16 }) {
|
|
|
392
394
|
strokeLinejoin="round"
|
|
393
395
|
width={size}
|
|
394
396
|
height={size}
|
|
397
|
+
className={className}
|
|
395
398
|
>
|
|
396
399
|
<path d="M20 6 9 17l-5-5" />
|
|
397
400
|
</svg>
|
|
@@ -626,6 +629,25 @@ export function LifeBuoyIcon({ size = 16 }) {
|
|
|
626
629
|
);
|
|
627
630
|
}
|
|
628
631
|
|
|
632
|
+
export function WrenchIcon({ size = 16, className = '' }) {
|
|
633
|
+
return (
|
|
634
|
+
<svg
|
|
635
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
636
|
+
viewBox="0 0 24 24"
|
|
637
|
+
fill="none"
|
|
638
|
+
stroke="currentColor"
|
|
639
|
+
strokeWidth={2}
|
|
640
|
+
strokeLinecap="round"
|
|
641
|
+
strokeLinejoin="round"
|
|
642
|
+
width={size}
|
|
643
|
+
height={size}
|
|
644
|
+
className={className}
|
|
645
|
+
>
|
|
646
|
+
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" />
|
|
647
|
+
</svg>
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
|
|
629
651
|
export function LogOutIcon({ size = 16 }) {
|
|
630
652
|
return (
|
|
631
653
|
<svg
|