tide-commander 1.87.0 → 1.89.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-S3Rke-8g.js → BossLogsModal-BK6N5fG2.js} +1 -1
- package/dist/assets/{BossSpawnModal-BjWGNCnz.js → BossSpawnModal-BTy-lus4.js} +1 -1
- package/dist/assets/{ControlsModal-6yfU0XjZ.js → ControlsModal-B4MhaF1V.js} +1 -1
- package/dist/assets/{DockerLogsModal-CYq0hNz6.js → DockerLogsModal-C33dAwy1.js} +1 -1
- package/dist/assets/{EmbeddedEditor-ZBdqRDqm.js → EmbeddedEditor-BfjjT-GF.js} +1 -1
- package/dist/assets/{GmailOAuthSetup-BcV5jAse.js → GmailOAuthSetup-TQyjHs3_.js} +1 -1
- package/dist/assets/{GoogleOAuthSetup-DyUW_STE.js → GoogleOAuthSetup-DAIzYKy8.js} +1 -1
- package/dist/assets/{IframeModal-D9A3dUUc.js → IframeModal-g8tC4aah.js} +1 -1
- package/dist/assets/IntegrationsPanel-CuKr7702.js +2 -0
- package/dist/assets/{LogViewerModal-BWkbY7wa.js → LogViewerModal-DO45Kea0.js} +1 -1
- package/dist/assets/{MonitoringModal-AZzokZAZ.js → MonitoringModal-OIwmagj2.js} +1 -1
- package/dist/assets/{PM2LogsModal-q98eiBfq.js → PM2LogsModal-BRQzSiFN.js} +1 -1
- package/dist/assets/{RestoreArchivedAreaModal-CTxRP2qE.js → RestoreArchivedAreaModal-CBRN9Xpb.js} +1 -1
- package/dist/assets/{Scene2DCanvas-C11dztp1.js → Scene2DCanvas-4J4ZefT6.js} +1 -1
- package/dist/assets/{SceneManager-CsW9MYrD.js → SceneManager-DZsJcYvW.js} +1 -1
- package/dist/assets/{SkillsPanel-BeZr9w6E.js → SkillsPanel-DHk7h3Ja.js} +1 -1
- package/dist/assets/SlackMultiInstanceSetup-Dp1q2zM1.js +2 -0
- package/dist/assets/{SpawnModal-DY_KM6lX.js → SpawnModal-CfozYMNI.js} +1 -1
- package/dist/assets/{SubordinateAssignmentModal-D6RvjGX9.js → SubordinateAssignmentModal-BBfbpVUr.js} +1 -1
- package/dist/assets/{TriggerManagerPanel-BmqjXv9T.js → TriggerManagerPanel-DQw9nt1r.js} +2 -2
- package/dist/assets/{WorkflowEditorPanel-Rd5ZjJmt.js → WorkflowEditorPanel-BM2ec8CS.js} +1 -1
- package/dist/assets/{index-DSvJOrb7.js → index-BiAZinYH.js} +2 -2
- package/dist/assets/{index-BYVHgVEo.js → index-BqbR55dr.js} +1 -1
- package/dist/assets/{index-DRGyDtmm.js → index-CcSJA57k.js} +1 -1
- package/dist/assets/{index-BtJyOo4p.js → index-DNEUJDeO.js} +1 -1
- package/dist/assets/{index-BoORE9Q1.js → index-DY9w7IcH.js} +1 -1
- package/dist/assets/{index-DHHRkTG1.js → index-bcwTXJ6F.js} +1 -1
- package/dist/assets/index-fZfyvIUZ.js +2 -0
- package/dist/assets/{index-BxaEkSIx.js → index-jXkaBxIq.js} +3 -3
- package/dist/assets/index-xEvpFBA8.js +8 -0
- package/dist/assets/main-Bw5ZddEN.css +1 -0
- package/dist/assets/main-D-YFCprA.js +213 -0
- package/dist/assets/{web-D3zCwsS9.js → web-BrBkKQlr.js} +1 -1
- package/dist/assets/{web-DS0FHmg8.js → web-DCu3NTho.js} +1 -1
- package/dist/assets/{web-DEq3Te_H.js → web-DX588C-g.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/src/packages/server/data/builtin-skills/explore-database.js +175 -0
- package/dist/src/packages/server/data/builtin-skills/index.js +2 -0
- package/dist/src/packages/server/data/event-queries.js +2 -0
- package/dist/src/packages/server/data/index.js +56 -2
- package/dist/src/packages/server/data/migrations/006_slack_messages_integration_instance.sql +9 -0
- package/dist/src/packages/server/index.js +2 -1
- package/dist/src/packages/server/integrations/gmail/gmail-trigger-handler.js +9 -1
- package/dist/src/packages/server/integrations/slack/index.js +65 -19
- package/dist/src/packages/server/integrations/slack/slack-client.js +44 -602
- package/dist/src/packages/server/integrations/slack/slack-config.js +229 -29
- package/dist/src/packages/server/integrations/slack/slack-instance-manifest.js +150 -0
- package/dist/src/packages/server/integrations/slack/slack-instance.js +801 -0
- package/dist/src/packages/server/integrations/slack/slack-polling-client.js +522 -0
- package/dist/src/packages/server/integrations/slack/slack-routes.js +243 -24
- package/dist/src/packages/server/integrations/slack/slack-trigger-handler.js +53 -20
- package/dist/src/packages/server/integrations/slack/slack-watermark-store.js +124 -0
- package/dist/src/packages/server/integrations/whatsapp/index.js +5 -4
- package/dist/src/packages/server/integrations/whatsapp/whatsapp-client.js +10 -0
- package/dist/src/packages/server/integrations/whatsapp/whatsapp-routes.js +68 -0
- package/dist/src/packages/server/integrations/whatsapp/whatsapp-trigger-handler.js +127 -0
- package/dist/src/packages/server/routes/database.js +221 -0
- package/dist/src/packages/server/routes/files.js +219 -18
- package/dist/src/packages/server/routes/index.js +2 -0
- package/dist/src/packages/server/services/building-service.js +41 -0
- package/dist/src/packages/server/services/database-service.js +61 -9
- package/dist/src/packages/server/services/index.js +1 -0
- package/dist/src/packages/server/services/ssh-tunnel-service.js +255 -0
- package/dist/src/packages/server/websocket/handler.js +2 -1
- package/dist/src/packages/server/websocket/handlers/database-handler.js +35 -0
- package/package.json +3 -1
- package/dist/assets/IntegrationsPanel-CHaNJBJW.js +0 -2
- package/dist/assets/index-BOr_tbLK.js +0 -2
- package/dist/assets/index-Co7njQ0Q.js +0 -8
- package/dist/assets/main-BrZe9Zbd.js +0 -201
- package/dist/assets/main-kpU9m5LW.css +0 -1
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Tunnel Service
|
|
3
|
+
*
|
|
4
|
+
* Manages SSH tunnel lifecycles for Database buildings. Each tunnel:
|
|
5
|
+
* 1. Opens an ssh2 Client to the configured jump host.
|
|
6
|
+
* 2. Listens on a local TCP port (auto-assigned or fixed via config.localPort).
|
|
7
|
+
* 3. On each incoming local connection, calls client.forwardOut() to relay
|
|
8
|
+
* traffic to the DB target host:port as seen FROM the SSH server.
|
|
9
|
+
*
|
|
10
|
+
* Tunnels are keyed by connection ID and reused across pool factories.
|
|
11
|
+
* Errors are surfaced as Error rejections; credentials are NEVER logged.
|
|
12
|
+
*/
|
|
13
|
+
import { Client as SSHClient } from 'ssh2';
|
|
14
|
+
import net from 'net';
|
|
15
|
+
import fs from 'fs';
|
|
16
|
+
import { createLogger } from '../utils/index.js';
|
|
17
|
+
const log = createLogger('SSHTunnelService');
|
|
18
|
+
// Active tunnels keyed by connection ID. Stored as Promise so concurrent
|
|
19
|
+
// callers share a single bring-up.
|
|
20
|
+
const tunnels = new Map();
|
|
21
|
+
function buildSSHConnectConfig(cfg) {
|
|
22
|
+
const base = {
|
|
23
|
+
host: cfg.host,
|
|
24
|
+
port: cfg.port || 22,
|
|
25
|
+
username: cfg.username,
|
|
26
|
+
readyTimeout: cfg.readyTimeoutMs ?? 20000,
|
|
27
|
+
keepaliveInterval: cfg.keepaliveIntervalMs ?? 10000,
|
|
28
|
+
};
|
|
29
|
+
if (cfg.authMethod === 'password') {
|
|
30
|
+
if (!cfg.password) {
|
|
31
|
+
throw new Error('SSH password required when authMethod is "password"');
|
|
32
|
+
}
|
|
33
|
+
base.password = cfg.password;
|
|
34
|
+
return base;
|
|
35
|
+
}
|
|
36
|
+
// privateKey auth: prefer inline, fall back to file path
|
|
37
|
+
let key;
|
|
38
|
+
if (cfg.privateKey && cfg.privateKey.trim().length > 0) {
|
|
39
|
+
key = cfg.privateKey;
|
|
40
|
+
}
|
|
41
|
+
else if (cfg.privateKeyPath && cfg.privateKeyPath.trim().length > 0) {
|
|
42
|
+
try {
|
|
43
|
+
key = fs.readFileSync(cfg.privateKeyPath);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
47
|
+
throw new Error(`Failed to read SSH private key file: ${msg}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!key) {
|
|
51
|
+
throw new Error('SSH private key required when authMethod is "privateKey"');
|
|
52
|
+
}
|
|
53
|
+
base.privateKey = key;
|
|
54
|
+
if (cfg.passphrase)
|
|
55
|
+
base.passphrase = cfg.passphrase;
|
|
56
|
+
return base;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Open the SSH client and listen on a local TCP port that forwards each
|
|
60
|
+
* incoming connection to remoteHost:remotePort via the SSH server.
|
|
61
|
+
*/
|
|
62
|
+
function openTunnel(connectionId, cfg, remoteHost, remotePort) {
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
let connectConfig;
|
|
65
|
+
try {
|
|
66
|
+
connectConfig = buildSSHConnectConfig(cfg);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
reject(err);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const client = new SSHClient();
|
|
73
|
+
let resolved = false;
|
|
74
|
+
const cleanupOnFailure = (err) => {
|
|
75
|
+
if (resolved)
|
|
76
|
+
return;
|
|
77
|
+
resolved = true;
|
|
78
|
+
try {
|
|
79
|
+
client.end();
|
|
80
|
+
}
|
|
81
|
+
catch { /* ignore */ }
|
|
82
|
+
reject(err);
|
|
83
|
+
};
|
|
84
|
+
client.on('error', (err) => {
|
|
85
|
+
log.error(`SSH error for connection ${connectionId}: ${err.message}`);
|
|
86
|
+
cleanupOnFailure(new Error(`SSH connection failed: ${err.message}`));
|
|
87
|
+
});
|
|
88
|
+
let handleRef;
|
|
89
|
+
client.on('close', () => {
|
|
90
|
+
if (handleRef && !handleRef.closed) {
|
|
91
|
+
handleRef.closed = true;
|
|
92
|
+
log.warn(`SSH client closed unexpectedly for ${connectionId}; tunnel marked dead`);
|
|
93
|
+
try {
|
|
94
|
+
handleRef.server.close();
|
|
95
|
+
}
|
|
96
|
+
catch { /* ignore */ }
|
|
97
|
+
// Remove from registry so next caller rebuilds the tunnel
|
|
98
|
+
if (tunnels.get(connectionId) instanceof Promise) {
|
|
99
|
+
tunnels.delete(connectionId);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
client.on('ready', () => {
|
|
104
|
+
const server = net.createServer((localSocket) => {
|
|
105
|
+
client.forwardOut('127.0.0.1', 0, remoteHost, remotePort, (err, stream) => {
|
|
106
|
+
if (err) {
|
|
107
|
+
log.error(`Forward-out failed for ${connectionId}: ${err.message}`);
|
|
108
|
+
localSocket.destroy(err);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
localSocket.pipe(stream).pipe(localSocket);
|
|
112
|
+
stream.on('error', () => localSocket.destroy());
|
|
113
|
+
localSocket.on('error', () => stream.destroy());
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
server.on('error', (err) => {
|
|
117
|
+
log.error(`Local tunnel server error (${connectionId}): ${err.message}`);
|
|
118
|
+
cleanupOnFailure(err);
|
|
119
|
+
});
|
|
120
|
+
const desiredPort = cfg.localPort && cfg.localPort > 0 ? cfg.localPort : 0;
|
|
121
|
+
server.listen(desiredPort, '127.0.0.1', () => {
|
|
122
|
+
const addr = server.address();
|
|
123
|
+
const localPort = typeof addr === 'object' && addr ? addr.port : desiredPort;
|
|
124
|
+
if (!localPort) {
|
|
125
|
+
cleanupOnFailure(new Error('Failed to determine local tunnel port'));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
resolved = true;
|
|
129
|
+
log.log(`Tunnel up: ${connectionId} 127.0.0.1:${localPort} -> ${cfg.host}:${cfg.port || 22} -> ${remoteHost}:${remotePort}`);
|
|
130
|
+
const handle = {
|
|
131
|
+
connectionId,
|
|
132
|
+
localHost: '127.0.0.1',
|
|
133
|
+
localPort,
|
|
134
|
+
remoteHost,
|
|
135
|
+
remotePort,
|
|
136
|
+
client,
|
|
137
|
+
server,
|
|
138
|
+
closed: false,
|
|
139
|
+
};
|
|
140
|
+
handleRef = handle;
|
|
141
|
+
resolve(handle);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
try {
|
|
145
|
+
client.connect(connectConfig);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
149
|
+
cleanupOnFailure(new Error(`Failed to start SSH connect: ${msg}`));
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get or create a tunnel for the given connection ID. If a tunnel already
|
|
155
|
+
* exists with the same target, it is reused; otherwise the prior one is
|
|
156
|
+
* closed and a new one created.
|
|
157
|
+
*/
|
|
158
|
+
export async function getOrCreateTunnel(connectionId, cfg, remoteHost, remotePort) {
|
|
159
|
+
const existingPromise = tunnels.get(connectionId);
|
|
160
|
+
if (existingPromise) {
|
|
161
|
+
try {
|
|
162
|
+
const existing = await existingPromise;
|
|
163
|
+
if (!existing.closed &&
|
|
164
|
+
existing.remoteHost === remoteHost &&
|
|
165
|
+
existing.remotePort === remotePort) {
|
|
166
|
+
return existing;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Fall through and recreate
|
|
171
|
+
}
|
|
172
|
+
await closeTunnel(connectionId);
|
|
173
|
+
}
|
|
174
|
+
const created = openTunnel(connectionId, cfg, remoteHost, remotePort);
|
|
175
|
+
tunnels.set(connectionId, created);
|
|
176
|
+
try {
|
|
177
|
+
return await created;
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
tunnels.delete(connectionId);
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Run a one-off transient tunnel (no caching). Caller MUST close it.
|
|
186
|
+
* Useful for "Test Connection" flows where we don't want to keep the
|
|
187
|
+
* tunnel alive after the test.
|
|
188
|
+
*/
|
|
189
|
+
export async function openTransientTunnel(cfg, remoteHost, remotePort) {
|
|
190
|
+
const transientId = `transient_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
191
|
+
return openTunnel(transientId, cfg, remoteHost, remotePort);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Close an active tunnel by connection ID.
|
|
195
|
+
*/
|
|
196
|
+
export async function closeTunnel(connectionId) {
|
|
197
|
+
const promise = tunnels.get(connectionId);
|
|
198
|
+
tunnels.delete(connectionId);
|
|
199
|
+
if (!promise)
|
|
200
|
+
return;
|
|
201
|
+
try {
|
|
202
|
+
const handle = await promise;
|
|
203
|
+
await closeTunnelHandle(handle);
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// Already failed to open; nothing to close.
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Close a tunnel handle (used for transient tunnels and via closeTunnel).
|
|
211
|
+
*/
|
|
212
|
+
export async function closeTunnelHandle(handle) {
|
|
213
|
+
if (handle.closed)
|
|
214
|
+
return;
|
|
215
|
+
handle.closed = true;
|
|
216
|
+
try {
|
|
217
|
+
await new Promise((resolve) => {
|
|
218
|
+
handle.server.close(() => resolve());
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
catch { /* ignore */ }
|
|
222
|
+
try {
|
|
223
|
+
handle.client.end();
|
|
224
|
+
}
|
|
225
|
+
catch { /* ignore */ }
|
|
226
|
+
log.log(`Tunnel closed: ${handle.connectionId}`);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Close every active tunnel. Called during graceful shutdown.
|
|
230
|
+
*/
|
|
231
|
+
export async function closeAllTunnels() {
|
|
232
|
+
const ids = Array.from(tunnels.keys());
|
|
233
|
+
await Promise.all(ids.map((id) => closeTunnel(id)));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Snapshot of currently open tunnels (for status/debug).
|
|
237
|
+
*/
|
|
238
|
+
export async function listOpenTunnels() {
|
|
239
|
+
const out = [];
|
|
240
|
+
for (const [id, promise] of tunnels.entries()) {
|
|
241
|
+
try {
|
|
242
|
+
const h = await promise;
|
|
243
|
+
if (!h.closed) {
|
|
244
|
+
out.push({
|
|
245
|
+
connectionId: id,
|
|
246
|
+
localPort: h.localPort,
|
|
247
|
+
remoteHost: h.remoteHost,
|
|
248
|
+
remotePort: h.remotePort,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch { /* skip failed */ }
|
|
253
|
+
}
|
|
254
|
+
return out;
|
|
255
|
+
}
|
|
@@ -17,7 +17,7 @@ import { handleBuildingCommand, handlePM2LogsStart, handlePM2LogsStop, handleDoc
|
|
|
17
17
|
import { handleSendCommand } from './handlers/command-handler.js';
|
|
18
18
|
import { handleCreateSecret, handleUpdateSecret, handleDeleteSecret, } from './handlers/secrets-handler.js';
|
|
19
19
|
import { secretsService } from '../services/secrets-service.js';
|
|
20
|
-
import { handleTestDatabaseConnection, handleListDatabases, handleListTables, handleGetTableSchema, handleExecuteQuery, handleRequestQueryHistory, handleToggleQueryFavorite, handleDeleteQueryHistory, handleClearQueryHistory, } from './handlers/database-handler.js';
|
|
20
|
+
import { handleTestDatabaseConnection, handleTestDatabaseConnectionTransient, handleListDatabases, handleListTables, handleGetTableSchema, handleExecuteQuery, handleRequestQueryHistory, handleToggleQueryFavorite, handleDeleteQueryHistory, handleClearQueryHistory, } from './handlers/database-handler.js';
|
|
21
21
|
import { handlePermissionResponse } from './handlers/permission-handler.js';
|
|
22
22
|
import { handleSendNotification } from './handlers/notification-handler.js';
|
|
23
23
|
import { handleSyncAreas, handleSyncBuildings } from './handlers/sync-handler.js';
|
|
@@ -185,6 +185,7 @@ const messageHandlers = {
|
|
|
185
185
|
boss_building_logs_start: handleBossBuildingLogsStart,
|
|
186
186
|
boss_building_logs_stop: handleBossBuildingLogsStop,
|
|
187
187
|
test_database_connection: handleTestDatabaseConnection,
|
|
188
|
+
test_database_connection_transient: handleTestDatabaseConnectionTransient,
|
|
188
189
|
list_databases: handleListDatabases,
|
|
189
190
|
execute_query: handleExecuteQuery,
|
|
190
191
|
request_query_history: handleRequestQueryHistory,
|
|
@@ -46,6 +46,41 @@ export async function handleTestDatabaseConnection(ctx, payload) {
|
|
|
46
46
|
},
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Handle test_database_connection_transient message — for testing an unsaved
|
|
51
|
+
* connection (e.g. from the Create Database modal "Test Connection" button).
|
|
52
|
+
* The connection object is passed inline; no building lookup is performed.
|
|
53
|
+
* If SSH is enabled, a one-shot tunnel is brought up and torn down per call.
|
|
54
|
+
*/
|
|
55
|
+
export async function handleTestDatabaseConnectionTransient(ctx, payload) {
|
|
56
|
+
const { requestId, connection } = payload;
|
|
57
|
+
if (!connection || !connection.id) {
|
|
58
|
+
ctx.sendToClient({
|
|
59
|
+
type: 'database_connection_result',
|
|
60
|
+
payload: {
|
|
61
|
+
buildingId: '',
|
|
62
|
+
connectionId: '',
|
|
63
|
+
requestId,
|
|
64
|
+
success: false,
|
|
65
|
+
error: 'Invalid connection payload',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
log.log(`Testing transient connection: ${connection.name} (${connection.engine})${connection.ssh?.enabled ? ' via SSH tunnel' : ''}`);
|
|
71
|
+
const result = await databaseService.testConnection(connection, { transient: true });
|
|
72
|
+
ctx.sendToClient({
|
|
73
|
+
type: 'database_connection_result',
|
|
74
|
+
payload: {
|
|
75
|
+
buildingId: '',
|
|
76
|
+
connectionId: connection.id,
|
|
77
|
+
requestId,
|
|
78
|
+
success: result.success,
|
|
79
|
+
error: result.error,
|
|
80
|
+
serverVersion: result.serverVersion,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
49
84
|
/**
|
|
50
85
|
* Handle list_databases message
|
|
51
86
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tide-commander",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.89.0",
|
|
4
4
|
"description": "Visual multi-agent orchestrator and manager for Claude Code with 3D/2D interface",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
"react-i18next": "^17.0.2",
|
|
101
101
|
"react-markdown": "^10.1.0",
|
|
102
102
|
"remark-gfm": "^4.0.1",
|
|
103
|
+
"ssh2": "^1.17.0",
|
|
103
104
|
"three": "^0.170.0",
|
|
104
105
|
"unzip-stream": "^0.3.4",
|
|
105
106
|
"ws": "^8.18.0"
|
|
@@ -120,6 +121,7 @@
|
|
|
120
121
|
"@types/prismjs": "^1.26.5",
|
|
121
122
|
"@types/react": "^19.2.8",
|
|
122
123
|
"@types/react-dom": "^19.2.3",
|
|
124
|
+
"@types/ssh2": "^1.15.5",
|
|
123
125
|
"@types/three": "^0.170.0",
|
|
124
126
|
"@types/unzip-stream": "^0.3.4",
|
|
125
127
|
"@types/ws": "^8.5.13",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/GmailOAuthSetup-BcV5jAse.js","assets/main-BrZe9Zbd.js","assets/vendor-react--Eh9ivFN.js","assets/vendor-three-Chj50gSY.js","assets/main-kpU9m5LW.css","assets/GoogleOAuthSetup-DyUW_STE.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{r as d,aJ as T,l as w,j as e,ab as B,bC as R}from"./main-BrZe9Zbd.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";const A={"gmail-oauth":d.lazy(()=>R(()=>import("./GmailOAuthSetup-BcV5jAse.js"),__vite__mapDeps([0,1,2,3,4])).then(s=>({default:s.GmailOAuthSetup}))),"google-oauth":d.lazy(()=>R(()=>import("./GoogleOAuthSetup-DyUW_STE.js"),__vite__mapDeps([5,1,2,3,4])).then(s=>({default:s.GoogleOAuthSetup})))},E={gmail:"✉️",slack:"💬",jira:"📋","google-calendar":"📅","google-drive":"📁",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.","google-drive":"Read, create, and edit files in Google Drive. Search and manage folders.",docx:"Generate and manipulate DOCX documents. Create reports, templates, and formatted documents."},z={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"],"google-drive":["Google Cloud Console project","OAuth 2.0 credentials (Client ID & Secret)","Google Drive 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 G({integration:s,onSave:u,onCancel:g}){const[p,I]=d.useState({...s.values}),[m,x]=d.useState({}),[h,C]=d.useState(!1),[y,b]=d.useState(!1);d.useEffect(()=>{I({...s.values}),x({}),b(!1)},[s.id]);const f=(t,l)=>{I(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)"},c={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:c,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:{...c,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:c,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:c,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:c,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 q({isOpen:s,onClose:u,initialTab:g}){const[p,I]=d.useState([]),[m,x]=d.useState(g||null),[h,C]=d.useState(!0),[y,b]=d.useState(null),f=d.useRef(g||null),k=d.useCallback(async()=>{try{const a=await T(w("/api/integrations"));if(!a.ok)throw new Error(`HTTP ${a.status}`);const c=await a.json();I(c),b(null),x(S=>{const j=S||g||(c.length>0?c[0].id:null);return f.current=j,j})}catch(a){b(`Failed to load integrations: ${a}`)}finally{C(!1)}},[g]);d.useEffect(()=>{s&&(C(!0),k(),g&&x(g))},[s,g]);const v=d.useCallback(async(a,c)=>{const S=await T(w(`/api/integrations/${a}/config`),{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});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})]}),z[n.id]&&e.jsxs("div",{style:o.section,children:[e.jsx("div",{style:o.sectionTitle,children:"Requirements"}),e.jsx("ul",{style:o.requirementList,children:z[n.id].map((a,c)=>e.jsxs("li",{style:o.requirementItem,children:[e.jsx("span",{style:{color:"var(--accent, #89b4fa)"},children:"•"}),a]},c))})]}),e.jsxs("div",{style:o.formSection,children:[e.jsx("div",{style:o.formSectionTitle,children:"Configuration"}),n.customComponent&&A[n.customComponent]?e.jsx(d.Suspense,{fallback:e.jsx("div",{style:{color:"var(--text-secondary)",fontSize:13},children:"Loading..."}),children:B.createElement(A[n.customComponent],{key:n.id,integration:n,onSave:a=>v(n.id,a),onCancel:u})}):e.jsx(G,{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{q as IntegrationsPanel};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{r as a,z as an,B as Et,u as $t,E as sn,j as e,V as ln,G as rn,H as on,J as St,S as y,K as Mt,L as jt,M as Tt,N as ct,O as se,P as cn,s as h,U as Bt,W as Ft,X as dn,v as Pt,w as Lt,I as u,Y as un,m as pn,Z as mn,_ as Wt,$ as Ht,a0 as fn,a1 as hn,a2 as gn,a3 as xn,a4 as bn,a5 as _n,a6 as wn,a7 as vn,a8 as Cn,a9 as jn,aa as Rt,C as Nn,ab as kn,ac as yn,ad as An,ae as In,af as En,ag as Sn,ah as Mn,ai as Tn,aj as Pn,ak as Ln,al as Rn,am as Dn,an as zn,ao as On,ap as $n,aq as Bn}from"./main-BrZe9Zbd.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";function Fn(_){const c=a.useRef(_);c.current=_,a.useEffect(()=>{if(!an())return;let w=null,I=!1;return Et.addListener("backButton",()=>{c.current()==="exit"&&Et.exitApp()}).then(E=>{I?E.remove():w=E}),()=>{I=!0,w&&(w.remove(),w=null)}},[])}const Wn=a.memo(function({className:c=""}){const{t:w}=$t(["common"]),[I,E]=sn(),Y=a.useRef(null),[H,ie]=a.useState(null);a.useLayoutEffect(()=>{const C=Y.current;if(!C)return;const Z=C.querySelector(".view-mode-toggle__btn--active");Z&&ie({left:Z.offsetLeft,width:Z.offsetWidth})},[I]);const M=a.useCallback(C=>{if(C!==I){if(typeof window<"u"&&window.dispatchEvent(new CustomEvent("tide:viewmode-switch-pressed",{detail:{mode:C}})),C==="3d"){requestAnimationFrame(()=>E(C));return}E(C)}},[I,E]);return e.jsxs("div",{className:`view-mode-toggle ${c}`,ref:Y,children:[H&&e.jsx("div",{className:"view-mode-toggle__indicator",style:{left:H.left,width:H.width}}),ln.map(C=>e.jsxs("button",{className:`view-mode-toggle__btn ${I===C?"view-mode-toggle__btn--active":""}`,onClick:()=>M(C),title:w(`common:viewMode.descriptions.${C}`),children:[e.jsxs("span",{className:"view-mode-toggle__icon",children:[C==="2d"&&e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2"}),e.jsx("line",{x1:"3",y1:"12",x2:"21",y2:"12"}),e.jsx("line",{x1:"12",y1:"3",x2:"12",y2:"21"})]}),C==="3d"&&e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("path",{d:"M12 2L2 7l10 5 10-5-10-5z"}),e.jsx("path",{d:"M2 17l10 5 10-5"}),e.jsx("path",{d:"M2 12l10 5 10-5"})]}),C==="flat"&&e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("rect",{x:"3",y:"3",width:"8",height:"8",rx:"1"}),e.jsx("rect",{x:"13",y:"3",width:"8",height:"8",rx:"1"}),e.jsx("rect",{x:"3",y:"13",width:"8",height:"8",rx:"1"}),e.jsx("rect",{x:"13",y:"13",width:"8",height:"8",rx:"1"})]}),C==="dashboard"&&e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("rect",{x:"3",y:"3",width:"7",height:"9",rx:"1"}),e.jsx("rect",{x:"14",y:"3",width:"7",height:"5",rx:"1"}),e.jsx("rect",{x:"14",y:"12",width:"7",height:"9",rx:"1"}),e.jsx("rect",{x:"3",y:"16",width:"7",height:"5",rx:"1"})]})]}),e.jsx("span",{className:"view-mode-toggle__label",children:w(`common:viewMode.labels.${C}`)})]},C))]})}),dt=3,ut=280,Dt=320,Ct=240,zt=64,Hn=["simple","chat","advanced"],Vn={simple:"Simple",chat:"Chat",advanced:"Advanced"},Gn={simple:"○",chat:"◐",advanced:"◉"},Xn={simple:"Simple view — clean messages only",chat:"Chat view — assistant replies (no tool calls)",advanced:"Advanced view — everything including tools"},Ot="flat-clear-context";function Un(_){const c=_.split("/").filter(Boolean);return c.length===0?_:c.slice(-2).join("/")}function qn(_){if(_.provider==="codex"){const Y=_.codexModel||"gpt-5.3-codex",H=On[Y];return{model:(H==null?void 0:H.label)||Y}}if(_.provider==="opencode")return{model:_.opencodeModel||"opencode"};const c=_.model||"sonnet",w=Bn[c],I=_.effort,E=I?$n[I]:void 0;return{model:(w==null?void 0:w.label)||c,effort:E==null?void 0:E.label}}function Kn(_,c){if(c.type==="rectangle"&&c.width&&c.height){const w=c.width/2,I=c.height/2;return _.x>=c.center.x-w&&_.x<=c.center.x+w&&_.z>=c.center.z-I&&_.z<=c.center.z+I}if(c.type==="circle"&&c.radius){const w=_.x-c.center.x,I=_.z-c.center.z;return w*w+I*I<=c.radius*c.radius}return!1}const Yn=kn.memo(function({agentId:c,terminalViewMode:w,onTerminalViewModeChange:I,inspectorOpen:E,onToggleInspector:Y,onImageClick:H,onFileClick:ie,onBashClick:M,onViewMarkdown:C,onRequestClearSubordinates:Z,onOpenBuilding:Re,keyboard:Ve,canNavigateBack:Ge,canNavigateForward:De,onNavigateBack:le,onNavigateForward:z,agentInfoOpen:ye,onToggleAgentInfo:J}){var Me,ne,nt,F;const g=yn(c),P=Ft(),me=a.useRef(null),Ae=a.useRef(null);a.useEffect(()=>{const i=Ae.current;if(!i)return;const r=o=>{o.button===3?(o.preventDefault(),o.stopPropagation(),le()):o.button===4&&(o.preventDefault(),o.stopPropagation(),z())},d=o=>{(o.button===3||o.button===4)&&o.preventDefault()};return i.addEventListener("mouseup",r),i.addEventListener("mousedown",d),()=>{i.removeEventListener("mouseup",r),i.removeEventListener("mousedown",d)}},[le,z]),a.useEffect(()=>{const i=Ae.current;if(!i)return;let r=0,d=0,o=0;const Ce=250,Te=600,Pe=80,xt=1.5,K=O=>{let T=O instanceof HTMLElement?O:null;for(;T&&T!==i;){const We=window.getComputedStyle(T).overflowX;if((We==="auto"||We==="scroll")&&T.scrollWidth>T.clientWidth)return!0;T=T.parentElement}return!1},Le=O=>{const T=Date.now();if(T<o){O.preventDefault();return}if(Math.abs(O.deltaX)<=Math.abs(O.deltaY)*xt){r=0;return}if(K(O.target)){r=0;return}T-d>Ce&&(r=0),d=T,r+=O.deltaX,r<=-Pe?(r=0,o=T+Te,O.preventDefault(),le()):r>=Pe&&(r=0,o=T+Te,O.preventDefault(),z())};return i.addEventListener("wheel",Le,{passive:!1}),()=>i.removeEventListener("wheel",Le)},[le,z]);const fe=Bt(),ze=a.useMemo(()=>{if(!g)return null;const i=new Set,r=[];for(const d of fe.values())d.archived||d.directories.length===0||d.assignedAgentIds.includes(c)&&(i.add(d.id),r.push(d));for(const d of fe.values())d.archived||d.directories.length===0||i.has(d.id)||Kn({x:g.position.x,z:g.position.z},d)&&(i.add(d.id),r.push(d));return r.length===0?null:r.flatMap(d=>d.directories.filter(o=>o&&o.trim().length>0).map(o=>({areaId:d.id,areaName:d.name,dir:o})))},[g,c,fe]),{branches:Xe,fetchRemote:Ue,fetchingDirs:Oe}=An(ze),Ie=a.useMemo(()=>{var d;const i=h.getAreaForAgent(c);if(!i)return[];const r=[];for(const o of P.values())o.type==="terminal"&&h.isPositionInArea(o.position,i)&&r.push({id:o.id,name:o.name,hasUrl:!!((d=o.terminalStatus)!=null&&d.url)});return r},[c,P]),he=a.useMemo(()=>{var d;const i=h.getAreaForAgent(c);if(!i)return[];const r=[];for(const o of P.values())o.type==="server"&&((d=o.pm2)!=null&&d.enabled)&&h.isPositionInArea(o.position,i)&&r.push({id:o.id,name:o.name});return r},[c,P]),re=a.useMemo(()=>{const i=h.getAreaForAgent(c);if(!i)return[];const r=[];for(const d of P.values())d.type==="database"&&d.database&&h.isPositionInArea(d.position,i)&&r.push({id:d.id,name:d.name});return r},[c,P]),[,oe]=a.useReducer(i=>i+1,0),V=((Me=me.current)==null?void 0:Me.search.searchMode)??!1,pt=a.useCallback(()=>{var i;(i=me.current)==null||i.search.toggleSearch(),oe()},[]),qe=In(),ce=qe.isPending(Ot),[$,U]=a.useState(null),G=$?P.get($):null,{height:q,onResizeStart:Ee}=En(),[B,Q]=a.useState(()=>jt(y.GIT_PANEL_OPEN,!1)),[ge,Ke]=a.useState(()=>jt(y.BUILDINGS_PANEL_OPEN,!1)),[de,xe]=a.useState(!1),mt=a.useCallback(()=>{xe(i=>{const r=!i;return r&&Sn.setEnabled(!0),r})},[]),ft=a.useCallback(()=>xe(!1),[]),be=a.useCallback(()=>{Q(i=>{const r=!i;return se(y.GIT_PANEL_OPEN,r),r})},[]),ht=a.useCallback(()=>{Ke(i=>{const r=!i;return se(y.BUILDINGS_PANEL_OPEN,r),r})},[]),Ye=a.useCallback(()=>{Q(!1),se(y.GIT_PANEL_OPEN,!1)},[]),gt=a.useCallback(()=>{Ke(!1),se(y.BUILDINGS_PANEL_OPEN,!1)},[]),$e=Mn();a.useEffect(()=>{if(!$)return;Ie.some(r=>r.id===$)||U(null)},[$,Ie]);const[_e,ue]=a.useState(!1),Be=a.useRef(null);if(a.useEffect(()=>{if(!_e)return;const i=r=>{Be.current&&!Be.current.contains(r.target)&&ue(!1)};return document.addEventListener("mousedown",i),()=>document.removeEventListener("mousedown",i)},[_e]),!g)return e.jsx("div",{className:"flat-chat flat-chat--empty",children:e.jsxs("div",{className:"flat-chat__placeholder",children:[e.jsx("span",{className:"flat-chat__placeholder-icon",children:"💬"}),e.jsx("span",{className:"flat-chat__placeholder-text",children:"Select an agent to start chatting"})]})});const ee=g.contextStats,Ze=!!ee,Je=ee?ee.totalTokens:g.contextUsed||0,we=ee?ee.contextWindow:g.contextLimit||2e5,x=ee?ee.usedPercent:Math.round(Je/we*100),L=Math.max(0,Math.min(100,x)),X=Math.round(L*10)/10,Se=Math.round((100-L)*10)/10,Fe=L>=80?"#ff4a4a":L>=60?"#ff9e4a":L>=40?"#ffd700":"#4aff9e",Qe=(Je/1e3).toFixed(1),et=(we/1e3).toFixed(1),te=g.cwd,tt=te?Un(te):null,pe=((ne=g.subordinateIds)==null?void 0:ne.length)||0,ve=pe>0;return e.jsxs("div",{ref:Ae,className:`flat-terminal-wrapper ${B||ge||de?"flat-terminal-wrapper--with-side-panel":""}`,children:[e.jsxs("div",{className:"flat-terminal-wrapper__header",children:[e.jsxs("button",{type:"button",className:`flat-terminal-wrapper__header-main ${ye?"flat-terminal-wrapper__header-main--active":""}`,onClick:J,title:ye?"Hide agent info":"Show agent info","aria-pressed":ye,children:[e.jsx(Wt,{agent:g,size:28}),e.jsxs("span",{className:"flat-terminal-wrapper__header-info",children:[e.jsx("span",{className:"flat-terminal-wrapper__header-name",children:g.name}),e.jsx("span",{className:"flat-terminal-wrapper__header-status",style:{color:Ht(g.status)},children:g.status})]}),g.taskLabel&&e.jsxs("span",{className:"flat-terminal-wrapper__header-task",title:g.taskLabel,children:["📋 ",g.taskLabel]}),e.jsxs("span",{className:"flat-terminal-wrapper__header-model",children:[e.jsx("img",{src:g.provider==="codex"?"/assets/codex.png":g.provider==="opencode"?"/assets/opencode.png":"/assets/claude.png",alt:g.provider,className:"flat-terminal-wrapper__header-provider-icon",title:g.provider==="codex"?"Codex Agent":g.provider==="opencode"?"OpenCode Agent":"Claude Agent"}),(()=>{const{model:i,effort:r}=qn(g);return e.jsxs("span",{className:"flat-terminal-wrapper__header-model-chip",title:r?`Model: ${i} · Effort: ${r}`:`Model: ${i}`,children:[e.jsx("span",{className:"flat-terminal-wrapper__header-model-name",children:i}),r&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"flat-terminal-wrapper__header-model-sep","aria-hidden":"true",children:"·"}),e.jsx("span",{className:"flat-terminal-wrapper__header-model-effort",children:r})]})]})})()]})]}),e.jsxs("div",{className:"flat-terminal-wrapper__header-meta",children:[e.jsx("div",{className:"flat-terminal-wrapper__view-mode",role:"group","aria-label":"Message view mode",children:Hn.map(i=>e.jsxs("button",{type:"button",className:`flat-terminal-wrapper__view-mode-btn ${w===i?"flat-terminal-wrapper__view-mode-btn--active":""}`,onClick:()=>I(i),title:Xn[i],"aria-pressed":w===i,children:[e.jsx("span",{className:"flat-terminal-wrapper__view-mode-icon","aria-hidden":"true",children:Gn[i]}),e.jsx("span",{className:"flat-terminal-wrapper__view-mode-label",children:Vn[i]})]},i))}),e.jsxs("div",{className:"flat-terminal-wrapper__actions",role:"group","aria-label":"Terminal actions",children:[e.jsx("button",{type:"button",className:"flat-terminal-wrapper__action-btn",onClick:le,disabled:!Ge,title:"Back to previous agent","aria-label":"Back to previous agent",children:e.jsx(u,{name:"arrow-left",size:14})}),e.jsx("button",{type:"button",className:"flat-terminal-wrapper__action-btn",onClick:z,disabled:!De,title:"Forward to next agent","aria-label":"Forward to next agent",children:e.jsx(u,{name:"arrow-right",size:14})}),e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn ${V?"flat-terminal-wrapper__action-btn--active":""}`,onClick:pt,title:V?"Close search":"Search messages","aria-pressed":V,children:e.jsx(u,{name:V?"cross":"search",size:14})}),e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn flat-terminal-wrapper__action-btn--danger ${ce?"flat-terminal-wrapper__action-btn--confirm":""}`,onClick:()=>qe.handleClick(Ot,()=>{var i;h.clearContext(c),(i=me.current)==null||i.historyLoader.clearHistory()}),title:ce?"Click again to confirm clear context":"Clear context",children:e.jsx(u,{name:ce?"question":"clear",size:14})}),e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn ${B?"flat-terminal-wrapper__action-btn--active":""}`,onClick:be,title:B?"Hide git panel":"Show git changes","aria-pressed":B,children:e.jsx(u,{name:"git-branch",size:14})}),e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn ${ge?"flat-terminal-wrapper__action-btn--active":""}`,onClick:ht,title:ge?"Hide buildings panel":"Show area buildings","aria-pressed":ge,children:e.jsx(u,{name:"buildings",size:14})}),e.jsxs("div",{className:"flat-terminal-wrapper__more",ref:Be,children:[e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn ${_e?"flat-terminal-wrapper__action-btn--active":""}`,onClick:()=>ue(i=>!i),title:"More actions","aria-expanded":_e,children:"⋮"}),_e&&e.jsxs("div",{className:"flat-terminal-wrapper__more-menu",role:"menu",children:[e.jsxs("button",{type:"button",role:"menuitem",className:`flat-terminal-wrapper__more-item ${de?"flat-terminal-wrapper__more-item--active":""}`,onClick:()=>{mt(),ue(!1)},title:de?"Hide Debug Panel":"Show Debug Panel",children:[e.jsx(u,{name:"bug",size:14}),e.jsx("span",{children:de?"Hide Debug Panel":"Show Debug Panel"})]}),e.jsx("div",{className:"flat-terminal-wrapper__more-divider"}),e.jsxs("button",{type:"button",role:"menuitem",className:"flat-terminal-wrapper__more-item",onClick:()=>{h.collapseContext(c),ue(!1)},disabled:g.status!=="idle",title:g.status!=="idle"?"Agent must be idle to collapse context":"Collapse context",children:[e.jsx(u,{name:"package",size:14}),e.jsx("span",{children:"Collapse context"})]}),ve&&e.jsxs("button",{type:"button",role:"menuitem",className:"flat-terminal-wrapper__more-item flat-terminal-wrapper__more-item--danger",onClick:()=>{Z(c,pe),ue(!1)},children:[e.jsx(u,{name:"crown",size:14}),e.jsxs("span",{children:["Clear ",pe," subordinate",pe===1?"":"s"]})]}),e.jsx("div",{className:"flat-terminal-wrapper__more-divider"}),e.jsxs("button",{type:"button",role:"menuitem",className:"flat-terminal-wrapper__more-item flat-terminal-wrapper__more-item--danger",onClick:()=>{h.killAgent(c),ue(!1)},children:[e.jsx(u,{name:"cross",size:14}),e.jsx("span",{children:"Remove agent"})]})]})]})]}),e.jsxs("button",{type:"button",className:`flat-terminal-wrapper__inspector-toggle ${E?"flat-terminal-wrapper__inspector-toggle--active":""}`,onClick:Y,title:E?"Hide inspector panel":"Show inspector panel","aria-label":E?"Hide inspector panel":"Show inspector panel","aria-pressed":E,children:[e.jsx("span",{className:"flat-terminal-wrapper__inspector-icon","aria-hidden":"true",children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("rect",{x:"1.5",y:"2.5",width:"13",height:"11",rx:"1.5"}),e.jsx("line",{x1:"10",y1:"2.5",x2:"10",y2:"13.5"})]})}),e.jsx("span",{className:"flat-terminal-wrapper__inspector-label",children:"Inspector"})]}),e.jsx("button",{type:"button",className:"flat-terminal-wrapper__close",onClick:()=>h.deselectAll(),title:"Close chat","aria-label":"Close chat",children:e.jsx(u,{name:"cross",size:14})})]})]}),e.jsx(Tn,{ref:me,agentId:c,agent:g,viewMode:w,isOpen:!0,onImageClick:H,onFileClick:ie,onBashClick:M,onViewMarkdown:C,keyboard:Ve,hasModalOpen:!1}),G&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"guake-bottom-terminal-resize",onMouseDown:Ee,role:"separator","aria-orientation":"horizontal","aria-label":"Resize embedded terminal"}),e.jsxs("div",{className:"flat-bottom-panel",role:"region","aria-label":`Embedded terminal: ${G.name}`,style:{height:q},children:[e.jsxs("div",{className:"flat-bottom-panel__header",children:[e.jsxs("span",{className:"flat-bottom-panel__title",children:[e.jsx(u,{name:"terminal",size:12}),e.jsx("span",{children:G.name}),!((nt=G.terminalStatus)!=null&&nt.url)&&e.jsx("span",{className:"flat-bottom-panel__muted",children:"(starting...)"})]}),e.jsx("button",{type:"button",className:"flat-bottom-panel__close",onClick:()=>U(null),title:"Close embedded terminal","aria-label":"Close embedded terminal",children:e.jsx(u,{name:"cross",size:12})})]}),e.jsx("div",{className:"flat-bottom-panel__body",children:(F=G.terminalStatus)!=null&&F.url?e.jsx(Pn,{terminalUrl:G.terminalStatus.url,visible:!0}):e.jsx("div",{className:"flat-bottom-panel__placeholder",children:"Starting terminal..."})})]})]}),e.jsxs("div",{className:"flat-terminal-wrapper__statusbar",role:"contentinfo",children:[g.isDetached&&e.jsxs("span",{className:"flat-terminal-wrapper__detached",title:"Reattaching session...",children:[e.jsx(u,{name:"refresh",size:12}),e.jsx("span",{children:"Reattaching"})]}),te&&tt&&e.jsxs("span",{className:"flat-terminal-wrapper__cwd",title:`Open in file explorer: ${te}`,"aria-label":`Open ${te} in file explorer`,role:"button",tabIndex:0,onClick:()=>h.openFileExplorer(te),onKeyDown:i=>{(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),h.openFileExplorer(te))},children:[e.jsx("span",{className:"flat-terminal-wrapper__cwd-icon",children:e.jsx(u,{name:"folder",size:12})}),e.jsx("span",{className:"flat-terminal-wrapper__cwd-text",children:tt})]}),ze&&ze.map(({areaId:i,areaName:r,dir:d})=>{const o=Xe.get(d),Ce=Oe.has(d),Te=d.split("/").filter(Boolean).pop()||d;return e.jsxs("span",{className:"flat-terminal-wrapper__area-dir",title:`${r}: ${d}${o?` (${o.branch}${o.ahead?` ↑${o.ahead}`:""}${o.behind?` ↓${o.behind}`:""})`:""}`,onClick:()=>h.openFileExplorerForAreaFolder(i,d),children:[e.jsx(u,{name:"folder-open",size:12}),e.jsx("span",{className:"flat-terminal-wrapper__area-dir-name",children:Te}),o&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"flat-terminal-wrapper__area-dir-branch",children:[e.jsx(u,{name:"git-branch",size:10})," ",o.branch]}),o.ahead>0&&e.jsxs("span",{className:"flat-terminal-wrapper__branch-ahead",title:`${o.ahead} ahead`,children:[e.jsx(u,{name:"arrow-up",size:9}),o.ahead]}),o.behind>0&&e.jsxs("span",{className:"flat-terminal-wrapper__branch-behind",title:`${o.behind} behind`,children:[e.jsx(u,{name:"arrow-down",size:9}),o.behind]}),e.jsx("span",{className:`flat-terminal-wrapper__area-fetch ${Ce?"flat-terminal-wrapper__area-fetch--fetching":""}`,title:"Git fetch",onClick:Pe=>{Pe.stopPropagation(),Ue(d)},children:e.jsx(u,{name:Ce?"hourglass":"download",size:12})})]})]},`${i}:${d}`)}),e.jsxs("span",{className:"flat-terminal-wrapper__context",onClick:()=>h.setContextModalAgentId(c),title:Ze?`Context usage: ${Qe}k / ${et}k tokens (${X}% used). Click to view stats.`:"Click to fetch context stats",children:[e.jsx("span",{className:"flat-terminal-wrapper__context-icon",children:e.jsx(u,{name:"dashboard",size:12})}),e.jsx("span",{className:"flat-terminal-wrapper__context-label",children:"Ctx:"}),e.jsx("span",{className:"flat-terminal-wrapper__context-bar",children:e.jsx("span",{className:"flat-terminal-wrapper__context-bar-fill",style:{width:`${L}%`,backgroundColor:Fe}})}),e.jsxs("span",{className:"flat-terminal-wrapper__context-tokens",style:{color:Fe},children:[Qe,"k/",et,"k"]}),e.jsxs("span",{className:"flat-terminal-wrapper__context-free",children:["(",Se,"% free)"]}),!Ze&&e.jsx("span",{className:"flat-terminal-wrapper__context-warning",title:"No context stats yet",children:e.jsx(u,{name:"warn",size:12})})]}),e.jsx("div",{className:"flat-terminal-wrapper__statusbar-spacer","aria-hidden":"true"}),Ie.length>0&&e.jsx("span",{className:"flat-terminal-wrapper__buildings",role:"group","aria-label":"Area terminals",children:Ie.map(i=>{const r=$===i.id;return e.jsx("button",{type:"button",className:`flat-terminal-wrapper__building-btn ${r?"flat-terminal-wrapper__building-btn--active":""} ${i.hasUrl?"":"flat-terminal-wrapper__building-btn--offline"}`,title:`${r?"Hide":"Show"} terminal: ${i.name}${i.hasUrl?"":" (starting...)"}`,onClick:()=>{if(r){U(null);return}i.hasUrl||h.sendBuildingCommand(i.id,"start"),U(i.id)},children:e.jsx(u,{name:"terminal",size:14})},i.id)})}),he.length>0&&e.jsx("span",{className:"flat-terminal-wrapper__buildings",role:"group","aria-label":"Area PM2 logs",children:he.map(i=>e.jsx("button",{type:"button",className:"flat-terminal-wrapper__building-btn",title:`Open logs: ${i.name}`,onClick:()=>Re(i.id),children:e.jsx(u,{name:"scroll",size:14})},i.id))}),re.length>0&&e.jsx("span",{className:"flat-terminal-wrapper__buildings",role:"group","aria-label":"Area databases",children:re.map(i=>e.jsx("button",{type:"button",className:"flat-terminal-wrapper__building-btn",title:`Open database: ${i.name}`,onClick:()=>Re(i.id),children:e.jsx(u,{name:"hard-drives",size:14})},i.id))}),e.jsx("div",{className:"flat-terminal-wrapper__theme",children:e.jsx(Ln,{})})]}),B&&e.jsx(Rn,{agentId:c,agents:$e,onClose:Ye,branchInfoMap:Xe,fetchRemote:Ue,fetchingDirs:Oe}),ge&&e.jsx(Dn,{agentId:c,onClose:gt}),de&&e.jsx(zn,{agentId:c,onClose:ft})]})});function ea({onAgentClick:_,onBuildingClick:c,onBuildingDoubleClick:w,onBuildingPopup:I,onOpenSpawnModal:E,onOpenBossSpawnModal:Y,onOpenAreaModal:H}){const{t:ie}=$t(["common"]),M=rn(),C=on(),[Z,Re]=a.useState(null),[Ve,Ge]=a.useState(null),[De,le]=a.useState(null),[z,ye]=a.useState(null),[J,g]=a.useState(null),[P,me]=a.useState(null),[Ae,fe]=a.useState(!1),ze=a.useCallback(()=>{fe(t=>!t)},[]),Xe=a.useCallback(()=>{fe(!1)},[]),[Ue,Oe]=a.useState(()=>{const t=St(y.VIEW_MODE);return t==="simple"||t==="chat"||t==="advanced"?t:"simple"}),Ie=a.useCallback(t=>{Oe(t),Mt(y.VIEW_MODE,t)},[]);a.useEffect(()=>{const t=n=>{if(n.key!==y.VIEW_MODE)return;const s=n.newValue;(s==="simple"||s==="chat"||s==="advanced")&&Oe(s)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)},[]);const[he,re]=a.useState(()=>jt(y.FLAT_INSPECTOR_OPEN,!1)),[oe,V]=a.useState(!1),pt=a.useCallback(()=>V(t=>!t),[]),qe=a.useCallback(()=>V(!1),[]);a.useEffect(()=>{window.dispatchEvent(new CustomEvent("tide-flat-agents-drawer-state",{detail:{open:oe}}))},[oe]),a.useEffect(()=>{window.dispatchEvent(new CustomEvent("tide-flat-inspector-state",{detail:{open:he}}))},[he]),a.useEffect(()=>{const t=()=>V(b=>!b),n=()=>{re(b=>{const l=!b;return se(y.FLAT_INSPECTOR_OPEN,l),l})},s=()=>{V(!1),re(!1),se(y.FLAT_INSPECTOR_OPEN,!1)},p=()=>V(!1),m=()=>{re(!1),se(y.FLAT_INSPECTOR_OPEN,!1)};return window.addEventListener("tide-toggle-flat-agents-drawer",t),window.addEventListener("tide-toggle-flat-inspector",n),window.addEventListener("tide-close-flat-side-views",s),window.addEventListener("tide-close-flat-agents-drawer-only",p),window.addEventListener("tide-close-flat-inspector-only",m),()=>{window.removeEventListener("tide-toggle-flat-agents-drawer",t),window.removeEventListener("tide-toggle-flat-inspector",n),window.removeEventListener("tide-close-flat-side-views",s),window.removeEventListener("tide-close-flat-agents-drawer-only",p),window.removeEventListener("tide-close-flat-inspector-only",m)}},[]);const ce=a.useRef(null),$=a.useRef(null),[U,G]=a.useState(()=>{const t=Tt(y.FLAT_MIDDLE_WIDTH,0);return t>=ut?t:null}),[q,Ee]=a.useState(()=>{const t=Tt(y.FLAT_INSPECTOR_WIDTH,0);return t>=Ct?t:null}),B=a.useCallback(t=>{if(typeof window>"u")return t;const n=q!==null?dt+q:0,s=window.innerWidth-zt-dt-Dt-n;return Math.max(ut,Math.min(Math.max(s,ut),t))},[q]),Q=a.useCallback(t=>{var m;if(typeof window>"u")return t;const n=(m=ce.current)==null?void 0:m.querySelector(".flat-middle"),s=(n==null?void 0:n.getBoundingClientRect().width)??ut,p=window.innerWidth-zt-s-dt-Dt-dt;return Math.max(Ct,Math.min(Math.max(p,Ct),t))},[]);a.useEffect(()=>{if(U===null&&q===null)return;const t=()=>{G(n=>{if(n===null)return n;const s=B(n);return s===n?n:s}),Ee(n=>{if(n===null)return n;const s=Q(n);return s===n?n:s})};return window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[U,q,B,Q]);const ge=a.useCallback(t=>{var s;if(t.button!==0)return;const n=(s=ce.current)==null?void 0:s.querySelector(".flat-middle");n&&(t.currentTarget.setPointerCapture(t.pointerId),$.current={kind:"middle",startX:t.clientX,startWidth:n.getBoundingClientRect().width,pointerId:t.pointerId},document.body.classList.add("flat-splitter-dragging"))},[]),Ke=a.useCallback(t=>{var s;if(t.button!==0)return;const n=(s=ce.current)==null?void 0:s.querySelector(".flat-inspector");n&&(t.currentTarget.setPointerCapture(t.pointerId),$.current={kind:"inspector",startX:t.clientX,startWidth:n.getBoundingClientRect().width,pointerId:t.pointerId},document.body.classList.add("flat-splitter-dragging"))},[]),de=a.useCallback(t=>{const n=$.current;if(!n||t.pointerId!==n.pointerId)return;const s=t.clientX-n.startX;n.kind==="middle"?G(B(n.startWidth+s)):Ee(Q(n.startWidth-s))},[B,Q]),xe=a.useCallback(t=>{const n=$.current;if(!n||t.pointerId!==n.pointerId)return;try{t.currentTarget.releasePointerCapture(t.pointerId)}catch{}if($.current=null,document.body.classList.remove("flat-splitter-dragging"),!(Math.abs(t.clientX-n.startX)>2))return;const p=t.clientX-n.startX;if(n.kind==="middle"){const m=B(n.startWidth+p);G(m),ct(y.FLAT_MIDDLE_WIDTH,m)}else{const m=Q(n.startWidth-p);Ee(m),ct(y.FLAT_INSPECTOR_WIDTH,m)}},[B,Q]),mt=a.useCallback(()=>{G(null),ct(y.FLAT_MIDDLE_WIDTH,0)},[]),ft=a.useCallback(()=>{Ee(null),ct(y.FLAT_INSPECTOR_WIDTH,0)},[]),[be,ht]=a.useState(()=>St(y.FLAT_INSPECTOR_VIEW)==="tracking"?"tracking":"agent"),Ye=a.useCallback(t=>{ht(t),Mt(y.FLAT_INSPECTOR_VIEW,t)},[]),gt=a.useCallback(()=>{re(t=>{const n=!t;return se(y.FLAT_INSPECTOR_OPEN,n),n})},[]),$e=a.useCallback(()=>{re(!1),se(y.FLAT_INSPECTOR_OPEN,!1)},[]),_e=cn(),ue=a.useCallback((t,n)=>{Re({url:t,name:n})},[]),Be=a.useCallback((t,n)=>{Ge({command:t,output:n,isLive:!1})},[]),ee=a.useCallback((t,n)=>{h.setFileViewerPath(t,n)},[]),Ze=a.useCallback(t=>{},[]),Je=a.useCallback((t,n)=>{le({agentId:t,count:n})},[]),we=a.useCallback(t=>{w?w(t):c(t)},[c,w]),x=a.useMemo(()=>C.size>0?Array.from(C)[0]:null,[C]);a.useEffect(()=>{fe(!1)},[x]);const L=a.useRef([]),X=a.useRef(-1),Se=a.useRef(!1),Fe=a.useRef(null),[Qe,et]=a.useState(!1),[te,tt]=a.useState(!1),pe=a.useRef(!1),ve=a.useRef(null),Me=a.useRef(!1),ne=a.useMemo(()=>new Set(M.map(t=>t.id)),[M]),nt=a.useMemo(()=>{const t=new Map(M.map(s=>[s.id,s])),n=new Map;for(const s of M)if((s.isBoss||s.class==="boss")&&s.subordinateIds&&s.subordinateIds.length>0){const p=s.subordinateIds.map(m=>t.get(m)).filter(m=>m!==void 0);p.length>0&&n.set(s.id,p)}return n},[M]),F=a.useCallback(()=>{const t=L.current,n=X.current;et(n>0),tt(n>=0&&n<t.length-1)},[]),i=a.useCallback(t=>{const n=L.current;if(n.length===0)return;let s=X.current+t;for(;s>=0&&s<n.length;){const p=n[s];if(ne.has(p)){Se.current=!0,X.current=s,F(),h.selectAgent(p);return}s+=t}},[ne,F]),r=a.useCallback(()=>i(-1),[i]),d=a.useCallback(()=>i(1),[i]);Fn(a.useCallback(()=>{const t=L.current,n=X.current;return t.length>0&&n>0?(i(-1),"handled"):"exit"},[i]));const o=a.useCallback((t,n)=>{if(typeof window>"u")return;const s=window.history.state,m={...typeof s=="object"&&s!==null?s:{},__flatAgentNav:{agentId:t}};n==="replace"?window.history.replaceState(m,"",window.location.href):window.history.pushState(m,"",window.location.href)},[]);a.useEffect(()=>{if(!x){pe.current=!1,ve.current=null;return}if(!pe.current){o(x,"replace"),pe.current=!0,ve.current=x;return}if(Me.current){Me.current=!1,ve.current=x;return}ve.current!==x&&(o(x,"push"),ve.current=x)},[x,o]),a.useEffect(()=>{const t=n=>{var b,l;const s=(l=(b=n.state)==null?void 0:b.__flatAgentNav)==null?void 0:l.agentId;if(!s||typeof s!="string"||!ne.has(s)||s===x)return;Me.current=!0,Se.current=!0;const p=L.current,m=p.lastIndexOf(s);m>=0?X.current=m:(p.push(s),X.current=p.length-1),F(),h.selectAgent(s)};return window.addEventListener("popstate",t),()=>window.removeEventListener("popstate",t)},[ne,x,F]),a.useEffect(()=>{if(!x){L.current=[],X.current=-1,F();return}if(Fe.current=x,Se.current){Se.current=!1,F();return}const t=L.current,n=X.current;if(n>=0&&t[n]===x){F();return}const s=n<t.length-1?t.slice(0,n+1):t.slice();s.push(x),s.length>100&&s.shift(),L.current=s,X.current=s.length-1,F()},[x,F]);const Ce=a.useCallback(t=>{_(t),V(!1)},[_]),Te=x??"",Pe=a.useCallback(()=>{},[]),xt=a.useCallback(t=>{Ce(t)},[Ce]),K=he,[Le,O]=a.useState(K),[T,We]=a.useState(K);a.useEffect(()=>{if(K){O(!0);return}We(!1);const t=setTimeout(()=>O(!1),240);return()=>clearTimeout(t)},[K]),a.useEffect(()=>{if(!Le||!K)return;let t=0;const n=requestAnimationFrame(()=>{t=requestAnimationFrame(()=>We(!0))});return()=>{cancelAnimationFrame(n),cancelAnimationFrame(t)}},[Le,K]);const Nt=a.useRef(null);a.useEffect(()=>{if(x)return;const t=n=>{if(n.key!==" "&&n.key!=="Backspace")return;const s=n.target;if(s.tagName==="INPUT"||s.tagName==="TEXTAREA"||s.isContentEditable)return;const p=Fe.current;!p||!ne.has(p)||(n.preventDefault(),h.selectAgent(p))};return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[x,ne]);const[Vt,kt]=a.useState(new Set),Gt=a.useCallback(t=>{kt(n=>{const s=new Set(n);return s.has(t)?s.delete(t):s.add(t),s})},[]),[je,Xt]=a.useState(()=>typeof window<"u"&&window.matchMedia("(max-width: 768px)").matches);a.useEffect(()=>{if(typeof window>"u")return;const t=window.matchMedia("(max-width: 768px)"),n=s=>Xt(s.matches);return t.addEventListener("change",n),()=>t.removeEventListener("change",n)},[]);const[at,Ut]=a.useState(null),qt=a.useCallback(t=>{Ut(n=>n===t?null:t)},[]),bt=Bt(),st=Ft(),[Kt]=dn(),Ne=a.useMemo(()=>{const t=new Map,n=[];for(const f of M){const k=h.getAreaForAgent(f.id);if(!Pt((k==null?void 0:k.id)??null))continue;if(!k||k.archived){n.push(f);continue}const j=t.get(k.id);j?j.push(f):t.set(k.id,[f])}const s=new Map,p=[];for(const f of st.values()){let k=!1;for(const j of bt.values())if(!j.archived&&Lt(j.id)&&h.isPositionInArea(f.position,j)){const ae=s.get(j.id);ae?ae.push(f):s.set(j.id,[f]),k=!0;break}!k&&Pt(null)&&p.push(f)}const m=[];for(const[,f]of bt){if(f.archived||!Lt(f.id))continue;const k=t.get(f.id),j=s.get(f.id)??[];(k&&k.length>0||j.length>0)&&m.push({area:f,agents:k??[],buildings:j})}(n.length>0||p.length>0)&&m.push({area:{id:"__unassigned__",name:"Unassigned",color:"#6272a4",center:{x:0,z:0},type:"circle",radius:0,directories:[],archived:!1,assignedAgentIds:[],zIndex:0},agents:n,buildings:p});const b=m.filter(f=>f.area.id!=="__unassigned__"),l=m.filter(f=>f.area.id==="__unassigned__");let A=1,N=1;const W=new Map;if(b.length>1){let f=1/0,k=-1/0,j=1/0,ae=-1/0;for(const R of b)f=Math.min(f,R.area.center.x),k=Math.max(k,R.area.center.x),j=Math.min(j,R.area.center.z),ae=Math.max(ae,R.area.center.z);const lt=k-f||1,rt=ae-j||1;if(b.length<=4){A=b.length,N=1;const R=[...b].sort((D,_t)=>D.area.center.x-_t.area.center.x);for(let D=0;D<R.length;D++)W.set(R[D].area.id,{row:1,col:D+1})}else{const R=[...b].sort((v,S)=>v.area.center.x-S.area.center.x),D=[];for(let v=1;v<R.length;v++)D.push(R[v].area.center.x-R[v-1].area.center.x);const _t=D.reduce((v,S)=>v+S,0)/D.length||1;let yt=1;for(const v of D)v>_t*1.3&&yt++;A=Math.max(2,Math.min(yt,b.length));const wt=[...b].sort((v,S)=>v.area.center.z-S.area.center.z),ot=[];for(let v=1;v<wt.length;v++)ot.push(wt[v].area.center.z-wt[v-1].area.center.z);const Qt=ot.reduce((v,S)=>v+S,0)/ot.length||1;let At=1;for(const v of ot)v>Qt*1.3&&At++;N=Math.max(2,Math.min(At,b.length)),A=Math.max(A,Math.ceil(b.length/N)),N=Math.max(N,Math.ceil(b.length/A));const en=lt/A,tn=rt/N,vt=new Set;for(const v of b){let S=Math.min(A-1,Math.max(0,Math.floor((v.area.center.x-f)/en))),ke=Math.min(N-1,Math.max(0,Math.floor((v.area.center.z-j)/tn))),He=`${ke},${S}`,It=0;const nn=N*A;for(;vt.has(He)&&It<nn;)S++,S>=A&&(S=0,ke=(ke+1)%N),He=`${ke},${S}`,It++;vt.has(He)&&(ke=N,S=0,He=`${ke},${S}`,N++),vt.add(He),W.set(v.area.id,{row:ke+1,col:S+1})}}}const it=f=>{f.sort((k,j)=>{var lt,rt,R,D;const ae=(((lt=k.position)==null?void 0:lt.z)??0)-(((rt=j.position)==null?void 0:rt.z)??0);return ae!==0?ae:(((R=k.position)==null?void 0:R.x)??0)-(((D=j.position)==null?void 0:D.x)??0)})};for(const f of b)it(f.agents);for(const f of l)it(f.agents);return{groups:[...b,...l],gridCols:A,gridRows:N,positions:W}},[M,bt,st,Kt]),Yt=a.useMemo(()=>{if(!z)return[];const t=M.find(n=>n.id===z.agentId);return t?[{id:"edit-agent",label:"Edit Agent",icon:e.jsx(u,{name:"edit",size:14}),onClick:()=>{window.dispatchEvent(new CustomEvent("tide:open-agent-edit",{detail:{agentId:t.id}}))}},{id:"open-chat",label:"Open Chat",icon:e.jsx(u,{name:"chat",size:14}),onClick:()=>_(t.id)},{id:"delete-agent",label:"Delete Agent",icon:e.jsx(u,{name:"trash",size:14}),danger:!0,onClick:()=>{me({agentId:t.id,name:t.name})}}]:[]},[z,M,_]),Zt=a.useMemo(()=>{var b;if(!J)return[];const t=st.get(J.buildingId);if(!t)return[];const n=[],s=t.type==="server"||t.type==="docker"||t.type==="terminal",p=t.status==="running",m=t.type==="boss";if(n.push({id:"open",label:t.type==="database"?"Open Database":t.type==="folder"?"Open Folder":t.type==="boss"?"View Boss Logs":t.type==="terminal"?"Open Terminal":t.type==="server"&&((b=t.pm2)!=null&&b.enabled)?"View PM2 Logs":"Open",icon:e.jsx(u,{name:t.type==="database"?"database":t.type==="folder"?"folder":t.type==="terminal"?"terminal":"eye",size:14}),onClick:()=>we(t.id)}),s&&(p||n.push({id:"start",label:"Start",icon:e.jsx(u,{name:"play",size:14}),onClick:()=>h.sendBuildingCommand(t.id,"start")}),p&&(n.push({id:"restart",label:"Restart",icon:e.jsx(u,{name:"refresh",size:14}),onClick:()=>h.sendBuildingCommand(t.id,"restart")}),n.push({id:"stop",label:"Stop",icon:e.jsx(u,{name:"stop",size:14}),onClick:()=>h.sendBuildingCommand(t.id,"stop")}))),m&&t.subordinateBuildingIds&&t.subordinateBuildingIds.length>0&&(n.push({id:"start-all",label:"Start All Subordinates",icon:e.jsx(u,{name:"launch",size:14}),onClick:()=>{for(const l of t.subordinateBuildingIds)h.sendBuildingCommand(l,"start")}}),n.push({id:"stop-all",label:"Stop All Subordinates",icon:e.jsx(u,{name:"pause",size:14}),onClick:()=>{for(const l of t.subordinateBuildingIds)h.sendBuildingCommand(l,"stop")}}),n.push({id:"restart-all",label:"Restart All Subordinates",icon:e.jsx(u,{name:"restart",size:14}),onClick:()=>{for(const l of t.subordinateBuildingIds)h.sendBuildingCommand(l,"restart")}})),s&&n.push({id:"health-check",label:"Health Check",icon:e.jsx(u,{name:"health",size:14}),onClick:()=>h.sendBuildingCommand(t.id,"healthCheck")}),n.push({id:"divider-edit",label:"",divider:!0,onClick:()=>{}}),n.push({id:"edit",label:"Edit Building",icon:e.jsx(u,{name:"edit",size:14}),onClick:()=>{window.dispatchEvent(new CustomEvent("tide:building-edit",{detail:{buildingId:t.id}}))}}),n.push({id:"clone",label:"Clone Building",icon:e.jsx(u,{name:"copy",size:14}),onClick:()=>{h.createBuilding({name:`${t.name} (Copy)`,type:t.type,style:t.style,color:t.color,scale:t.scale,position:{x:t.position.x+2,z:t.position.z+2},cwd:t.cwd,folderPath:t.folderPath,commands:t.commands,pm2:t.pm2,docker:t.docker,database:t.database,terminal:t.terminal,urls:t.urls,subordinateBuildingIds:t.subordinateBuildingIds})}}),t.urls&&t.urls.length>0)for(const l of t.urls)n.push({id:`url-${l.label}`,label:l.label,icon:e.jsx(u,{name:"link",size:14}),onClick:()=>window.open(l.url,"_blank","noopener,noreferrer")});return n.push({id:"divider-danger",label:"",divider:!0,onClick:()=>{}}),n.push({id:"delete",label:"Delete Building",icon:e.jsx(u,{name:"trash",size:14}),danger:!0,onClick:()=>h.deleteBuilding(t.id)}),n},[J,st,we]),Jt=a.useCallback(t=>{const n=new Set(Ne.groups.map(s=>s.area.id));n.delete(t),kt(n),requestAnimationFrame(()=>{const s=Nt.current;if(!s)return;const p=s.querySelector(`[data-area-id="${t}"]`);if(!p)return;const m=s.getBoundingClientRect(),l=p.getBoundingClientRect().top-m.top+s.scrollTop-8;s.scrollTo({top:Math.max(0,l),behavior:"smooth"})})},[Ne]);return e.jsxs("div",{ref:ce,className:`flat-view ${K?"flat-view--with-inspector":""} ${x?"flat-view--has-chat":""} ${oe?"flat-view--mobile-sidebar-open":""}`,style:(()=>{if(U===null&&q===null)return;const t={};return U!==null&&(t["--flat-middle-width"]=`${U}px`),q!==null&&(t["--flat-inspector-width"]=`${q}px`),t})(),children:[oe&&e.jsx("div",{className:"flat-mobile-sidebar-backdrop",onClick:qe,"aria-hidden":"true"}),e.jsxs("div",{className:"flat-middle",children:[e.jsx("div",{className:"flat-middle__header",children:e.jsxs("div",{className:"flat-middle__actions",children:[e.jsx("button",{className:"flat-cta-btn flat-cta-btn--agent",onClick:E,title:"Create new agent",children:"+ Agent"}),e.jsx("button",{className:"flat-cta-btn flat-cta-btn--boss",onClick:Y,title:"Create new boss agent",children:"+ Boss"}),e.jsx("button",{className:"flat-cta-btn flat-cta-btn--area",onClick:H,title:"Create new area",children:"+ Area"})]})}),e.jsx("div",{className:"flat-middle__content",children:e.jsx(un,{activeAgentId:Te,onClose:Pe,onSelectAgent:xt,collapsedAreas:Vt,onToggleArea:Gt,agentListRef:Nt})})]}),e.jsx("div",{className:"flat-splitter flat-splitter--middle",role:"separator","aria-orientation":"vertical","aria-label":"Resize agents panel",title:"Drag to resize · Double-click to reset",onPointerDown:ge,onPointerMove:de,onPointerUp:xe,onPointerCancel:xe,onDoubleClick:mt}),e.jsxs("div",{className:"flat-right",children:[e.jsxs("button",{type:"button",className:"flat-mobile-sidebar-toggle","aria-label":oe?"Close agents sidebar":"Open agents sidebar","aria-expanded":oe,onClick:pt,children:[e.jsx(u,{name:"list",size:18}),e.jsx("span",{className:"flat-mobile-sidebar-toggle__label",children:"Agents"})]}),x?e.jsx(Yn,{agentId:x,terminalViewMode:Ue,onTerminalViewModeChange:Ie,inspectorOpen:he,onToggleInspector:gt,onImageClick:ue,onFileClick:ee,onBashClick:Be,onViewMarkdown:Ze,onRequestClearSubordinates:Je,onOpenBuilding:we,keyboard:_e,canNavigateBack:Qe,canNavigateForward:te,onNavigateBack:r,onNavigateForward:d,agentInfoOpen:Ae,onToggleAgentInfo:ze}):e.jsx("div",{className:"flat-chat flat-chat--empty",children:e.jsxs("div",{className:"flat-map",children:[e.jsxs("div",{className:"flat-map__header",children:[e.jsx("span",{className:"flat-map__title",children:"🗺️ Areas"}),e.jsx("span",{className:"flat-map__hint",children:"Click an area to focus it, or an agent to chat"}),e.jsx(Wn,{className:"flat-map__view-mode"})]}),e.jsx("div",{className:"flat-map__grid",style:{gridTemplateColumns:`repeat(${Ne.gridCols}, 1fr)`},children:Ne.groups.length===0?e.jsx("div",{className:"flat-map__empty",children:e.jsx("span",{children:"No areas or agents yet"})}):(()=>{var n;const t=je&&at?((n=Ne.positions.get(at))==null?void 0:n.row)??null:null;return Ne.groups.map(s=>{const p=s.area.id,m=Ne.positions.get(p),b=je&&at!==p;return je&&t!=null&&(m==null?void 0:m.row)===t&&p!==at?null:e.jsxs("div",{className:`flat-map-area-card${b?" flat-map-area-card--collapsed":""}`,style:{"--area-color":s.area.color,gridRow:m==null?void 0:m.row,gridColumn:m==null?void 0:m.col},children:[e.jsxs("button",{type:"button",className:"flat-map-area-card__header",onClick:()=>je?qt(p):Jt(p),title:je?b?`Expand ${s.area.name}`:`Collapse ${s.area.name}`:`Focus ${s.area.name} in left panel`,"aria-expanded":je?!b:void 0,children:[e.jsx("span",{className:"flat-map-area-card__color",style:{background:s.area.color}}),e.jsx("span",{className:"flat-map-area-card__name",children:s.area.name}),e.jsx("span",{className:"flat-map-area-card__count",children:s.agents.length}),je&&e.jsx(u,{name:b?"caret-down":"caret-up",size:11,className:"flat-map-area-card__caret"})]}),e.jsx("div",{className:"flat-map-area-card__agents",children:s.agents.map(l=>{const A=l.isBoss||l.class==="boss",N=A?nt.get(l.id):void 0,W=pn(l),it=W.usedPercent>=80?"#ff4a4a":W.usedPercent>=60?"#ff9e4a":W.usedPercent>=40?"#ffd700":"#4aff9e",f=`Context: ${(W.totalTokens/1e3).toFixed(1)}k / ${(W.contextWindow/1e3).toFixed(1)}k (${W.usedPercent}% used, ${W.freePercent}% free)`,k=l.latestTodos&&l.latestTodos.length>0||N&&N.length>0;return e.jsx(mn,{todos:l.latestTodos,subordinates:N,position:"top",children:e.jsxs("button",{type:"button",className:`flat-map-agent-chip ${l.status}`,onClick:()=>_(l.id),onContextMenu:j=>{j.preventDefault(),j.stopPropagation(),ye({agentId:l.id,position:{x:j.clientX,y:j.clientY}})},title:k?void 0:`${A?"Boss · ":""}Open chat with ${l.name}
|
|
2
|
-
${f}`,children:[e.jsx(Wt,{agent:l,size:16}),A&&e.jsx("span",{className:"flat-map-agent-chip__crown","aria-hidden":"true",children:e.jsx(u,{name:"crown",size:11,color:"#ffd700",weight:"fill"})}),e.jsx("span",{className:"flat-map-agent-chip__name",children:l.name}),e.jsx("img",{src:l.provider==="codex"?"/assets/codex.png":l.provider==="opencode"?"/assets/opencode.png":"/assets/claude.png",alt:l.provider,className:"flat-map-agent-chip__provider-icon",title:l.provider==="codex"?"Codex Agent":l.provider==="opencode"?"OpenCode Agent":"Claude Agent"}),e.jsx("span",{className:"flat-map-agent-chip__dot",style:{backgroundColor:Ht(l.status)}}),l.latestTodos&&l.latestTodos.length>0&&e.jsx(fn,{todos:l.latestTodos,maxDots:6}),A&&N&&N.length>0&&e.jsx(hn,{subordinates:N,maxDots:6}),e.jsx("span",{className:"flat-map-agent-chip__context-bar","aria-hidden":"true",children:e.jsx("span",{className:"flat-map-agent-chip__context-bar-fill",style:{width:`${W.usedPercent}%`,backgroundColor:it}})})]})},l.id)})}),s.buildings.length>0&&e.jsx("div",{className:"flat-map-area-card__buildings",children:s.buildings.map(l=>e.jsxs("button",{type:"button",className:`flat-map-building-chip flat-map-building-chip--${l.status}`,onClick:A=>{if(I){const N=A.currentTarget.getBoundingClientRect();I(l.id,{x:N.right,y:N.top+N.height/2})}else we(l.id)},onContextMenu:A=>{A.preventDefault(),A.stopPropagation(),g({buildingId:l.id,position:{x:A.clientX,y:A.clientY}})},title:`${l.name} · ${l.type} · ${l.status}`,children:[e.jsx(u,{name:gn(l.type),size:12}),e.jsx("span",{className:"flat-map-building-chip__name",children:l.name}),e.jsx("span",{className:"flat-map-building-chip__dot",style:{backgroundColor:xn(l.status)}})]},l.id))})]},p)})})()})]})})]}),K&&e.jsx("div",{className:"flat-splitter flat-splitter--inspector",role:"separator","aria-orientation":"vertical","aria-label":"Resize inspector panel",title:"Drag to resize · Double-click to reset",onPointerDown:Ke,onPointerMove:de,onPointerUp:xe,onPointerCancel:xe,onDoubleClick:ft}),Le&&e.jsxs("aside",{className:`flat-inspector ${T?"flat-inspector--open":"flat-inspector--closing"}`,"aria-label":"Inspector panel",children:[e.jsxs("div",{className:"flat-inspector__header",children:[e.jsxs("div",{className:"flat-inspector__tabs",role:"tablist","aria-label":"Inspector view",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":be==="agent",className:`flat-inspector__tab ${be==="agent"?"flat-inspector__tab--active":""}`,onClick:()=>Ye("agent"),children:"Agent"}),e.jsx("button",{type:"button",role:"tab","aria-selected":be==="tracking",className:`flat-inspector__tab ${be==="tracking"?"flat-inspector__tab--active":""}`,onClick:()=>Ye("tracking"),children:"Tracking"})]}),e.jsx("button",{type:"button",className:"flat-inspector__close",onClick:$e,title:"Close inspector","aria-label":"Close inspector",children:"✕"})]}),e.jsx("div",{className:"flat-inspector__body",children:be==="tracking"?e.jsx(bn,{activeAgentId:x??"",onSelectAgent:t=>{_(t),window.innerWidth<=768&&$e()}}):(()=>{if(!x)return e.jsx("div",{className:"flat-inspector__empty",children:e.jsx("span",{children:"Select an agent to inspect"})});const t=M.find(n=>n.id===x);return t?e.jsx(_n,{agent:t,onFocusAgent:n=>{_(n),window.innerWidth<=768&&$e()},onKillAgent:n=>h.killAgent(n)}):e.jsx("div",{className:"flat-inspector__empty",children:e.jsx("span",{children:"Agent not found"})})})()})]}),Z&&e.jsx(wn,{url:Z.url,name:Z.name,onClose:()=>Re(null)}),Ve&&e.jsx(vn,{state:Ve,onClose:()=>Ge(null)}),De&&e.jsx(Cn,{action:"clear-subordinates",selectedAgentId:De.agentId,subordinateCount:De.count,onClose:()=>le(null),onClearHistory:()=>{}}),e.jsx(jn,{agent:x?M.find(t=>t.id===x)??null:null,isOpen:Ae&&!!x,onClose:Xe}),e.jsx(Rt,{isOpen:z!==null,position:(z==null?void 0:z.position)??{x:0,y:0},worldPosition:{x:0,z:0},actions:Yt,onClose:()=>ye(null)}),e.jsx(Rt,{isOpen:J!==null,position:(J==null?void 0:J.position)??{x:0,y:0},worldPosition:{x:0,z:0},actions:Zt,onClose:()=>g(null)}),e.jsx(Nn,{isOpen:P!==null,title:ie("common:confirm.removeAgentTitle"),message:ie("common:confirm.removeAgentMessage",{name:(P==null?void 0:P.name)??""}),confirmLabel:ie("common:buttons.remove"),cancelLabel:ie("common:buttons.cancel"),variant:"danger",onConfirm:()=>{P&&h.removeAgentFromServer(P.agentId)},onClose:()=>me(null)})]})}export{ea as FlatView};
|