tide-commander 1.43.1 → 1.45.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-CVg_MfdE.js → BossLogsModal-N4CnX-0x.js} +1 -1
- package/dist/assets/{BossSpawnModal-Bikb7hBY.js → BossSpawnModal-4CPjS2xn.js} +1 -1
- package/dist/assets/ControlsModal-Cr5klRxS.js +1 -0
- package/dist/assets/{DockerLogsModal-Cry5-Tvn.js → DockerLogsModal-D6U9obTe.js} +1 -1
- package/dist/assets/{EmbeddedEditor-CIhFmW0L.js → EmbeddedEditor-Bnm-9Q73.js} +1 -1
- package/dist/assets/{GmailOAuthSetup-Dy5O_2Fa.js → GmailOAuthSetup-GoKvyYWS.js} +1 -1
- package/dist/assets/{GoogleOAuthSetup-CZPe6iiU.js → GoogleOAuthSetup-D3sAGlZq.js} +1 -1
- package/dist/assets/{IframeModal-P4PrKR61.js → IframeModal-DQqev6_V.js} +1 -1
- package/dist/assets/{IntegrationsPanel-CeKz_I5C.js → IntegrationsPanel-C9hWD7mO.js} +2 -2
- package/dist/assets/{LogViewerModal-Cu0ojz2h.js → LogViewerModal-DB0xx-oB.js} +1 -1
- package/dist/assets/{MonitoringModal-Bo7YZKga.js → MonitoringModal-BspW74kP.js} +1 -1
- package/dist/assets/{PM2LogsModal-DjSjBB5n.js → PM2LogsModal-Cz4GZtyl.js} +1 -1
- package/dist/assets/{RestoreArchivedAreaModal-Cr0dVcm7.js → RestoreArchivedAreaModal-KCCSJy3B.js} +1 -1
- package/dist/assets/{SaveSnapshotModal-Cngm66r9.js → SaveSnapshotModal-DqZ1JedM.js} +1 -1
- package/dist/assets/{Scene2DCanvas-CxUD-QLv.js → Scene2DCanvas-MRhWT6EA.js} +1 -1
- package/dist/assets/{SceneManager-CFq_dIjf.js → SceneManager-DggU0iAh.js} +1 -1
- package/dist/assets/{SkillsPanel-DeNlZjhm.js → SkillsPanel-DZC0Im2z.js} +1 -1
- package/dist/assets/{SnapshotManager-DyGSyuTV.js → SnapshotManager-3LQMRFLh.js} +1 -1
- package/dist/assets/{SpawnModal-DCk35phK.js → SpawnModal-C_e6q2uv.js} +1 -1
- package/dist/assets/{SubordinateAssignmentModal-q4of-xB_.js → SubordinateAssignmentModal-BZdSk9WL.js} +1 -1
- package/dist/assets/{SupervisorPanel-B4g4RnXX.js → SupervisorPanel-CxId5lI7.js} +1 -1
- package/dist/assets/{TriggerManagerPanel-yKzt3ymQ.js → TriggerManagerPanel-BCzGGCPD.js} +1 -1
- package/dist/assets/{WorkflowEditorPanel-BEhxdbzG.js → WorkflowEditorPanel-BmNCGmxP.js} +1 -1
- package/dist/assets/{index-Cx3vkOU7.js → index-8WVMR823.js} +1 -1
- package/dist/assets/{index-3Q4Y5M5A.js → index-B8SWRPUd.js} +1 -1
- package/dist/assets/{index-egvzmURy.js → index-Bhb-rse9.js} +3 -3
- package/dist/assets/{index-Dm4Ql23t.js → index-C9B8kaWK.js} +1 -1
- package/dist/assets/{index-D9CfgwK1.js → index-COBkxsEU.js} +1 -1
- package/dist/assets/{index-CNyYl9DR.js → index-CcYTUJp1.js} +1 -1
- package/dist/assets/{index-Brczvyiq.js → index-CvJuv-ho.js} +2 -2
- package/dist/assets/{index-mlbu3rRR.js → index-Sej69v19.js} +1 -1
- package/dist/assets/main-6CnCKW13.js +153 -0
- package/dist/assets/main-DjGrMNoB.css +1 -0
- package/dist/assets/{web-CTzGBDAL.js → web-CrUhsC9T.js} +1 -1
- package/dist/assets/{web-Dp1qM35w.js → web-RTEsf66y.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/src/packages/server/data/index.js +43 -0
- package/dist/src/packages/server/index.js +2 -0
- package/dist/src/packages/server/routes/agents.js +33 -0
- package/dist/src/packages/server/services/agent-service.js +42 -2
- package/dist/src/packages/server/websocket/handler.js +3 -1
- package/dist/src/packages/server/websocket/handlers/agent-handler.js +48 -0
- package/package.json +1 -1
- package/dist/assets/ControlsModal-CkLjXrTR.js +0 -1
- package/dist/assets/main-BmmvF2Ey.js +0 -153
- package/dist/assets/main-Chjl2UXl.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{by as a}from"./main-6CnCKW13.js";import{ImpactStyle as i,NotificationType as r}from"./index-CvJuv-ho.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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{by as s}from"./main-6CnCKW13.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};
|
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-6CnCKW13.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-DjGrMNoB.css">
|
|
30
30
|
</head>
|
|
31
31
|
<body>
|
|
32
32
|
<div id="app"></div>
|
|
@@ -27,9 +27,11 @@ const SKILLS_FILE = path.join(DATA_DIR, 'skills.json');
|
|
|
27
27
|
const CUSTOM_CLASSES_FILE = path.join(DATA_DIR, 'custom-agent-classes.json');
|
|
28
28
|
const RUNNING_PROCESSES_FILE = path.join(DATA_DIR, 'running-processes.json');
|
|
29
29
|
const SECRETS_FILE = path.join(DATA_DIR, 'secrets.json');
|
|
30
|
+
const SESSION_HISTORY_FILE = path.join(DATA_DIR, 'session-history.json');
|
|
30
31
|
const AREA_LOGOS_DIR = path.join(DATA_DIR, 'area-logos');
|
|
31
32
|
// Maximum history entries per agent
|
|
32
33
|
const MAX_HISTORY_PER_AGENT = 50;
|
|
34
|
+
const MAX_SESSION_HISTORY_PER_AGENT = 100;
|
|
33
35
|
const MAX_DELEGATION_HISTORY_PER_BOSS = 100;
|
|
34
36
|
// Ensure data directory exists
|
|
35
37
|
function ensureDataDir() {
|
|
@@ -134,6 +136,9 @@ function toStoredAgents(agents) {
|
|
|
134
136
|
lastAssignedTask: agent.lastAssignedTask,
|
|
135
137
|
lastAssignedTaskTime: agent.lastAssignedTaskTime,
|
|
136
138
|
taskLabel: agent.taskLabel,
|
|
139
|
+
trackingStatus: agent.trackingStatus,
|
|
140
|
+
trackingStatusDetail: agent.trackingStatusDetail,
|
|
141
|
+
trackingStatusTimestamp: agent.trackingStatusTimestamp,
|
|
137
142
|
isBoss: agent.isBoss,
|
|
138
143
|
subordinateIds: agent.subordinateIds,
|
|
139
144
|
bossId: agent.bossId,
|
|
@@ -780,3 +785,41 @@ export function deleteQueryHistory(buildingId) {
|
|
|
780
785
|
log.error(` Failed to delete query history for building ${buildingId}:`, err);
|
|
781
786
|
}
|
|
782
787
|
}
|
|
788
|
+
export function loadSessionHistory() {
|
|
789
|
+
ensureDataDir();
|
|
790
|
+
const data = safeReadJsonSync(SESSION_HISTORY_FILE, 'Session history');
|
|
791
|
+
if (data?.histories) {
|
|
792
|
+
log.log(` Loaded session history for ${Object.keys(data.histories).length} agents`);
|
|
793
|
+
return new Map(Object.entries(data.histories));
|
|
794
|
+
}
|
|
795
|
+
return new Map();
|
|
796
|
+
}
|
|
797
|
+
export function saveSessionHistory(histories) {
|
|
798
|
+
ensureDataDir();
|
|
799
|
+
try {
|
|
800
|
+
atomicWriteJsonSync(SESSION_HISTORY_FILE, {
|
|
801
|
+
histories: Object.fromEntries(histories),
|
|
802
|
+
savedAt: Date.now(),
|
|
803
|
+
version: '1.0.0',
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
catch (err) {
|
|
807
|
+
log.error(' Failed to save session history:', err);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
export function addSessionHistoryEntry(histories, agentId, entry) {
|
|
811
|
+
let agentHistory = histories.get(agentId);
|
|
812
|
+
if (!agentHistory) {
|
|
813
|
+
agentHistory = [];
|
|
814
|
+
histories.set(agentId, agentHistory);
|
|
815
|
+
}
|
|
816
|
+
// Add to beginning (most recent first)
|
|
817
|
+
agentHistory.unshift(entry);
|
|
818
|
+
// Trim to max entries
|
|
819
|
+
if (agentHistory.length > MAX_SESSION_HISTORY_PER_AGENT) {
|
|
820
|
+
agentHistory.pop();
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
export function getSessionHistoryForAgent(histories, agentId) {
|
|
824
|
+
return histories.get(agentId) || [];
|
|
825
|
+
}
|
|
@@ -59,6 +59,7 @@ async function main() {
|
|
|
59
59
|
eventRetentionService.init();
|
|
60
60
|
// Initialize services
|
|
61
61
|
agentService.initAgents();
|
|
62
|
+
agentService.initSessionHistory();
|
|
62
63
|
runtimeService.init();
|
|
63
64
|
supervisorService.init();
|
|
64
65
|
bossService.init();
|
|
@@ -209,6 +210,7 @@ async function main() {
|
|
|
209
210
|
buildingService.stopTerminalStatusPolling();
|
|
210
211
|
buildingService.cleanupAllTerminals();
|
|
211
212
|
await runtimeService.shutdown();
|
|
213
|
+
agentService.shutdownSessionHistory();
|
|
212
214
|
agentService.flushPersistAgents();
|
|
213
215
|
closeEventDb();
|
|
214
216
|
wss.clients.forEach((client) => client.terminate());
|
|
@@ -9,6 +9,7 @@ import * as path from 'path';
|
|
|
9
9
|
import * as os from 'os';
|
|
10
10
|
import { agentService, runtimeService, bossMessageService } from '../services/index.js';
|
|
11
11
|
import { getClaudeProjectDir, loadAreas, saveAreas } from '../data/index.js';
|
|
12
|
+
import { loadSession } from '../claude/session-loader.js';
|
|
12
13
|
import { getAllCustomClasses } from '../services/custom-class-service.js';
|
|
13
14
|
// Session listing is done inline for performance
|
|
14
15
|
import { createLogger } from '../utils/logger.js';
|
|
@@ -586,6 +587,38 @@ router.get('/:id/history', async (req, res) => {
|
|
|
586
587
|
res.status(500).json({ error: err.message });
|
|
587
588
|
}
|
|
588
589
|
});
|
|
590
|
+
// GET /api/agents/:id/session-history - Get archived session history for an agent
|
|
591
|
+
router.get('/:id/session-history', (_req, res) => {
|
|
592
|
+
try {
|
|
593
|
+
const entries = agentService.getAgentSessionHistory(_req.params.id);
|
|
594
|
+
res.json({ entries });
|
|
595
|
+
}
|
|
596
|
+
catch (err) {
|
|
597
|
+
log.error(' Failed to load session history:', err);
|
|
598
|
+
res.status(500).json({ error: err.message });
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
// GET /api/agents/:id/session-preview/:sessionId - Preview messages from an archived session
|
|
602
|
+
router.get('/:id/session-preview/:sessionId', async (req, res) => {
|
|
603
|
+
try {
|
|
604
|
+
const agent = agentService.getAgent(req.params.id);
|
|
605
|
+
if (!agent) {
|
|
606
|
+
res.status(404).json({ error: 'Agent not found' });
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
const limit = parseInt(req.query.limit) || 30;
|
|
610
|
+
const history = await loadSession(agent.cwd, req.params.sessionId, limit, 0);
|
|
611
|
+
if (!history) {
|
|
612
|
+
res.status(404).json({ error: 'Session not found' });
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
res.json({ messages: history.messages, totalCount: history.totalCount });
|
|
616
|
+
}
|
|
617
|
+
catch (err) {
|
|
618
|
+
log.error(' Failed to load session preview:', err);
|
|
619
|
+
res.status(500).json({ error: err.message });
|
|
620
|
+
}
|
|
621
|
+
});
|
|
589
622
|
// GET /api/agents/:id/search - Search conversation history
|
|
590
623
|
router.get('/:id/search', async (req, res) => {
|
|
591
624
|
try {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
import * as fs from 'fs';
|
|
6
6
|
import * as os from 'os';
|
|
7
7
|
import * as path from 'path';
|
|
8
|
-
import { loadAgents, saveAgents, saveAgentsAsync, getDataDir, loadAreas, saveAreas } from '../data/index.js';
|
|
9
|
-
import { listSessions, getSessionSummary, loadSession, loadToolHistory, searchSession, } from '../claude/session-loader.js';
|
|
8
|
+
import { loadAgents, saveAgents, saveAgentsAsync, getDataDir, loadAreas, saveAreas, loadSessionHistory, saveSessionHistory, addSessionHistoryEntry, getSessionHistoryForAgent } from '../data/index.js';
|
|
9
|
+
import { listSessions, getSessionSummary, getProjectDir, loadSession, loadToolHistory, searchSession, } from '../claude/session-loader.js';
|
|
10
10
|
import { loadSubagentHistory } from '../claude/subagent-history-loader.js';
|
|
11
11
|
import { logger, generateId } from '../utils/index.js';
|
|
12
12
|
const log = logger.agent;
|
|
@@ -650,5 +650,45 @@ Please acknowledge this update and continue with your work.
|
|
|
650
650
|
`;
|
|
651
651
|
}
|
|
652
652
|
// ============================================================================
|
|
653
|
+
// Session History
|
|
654
|
+
// ============================================================================
|
|
655
|
+
let sessionHistories = new Map();
|
|
656
|
+
export function initSessionHistory() {
|
|
657
|
+
sessionHistories = loadSessionHistory();
|
|
658
|
+
log.log?.(` Loaded session history for ${sessionHistories.size} agents`);
|
|
659
|
+
}
|
|
660
|
+
export function shutdownSessionHistory() {
|
|
661
|
+
saveSessionHistory(sessionHistories);
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Archive the current session for an agent before it gets cleared.
|
|
665
|
+
* Call this before setting sessionId to undefined.
|
|
666
|
+
*/
|
|
667
|
+
export function archiveCurrentSession(agentId) {
|
|
668
|
+
const agent = agents.get(agentId);
|
|
669
|
+
if (!agent || !agent.sessionId)
|
|
670
|
+
return;
|
|
671
|
+
const entry = {
|
|
672
|
+
sessionId: agent.sessionId,
|
|
673
|
+
summary: agent.taskLabel || agent.lastAssignedTask || agent.currentTask || 'No description',
|
|
674
|
+
startedAt: agent.createdAt,
|
|
675
|
+
endedAt: Date.now(),
|
|
676
|
+
};
|
|
677
|
+
addSessionHistoryEntry(sessionHistories, agentId, entry);
|
|
678
|
+
saveSessionHistory(sessionHistories);
|
|
679
|
+
log.log?.(`Archived session ${agent.sessionId} for agent ${agent.name}`);
|
|
680
|
+
}
|
|
681
|
+
export function getAgentSessionHistory(agentId) {
|
|
682
|
+
const agent = agents.get(agentId);
|
|
683
|
+
const entries = getSessionHistoryForAgent(sessionHistories, agentId);
|
|
684
|
+
if (!agent)
|
|
685
|
+
return entries;
|
|
686
|
+
const projectDir = getProjectDir(agent.cwd);
|
|
687
|
+
return entries.map((entry) => ({
|
|
688
|
+
...entry,
|
|
689
|
+
fileExists: fs.existsSync(path.join(projectDir, `${entry.sessionId}.jsonl`)),
|
|
690
|
+
}));
|
|
691
|
+
}
|
|
692
|
+
// ============================================================================
|
|
653
693
|
// Utilities
|
|
654
694
|
// ============================================================================
|
|
@@ -9,7 +9,7 @@ import { logger } from '../utils/index.js';
|
|
|
9
9
|
import { setNotificationBroadcast, setExecBroadcast, setFocusAgentBroadcast, setAgentsBroadcast, setTriggerBroadcast } from '../routes/index.js';
|
|
10
10
|
import { validateWebSocketAuth, isAuthEnabled } from '../auth/index.js';
|
|
11
11
|
import { incrementWsSent, incrementWsReceived, setWsClientsCount } from '../routes/perf.js';
|
|
12
|
-
import { handleSpawnAgent, handleKillAgent, handleStopAgent, handleClearContext, handleCollapseContext, handleRequestContextStats, handleMoveAgent, handleRemoveAgent, handleRenameAgent, handleUpdateAgentProperties, handleCreateDirectory, handleReattachAgent, } from './handlers/agent-handler.js';
|
|
12
|
+
import { handleSpawnAgent, handleKillAgent, handleStopAgent, handleClearContext, handleRestoreSession, handleRequestSessionHistory, handleCollapseContext, handleRequestContextStats, handleMoveAgent, handleRemoveAgent, handleRenameAgent, handleUpdateAgentProperties, handleCreateDirectory, handleReattachAgent, } from './handlers/agent-handler.js';
|
|
13
13
|
import { handleCreateSkill, handleUpdateSkill, handleDeleteSkill, handleAssignSkill, handleUnassignSkill, handleRequestAgentSkills, } from './handlers/skill-handler.js';
|
|
14
14
|
import { handleSpawnBossAgent, handleAssignSubordinates, handleRemoveSubordinate, handleSendBossCommand, handleRequestDelegationHistory, } from './handlers/boss-handler.js';
|
|
15
15
|
import { handleCreateCustomAgentClass, handleUpdateCustomAgentClass, handleDeleteCustomAgentClass, } from './handlers/custom-class-handler.js';
|
|
@@ -138,6 +138,8 @@ const messageHandlers = {
|
|
|
138
138
|
kill_agent: handleKillAgent,
|
|
139
139
|
stop_agent: handleStopAgent,
|
|
140
140
|
clear_context: handleClearContext,
|
|
141
|
+
restore_session: handleRestoreSession,
|
|
142
|
+
request_session_history: handleRequestSessionHistory,
|
|
141
143
|
collapse_context: handleCollapseContext,
|
|
142
144
|
create_directory: handleCreateDirectory,
|
|
143
145
|
remove_agent: handleRemoveAgent,
|
|
@@ -151,6 +151,8 @@ export async function handleStopAgent(ctx, payload) {
|
|
|
151
151
|
export async function handleClearContext(ctx, payload) {
|
|
152
152
|
const agent = agentService.getAgent(payload.agentId);
|
|
153
153
|
log.log(`Agent ${agent?.name || payload.agentId}: User requested context clear`);
|
|
154
|
+
// Archive the current session before clearing
|
|
155
|
+
agentService.archiveCurrentSession(payload.agentId);
|
|
154
156
|
await runtimeService.stopAgent(payload.agentId);
|
|
155
157
|
agentService.updateAgent(payload.agentId, {
|
|
156
158
|
status: 'idle',
|
|
@@ -170,6 +172,47 @@ export async function handleClearContext(ctx, payload) {
|
|
|
170
172
|
ctx.sendActivity(payload.agentId, 'Context cleared - new session on next command');
|
|
171
173
|
log.log(`Agent ${agent?.name || payload.agentId}: Context cleared, session reset`);
|
|
172
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Handle restore_session message - restores a previous session for an agent
|
|
177
|
+
*/
|
|
178
|
+
export async function handleRestoreSession(ctx, payload) {
|
|
179
|
+
const agent = agentService.getAgent(payload.agentId);
|
|
180
|
+
if (!agent) {
|
|
181
|
+
ctx.sendError(`Agent not found: ${payload.agentId}`);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
log.log(`Agent ${agent.name}: Restoring session ${payload.sessionId}`);
|
|
185
|
+
// Archive the current session first (if any)
|
|
186
|
+
agentService.archiveCurrentSession(payload.agentId);
|
|
187
|
+
// Stop any running process
|
|
188
|
+
await runtimeService.stopAgent(payload.agentId);
|
|
189
|
+
// Set the restored session ID
|
|
190
|
+
agentService.updateAgent(payload.agentId, {
|
|
191
|
+
status: 'idle',
|
|
192
|
+
currentTask: undefined,
|
|
193
|
+
taskLabel: undefined,
|
|
194
|
+
currentTool: undefined,
|
|
195
|
+
sessionId: payload.sessionId,
|
|
196
|
+
tokensUsed: 0,
|
|
197
|
+
contextUsed: 0,
|
|
198
|
+
contextStats: undefined,
|
|
199
|
+
});
|
|
200
|
+
ctx.sendActivity(payload.agentId, `Session restored - will resume on next command`);
|
|
201
|
+
log.log(`Agent ${agent.name}: Session restored to ${payload.sessionId}`);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Handle request_session_history - returns archived sessions for an agent
|
|
205
|
+
*/
|
|
206
|
+
export function handleRequestSessionHistory(ctx, payload) {
|
|
207
|
+
const entries = agentService.getAgentSessionHistory(payload.agentId);
|
|
208
|
+
ctx.sendToClient({
|
|
209
|
+
type: 'session_history',
|
|
210
|
+
payload: {
|
|
211
|
+
agentId: payload.agentId,
|
|
212
|
+
entries,
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
}
|
|
173
216
|
/**
|
|
174
217
|
* Handle collapse_context message - sends /compact command to collapse context
|
|
175
218
|
*/
|
|
@@ -707,6 +750,9 @@ export async function handleUpdateAgentProperties(ctx, payload) {
|
|
|
707
750
|
}
|
|
708
751
|
agentUpdates.cwd = updates.cwd;
|
|
709
752
|
}
|
|
753
|
+
if (updates.shortcut !== undefined) {
|
|
754
|
+
agentUpdates.shortcut = updates.shortcut;
|
|
755
|
+
}
|
|
710
756
|
// Apply agent property updates if any
|
|
711
757
|
// agentService.updateAgent tracks pending property changes for notification on next command
|
|
712
758
|
if (Object.keys(agentUpdates).length > 0) {
|
|
@@ -806,6 +852,8 @@ export async function handleUpdateAgentProperties(ctx, payload) {
|
|
|
806
852
|
// Claude sessions are tied to the directory they were created in
|
|
807
853
|
if (cwdChanged && sessionId) {
|
|
808
854
|
log.log(`Agent ${agent.name}: Working directory changed to ${updates.cwd}, clearing session (cwd change requires new session)`);
|
|
855
|
+
// Archive the current session before clearing
|
|
856
|
+
agentService.archiveCurrentSession(agentId);
|
|
809
857
|
try {
|
|
810
858
|
// Stop the current Claude process
|
|
811
859
|
await runtimeService.stopAgent(agentId);
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{u as S,b9 as Y,r as m,ba as X,b8 as w,j as e,f as _,bb as W,bc as Z,z as U,h as H,s as y,bd as z,be as A}from"./main-BmmvF2Ey.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";function q({shortcut:t,onUpdate:a}){const{t:s}=S(["config","terminal"]),o=Y(),[l,h]=m.useState(!1),[i,j]=m.useState(null),f=m.useRef(null),b=m.useMemo(()=>i?X(o,i,t.id,t.context):[],[i,o,t.id,t.context]);m.useEffect(()=>{if(!l)return;const p=c=>{if(c.preventDefault(),c.stopPropagation(),c.key==="Escape"&&!c.ctrlKey&&!c.altKey&&!c.shiftKey&&!c.metaKey){h(!1),j(null);return}if(["Control","Alt","Shift","Meta"].includes(c.key))return;let v=c.key;c.code.startsWith("Key")&&c.code.length===4?v=c.code.charAt(3).toLowerCase():c.code.startsWith("Digit")&&c.code.length===6?v=c.code.charAt(5):c.code==="Space"&&(v="Space");const x={key:v,modifiers:{ctrl:c.ctrlKey,alt:c.altKey,shift:c.shiftKey,meta:c.metaKey}};j(x)};return document.addEventListener("keydown",p,!0),()=>document.removeEventListener("keydown",p,!0)},[l]),m.useEffect(()=>{if(!l)return;const p=c=>{f.current&&!f.current.contains(c.target)&&(i&&b.length===0&&a(i),h(!1),j(null))};return document.addEventListener("mousedown",p),()=>document.removeEventListener("mousedown",p)},[l,i,b,a]);const k=()=>{l?(i&&b.length===0&&a(i),h(!1),j(null)):(h(!0),j(null))},g=p=>{p.stopPropagation(),a({key:"",modifiers:{}})};let d;return l?i?d=w({...t,...i}):d=s("config:shortcuts.pressKeys"):t.key?d=w(t):d=s("config:shortcuts.notSet"),e.jsxs("div",{className:"key-capture-container",children:[e.jsx("button",{ref:f,className:`key-capture-input ${l?"capturing":""} ${b.length>0?"conflict":""} ${t.enabled?"":"disabled"}`,onClick:k,title:s(l?"config:shortcuts.pressKeysOrClick":"config:shortcuts.clickToChange"),children:e.jsx("span",{className:"key-capture-value",children:d})}),t.key&&!l&&e.jsx("button",{className:"key-capture-clear",onClick:g,title:s("config:shortcuts.clearShortcut"),children:"×"}),b.length>0&&e.jsx("div",{className:"key-capture-conflict",children:s("config:shortcuts.conflictsWith",{names:b.map(p=>s(`terminal:controls.shortcuts.${p.id}.name`,{defaultValue:p.name})).join(", ")})})]})}const V={global:"terminal:controls.contextGlobal",commander:"terminal:controls.contextCommander",toolbox:"terminal:controls.contextToolbox"},Q={global:"terminal:controls.contextGlobalDesc",commander:"terminal:controls.contextCommanderDesc",toolbox:"terminal:controls.contextToolboxDesc"},R={camera:["camera-pan","camera-orbit","camera-rotate","camera-zoom","camera-tilt"],interaction:["primary-action","selection-box","context-menu","move-command"]},J={camera:"terminal:controls.cameraControls",interaction:"terminal:controls.interaction"};function oe({isOpen:t,onClose:a}){const{t:s}=S(["terminal","common"]),o=_(),l=W(),h=Z(),[i,j]=m.useState("keyboard"),[f,b]=m.useState(""),[k,g]=m.useState("all"),[d,p]=m.useState(!1),[c,v]=m.useState(null),x=U.useRef(null),{handleMouseDown:D,handleClick:M}=H(a);if(m.useEffect(()=>{if(!t||d)return;const r=n=>{n.key==="Escape"&&(n.preventDefault(),n.stopPropagation(),a())};return document.addEventListener("keydown",r,!0),()=>document.removeEventListener("keydown",r,!0)},[t,a,d]),m.useEffect(()=>{t||(b(""),p(!1),v(null))},[t]),m.useEffect(()=>{if(!t||!d)return;const r=n=>{if(n.key==="Escape"){n.preventDefault(),n.stopPropagation(),p(!1),v(null);return}if(["Control","Alt","Shift","Meta"].includes(n.key))return;n.preventDefault(),n.stopPropagation();let u=n.key;n.code.startsWith("Key")&&n.code.length===4?u=n.code.charAt(3).toLowerCase():n.code.startsWith("Digit")&&n.code.length===6?u=n.code.charAt(5):n.code==="Space"&&(u="Space"),v({key:u,modifiers:{ctrl:n.ctrlKey,alt:n.altKey,shift:n.shiftKey,meta:n.metaKey}})};return document.addEventListener("keydown",r,!0),()=>document.removeEventListener("keydown",r,!0)},[t,d]),!t)return null;const E=o.shortcuts.filter(r=>{const n=s(`terminal:controls.shortcuts.${r.id}.name`,{defaultValue:r.name}),u=s(`terminal:controls.shortcuts.${r.id}.description`,{defaultValue:r.description});if(d&&c){const O=C=>C===" "||C==="Space"?"Space":C.length===1?C.toLowerCase():C,$=O(r.key),B=O(c.key);if(!(B.length===1&&/^[a-zA-Z]$/.test($)?`Key${$.toUpperCase()}`==`Key${B.toUpperCase()}`:$===B))return!1;const K=r.modifiers,T=c.modifiers;return(K.ctrl||!1)===(T.ctrl||!1)&&(K.alt||!1)===(T.alt||!1)&&(K.shift||!1)===(T.shift||!1)&&(K.meta||!1)===(T.meta||!1)}if(!f)return!0;const N=f.toLowerCase();return n.toLowerCase().includes(N)||u.toLowerCase().includes(N)||w(r).toLowerCase().includes(N)}),L=E.reduce((r,n)=>(r[n.context]||(r[n.context]=[]),r[n.context].push(n),r),{}),G=(r,n)=>{y.updateShortcut(r,n)},F=()=>{i==="keyboard"?confirm(s("terminal:controls.confirmResetKeyboard"))&&y.resetShortcuts():i==="mouse"?confirm(s("terminal:controls.confirmResetMouse"))&&y.resetMouseControls():i==="trackpad"&&confirm(s("terminal:controls.confirmResetTrackpad"))&&y.resetMouseControls()},P=["global","commander","toolbox"],I=l.bindings.reduce((r,n)=>(R.camera.includes(n.action)?r.camera.push(n):R.interaction.includes(n.action)&&r.interaction.push(n),r),{camera:[],interaction:[]});return e.jsx("div",{className:"shortcuts-modal-overlay",onMouseDown:D,onClick:M,children:e.jsxs("div",{className:"shortcuts-modal controls-modal",children:[e.jsxs("div",{className:"shortcuts-modal-header",children:[e.jsxs("div",{className:"shortcuts-modal-title",children:[e.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("circle",{cx:"12",cy:"12",r:"3"}),e.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"})]}),e.jsx("span",{children:s("terminal:controls.title")})]}),e.jsx("button",{className:"shortcuts-modal-close",onClick:a,children:"×"})]}),e.jsxs("div",{className:"controls-main-tabs",children:[e.jsxs("button",{className:`controls-main-tab ${i==="keyboard"?"active":""}`,onClick:()=>j("keyboard"),children:[e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("rect",{x:"2",y:"4",width:"20",height:"16",rx:"2"}),e.jsx("path",{d:"M6 8h.01M10 8h.01M14 8h.01M18 8h.01M6 12h.01M18 12h.01M8 16h8"})]}),s("terminal:controls.keyboard")]}),e.jsxs("button",{className:`controls-main-tab ${i==="mouse"?"active":""}`,onClick:()=>j("mouse"),children:[e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("rect",{x:"6",y:"3",width:"12",height:"18",rx:"6"}),e.jsx("line",{x1:"12",y1:"7",x2:"12",y2:"11"})]}),s("terminal:controls.mouse")]}),e.jsxs("button",{className:`controls-main-tab ${i==="trackpad"?"active":""}`,onClick:()=>j("trackpad"),children:[e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("rect",{x:"2",y:"4",width:"20",height:"16",rx:"2"}),e.jsx("circle",{cx:"12",cy:"12",r:"3"})]}),s("terminal:controls.trackpad")]})]}),i==="keyboard"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"shortcuts-modal-toolbar",children:[d?e.jsxs("div",{className:"shortcuts-search find-by-shortcut-active",children:[e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("rect",{x:"2",y:"4",width:"20",height:"16",rx:"2"}),e.jsx("path",{d:"M6 8h.01M10 8h.01M14 8h.01M18 8h.01M6 12h.01M18 12h.01M8 16h8"})]}),c?e.jsxs("span",{className:"find-by-shortcut-display",children:[w({key:c.key,modifiers:c.modifiers}),e.jsx("button",{className:"shortcuts-search-clear",onClick:()=>v(null),children:"×"})]}):e.jsx("span",{className:"find-by-shortcut-prompt",children:s("terminal:controls.pressKeyCombination")})]}):e.jsxs("div",{className:"shortcuts-search",children:[e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("circle",{cx:"11",cy:"11",r:"8"}),e.jsx("path",{d:"M21 21l-4.35-4.35"})]}),e.jsx("input",{ref:x,type:"text",placeholder:s("terminal:controls.searchShortcuts"),value:f,onChange:r=>b(r.target.value),autoFocus:!0}),f&&e.jsx("button",{className:"shortcuts-search-clear",onClick:()=>b(""),children:"×"})]}),e.jsx("button",{className:`shortcuts-find-by-key-btn ${d?"active":""}`,onClick:()=>{p(!d),v(null),b("")},title:s(d?"terminal:controls.switchToTextSearch":"terminal:controls.findByPressingKeys"),children:e.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[e.jsx("rect",{x:"2",y:"4",width:"20",height:"16",rx:"2"}),e.jsx("path",{d:"M6 8h.01M10 8h.01M14 8h.01M18 8h.01M6 12h.01M18 12h.01M8 16h8"})]})}),e.jsx("button",{className:"shortcuts-reset-all-btn",onClick:F,children:s("common:buttons.reset")})]}),e.jsxs("div",{className:"shortcuts-context-tabs",children:[e.jsxs("button",{className:`shortcuts-context-tab ${k==="all"?"active":""}`,onClick:()=>g("all"),children:[s("common:labels.all"),e.jsx("span",{className:"shortcuts-context-tab-count",children:E.length})]}),P.map(r=>{var u;const n=((u=L[r])==null?void 0:u.length)||0;return e.jsxs("button",{className:`shortcuts-context-tab ${k===r?"active":""}`,onClick:()=>g(r),children:[s(V[r]),e.jsx("span",{className:"shortcuts-context-tab-count",children:n})]},r)})]}),e.jsxs("div",{className:"shortcuts-modal-content",children:[P.map(r=>{const n=L[r]||[];return n.length===0||k!=="all"&&k!==r?null:e.jsxs("div",{className:"shortcuts-context-group",children:[k==="all"&&e.jsxs("div",{className:"shortcuts-context-header",children:[e.jsx("span",{className:"shortcuts-context-label",children:s(V[r])}),e.jsx("span",{className:"shortcuts-context-description",children:s(Q[r])})]}),e.jsx("div",{className:"shortcuts-grid",children:n.map(u=>e.jsxs("div",{className:"shortcut-item",children:[e.jsxs("div",{className:"shortcut-item-info",children:[e.jsx("span",{className:"shortcut-item-name",children:s(`terminal:controls.shortcuts.${u.id}.name`,{defaultValue:u.name})}),e.jsx("span",{className:"shortcut-item-description",children:s(`terminal:controls.shortcuts.${u.id}.description`,{defaultValue:u.description})})]}),e.jsx(q,{shortcut:u,onUpdate:N=>G(u.id,N)})]},u.id))})]},r)}),E.length===0&&e.jsx("div",{className:"shortcuts-empty",children:d?c?e.jsx("p",{children:s("terminal:controls.noShortcutBoundTo",{keys:w({key:c.key,modifiers:c.modifiers})})}):e.jsx("p",{children:s("terminal:controls.pressKeyCombinationToFind")}):e.jsx("p",{children:s("terminal:controls.noShortcutsFound",{query:f})})})]})]}),i==="mouse"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"shortcuts-modal-toolbar",children:[e.jsx("span",{className:"mouse-controls-subtitle",children:s("terminal:controls.cameraAndInteraction")}),e.jsx("button",{className:"shortcuts-reset-all-btn",onClick:F,children:s("common:buttons.reset")})]}),e.jsxs("div",{className:"shortcuts-modal-content mouse-controls-content",children:[e.jsx("div",{className:"mouse-controls-bindings",children:Object.entries(I).map(([r,n])=>e.jsxs("div",{className:"shortcuts-context-group",children:[e.jsx("div",{className:"shortcuts-context-header",children:e.jsx("span",{className:"shortcuts-context-label",children:s(J[r])})}),e.jsx("div",{className:"shortcuts-grid",children:n.map(u=>e.jsx(ee,{binding:u},u.id))})]},r))}),e.jsxs("div",{className:"shortcuts-context-group",children:[e.jsxs("div",{className:"shortcuts-context-header",children:[e.jsx("span",{className:"shortcuts-context-label",children:s("terminal:controls.sensitivity")}),e.jsx("span",{className:"shortcuts-context-description",children:s("terminal:controls.adjustCameraSpeed")})]}),e.jsx(te,{sensitivity:l.sensitivity})]})]})]}),i==="trackpad"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"shortcuts-modal-toolbar",children:[e.jsx("span",{className:"mouse-controls-subtitle",children:s("terminal:controls.trackpadGestureSettings")}),e.jsx("button",{className:"shortcuts-reset-all-btn",onClick:F,children:s("common:buttons.reset")})]}),e.jsx("div",{className:"shortcuts-modal-content trackpad-controls-content",children:e.jsx(se,{config:h})})]}),e.jsx("div",{className:"shortcuts-modal-footer",children:e.jsx("span",{className:"shortcuts-modal-hint",children:s(i==="keyboard"?d?"terminal:controls.hintFindByShortcut":"terminal:controls.hintKeyboard":i==="mouse"?"terminal:controls.hintMouse":"terminal:controls.hintTrackpad")})})]})})}function ee({binding:t}){const{t:a}=S(["terminal"]),s=W(),[o,l]=m.useState(!1),[h,i]=m.useState(null);m.useEffect(()=>{if(!o)return;const d=x=>{x.preventDefault(),x.stopPropagation();const M={0:"left",1:"middle",2:"right",3:"back",4:"forward"}[x.button];M&&i({button:M,modifiers:{ctrl:x.ctrlKey,alt:x.altKey,shift:x.shiftKey,meta:x.metaKey}})},p=x=>{x.key==="Escape"&&(x.preventDefault(),x.stopPropagation(),l(!1),i(null))},c=()=>{h&&z(s.bindings,h,t.id).length===0&&y.updateMouseBinding(t.id,{button:h.button,modifiers:h.modifiers}),l(!1),i(null)},v=setTimeout(()=>{document.addEventListener("mousedown",d,!0),document.addEventListener("keydown",p,!0),document.addEventListener("click",c,!0)},100);return()=>{clearTimeout(v),document.removeEventListener("mousedown",d,!0),document.removeEventListener("keydown",p,!0),document.removeEventListener("click",c,!0)}},[o,h,t.id,s.bindings]);const j=h?z(s.bindings,h,t.id):[],f=a(`terminal:controls.mouseBindings.${t.id}.name`,{defaultValue:t.name}),b=a(`terminal:controls.mouseBindings.${t.id}.description`,{defaultValue:t.description}),k=d=>a(`terminal:controls.mouseButtons.${d}`,{defaultValue:d}),g=h?A({...t,...h},k):A(t,k);return e.jsxs("div",{className:`shortcut-item ${t.enabled?"":"disabled"}`,children:[e.jsxs("div",{className:"shortcut-item-info",children:[e.jsx("span",{className:"shortcut-item-name",children:f}),e.jsx("span",{className:"shortcut-item-description",children:b})]}),e.jsxs("div",{className:"key-capture-container",children:[e.jsx("button",{className:`key-capture-input ${o?"capturing":""} ${j.length>0?"conflict":""}`,onClick:()=>l(!0),children:o?h?e.jsx("span",{className:"key-capture-value",style:{color:"#f1fa8c"},children:g}):e.jsx("span",{style:{color:"#6272a4",fontStyle:"italic"},children:a("terminal:controls.clickToCapture")}):e.jsx("span",{className:"key-capture-value",children:g})}),j.length>0&&e.jsxs("span",{className:"key-capture-conflict",children:[a("terminal:controls.conflicts"),": ",j.map(d=>a(`terminal:controls.mouseBindings.${d.id}.name`,{defaultValue:d.name})).join(", ")]})]})]})}function te({sensitivity:t}){const{t:a}=S(["terminal"]),s=m.useCallback((o,l)=>{y.updateCameraSensitivity({[o]:l})},[]);return e.jsxs("div",{className:"sensitivity-inline-settings",children:[e.jsxs("div",{className:"sensitivity-sliders",children:[e.jsxs("div",{className:"sensitivity-slider-row",children:[e.jsx("label",{children:a("terminal:controls.panSpeed")}),e.jsx("input",{type:"range",min:"0.1",max:"3",step:"0.1",value:t.panSpeed,onChange:o=>s("panSpeed",parseFloat(o.target.value))}),e.jsxs("span",{className:"sensitivity-slider-value",children:[t.panSpeed.toFixed(1),"x"]})]}),e.jsxs("div",{className:"sensitivity-slider-row",children:[e.jsx("label",{children:a("terminal:controls.orbitSpeed")}),e.jsx("input",{type:"range",min:"0.1",max:"3",step:"0.1",value:t.orbitSpeed,onChange:o=>s("orbitSpeed",parseFloat(o.target.value))}),e.jsxs("span",{className:"sensitivity-slider-value",children:[t.orbitSpeed.toFixed(1),"x"]})]}),e.jsxs("div",{className:"sensitivity-slider-row",children:[e.jsx("label",{children:a("terminal:controls.zoomSpeed")}),e.jsx("input",{type:"range",min:"0.1",max:"3",step:"0.1",value:t.zoomSpeed,onChange:o=>s("zoomSpeed",parseFloat(o.target.value))}),e.jsxs("span",{className:"sensitivity-slider-value",children:[t.zoomSpeed.toFixed(1),"x"]})]}),e.jsxs("div",{className:"sensitivity-slider-row",children:[e.jsx("label",{children:a("terminal:controls.smoothing")}),e.jsx("input",{type:"range",min:"0",max:"1",step:"0.1",value:t.smoothing,onChange:o=>s("smoothing",parseFloat(o.target.value))}),e.jsx("span",{className:"sensitivity-slider-value",children:t.smoothing.toFixed(1)})]})]}),e.jsxs("div",{className:"sensitivity-checkboxes-inline",children:[e.jsxs("label",{className:"sensitivity-checkbox-inline",children:[e.jsx("input",{type:"checkbox",checked:t.invertPanX,onChange:o=>s("invertPanX",o.target.checked)}),e.jsx("span",{children:a("terminal:controls.invertPanX")})]}),e.jsxs("label",{className:"sensitivity-checkbox-inline",children:[e.jsx("input",{type:"checkbox",checked:t.invertPanY,onChange:o=>s("invertPanY",o.target.checked)}),e.jsx("span",{children:a("terminal:controls.invertPanY")})]}),e.jsxs("label",{className:"sensitivity-checkbox-inline",children:[e.jsx("input",{type:"checkbox",checked:t.invertOrbitX,onChange:o=>s("invertOrbitX",o.target.checked)}),e.jsx("span",{children:a("terminal:controls.invertOrbitX")})]}),e.jsxs("label",{className:"sensitivity-checkbox-inline",children:[e.jsx("input",{type:"checkbox",checked:t.invertOrbitY,onChange:o=>s("invertOrbitY",o.target.checked)}),e.jsx("span",{children:a("terminal:controls.invertOrbitY")})]})]})]})}function se({config:t}){const{t:a}=S(["terminal"]),s=m.useCallback((l,h)=>{y.updateTrackpadConfig({[l]:h})},[]),o=m.useCallback((l,h)=>{y.updateTrackpadConfig({sensitivity:{[l]:h}})},[]);return e.jsxs("div",{className:"trackpad-settings",children:[e.jsxs("div",{className:"shortcuts-context-group",children:[e.jsxs("div",{className:"shortcuts-context-header",children:[e.jsx("span",{className:"shortcuts-context-label",children:a("terminal:controls.trackpadGestures")}),e.jsx("span",{className:"shortcuts-context-description",children:a("terminal:controls.enableTrackpadSupport")})]}),e.jsx("div",{className:"trackpad-toggle-row",children:e.jsxs("label",{className:"trackpad-toggle",children:[e.jsx("input",{type:"checkbox",checked:t.enabled,onChange:l=>s("enabled",l.target.checked)}),e.jsx("span",{className:"trackpad-toggle-label",children:a("terminal:controls.enableTrackpadGestures")})]})})]}),e.jsxs("div",{className:"shortcuts-context-group",children:[e.jsxs("div",{className:"shortcuts-context-header",children:[e.jsx("span",{className:"shortcuts-context-label",children:a("terminal:controls.gestureControls")}),e.jsx("span",{className:"shortcuts-context-description",children:a("terminal:controls.enableDisableGestures")})]}),e.jsxs("div",{className:"trackpad-gestures-grid",children:[e.jsxs("label",{className:`trackpad-gesture-item ${t.enabled?"":"disabled"}`,children:[e.jsx("input",{type:"checkbox",checked:t.pinchToZoom,onChange:l=>s("pinchToZoom",l.target.checked),disabled:!t.enabled}),e.jsxs("div",{className:"trackpad-gesture-info",children:[e.jsx("span",{className:"trackpad-gesture-name",children:a("terminal:controls.pinchToZoom")}),e.jsx("span",{className:"trackpad-gesture-desc",children:a("terminal:controls.pinchToZoomDesc")})]})]}),e.jsxs("label",{className:`trackpad-gesture-item ${t.enabled?"":"disabled"}`,children:[e.jsx("input",{type:"checkbox",checked:t.twoFingerPan,onChange:l=>s("twoFingerPan",l.target.checked),disabled:!t.enabled}),e.jsxs("div",{className:"trackpad-gesture-info",children:[e.jsx("span",{className:"trackpad-gesture-name",children:a("terminal:controls.twoFingerPan")}),e.jsx("span",{className:"trackpad-gesture-desc",children:a("terminal:controls.twoFingerPanDesc")})]})]}),e.jsxs("label",{className:`trackpad-gesture-item ${t.enabled?"":"disabled"}`,children:[e.jsx("input",{type:"checkbox",checked:t.shiftTwoFingerOrbit,onChange:l=>s("shiftTwoFingerOrbit",l.target.checked),disabled:!t.enabled}),e.jsxs("div",{className:"trackpad-gesture-info",children:[e.jsx("span",{className:"trackpad-gesture-name",children:a("terminal:controls.shiftTwoFingerOrbit")}),e.jsx("span",{className:"trackpad-gesture-desc",children:a("terminal:controls.shiftTwoFingerOrbitDesc")})]})]})]})]}),e.jsxs("div",{className:"shortcuts-context-group",children:[e.jsxs("div",{className:"shortcuts-context-header",children:[e.jsx("span",{className:"shortcuts-context-label",children:a("terminal:controls.sensitivity")}),e.jsx("span",{className:"shortcuts-context-description",children:a("terminal:controls.adjustGestureSensitivity")})]}),e.jsxs("div",{className:"trackpad-sensitivity-sliders",children:[e.jsxs("div",{className:`trackpad-slider-row ${!t.enabled||!t.pinchToZoom?"disabled":""}`,children:[e.jsx("label",{children:a("terminal:controls.zoom")}),e.jsx("input",{type:"range",min:"0.1",max:"3",step:"0.1",value:t.sensitivity.zoom,onChange:l=>o("zoom",parseFloat(l.target.value)),disabled:!t.enabled||!t.pinchToZoom}),e.jsxs("span",{className:"trackpad-slider-value",children:[t.sensitivity.zoom.toFixed(1),"x"]})]}),e.jsxs("div",{className:`trackpad-slider-row ${!t.enabled||!t.twoFingerPan?"disabled":""}`,children:[e.jsx("label",{children:a("terminal:controls.pan")}),e.jsx("input",{type:"range",min:"0.1",max:"3",step:"0.1",value:t.sensitivity.pan,onChange:l=>o("pan",parseFloat(l.target.value)),disabled:!t.enabled||!t.twoFingerPan}),e.jsxs("span",{className:"trackpad-slider-value",children:[t.sensitivity.pan.toFixed(1),"x"]})]}),e.jsxs("div",{className:`trackpad-slider-row ${!t.enabled||!t.shiftTwoFingerOrbit?"disabled":""}`,children:[e.jsx("label",{children:a("terminal:controls.orbit")}),e.jsx("input",{type:"range",min:"0.1",max:"3",step:"0.1",value:t.sensitivity.orbit,onChange:l=>o("orbit",parseFloat(l.target.value)),disabled:!t.enabled||!t.shiftTwoFingerOrbit}),e.jsxs("span",{className:"trackpad-slider-value",children:[t.sensitivity.orbit.toFixed(1),"x"]})]})]})]})]})}export{oe as ControlsModal};
|