tide-commander 1.45.0 → 1.47.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/dist/assets/{BossLogsModal-N4CnX-0x.js → BossLogsModal-BEZSJWBV.js} +1 -1
- package/dist/assets/BossSpawnModal-BknVJp2f.js +1 -0
- package/dist/assets/{ControlsModal-Cr5klRxS.js → ControlsModal-BZKmtLz7.js} +1 -1
- package/dist/assets/{DockerLogsModal-D6U9obTe.js → DockerLogsModal-DD8gRVu6.js} +1 -1
- package/dist/assets/{EmbeddedEditor-Bnm-9Q73.js → EmbeddedEditor-DMcKiZ5q.js} +1 -1
- package/dist/assets/{GmailOAuthSetup-GoKvyYWS.js → GmailOAuthSetup-CO2LqLvU.js} +1 -1
- package/dist/assets/{GoogleOAuthSetup-D3sAGlZq.js → GoogleOAuthSetup-OVzavssB.js} +1 -1
- package/dist/assets/{IframeModal-DQqev6_V.js → IframeModal-DJn-dNqr.js} +1 -1
- package/dist/assets/IntegrationsPanel-C0JSiDOw.js +2 -0
- package/dist/assets/{LogViewerModal-DB0xx-oB.js → LogViewerModal-BgIfdR-l.js} +1 -1
- package/dist/assets/{MonitoringModal-BspW74kP.js → MonitoringModal-Dm8wbcHY.js} +1 -1
- package/dist/assets/{PM2LogsModal-Cz4GZtyl.js → PM2LogsModal-CDULU4yk.js} +1 -1
- package/dist/assets/{RestoreArchivedAreaModal-KCCSJy3B.js → RestoreArchivedAreaModal-DLuiZj6S.js} +1 -1
- package/dist/assets/{SaveSnapshotModal-DqZ1JedM.js → SaveSnapshotModal-CbfjHVJz.js} +1 -1
- package/dist/assets/Scene2DCanvas-Dw9o4Fk8.js +1 -0
- package/dist/assets/{SceneManager-DggU0iAh.js → SceneManager-KAhHYpUf.js} +1 -1
- package/dist/assets/SkillsPanel-BYy3W8hd.js +28 -0
- package/dist/assets/SnapshotManager-LxlHIjaa.js +1 -0
- package/dist/assets/SpawnModal-Ch7yKsdS.js +1 -0
- package/dist/assets/SubordinateAssignmentModal-zuSTZAqj.js +1 -0
- package/dist/assets/{SupervisorPanel-CxId5lI7.js → SupervisorPanel-tTfMa-0x.js} +1 -1
- package/dist/assets/{TriggerManagerPanel-BCzGGCPD.js → TriggerManagerPanel-BoHdbpqk.js} +2 -2
- package/dist/assets/{WorkflowEditorPanel-BmNCGmxP.js → WorkflowEditorPanel-Cusd-51G.js} +2 -2
- package/dist/assets/{index-8WVMR823.js → index-BPn1NjZ5.js} +1 -1
- package/dist/assets/{index-CvJuv-ho.js → index-BoFICHSl.js} +2 -2
- package/dist/assets/{index-Sej69v19.js → index-C_3LXJYS.js} +3 -3
- package/dist/assets/{index-Bhb-rse9.js → index-CeMGJMtZ.js} +3 -3
- package/dist/assets/{index-COBkxsEU.js → index-ChZ1qMl3.js} +1 -1
- package/dist/assets/{index-C9B8kaWK.js → index-Cxx3kFoj.js} +1 -1
- package/dist/assets/{index-CcYTUJp1.js → index-D3KwWKEv.js} +4 -4
- package/dist/assets/index-ifiZ65Cu.js +1 -0
- package/dist/assets/main-3GpIvzEr.css +1 -0
- package/dist/assets/main-BsOvZp5M.js +153 -0
- package/dist/assets/{web-RTEsf66y.js → web-B5moyGVG.js} +1 -1
- package/dist/assets/{web-CrUhsC9T.js → web-BYzo_b4X.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/src/packages/server/data/index.js +25 -0
- package/dist/src/packages/server/routes/config.js +7 -0
- package/dist/src/packages/server/routes/custom-class-icons.js +138 -0
- package/dist/src/packages/server/routes/index.js +2 -0
- package/dist/src/packages/server/services/custom-class-service.js +7 -2
- package/package.json +1 -1
- package/dist/assets/BossSpawnModal-4CPjS2xn.js +0 -1
- package/dist/assets/IntegrationsPanel-C9hWD7mO.js +0 -2
- package/dist/assets/Scene2DCanvas-MRhWT6EA.js +0 -1
- package/dist/assets/SkillsPanel-DZC0Im2z.js +0 -28
- package/dist/assets/SnapshotManager-3LQMRFLh.js +0 -1
- package/dist/assets/SpawnModal-C_e6q2uv.js +0 -1
- package/dist/assets/SubordinateAssignmentModal-BZdSk9WL.js +0 -1
- package/dist/assets/index-B8SWRPUd.js +0 -1
- package/dist/assets/main-6CnCKW13.js +0 -153
- package/dist/assets/main-DjGrMNoB.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{bz as s}from"./main-BsOvZp5M.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class f extends s{constructor(){super(...arguments),this.pending=[],this.deliveredNotifications=[],this.hasNotificationSupport=()=>{if(!("Notification"in window)||!Notification.requestPermission)return!1;if(Notification.permission!=="granted")try{new Notification("")}catch(i){if(i instanceof Error&&i.name==="TypeError")return!1}return!0}}async getDeliveredNotifications(){const i=[];for(const t of this.deliveredNotifications){const e={title:t.title,id:parseInt(t.tag),body:t.body};i.push(e)}return{notifications:i}}async removeDeliveredNotifications(i){for(const t of i.notifications){const e=this.deliveredNotifications.find(n=>n.tag===String(t.id));e==null||e.close(),this.deliveredNotifications=this.deliveredNotifications.filter(()=>!e)}}async removeAllDeliveredNotifications(){for(const i of this.deliveredNotifications)i.close();this.deliveredNotifications=[]}async createChannel(){throw this.unimplemented("Not implemented on web.")}async deleteChannel(){throw this.unimplemented("Not implemented on web.")}async listChannels(){throw this.unimplemented("Not implemented on web.")}async schedule(i){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");for(const t of i.notifications)this.sendNotification(t);return{notifications:i.notifications.map(t=>({id:t.id}))}}async getPending(){return{notifications:this.pending}}async registerActionTypes(){throw this.unimplemented("Not implemented on web.")}async cancel(i){this.pending=this.pending.filter(t=>!i.notifications.find(e=>e.id===t.id))}async areEnabled(){const{display:i}=await this.checkPermissions();return{value:i==="granted"}}async changeExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async checkExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async requestPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(await Notification.requestPermission())}}async checkPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(Notification.permission)}}transformNotificationPermission(i){switch(i){case"granted":return"granted";case"denied":return"denied";default:return"prompt"}}sendPending(){var i;const t=[],e=new Date().getTime();for(const n of this.pending)!((i=n.schedule)===null||i===void 0)&&i.at&&n.schedule.at.getTime()<=e&&(this.buildNotification(n),t.push(n));this.pending=this.pending.filter(n=>!t.find(o=>o===n))}sendNotification(i){var t;if(!((t=i.schedule)===null||t===void 0)&&t.at){const e=i.schedule.at.getTime()-new Date().getTime();this.pending.push(i),setTimeout(()=>{this.sendPending()},e);return}this.buildNotification(i)}buildNotification(i){const t=new Notification(i.title,{body:i.body,tag:String(i.id)});return t.addEventListener("click",this.onClick.bind(this,i),!1),t.addEventListener("show",this.onShow.bind(this,i),!1),t.addEventListener("close",()=>{this.deliveredNotifications=this.deliveredNotifications.filter(()=>!this)},!1),this.deliveredNotifications.push(t),t}onClick(i){const t={actionId:"tap",notification:i};this.notifyListeners("localNotificationActionPerformed",t)}onShow(i){this.notifyListeners("localNotificationReceived",i)}}export{f as LocalNotificationsWeb};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{bz as a}from"./main-BsOvZp5M.js";import{ImpactStyle as i,NotificationType as r}from"./index-BoFICHSl.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class u extends a{constructor(){super(...arguments),this.selectionStarted=!1}async impact(t){const e=this.patternForImpact(t==null?void 0:t.style);this.vibrateWithPattern(e)}async notification(t){const e=this.patternForNotification(t==null?void 0:t.type);this.vibrateWithPattern(e)}async vibrate(t){const e=(t==null?void 0:t.duration)||300;this.vibrateWithPattern([e])}async selectionStart(){this.selectionStarted=!0}async selectionChanged(){this.selectionStarted&&this.vibrateWithPattern([70])}async selectionEnd(){this.selectionStarted=!1}patternForImpact(t=i.Heavy){return t===i.Medium?[43]:t===i.Light?[20]:[61]}patternForNotification(t=r.Success){return t===r.Warning?[30,40,30,50,60]:t===r.Error?[27,45,50]:[35,65,21]}vibrateWithPattern(t){if(navigator.vibrate)navigator.vibrate(t);else throw this.unavailable("Browser does not support the vibrate API")}}export{u as HapticsWeb};
|
package/dist/index.html
CHANGED
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16x16.png" />
|
|
23
23
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png" />
|
|
24
24
|
<title>Tide Commander</title>
|
|
25
|
-
<script type="module" crossorigin src="/assets/main-
|
|
25
|
+
<script type="module" crossorigin src="/assets/main-BsOvZp5M.js"></script>
|
|
26
26
|
<link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
|
|
27
27
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react--Eh9ivFN.js">
|
|
28
28
|
<link rel="modulepreload" crossorigin href="/assets/vendor-three-Chj50gSY.js">
|
|
29
|
-
<link rel="stylesheet" crossorigin href="/assets/main-
|
|
29
|
+
<link rel="stylesheet" crossorigin href="/assets/main-3GpIvzEr.css">
|
|
30
30
|
</head>
|
|
31
31
|
<body>
|
|
32
32
|
<div id="app"></div>
|
|
@@ -29,6 +29,7 @@ const RUNNING_PROCESSES_FILE = path.join(DATA_DIR, 'running-processes.json');
|
|
|
29
29
|
const SECRETS_FILE = path.join(DATA_DIR, 'secrets.json');
|
|
30
30
|
const SESSION_HISTORY_FILE = path.join(DATA_DIR, 'session-history.json');
|
|
31
31
|
const AREA_LOGOS_DIR = path.join(DATA_DIR, 'area-logos');
|
|
32
|
+
const CLASS_ICONS_DIR = path.join(DATA_DIR, 'custom-class-icons');
|
|
32
33
|
// Maximum history entries per agent
|
|
33
34
|
const MAX_HISTORY_PER_AGENT = 50;
|
|
34
35
|
const MAX_SESSION_HISTORY_PER_AGENT = 100;
|
|
@@ -257,6 +258,30 @@ export function deleteAreaLogo(filename) {
|
|
|
257
258
|
log.log(` Deleted area logo: ${filename}`);
|
|
258
259
|
}
|
|
259
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Ensure custom class icons directory exists
|
|
263
|
+
*/
|
|
264
|
+
export function ensureClassIconsDir() {
|
|
265
|
+
if (!fs.existsSync(CLASS_ICONS_DIR)) {
|
|
266
|
+
fs.mkdirSync(CLASS_ICONS_DIR, { recursive: true });
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get path to the custom class icons directory
|
|
271
|
+
*/
|
|
272
|
+
export function getClassIconsDir() {
|
|
273
|
+
return CLASS_ICONS_DIR;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Delete a class icon file from disk
|
|
277
|
+
*/
|
|
278
|
+
export function deleteClassIcon(filename) {
|
|
279
|
+
const filePath = path.join(CLASS_ICONS_DIR, path.basename(filename));
|
|
280
|
+
if (fs.existsSync(filePath)) {
|
|
281
|
+
fs.unlinkSync(filePath);
|
|
282
|
+
log.log(` Deleted class icon: ${filename}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
260
285
|
/**
|
|
261
286
|
* Update a single agent's session ID
|
|
262
287
|
*/
|
|
@@ -72,6 +72,13 @@ const CONFIG_CATEGORIES = [
|
|
|
72
72
|
files: ['custom-models/*'],
|
|
73
73
|
sourceDir: 'home',
|
|
74
74
|
},
|
|
75
|
+
{
|
|
76
|
+
id: 'custom-class-icons',
|
|
77
|
+
name: 'Custom Class Icons',
|
|
78
|
+
description: 'PNG/JPEG/WebP icon files for custom agent classes',
|
|
79
|
+
files: ['custom-class-icons/*'],
|
|
80
|
+
sourceDir: 'data',
|
|
81
|
+
},
|
|
75
82
|
{
|
|
76
83
|
id: 'hooks',
|
|
77
84
|
name: 'Hooks',
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Class Icon Routes
|
|
3
|
+
* REST API endpoints for uploading, serving, and deleting custom class PNG icons
|
|
4
|
+
*/
|
|
5
|
+
import { Router } from 'express';
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { ensureClassIconsDir, getClassIconsDir, deleteClassIcon } from '../data/index.js';
|
|
9
|
+
import { getCustomClass, updateCustomClass } from '../services/custom-class-service.js';
|
|
10
|
+
import { createLogger } from '../utils/logger.js';
|
|
11
|
+
const log = createLogger('ClassIcons');
|
|
12
|
+
const router = Router();
|
|
13
|
+
// Allowed image MIME types
|
|
14
|
+
const ALLOWED_IMAGE_TYPES = new Set([
|
|
15
|
+
'image/png', 'image/jpeg', 'image/webp',
|
|
16
|
+
]);
|
|
17
|
+
// Max icon file size: 2MB
|
|
18
|
+
const MAX_ICON_SIZE = 2 * 1024 * 1024;
|
|
19
|
+
// Extension map from content type
|
|
20
|
+
const EXT_MAP = {
|
|
21
|
+
'image/png': '.png',
|
|
22
|
+
'image/jpeg': '.jpg',
|
|
23
|
+
'image/webp': '.webp',
|
|
24
|
+
};
|
|
25
|
+
// MIME map from file extension
|
|
26
|
+
const MIME_MAP = {
|
|
27
|
+
'.png': 'image/png',
|
|
28
|
+
'.jpg': 'image/jpeg',
|
|
29
|
+
'.jpeg': 'image/jpeg',
|
|
30
|
+
'.webp': 'image/webp',
|
|
31
|
+
};
|
|
32
|
+
// GET /api/custom-class-icons/:filename - Serve an icon file
|
|
33
|
+
router.get('/:filename', (req, res) => {
|
|
34
|
+
try {
|
|
35
|
+
ensureClassIconsDir();
|
|
36
|
+
const filename = path.basename(String(req.params.filename)); // sanitize
|
|
37
|
+
const filePath = path.join(getClassIconsDir(), filename);
|
|
38
|
+
if (!fs.existsSync(filePath)) {
|
|
39
|
+
res.status(404).json({ error: 'Icon not found' });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const ext = path.extname(filename).toLowerCase();
|
|
43
|
+
const contentType = MIME_MAP[ext] || 'application/octet-stream';
|
|
44
|
+
res.setHeader('Content-Type', contentType);
|
|
45
|
+
res.setHeader('Cache-Control', 'public, max-age=31536000'); // 1 year - filenames are unique per class
|
|
46
|
+
fs.createReadStream(filePath).pipe(res);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
log.error(' Failed to serve class icon:', err);
|
|
50
|
+
res.status(500).json({ error: err.message });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// POST /api/custom-class-icons/:classId - Upload an icon for a custom class
|
|
54
|
+
router.post('/:classId', (req, res) => {
|
|
55
|
+
try {
|
|
56
|
+
ensureClassIconsDir();
|
|
57
|
+
const classId = String(req.params.classId);
|
|
58
|
+
const contentType = req.headers['content-type'] || '';
|
|
59
|
+
// Validate class exists
|
|
60
|
+
const customClass = getCustomClass(classId);
|
|
61
|
+
if (!customClass) {
|
|
62
|
+
res.status(404).json({ error: `Custom class not found: ${classId}` });
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Validate image type
|
|
66
|
+
if (!ALLOWED_IMAGE_TYPES.has(contentType)) {
|
|
67
|
+
res.status(400).json({ error: `Invalid image type: ${contentType}. Allowed: ${[...ALLOWED_IMAGE_TYPES].join(', ')}` });
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Delete existing icon for this class if any
|
|
71
|
+
if (customClass.iconPath) {
|
|
72
|
+
deleteClassIcon(customClass.iconPath);
|
|
73
|
+
}
|
|
74
|
+
// Determine extension and filename
|
|
75
|
+
const ext = EXT_MAP[contentType] || '.png';
|
|
76
|
+
const filename = `${classId}${ext}`;
|
|
77
|
+
const filePath = path.join(getClassIconsDir(), filename);
|
|
78
|
+
// Collect body data
|
|
79
|
+
const chunks = [];
|
|
80
|
+
let totalSize = 0;
|
|
81
|
+
req.on('data', (chunk) => {
|
|
82
|
+
totalSize += chunk.length;
|
|
83
|
+
if (totalSize > MAX_ICON_SIZE) {
|
|
84
|
+
res.status(413).json({ error: `Icon too large. Max size: ${MAX_ICON_SIZE / 1024 / 1024}MB` });
|
|
85
|
+
req.destroy();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
chunks.push(chunk);
|
|
89
|
+
});
|
|
90
|
+
req.on('end', () => {
|
|
91
|
+
if (res.headersSent)
|
|
92
|
+
return; // Already sent 413
|
|
93
|
+
const buffer = Buffer.concat(chunks);
|
|
94
|
+
fs.writeFileSync(filePath, buffer);
|
|
95
|
+
log.log(` Uploaded class icon: ${filename} (${buffer.length} bytes)`);
|
|
96
|
+
// Update the class's iconPath field
|
|
97
|
+
updateCustomClass(classId, { iconPath: filename });
|
|
98
|
+
res.json({
|
|
99
|
+
success: true,
|
|
100
|
+
filename,
|
|
101
|
+
url: `/api/custom-class-icons/${filename}`,
|
|
102
|
+
size: buffer.length,
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
req.on('error', (err) => {
|
|
106
|
+
log.error(' Icon upload error:', err);
|
|
107
|
+
if (!res.headersSent) {
|
|
108
|
+
res.status(500).json({ error: 'Upload failed' });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
log.error(' Failed to upload class icon:', err);
|
|
114
|
+
res.status(500).json({ error: err.message });
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
// DELETE /api/custom-class-icons/:classId - Delete the icon for a custom class
|
|
118
|
+
router.delete('/:classId', (req, res) => {
|
|
119
|
+
try {
|
|
120
|
+
const classId = String(req.params.classId);
|
|
121
|
+
const customClass = getCustomClass(classId);
|
|
122
|
+
if (!customClass) {
|
|
123
|
+
res.status(404).json({ error: `Custom class not found: ${classId}` });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (customClass.iconPath) {
|
|
127
|
+
deleteClassIcon(customClass.iconPath);
|
|
128
|
+
updateCustomClass(classId, { iconPath: undefined });
|
|
129
|
+
log.log(` Removed icon for class ${classId}`);
|
|
130
|
+
}
|
|
131
|
+
res.json({ success: true });
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
log.error(' Failed to delete class icon:', err);
|
|
135
|
+
res.status(500).json({ error: err.message });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
export default router;
|
|
@@ -16,6 +16,7 @@ import sttRouter from './stt.js';
|
|
|
16
16
|
import voiceAssistantRouter from './voice-assistant.js';
|
|
17
17
|
import snapshotsRouter from './snapshots.js';
|
|
18
18
|
import areasRouter from './areas.js';
|
|
19
|
+
import customClassIconsRouter from './custom-class-icons.js';
|
|
19
20
|
import workspacesRouter from './workspaces.js';
|
|
20
21
|
import perfRouter from './perf.js';
|
|
21
22
|
import triggerRouter, { setBroadcast as setTriggerBroadcast } from './trigger-routes.js';
|
|
@@ -40,6 +41,7 @@ router.use('/stt', sttRouter);
|
|
|
40
41
|
router.use('/voice-assistant', voiceAssistantRouter);
|
|
41
42
|
router.use('/snapshots', snapshotsRouter);
|
|
42
43
|
router.use('/areas', areasRouter);
|
|
44
|
+
router.use('/custom-class-icons', customClassIconsRouter);
|
|
43
45
|
router.use('/workspaces', workspacesRouter);
|
|
44
46
|
router.use('/perf', perfRouter);
|
|
45
47
|
router.use('/triggers', triggerRouter);
|
|
@@ -6,7 +6,7 @@ import { EventEmitter } from 'events';
|
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import * as os from 'os';
|
|
9
|
-
import { loadCustomAgentClasses, saveCustomAgentClasses } from '../data/index.js';
|
|
9
|
+
import { loadCustomAgentClasses, saveCustomAgentClasses, deleteClassIcon } from '../data/index.js';
|
|
10
10
|
import { createLogger, generateSlug } from '../utils/index.js';
|
|
11
11
|
const log = createLogger('CustomClassService');
|
|
12
12
|
// In-memory store
|
|
@@ -212,10 +212,15 @@ export function updateCustomClass(id, updates) {
|
|
|
212
212
|
* Delete a custom agent class
|
|
213
213
|
*/
|
|
214
214
|
export function deleteCustomClass(id) {
|
|
215
|
-
|
|
215
|
+
const existing = customClasses.get(id);
|
|
216
|
+
if (!existing) {
|
|
216
217
|
log.warn(`Custom class not found: ${id}`);
|
|
217
218
|
return false;
|
|
218
219
|
}
|
|
220
|
+
// Delete class icon file if exists
|
|
221
|
+
if (existing.iconPath) {
|
|
222
|
+
deleteClassIcon(existing.iconPath);
|
|
223
|
+
}
|
|
219
224
|
customClasses.delete(id);
|
|
220
225
|
persistClasses();
|
|
221
226
|
// Delete instructions file
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{u as $e,f as Ae,M as Le,L as Ee,r as t,P as _e,S as se,w as De,U as O,A as ae,a2 as P,a3 as j,j as s,W as Ie,Y as Be,Z as T,_ as A,$ as L,a1 as Re,s as Oe}from"./main-6CnCKW13.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";function ne(m){const h=j.filter(S=>!m.has(`Boss ${S}`));return h.length===0?`Boss ${j[Math.floor(Math.random()*j.length)]}-${Date.now()%1e3}`:`Boss ${h[Math.floor(Math.random()*h.length)]}`}function Fe({isOpen:m,onClose:h,onSpawnStart:S,onSpawnEnd:E,spawnPosition:le}){const{t:n}=$e(["terminal","common"]),{agents:g}=Ae(),o=Le(),C=Ee(),[r,p]=t.useState(""),[k,te]=t.useState(()=>_e(se.LAST_CWD)),[c,_]=t.useState("boss"),[U,q]=t.useState(!1),[ie,M]=t.useState(!1),[F,ce]=t.useState(!0),[W,oe]=t.useState("bypass"),[d,D]=t.useState("claude"),[b,N]=t.useState({fullAuto:!0,sandbox:"workspace-write",approvalMode:"on-request",search:!1}),[G,re]=t.useState("opus"),[K,de]=t.useState("gpt-5.3-codex"),[v,y]=t.useState(new Set),[z,I]=t.useState(new Set),[u,pe]=t.useState(""),[f,ue]=t.useState(""),[H,me]=t.useState(""),$=t.useRef(null),B=t.useRef(!1),J=t.useRef(!1),x=t.useMemo(()=>C.filter(e=>e.enabled),[C]),Y=t.useMemo(()=>{if(!f.trim())return x;const e=f.toLowerCase();return x.filter(a=>a.name.toLowerCase().includes(e)||a.description.toLowerCase().includes(e)||a.slug.toLowerCase().includes(e))},[x,f]),he=t.useMemo(()=>{var a;const e=o.find(l=>l.id===c);return(a=e==null?void 0:e.defaultSkillIds)!=null&&a.length?C.filter(l=>e.defaultSkillIds.includes(l.id)):[]},[o,c,C]),we=["full-notifications","streaming-exec","task-label","report-task-to-boss"];t.useEffect(()=>{if(m&&!J.current&&x.length>0){const a=x.filter(l=>we.includes(l.slug)).map(l=>l.id);a.length>0&&I(new Set(a))}J.current=m},[m,x]);const xe=t.useCallback(e=>{I(a=>{const l=new Set(a);return l.has(e)?l.delete(e):l.add(e),l})},[]),i=t.useMemo(()=>o.find(e=>e.id===c),[o,c]),be=t.useMemo(()=>{if(i!=null&&i.model)return i.model},[i]),fe=t.useMemo(()=>{if(i!=null&&i.customModelPath)return De(`/api/custom-models/${i.id}`)},[i]),je=i==null?void 0:i.modelScale,Ne=t.useMemo(()=>i?"scout":c==="boss"?"architect":c,[c,i]),V=Array.from(g.values()).filter(e=>!e.isBoss&&e.class!=="boss"&&!e.bossId),X=t.useMemo(()=>{if(!u.trim())return o;const e=u.toLowerCase();return o.filter(a=>a.name.toLowerCase().includes(e)||a.description.toLowerCase().includes(e)||a.id.toLowerCase().includes(e))},[o,u]),Z=t.useMemo(()=>{if(!u.trim())return O;const e=u.toLowerCase();return O.filter(a=>{const l=ae[a.id];return l?a.name.toLowerCase().includes(e)||a.id.toLowerCase().includes(e)||l.description.toLowerCase().includes(e):!1})},[u]),Q=t.useMemo(()=>{if(!u.trim())return!0;const e=u.toLowerCase(),a=P.boss;return"boss".includes(e)||a.description.toLowerCase().includes(e)},[u]);t.useEffect(()=>{if(m&&!B.current){B.current=!0;const e=new Set(Array.from(g.values()).map(l=>l.name)),a=o.find(l=>l.id===c);if(a){const l=j.filter(w=>!e.has(`${a.name} ${w}`));if(l.length===0){const w=j[Math.floor(Math.random()*j.length)];p(`${a.name} ${w}-${Date.now()%1e3}`)}else p(`${a.name} ${l[Math.floor(Math.random()*l.length)]}`)}else p(ne(e));y(new Set),$.current&&($.current.focus(),$.current.select())}else m||(B.current=!1)},[m,g]),t.useEffect(()=>{if(!m)return;const e=o.find(a=>a.id===c);if(e)if(r.startsWith("Boss ")){const a=r.substring(5);p(`${e.name} ${a}`)}else{const a=o.find(l=>r.startsWith(l.name+" "));if(a){const l=r.substring(a.name.length+1);p(`${e.name} ${l}`)}else p(`${e.name} ${r}`)}else{const a=o.find(l=>r.startsWith(l.name+" "));if(a){const l=r.substring(a.name.length+1);p(`Boss ${l}`)}else r.startsWith("Boss ")||p(`Boss ${r}`)}},[c]);const ve=()=>{if(M(!1),!k.trim()){M(!0);return}if(!r.trim()){const l=new Set(Array.from(g.values()).map(w=>w.name));p(ne(l));return}Re(se.LAST_CWD,k),S();const e=H.trim()||void 0,a=Array.from(z);Oe.spawnBossAgent(r.trim(),c,k.trim(),le||void 0,Array.from(v),d==="claude"?F:!1,W,d,d==="codex"?b:void 0,d==="codex"?K:void 0,d==="claude"?G:void 0,e,a),p(""),y(new Set),I(new Set),E(),h()},Se=()=>{q(!1),p(""),y(new Set),E(),h()},ge=()=>{q(!1),M(!0),E()};t.useEffect(()=>(window.__bossSpawnModalSuccess=Se,window.__bossSpawnModalError=ge,()=>{delete window.__bossSpawnModalSuccess,delete window.__bossSpawnModalError}),[r]);const Ce=e=>{e.target===e.currentTarget&&h()},ke=e=>{e.key==="Escape"&&h()},Me=e=>{const a=new Set(v);a.has(e)?a.delete(e):a.add(e),y(a)};if(!m)return null;const R=P.boss;return s.jsx("div",{className:`modal-overlay ${m?"visible":""}`,onClick:Ce,onKeyDown:ke,children:s.jsxs("div",{className:"modal boss-spawn-modal",children:[s.jsxs("div",{className:"modal-header",children:[s.jsx("span",{className:"boss-header-icon",children:R.icon}),n("terminal:spawn.deployBossTitle")]}),s.jsxs("div",{className:"modal-body spawn-modal-body",children:[s.jsxs("div",{className:"spawn-top-section",children:[s.jsx("div",{className:"spawn-preview-compact",children:s.jsx(Ie,{agentClass:Ne,modelFile:be,customModelUrl:fe,modelScale:je,width:100,height:120})}),s.jsxs("div",{className:"spawn-class-section",children:[s.jsx("div",{className:"spawn-class-label",children:n("terminal:spawn.bossClass")}),o.length+O.length+1>6&&s.jsx("input",{type:"text",className:"spawn-input class-search-input",placeholder:n("terminal:spawn.filterClasses"),value:u,onChange:e=>pe(e.target.value)}),s.jsxs("div",{className:"class-selector-inline",children:[X.map(e=>s.jsxs("button",{className:`class-chip ${c===e.id?"selected":""}`,onClick:()=>_(e.id),title:e.description,children:[s.jsx("span",{className:"class-chip-icon",children:e.icon}),s.jsx("span",{className:"class-chip-name",children:e.name})]},e.id)),Q&&s.jsxs("button",{className:`class-chip ${c==="boss"?"selected":""}`,onClick:()=>_("boss"),title:R.description,children:[s.jsx("span",{className:"class-chip-icon",children:R.icon}),s.jsx("span",{className:"class-chip-name",children:n("terminal:spawn.bossClassName")})]}),Z.map(e=>{const a=ae[e.id];return a?s.jsxs("button",{className:`class-chip ${c===e.id?"selected":""}`,onClick:()=>_(e.id),title:a.description,children:[s.jsx("span",{className:"class-chip-icon",children:a.icon}),s.jsx("span",{className:"class-chip-name",children:e.name})]},e.id):null}),u&&X.length===0&&!Q&&Z.length===0&&s.jsx("div",{className:"class-search-empty",children:n("terminal:spawn.noClassesMatch",{query:u})})]})]})]}),s.jsxs("div",{className:"spawn-form-section",children:[s.jsxs("div",{className:"spawn-form-row",children:[s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:n("common:labels.name")}),s.jsx("input",{ref:$,type:"text",className:"spawn-input",placeholder:n("terminal:spawn.bossNamePlaceholder"),value:r,onChange:e=>p(e.target.value)})]}),s.jsxs("div",{className:"spawn-field spawn-field-wide",children:[s.jsx("label",{className:"spawn-label",children:n("terminal:spawn.workingDir")}),s.jsx(Be,{value:k,onChange:e=>{te(e),M(!1)},placeholder:n("terminal:spawn.workingDirPlaceholder"),className:"spawn-input",hasError:ie,directoriesOnly:!0})]})]}),s.jsxs("div",{className:"spawn-form-row",children:[s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:n("common:labels.runtime")}),s.jsxs("div",{className:"spawn-select-row",children:[s.jsxs("button",{className:`spawn-select-btn ${d==="claude"?"selected":""}`,onClick:()=>D("claude"),title:n("terminal:spawn.useClaudeCli"),children:[s.jsx("img",{src:"/assets/claude.ico",alt:"Claude",className:"spawn-provider-icon"}),s.jsx("span",{children:"Claude"})]}),s.jsxs("button",{className:`spawn-select-btn ${d==="codex"?"selected":""}`,onClick:()=>D("codex"),title:n("terminal:spawn.useCodexCli"),children:[s.jsx("img",{src:"/assets/codex.ico",alt:"Codex",className:"spawn-provider-icon"}),s.jsx("span",{children:"Codex"})]}),s.jsxs("button",{className:`spawn-select-btn spawn-select-btn--opencode ${d==="opencode"?"selected":""}`,onClick:()=>D("opencode"),title:"Use OpenCode CLI (multi-provider)",children:[s.jsx("span",{children:"🟢"}),s.jsx("span",{children:"OpenCode"})]})]})]}),s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:n("common:labels.permissions")}),s.jsx("div",{className:"spawn-select-row",children:Object.keys(T).map(e=>s.jsxs("button",{className:`spawn-select-btn ${W===e?"selected":""}`,onClick:()=>oe(e),title:T[e].description,children:[s.jsx("span",{children:e==="bypass"?"⚡":"🔐"}),s.jsx("span",{children:T[e].label})]},e))})]})]}),s.jsxs("div",{className:"spawn-form-row",children:[s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:n("common:labels.model")}),d==="claude"?s.jsx("div",{className:"spawn-select-row",children:Object.keys(A).map(e=>s.jsxs("button",{className:`spawn-select-btn ${G===e?"selected":""}`,onClick:()=>re(e),title:A[e].description,children:[s.jsx("span",{children:A[e].icon}),s.jsx("span",{children:A[e].label})]},e))}):d==="codex"?s.jsx("div",{className:"spawn-select-row spawn-select-row--codex-models",children:Object.keys(L).map(e=>s.jsxs("button",{className:`spawn-select-btn ${K===e?"selected":""}`,onClick:()=>de(e),title:L[e].description,children:[s.jsx("span",{children:L[e].icon}),s.jsx("span",{children:L[e].label})]},e))}):d==="opencode"?s.jsx("input",{type:"text",className:"spawn-input",defaultValue:"minimax/MiniMax-M1-80k",placeholder:"provider/model (e.g., minimax/MiniMax-M1-80k)"}):s.jsx("div",{className:"spawn-inline-hint",children:n("terminal:spawn.codex.configuration")})]}),s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:n("common:labels.browser")}),s.jsx("div",{className:"spawn-form-row spawn-options-row",children:s.jsxs("label",{className:"spawn-checkbox",children:[s.jsx("input",{type:"checkbox",checked:F,onChange:e=>ce(e.target.checked),disabled:d!=="claude"}),s.jsx("span",{children:n("terminal:spawn.chromeBrowser")})]})})]})]}),d==="codex"&&s.jsx("div",{className:"spawn-form-row",children:s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:n("terminal:spawn.codex.config")}),s.jsxs("div",{className:"spawn-options-row",style:{display:"flex",flexDirection:"column",gap:8},children:[s.jsxs("label",{className:"spawn-checkbox",children:[s.jsx("input",{type:"checkbox",checked:b.fullAuto!==!1,onChange:e=>N(a=>({...a,fullAuto:e.target.checked}))}),s.jsx("span",{children:n("terminal:spawn.codex.useFullAuto")})]}),s.jsxs("label",{className:"spawn-checkbox",children:[s.jsx("input",{type:"checkbox",checked:!!b.search,onChange:e=>N(a=>({...a,search:e.target.checked}))}),s.jsx("span",{children:n("terminal:spawn.codex.enableSearch")})]}),b.fullAuto===!1&&s.jsxs(s.Fragment,{children:[s.jsxs("select",{className:"spawn-input",value:b.sandbox||"workspace-write",onChange:e=>N(a=>({...a,sandbox:e.target.value})),children:[s.jsx("option",{value:"read-only",children:n("terminal:spawn.codex.sandboxReadOnly")}),s.jsx("option",{value:"workspace-write",children:n("terminal:spawn.codex.sandboxWorkspaceWrite")}),s.jsx("option",{value:"danger-full-access",children:n("terminal:spawn.codex.sandboxDangerFullAccess")})]}),s.jsxs("select",{className:"spawn-input",value:b.approvalMode||"on-request",onChange:e=>N(a=>({...a,approvalMode:e.target.value})),children:[s.jsx("option",{value:"untrusted",children:n("terminal:spawn.codex.approvalsUntrusted")}),s.jsx("option",{value:"on-failure",children:n("terminal:spawn.codex.approvalsOnFailure")}),s.jsx("option",{value:"on-request",children:n("terminal:spawn.codex.approvalsOnRequest")}),s.jsx("option",{value:"never",children:n("terminal:spawn.codex.approvalsNever")})]})]}),s.jsx("input",{type:"text",className:"spawn-input",placeholder:n("terminal:spawn.codex.profileOptional"),value:b.profile||"",onChange:e=>N(a=>({...a,profile:e.target.value||void 0}))})]})]})}),x.length>0&&s.jsxs("div",{className:"spawn-skills-section",children:[s.jsxs("label",{className:"spawn-label",children:[n("terminal:spawn.skills")," ",s.jsxs("span",{className:"spawn-label-hint",children:["(",n("common:labels.optional"),")"]})]}),x.length>6&&s.jsx("input",{type:"text",className:"spawn-input skill-search-input",placeholder:n("terminal:spawn.filterSkills"),value:f,onChange:e=>ue(e.target.value)}),s.jsxs("div",{className:"spawn-skills-inline",children:[Y.map(e=>{const a=z.has(e.id);return he.some(w=>w.id===e.id)?null:s.jsxs("button",{className:`spawn-skill-chip ${a?"selected":""}`,onClick:()=>xe(e.id),title:e.description,children:[a&&s.jsx("span",{className:"spawn-skill-check",children:"✓"}),s.jsx("span",{children:e.name}),e.builtin&&s.jsx("span",{className:"spawn-skill-builtin",children:"TC"})]},e.id)}),f&&Y.length===0&&s.jsx("div",{className:"skill-search-empty",children:n("terminal:spawn.noSkillsMatch",{query:f})})]})]}),s.jsxs("div",{className:"spawn-custom-instructions-section",children:[s.jsxs("label",{className:"spawn-label",children:[n("terminal:spawn.customInstructions")," ",s.jsxs("span",{className:"spawn-label-hint",children:["(",n("common:labels.optional"),")"]})]}),s.jsx("textarea",{className:"spawn-input spawn-textarea",placeholder:n("terminal:spawn.customInstructionsBossPlaceholder"),value:H,onChange:e=>me(e.target.value),rows:3})]}),s.jsxs("div",{className:"spawn-subordinates-section",children:[s.jsxs("label",{className:"spawn-label",children:[n("terminal:spawn.initialSubordinates")," ",s.jsxs("span",{className:"spawn-label-hint",children:["(",n("common:labels.optional"),")"]})]}),s.jsx("div",{className:"subordinates-selector-compact",children:V.length===0?s.jsx("div",{className:"subordinates-empty",children:n("terminal:spawn.noAvailableAgents")}):V.map(e=>{const a=v.has(e.id),l=P[e.class],w=o.find(ye=>ye.id===e.class),ee=l||w||{icon:"🤖",color:"#888888"};return s.jsxs("button",{className:`subordinate-chip ${a?"selected":""}`,onClick:()=>Me(e.id),children:[a&&s.jsx("span",{className:"subordinate-check",children:"✓"}),s.jsx("span",{className:"subordinate-chip-icon",style:{color:ee.color},children:ee.icon}),s.jsx("span",{className:"subordinate-chip-name",children:e.name})]},e.id)})}),v.size>0&&s.jsxs("div",{className:"subordinates-count",children:[v.size," ",n("common:labels.selected").toLowerCase()]})]})]})]}),s.jsxs("div",{className:"modal-footer",children:[s.jsx("button",{className:"btn btn-secondary",onClick:h,children:n("common:buttons.cancel")}),s.jsx("button",{className:"btn btn-boss",onClick:ve,disabled:U,children:n(U?"common:buttons.deploying":"common:buttons2.deployBoss")})]})]})})}export{Fe as BossSpawnModal};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/GmailOAuthSetup-GoKvyYWS.js","assets/main-6CnCKW13.js","assets/modulepreload-polyfill-B5Qt9EMX.js","assets/vendor-react--Eh9ivFN.js","assets/vendor-three-Chj50gSY.js","assets/main-DjGrMNoB.css","assets/GoogleOAuthSetup-D3sAGlZq.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{r as c,V as I,w,j as e,z as B,aN as R}from"./main-6CnCKW13.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";const z={"gmail-oauth":c.lazy(()=>R(()=>import("./GmailOAuthSetup-GoKvyYWS.js"),__vite__mapDeps([0,1,2,3,4,5])).then(s=>({default:s.GmailOAuthSetup}))),"google-oauth":c.lazy(()=>R(()=>import("./GoogleOAuthSetup-D3sAGlZq.js"),__vite__mapDeps([6,1,2,3,4,5])).then(s=>({default:s.GoogleOAuthSetup})))},E={gmail:"✉️",slack:"💬",jira:"📋","google-calendar":"📅",docx:"📄"},N={gmail:"Send and receive emails through Gmail. Supports OAuth 2.0 authentication for secure access to your inbox.",slack:"Connect to Slack workspaces. Send messages, receive notifications, and integrate with channels.",jira:"Manage Jira issues and projects. Create tickets, track progress, and handle service desk requests.","google-calendar":"Access Google Calendar events. Create, update, and monitor calendar entries.",docx:"Generate and manipulate DOCX documents. Create reports, templates, and formatted documents."},A={gmail:["Google Cloud Console project","OAuth 2.0 credentials (Client ID & Secret)","Gmail API enabled"],slack:["Slack App with Bot Token and App-Level Token (Socket Mode)",'Enable Socket Mode in your app settings under "Socket Mode"','Enable Events in the "Event Subscriptions" section of your app config',"Subscribe to bot events: message.channels, message.groups, message.im","Required Bot Token scopes: channels:history, channels:read, chat:write, groups:history, groups:read, im:history, im:read, users:read"],jira:["Jira Cloud instance URL","API Token (from Atlassian account)","Account email address"],"google-calendar":["Google Cloud Console project","OAuth 2.0 credentials","Calendar API enabled"],docx:["No external credentials required","Templates directory (optional)"]},o={overlay:{position:"fixed",inset:0,background:"rgba(0, 0, 0, 0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e4,backdropFilter:"blur(4px)",animation:"fadeIn 0.15s ease-out"},modal:{background:"var(--surface-0, #1e1e2e)",borderRadius:12,border:"1px solid var(--border, #313244)",width:"90vw",maxWidth:720,maxHeight:"85vh",display:"flex",flexDirection:"column",overflow:"hidden",boxShadow:"0 20px 60px rgba(0, 0, 0, 0.5)",animation:"slideUp 0.2s ease-out"},header:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"16px 20px",borderBottom:"1px solid var(--border, #313244)",background:"var(--surface-1, #181825)"},headerTitle:{fontSize:16,fontWeight:600,color:"var(--text-primary, #cdd6f4)",display:"flex",alignItems:"center",gap:8},closeBtn:{background:"none",border:"none",color:"var(--text-secondary, #a6adc8)",fontSize:20,cursor:"pointer",padding:"4px 8px",borderRadius:6,lineHeight:1},tabs:{display:"flex",borderBottom:"1px solid var(--border, #313244)",background:"var(--surface-1, #181825)",overflowX:"auto",scrollbarWidth:"none"},tab:s=>({padding:"10px 16px",background:"none",border:"none",borderBottom:s?"2px solid var(--accent, #89b4fa)":"2px solid transparent",color:s?"var(--accent, #89b4fa)":"var(--text-secondary, #a6adc8)",fontSize:13,fontWeight:s?600:400,cursor:"pointer",display:"flex",alignItems:"center",gap:6,whiteSpace:"nowrap",transition:"color 0.15s, border-color 0.15s",flexShrink:0}),tabStatus:(s,u)=>({width:6,height:6,borderRadius:"50%",background:u?"#f38ba8":s?"#a6e3a1":"#fab387",flexShrink:0}),body:{flex:1,overflow:"auto",padding:20},integrationHeader:{display:"flex",alignItems:"flex-start",gap:12,marginBottom:16},iconCircle:{width:44,height:44,borderRadius:10,background:"var(--surface-1, #181825)",border:"1px solid var(--border, #313244)",display:"flex",alignItems:"center",justifyContent:"center",fontSize:22,flexShrink:0},integrationMeta:{flex:1},integrationName:{fontSize:15,fontWeight:600,color:"var(--text-primary, #cdd6f4)",marginBottom:4,display:"flex",alignItems:"center",gap:8},description:{fontSize:13,color:"var(--text-secondary, #a6adc8)",lineHeight:1.5},statusBadge:(s,u)=>({display:"inline-flex",alignItems:"center",gap:4,padding:"2px 8px",borderRadius:10,fontSize:11,fontWeight:600,background:u?"rgba(243, 139, 168, 0.15)":s?"rgba(166, 227, 161, 0.15)":"rgba(250, 179, 135, 0.15)",color:u?"#f38ba8":s?"#a6e3a1":"#fab387"}),section:{marginTop:16,padding:12,borderRadius:8,background:"var(--surface-1, #181825)",border:"1px solid var(--border, #313244)"},sectionTitle:{fontSize:12,fontWeight:600,color:"var(--text-secondary, #a6adc8)",textTransform:"uppercase",letterSpacing:"0.5px",marginBottom:8},requirementList:{listStyle:"none",margin:0,padding:0,display:"flex",flexDirection:"column",gap:4},requirementItem:{fontSize:12,color:"var(--text-secondary, #a6adc8)",display:"flex",alignItems:"center",gap:6},formSection:{marginTop:16},formSectionTitle:{fontSize:12,fontWeight:600,color:"var(--text-secondary, #a6adc8)",textTransform:"uppercase",letterSpacing:"0.5px",marginBottom:12}};function O({integration:s,onSave:u,onCancel:g}){const[p,T]=c.useState({...s.values}),[m,x]=c.useState({}),[h,C]=c.useState(!1),[y,b]=c.useState(!1);c.useEffect(()=>{T({...s.values}),x({}),b(!1)},[s.id]);const f=(t,l)=>{T(r=>({...r,[t]:l})),x(r=>{const i={...r};return delete i[t],i}),b(!1)},k=async t=>{t.preventDefault();const l={};for(const r of s.schema)if(r.required&&!p[r.key]&&p[r.key]!==0&&p[r.key]!==!1&&(l[r.key]=`${r.label} is required`),r.validate){const i=r.validate(p[r.key]);i&&(l[r.key]=i)}if(Object.keys(l).length>0){x(l);return}C(!0);try{await u(p),b(!0),setTimeout(()=>b(!1),3e3)}catch(r){x({_form:String(r)})}finally{C(!1)}},v=new Map;for(const t of s.schema){const l=t.group||"";v.has(l)||v.set(l,[]),v.get(l).push(t)}const n={display:"flex",flexDirection:"column",gap:4,marginBottom:12},a={fontSize:13,fontWeight:500,color:"var(--text-primary, #cdd6f4)"},d={padding:"8px 10px",borderRadius:6,border:"1px solid var(--border, #313244)",background:"var(--surface-0, #1e1e2e)",color:"var(--text-primary, #cdd6f4)",fontSize:13,outline:"none",width:"100%",boxSizing:"border-box"},S={fontSize:11,color:"var(--text-secondary, #a6adc8)"},j={fontSize:11,color:"#f38ba8"},_=t=>{var r;const l=p[t.key]??t.defaultValue??"";switch(t.type){case"boolean":return e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:8,fontSize:13,color:"var(--text-primary, #cdd6f4)",cursor:"pointer"},children:[e.jsx("input",{type:"checkbox",checked:!!l,onChange:i=>f(t.key,i.target.checked)}),t.label]});case"select":return e.jsxs("select",{style:d,value:String(l),onChange:i=>f(t.key,i.target.value),children:[e.jsx("option",{value:"",children:t.placeholder||"Select..."}),(r=t.options)==null?void 0:r.map(i=>e.jsx("option",{value:i.value,children:i.label},i.value))]});case"textarea":return e.jsx("textarea",{style:{...d,resize:"vertical",minHeight:80},value:String(l),placeholder:t.placeholder,onChange:i=>f(t.key,i.target.value),rows:4});case"number":return e.jsx("input",{type:"number",style:d,value:l===""?"":Number(l),placeholder:t.placeholder,onChange:i=>f(t.key,i.target.value===""?"":Number(i.target.value))});case"password":return e.jsx("input",{type:"password",style:d,value:String(l),placeholder:t.placeholder,onChange:i=>f(t.key,i.target.value),autoComplete:"off"});default:return e.jsx("input",{type:t.type,style:d,value:String(l),placeholder:t.placeholder,onChange:i=>f(t.key,i.target.value)})}};return e.jsxs("form",{onSubmit:k,children:[m._form&&e.jsx("div",{style:{...j,marginBottom:12,padding:"8px 10px",borderRadius:6,background:"rgba(243, 139, 168, 0.1)"},children:m._form}),Array.from(v.entries()).map(([t,l])=>e.jsxs("div",{children:[t&&e.jsx("div",{style:{...o.sectionTitle,marginTop:16,marginBottom:8},children:t}),l.map(r=>e.jsxs("div",{style:n,children:[r.type!=="boolean"&&e.jsxs("label",{style:a,children:[r.label,r.required&&e.jsx("span",{style:{color:"#f38ba8",marginLeft:2},children:"*"})]}),_(r),r.description&&e.jsx("span",{style:S,children:r.description}),m[r.key]&&e.jsx("span",{style:j,children:m[r.key]})]},r.key))]},t||"_default")),e.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",marginTop:16,paddingTop:12,borderTop:"1px solid var(--border, #313244)"},children:[e.jsx("button",{type:"button",onClick:g,style:{padding:"8px 16px",borderRadius:6,border:"1px solid var(--border, #313244)",background:"none",color:"var(--text-secondary, #a6adc8)",fontSize:13,cursor:"pointer"},children:"Cancel"}),e.jsx("button",{type:"submit",disabled:h,style:{padding:"8px 16px",borderRadius:6,border:"none",background:y?"#a6e3a1":"var(--accent, #89b4fa)",color:"#1e1e2e",fontSize:13,fontWeight:600,cursor:h?"wait":"pointer",opacity:h?.7:1},children:h?"Saving...":y?"Saved":"Save Configuration"})]})]})}function W({isOpen:s,onClose:u,initialTab:g}){const[p,T]=c.useState([]),[m,x]=c.useState(g||null),[h,C]=c.useState(!0),[y,b]=c.useState(null),f=c.useRef(g||null),k=c.useCallback(async()=>{try{const a=await I(w("/api/integrations"));if(!a.ok)throw new Error(`HTTP ${a.status}`);const d=await a.json();T(d),b(null),x(S=>{const j=S||g||(d.length>0?d[0].id:null);return f.current=j,j})}catch(a){b(`Failed to load integrations: ${a}`)}finally{C(!1)}},[g]);c.useEffect(()=>{s&&(C(!0),k(),g&&x(g))},[s,g]);const v=c.useCallback(async(a,d)=>{const S=await I(w(`/api/integrations/${a}/config`),{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(d)});if(!S.ok){const j=await S.json().catch(()=>({}));throw new Error(j.error||`HTTP ${S.status}`)}await k()},[k]);if(!s)return null;const n=p.find(a=>a.id===m);return e.jsx("div",{style:o.overlay,onClick:u,children:e.jsxs("div",{style:o.modal,onClick:a=>a.stopPropagation(),children:[e.jsxs("div",{style:o.header,children:[e.jsxs("div",{style:o.headerTitle,children:[e.jsx("span",{children:"🔌"}),e.jsx("span",{children:"Integrations"})]}),e.jsx("button",{style:o.closeBtn,onClick:u,title:"Close",children:"×"})]}),h&&e.jsx("div",{style:{padding:40,textAlign:"center",color:"var(--text-secondary, #a6adc8)"},children:"Loading integrations..."}),y&&e.jsxs("div",{style:{padding:20,textAlign:"center"},children:[e.jsx("div",{style:{color:"#f38ba8",marginBottom:8},children:y}),e.jsx("button",{onClick:k,style:{padding:"6px 12px",borderRadius:6,border:"1px solid var(--border, #313244)",background:"none",color:"var(--text-primary, #cdd6f4)",cursor:"pointer",fontSize:13},children:"Retry"})]}),!h&&!y&&p.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("div",{style:o.tabs,children:p.map(a=>e.jsxs("button",{style:o.tab(m===a.id),onClick:()=>x(a.id),children:[e.jsx("span",{children:E[a.id]||"🔌"}),e.jsx("span",{children:a.name}),e.jsx("span",{style:o.tabStatus(a.status.connected,!!a.status.error)})]},a.id))}),e.jsx("div",{style:o.body,children:n&&e.jsxs("div",{children:[e.jsxs("div",{style:o.integrationHeader,children:[e.jsx("div",{style:o.iconCircle,children:E[n.id]||"🔌"}),e.jsxs("div",{style:o.integrationMeta,children:[e.jsxs("div",{style:o.integrationName,children:[n.name,e.jsx("span",{style:o.statusBadge(n.status.connected,!!n.status.error),children:n.status.error?"✗ Error":n.status.connected?"✓ Connected":"⚠ Not Configured"})]}),e.jsx("div",{style:o.description,children:N[n.id]||n.description})]})]}),n.status.error&&e.jsxs("div",{style:{...o.section,borderColor:"rgba(243, 139, 168, 0.3)",background:"rgba(243, 139, 168, 0.05)"},children:[e.jsx("div",{style:{...o.sectionTitle,color:"#f38ba8"},children:"Error"}),e.jsx("div",{style:{fontSize:12,color:"#f38ba8"},children:n.status.error})]}),A[n.id]&&e.jsxs("div",{style:o.section,children:[e.jsx("div",{style:o.sectionTitle,children:"Requirements"}),e.jsx("ul",{style:o.requirementList,children:A[n.id].map((a,d)=>e.jsxs("li",{style:o.requirementItem,children:[e.jsx("span",{style:{color:"var(--accent, #89b4fa)"},children:"•"}),a]},d))})]}),e.jsxs("div",{style:o.formSection,children:[e.jsx("div",{style:o.formSectionTitle,children:"Configuration"}),n.customComponent&&z[n.customComponent]?e.jsx(c.Suspense,{fallback:e.jsx("div",{style:{color:"var(--text-secondary)",fontSize:13},children:"Loading..."}),children:B.createElement(z[n.customComponent],{key:n.id,integration:n,onSave:a=>v(n.id,a),onCancel:u})}):e.jsx(O,{integration:n,onSave:a=>v(n.id,a),onCancel:u})]})]})})]}),!h&&!y&&p.length===0&&e.jsx("div",{style:{padding:40,textAlign:"center",color:"var(--text-secondary, #a6adc8)"},children:"No integrations available."})]})})}export{W as IntegrationsPanel};
|