tide-commander 1.69.0 → 1.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/assets/{BossLogsModal-CMDdkhTL.js → BossLogsModal-BsOGAk9j.js} +1 -1
  2. package/dist/assets/{BossSpawnModal-C7lw2Wzh.js → BossSpawnModal-BiQgeh5g.js} +1 -1
  3. package/dist/assets/{ControlsModal-BtJJYkcM.js → ControlsModal-rRm2EyLt.js} +1 -1
  4. package/dist/assets/{DockerLogsModal-Lw19ZQVz.js → DockerLogsModal-DOJuVWO5.js} +1 -1
  5. package/dist/assets/{EmbeddedEditor-UwKqvTkJ.js → EmbeddedEditor-DSMa-_pv.js} +1 -1
  6. package/dist/assets/{GmailOAuthSetup-BOlxzJ7D.js → GmailOAuthSetup-BcXXMAz0.js} +1 -1
  7. package/dist/assets/{GoogleOAuthSetup-DYvaSFQp.js → GoogleOAuthSetup-Dz6GJobg.js} +1 -1
  8. package/dist/assets/{IframeModal-DRJROx67.js → IframeModal-JzopEsaR.js} +1 -1
  9. package/dist/assets/{IntegrationsPanel-Bp1O-I5s.js → IntegrationsPanel-Csc5cKbJ.js} +2 -2
  10. package/dist/assets/{LogViewerModal-BIlhbii5.js → LogViewerModal-nLCP_OiC.js} +1 -1
  11. package/dist/assets/{MonitoringModal-CuDrTaVn.js → MonitoringModal-DWAF5qrY.js} +1 -1
  12. package/dist/assets/{PM2LogsModal-C1VLY7hc.js → PM2LogsModal-CMjRymzO.js} +1 -1
  13. package/dist/assets/{RestoreArchivedAreaModal-ObvIYj2V.js → RestoreArchivedAreaModal-CE6qum43.js} +1 -1
  14. package/dist/assets/{Scene2DCanvas-BM_GFevb.js → Scene2DCanvas-C_jzVCus.js} +1 -1
  15. package/dist/assets/{SceneManager-FeZQ9HI1.js → SceneManager-DJi4cg4u.js} +1 -1
  16. package/dist/assets/{SkillsPanel-CtFwVaQj.js → SkillsPanel-CICFRA3e.js} +1 -1
  17. package/dist/assets/SpawnModal-DbMA6ZCI.js +1 -0
  18. package/dist/assets/{SubordinateAssignmentModal-aDkxc3YR.js → SubordinateAssignmentModal-S5pOdh3o.js} +1 -1
  19. package/dist/assets/{TriggerManagerPanel-CQxcjiJu.js → TriggerManagerPanel-_2o_eFr0.js} +1 -1
  20. package/dist/assets/{WorkflowEditorPanel-D_8Bnuzv.js → WorkflowEditorPanel-CG_rbU3P.js} +1 -1
  21. package/dist/assets/index-4VITMkmG.css +1 -0
  22. package/dist/assets/{index-BIkn0arf.js → index-AbUJ8e_m.js} +3 -3
  23. package/dist/assets/index-BM1t8tTI.js +2 -0
  24. package/dist/assets/{index-BMayWtlQ.js → index-BTg-aafr.js} +1 -1
  25. package/dist/assets/{index-9Bftos7u.js → index-BjRsxWRo.js} +4 -4
  26. package/dist/assets/{index-K0KrIo24.js → index-CG9ZWXHv.js} +3 -3
  27. package/dist/assets/{index-YH8hJh62.js → index-COtpp3Go.js} +2 -2
  28. package/dist/assets/{index-BYR78OCI.js → index-DL5oZ7JS.js} +1 -1
  29. package/dist/assets/{index-Br8WLiXq.js → index-LOZw5AOm.js} +1 -1
  30. package/dist/assets/{index-CX4tk_vI.js → index-XfOLLSJr.js} +1 -1
  31. package/dist/assets/{main--_0rf6yB.js → main-C-iXDssE.js} +10 -10
  32. package/dist/assets/{web-Dn-wQDim.js → web-C_fa0QQi.js} +1 -1
  33. package/dist/assets/{web-BuuzpQy3.js → web-xu-du3ss.js} +1 -1
  34. package/dist/index.html +1 -1
  35. package/dist/src/packages/server/claude/runner.js +42 -33
  36. package/dist/src/packages/server/codex/backend.js +5 -0
  37. package/dist/src/packages/server/services/runtime-command-execution.js +29 -12
  38. package/dist/src/packages/shared/agent-types.js +8 -0
  39. package/package.json +1 -1
  40. package/dist/assets/SpawnModal-37ChIpU2.js +0 -1
  41. package/dist/assets/index-D8fn_Wjl.js +0 -1
  42. package/dist/assets/index-DDfjGtDT.css +0 -1
@@ -1 +1 @@
1
- import{b_ as s}from"./main--_0rf6yB.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class l 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{l as LocalNotificationsWeb};
1
+ import{b$ as s}from"./main-C-iXDssE.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class l 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{l as LocalNotificationsWeb};
@@ -1 +1 @@
1
- import{b_ as a}from"./main--_0rf6yB.js";import{ImpactStyle as i,NotificationType as r}from"./index-YH8hJh62.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class h 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{h as HapticsWeb};
1
+ import{b$ as a}from"./main-C-iXDssE.js";import{ImpactStyle as i,NotificationType as r}from"./index-COtpp3Go.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class h 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{h as HapticsWeb};
package/dist/index.html CHANGED
@@ -22,7 +22,7 @@
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--_0rf6yB.js"></script>
25
+ <script type="module" crossorigin src="/assets/main-C-iXDssE.js"></script>
26
26
  <link rel="modulepreload" crossorigin href="/assets/vendor-react--Eh9ivFN.js">
27
27
  <link rel="modulepreload" crossorigin href="/assets/vendor-three-Chj50gSY.js">
28
28
  <link rel="stylesheet" crossorigin href="/assets/main-BXDdkAuE.css">
@@ -305,26 +305,33 @@ export class ClaudeRunner {
305
305
  log.error(`❌ [SEND_MESSAGE] No active process for agent ${agentId}`);
306
306
  return false;
307
307
  }
308
- // tmux mode: send via tmux send-keys — EXCEPT for backends that close stdin
309
- // after the initial prompt (codex). Those are launched as `cat <file> | codex`
310
- // so codex's stdin is the pipe, NOT the tmux pane. Once cat hits EOF, codex
311
- // gets EOF; tmux send-keys would write to a pane codex isn't reading. We must
312
- // queue those messages and deliver them via respawn-with-session-resume
313
- // triggered by the watchdog_missing_process handler when the session dies.
314
- // Also queue mid-turn messages for all backends — send-keys mid-turn is
315
- // unreliable and can interfere with the current prompt being processed.
308
+ // tmux mode dispatch:
309
+ // - Stdin-closed backends (codex, opencode) MUST queue. They were
310
+ // launched as `cat <file> | codex …` so their stdin is the pipe, not
311
+ // the tmux pane. Once cat hits EOF they receive EOF; tmux send-keys
312
+ // would write to a pane they aren't reading. Delivery happens via
313
+ // respawn-with-session-resume when the session dies (handled by the
314
+ // watchdog_missing_process branch).
315
+ // - Stdin-open backends (claude) are launched as
316
+ // `(cat <file>; cat) | claude --input-format stream-json …` — the
317
+ // trailing `cat` reads from the tmux pane, so send-keys writes are
318
+ // fed to claude's stdin as additional stream-json lines. Claude
319
+ // handles mid-turn `{type:"user",…}` messages natively (queues them
320
+ // internally for post-turn or injects them per its own protocol), so
321
+ // we write immediately regardless of turnState instead of blocking
322
+ // the user until step_complete.
316
323
  if (activeProcess.tmuxSession) {
317
324
  const tmuxTurnState = activeProcess.turnState || 'processing';
318
325
  const tmuxBackendClosesStdin = this.backend.shouldCloseStdinAfterPrompt?.() === true;
319
- if (tmuxTurnState === 'processing' || tmuxBackendClosesStdin) {
326
+ if (tmuxBackendClosesStdin) {
320
327
  const queue = this.messageQueue.get(agentId) ?? [];
321
328
  queue.push(message);
322
329
  this.messageQueue.set(agentId, queue);
323
- log.log(`📋 [QUEUE-TMUX] Agent ${agentId}: queued message (turnState=${tmuxTurnState}, closesStdin=${tmuxBackendClosesStdin}, queue=${queue.length}, ${message.length} chars)`);
330
+ log.log(`📋 [QUEUE-TMUX] Agent ${agentId}: queued message (stdin-closed backend, turnState=${tmuxTurnState}, queue=${queue.length}, ${message.length} chars)`);
324
331
  return true;
325
332
  }
326
333
  const stdinInput = this.backend.formatStdinInput(message);
327
- log.log(`📨 [SEND_MESSAGE] Agent ${agentId} (tmux mode), sending via tmux send-keys (${stdinInput.length} chars)`);
334
+ log.log(`📨 [SEND_MESSAGE] Agent ${agentId} (tmux, turnState=${tmuxTurnState}), sending via tmux send-keys (${stdinInput.length} chars)`);
328
335
  const ok = sendToTmux(agentId, stdinInput);
329
336
  if (ok) {
330
337
  activeProcess.turnState = 'processing';
@@ -334,35 +341,37 @@ export class ClaudeRunner {
334
341
  const turnState = activeProcess.turnState || 'processing';
335
342
  const messageLen = message.length;
336
343
  const backendClosesStdin = this.backend.shouldCloseStdinAfterPrompt?.() === true;
337
- // Queue mid-turn messages BEFORE any stdin-writability check. Writing to the OS
338
- // stdin pipe mid-turn is unreliable on all backends (async callback + possible
339
- // pipe close), and backends like codex/opencode explicitly close stdin after the
340
- // initial prompt so there is nothing to write to at all. For stdin-closed backends
341
- // we queue regardless of turnState — there is a race window between step_complete
342
- // (turnState flips to 'waiting_for_input') and process exit where direct stdin
343
- // write would fail, the fallthrough path SIGINTs the old process, and the
344
- // respawn-with-queue path is skipped (cleanTurnEnd requires a clean exit).
345
- // The queue is the source of truth; drain happens after the current turn ends
346
- // (via stdin for stdin-open backends, or via session-resume respawn for
347
- // stdin-closed ones).
348
- if (turnState === 'processing' || backendClosesStdin) {
344
+ // Stdin-closed backends (codex, opencode) MUST always queue: there is
345
+ // literally no open stdin to write to after the initial prompt.
346
+ // sendCommand's interrupt-and-restart branch handles mid-turn prompts for
347
+ // these by stopping+respawning; this queue catches the narrow
348
+ // step_complete/process_exit race window where respawn is the only
349
+ // delivery path (cleanTurnEnd in runner.ts:248 picks it up).
350
+ if (backendClosesStdin) {
349
351
  const queue = this.messageQueue.get(agentId) ?? [];
350
352
  queue.push(message);
351
353
  this.messageQueue.set(agentId, queue);
352
- log.log(`📋 [QUEUE] Agent ${agentId}: queued message for post-turn delivery (turnState=${turnState}, closesStdin=${backendClosesStdin}, queue=${queue.length}, ${messageLen} chars)`);
354
+ log.log(`📋 [QUEUE] Agent ${agentId}: queued message for respawn delivery (stdin-closed backend, turnState=${turnState}, queue=${queue.length}, ${messageLen} chars)`);
353
355
  return true;
354
356
  }
355
- // Agent is waiting for input: send directly via stdin (immediate processing)
357
+ // Stdin-open backends (claude): write directly regardless of turnState.
358
+ // Claude's --input-format stream-json accepts additional
359
+ // {type:"user",...} JSON lines at any time and interleaves them with the
360
+ // current turn per its own protocol. Blocking on 'waiting_for_input'
361
+ // previously made the user wait for step_complete before Claude even saw
362
+ // the message; now it goes straight to Claude's stdin.
356
363
  const stdin = activeProcess.process.stdin;
357
- if (!stdin) {
358
- log.error(`❌ [SEND_MESSAGE] stdin is null for agent ${agentId}`);
359
- return false;
360
- }
361
- if (!stdin.writable) {
362
- log.error(`❌ [SEND_MESSAGE] stdin is not writable for agent ${agentId} (destroyed: ${stdin.destroyed}, closed: ${stdin.closed})`);
363
- return false;
364
+ if (!stdin || !stdin.writable) {
365
+ // Defensive fallback: if stdin unexpectedly isn't writable (pipe
366
+ // closed, process dying), queue so the respawn path can recover the
367
+ // message instead of dropping it.
368
+ log.warn(`⚠️ [SEND_MESSAGE] Agent ${agentId}: stdin not writable (stdin=${!!stdin}, writable=${stdin?.writable}); queueing for recovery path (turnState=${turnState}, ${messageLen} chars)`);
369
+ const queue = this.messageQueue.get(agentId) ?? [];
370
+ queue.push(message);
371
+ this.messageQueue.set(agentId, queue);
372
+ return true;
364
373
  }
365
- log.log(`📨 [SEND_MESSAGE] Agent ${agentId} is idle (turnState=${turnState}), sending directly via stdin (${messageLen} chars)`);
374
+ log.log(`📨 [SEND_MESSAGE] Agent ${agentId} (turnState=${turnState}), sending directly via stdin (${messageLen} chars)`);
366
375
  return this.writeToStdin(agentId, activeProcess, message);
367
376
  }
368
377
  /**
@@ -85,6 +85,11 @@ export class CodexBackend {
85
85
  if (codexConfig?.profile) {
86
86
  args.push('--profile', codexConfig.profile);
87
87
  }
88
+ if (codexConfig?.reasoningEffort) {
89
+ // Pass as a two-arg pair so the spawned process receives the flag and
90
+ // value as separate argv entries — no shell-level quoting needed.
91
+ args.push('-c', `model_reasoning_effort=${codexConfig.reasoningEffort}`);
92
+ }
88
93
  if (config.workingDir) {
89
94
  args.push('-C', config.workingDir);
90
95
  }
@@ -69,10 +69,29 @@ export function createRuntimeCommandExecution(deps) {
69
69
  }
70
70
  const processRunning = runner.isRunning(agentId);
71
71
  // For backends that close stdin after the initial prompt (codex, opencode),
72
- // a new user prompt arriving mid-turn should INTERRUPT the current work and
73
- // RESTART the session with the new prompt — not wait for the current turn
74
- // to finish and then deliver the queued message via session-resume (which
75
- // is the default queue-based behavior for these backends).
72
+ // a new user prompt arriving while the process is alive should INTERRUPT
73
+ // the current work and RESTART the session with the new prompt — not wait
74
+ // for the current turn to finish and then deliver the queued message via
75
+ // session-resume (which is the default queue-based behavior).
76
+ //
77
+ // Why no turnState gate: stdin is closed, so there's literally no way to
78
+ // deliver a follow-up prompt without respawning. 'waiting_for_input' is
79
+ // also not a reliable "turn is over" signal across these backends —
80
+ // opencode's NDJSON emits `step_finish` per LLM step (see
81
+ // src/packages/server/opencode/json-event-parser.ts:197-207), so during a
82
+ // single conversational turn the runner's turnState oscillates
83
+ // processing → waiting_for_input → processing → … between steps. Gating
84
+ // on 'waiting_for_input' would strand the new prompt on those mid-turn
85
+ // windows: sendMessage would queue it, but the process isn't exiting
86
+ // (it's starting the next step), so the queue-respawn path never fires.
87
+ // Codex happens to emit `step_complete` once per turn (via
88
+ // src/packages/server/codex/json-event-parser.ts:300-301), so the old
89
+ // gate looked fine there — but the correct invariant for ALL stdin-closed
90
+ // backends is: process-alive + new-prompt ⇒ interrupt + respawn.
91
+ //
92
+ // SIGINT on a process already at true turn-end (about to exit cleanly on
93
+ // its own) is harmless — process-lifecycle's stop() just short-circuits
94
+ // the natural exit, and the fresh spawn still resumes the same sessionId.
76
95
  //
77
96
  // Safe for tmux mode: runner.stop() routes through
78
97
  // src/packages/server/claude/runner/process-lifecycle.ts:281-284 which
@@ -86,14 +105,12 @@ export function createRuntimeCommandExecution(deps) {
86
105
  const backendClosesStdin = runner.closesStdinAfterPrompt?.() === true;
87
106
  if (processRunning && backendClosesStdin && !forceNewSession) {
88
107
  const turnState = runner.getTurnState?.(agentId);
89
- if (turnState !== 'waiting_for_input') {
90
- log.log(`[sendCommand] Agent ${agentId} (${agent.provider}): mid-turn prompt (turnState=${turnState ?? 'unknown'}) interrupting current work and restarting session with new prompt`);
91
- emitOutput(agentId, '🛑 [System] Interrupting current work to process new prompt…', false, undefined, 'system-interrupt-restart');
92
- await runner.stop(agentId, true);
93
- agentService.updateAgent(agentId, { taskCount: (agent.taskCount || 0) + 1 });
94
- await executeCommand(agentId, command, systemPrompt, forceNewSession, customAgent);
95
- return;
96
- }
108
+ log.log(`[sendCommand] Agent ${agentId} (${agent.provider}): in-flight prompt (turnState=${turnState ?? 'unknown'}) — interrupting current work and restarting session with new prompt`);
109
+ emitOutput(agentId, '🛑 [System] Interrupting current work to process new prompt…', false, undefined, 'system-interrupt-restart');
110
+ await runner.stop(agentId, true);
111
+ agentService.updateAgent(agentId, { taskCount: (agent.taskCount || 0) + 1 });
112
+ await executeCommand(agentId, command, systemPrompt, forceNewSession, customAgent);
113
+ return;
97
114
  }
98
115
  if (processRunning && !forceNewSession) {
99
116
  if (runner.supportsStdin()) {
@@ -16,6 +16,14 @@ export const PERMISSION_MODES = {
16
16
  bypass: { label: 'Permissionless', description: 'Skip all permission prompts (less safe, faster)' },
17
17
  interactive: { label: 'Interactive', description: 'Ask for approval before sensitive operations' },
18
18
  };
19
+ export const CODEX_REASONING_EFFORTS = {
20
+ none: { label: 'None', description: 'No reasoning', icon: '⚪' },
21
+ minimal: { label: 'Minimal', description: 'Least reasoning, fastest', icon: '💨' },
22
+ low: { label: 'Low', description: 'Light reasoning', icon: '🏃' },
23
+ medium: { label: 'Medium', description: 'Balanced reasoning', icon: '⚖️' },
24
+ high: { label: 'High', description: 'Deep reasoning', icon: '🔬' },
25
+ xhigh: { label: 'X-High', description: 'Extra-high reasoning, slowest', icon: '🧠' },
26
+ };
19
27
  export const CODEX_MODELS = {
20
28
  'gpt-5.5': {
21
29
  label: 'GPT-5.5',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tide-commander",
3
- "version": "1.69.0",
3
+ "version": "1.70.0",
4
4
  "description": "Visual multi-agent orchestrator and manager for Claude Code with 3D/2D interface",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1 +0,0 @@
1
- import{u as Ve,ar as Ze,as as es,at as ss,au as as,r as t,C as ye,S as ne,av as te,A as Ae,l as le,aw as ns,s as S,h as ts,j as s,ax as ls,N as De,ay as x,az as os,aA as oe,I as ie,ac as T,aa as K,aB as is,ab as ce,aC as cs,E as rs}from"./main--_0rf6yB.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";function Ee(r,g){const b=g.filter(C=>!r.has(C));return b.length===0?`${g[Math.floor(Math.random()*g.length)]}-${Date.now()%1e3}`:b[Math.floor(Math.random()*b.length)]}function us({isOpen:r,onClose:g,onSpawnStart:b,onSpawnEnd:C,spawnPosition:Ie,spawnAreaId:N}){const{t:a}=Ve(["terminal","common"]),P=Ze(),p=es(),re=ss(),H=re.length>0?re:as,[m,v]=t.useState(""),[M,F]=t.useState(()=>ye(ne.LAST_CWD)),[i,k]=t.useState("scout"),[de,E]=t.useState(!1),[Le,z]=t.useState(!1),[pe,J]=t.useState(!1),[me,ue]=t.useState(""),[y,Y]=t.useState([]),[A,R]=t.useState(null),[_e,he]=t.useState(!1),[I,we]=t.useState(""),[h,$e]=t.useState(""),[U,Te]=t.useState(!1),[q,Pe]=t.useState("bypass"),[o,X]=t.useState("claude"),[j,L]=t.useState({fullAuto:!0,sandbox:"workspace-write",approvalMode:"on-request",search:!1}),[xe,Q]=t.useState(new Set),[V,fe]=t.useState("opus[1m]"),[Z,ge]=t.useState("xHigh"),[ee,Fe]=t.useState("gpt-5.3-codex"),[se,ze]=t.useState("minimax/MiniMax-M1-80k"),[je,Re]=t.useState(""),[D,Ue]=t.useState(""),O=t.useRef(null),Ne=t.useRef(!1),_=t.useCallback(()=>{window.__spawnModalAreaContext=null},[]),w=t.useMemo(()=>P.filter(e=>e.enabled),[P]),qe=["full-notifications","streaming-exec","task-label","report-task-to-boss","agent-tracking","send-message-to-agent"];t.useEffect(()=>{if(r&&!Ne.current){if(w.length>0){const l=w.filter(c=>qe.includes(c.slug)).map(c=>c.id);l.length>0&&Q(new Set(l))}const n=ye(ne.DEFAULT_AGENT_CLASS);if(n==="random"){const c=[...Object.keys(cs),...p.map(u=>u.id)];k(c[Math.floor(Math.random()*c.length)])}else k(n||"scout")}Ne.current=r},[r,w,p]);const ve=t.useMemo(()=>{if(!D.trim())return w;const e=D.toLowerCase();return w.filter(n=>n.name.toLowerCase().includes(e)||n.description.toLowerCase().includes(e)||n.slug.toLowerCase().includes(e))},[w,D]),Oe=t.useCallback(e=>{Q(n=>{const l=new Set(n);return l.has(e)?l.delete(e):l.add(e),l})},[]);t.useMemo(()=>w.filter(e=>e.assignedAgentClasses.includes(i)),[w,i]);const We=t.useMemo(()=>{var n;const e=p.find(l=>l.id===i);return(n=e==null?void 0:e.defaultSkillIds)!=null&&n.length?P.filter(l=>e.defaultSkillIds.includes(l.id)):[]},[p,i,P]),Se=t.useMemo(()=>{if(!I.trim())return y;const e=I.toLowerCase();return y.filter(n=>n.sessionId.toLowerCase().includes(e)||n.projectPath.toLowerCase().includes(e)||n.firstMessage&&n.firstMessage.toLowerCase().includes(e))},[y,I]),W=t.useMemo(()=>{if(!h.trim())return p;const e=h.toLowerCase();return p.filter(n=>n.name.toLowerCase().includes(e)||n.description.toLowerCase().includes(e)||n.id.toLowerCase().includes(e))},[p,h]),B=t.useMemo(()=>{if(!h.trim())return te;const e=h.toLowerCase();return te.filter(n=>{const l=Ae[n.id];return n.name.toLowerCase().includes(e)||n.id.toLowerCase().includes(e)||l.description.toLowerCase().includes(e)})},[h]);t.useEffect(()=>{if(!r||!h.trim())return;const e=[...W.map(n=>n.id),...B.map(n=>n.id)];e.length===1&&e[0]!==i&&k(e[0])},[r,h,W,B,i]);const d=t.useMemo(()=>p.find(e=>e.id===i),[p,i]),Be=t.useMemo(()=>{if(d!=null&&d.model)return d.model},[d]),Ge=t.useMemo(()=>{if(d!=null&&d.customModelPath)return le(`/api/custom-models/${d.id}`)},[d]),Ke=d==null?void 0:d.modelScale,He=t.useMemo(()=>d?"scout":i,[i,d]),G=t.useCallback(async e=>{he(!0);try{const n=e?le(`/api/agents/claude-sessions?cwd=${encodeURIComponent(e)}`):le("/api/agents/claude-sessions"),c=await(await ns(n)).json();Y(c.sessions||[])}catch(n){console.error("Failed to fetch sessions:",n),Y([])}finally{he(!1)}},[]);t.useEffect(()=>{r?G(M||void 0):(Y([]),R(null),we(""))},[r,G]),t.useEffect(()=>{if(!r)return;const e=setTimeout(()=>{G(M||void 0),R(null)},300);return()=>clearTimeout(e)},[M,r,G]),t.useEffect(()=>{if(!r||!N)return;const e=S.getState().areas.get(N);if(e!=null&&e.directories&&e.directories.length>0){F(e.directories[0]);return}const n=Array.from(S.getState().agents.values()).filter(f=>{var $;return(($=S.getAreaForAgent(f.id))==null?void 0:$.id)===N&&f.cwd});if(n.length===0)return;const l=new Map;for(const f of n)l.set(f.cwd,(l.get(f.cwd)||0)+1);let c="",u=0;for(const[f,$]of l)$>u&&(c=f,u=$);c&&F(c)},[r,N]),t.useEffect(()=>{if(r){const e=new Set(Array.from(S.getState().agents.values()).map(u=>u.name)),n=Ee(e,H),l=p.find(u=>u.id===i),c=l?`${l.name} ${n}`:n;v(c),O.current&&(O.current.focus(),O.current.select())}},[r,H]),t.useEffect(()=>{if(!r)return;const e=p.find(n=>n.id===i);if(e){const n=p.find(l=>m.startsWith(l.name+" "));if(n){const l=m.substring(n.name.length+1);v(`${e.name} ${l}`)}else v(`${e.name} ${m}`)}else{const n=p.find(l=>m.startsWith(l.name+" "));if(n){const l=m.substring(n.name.length+1);v(l)}}},[i]),t.useEffect(()=>{i==="boss"&&fe("claude-opus-4-7")},[i]);const Je=()=>{var c;console.log("[SpawnModal] handleSpawn called"),z(!1);const e=A&&((c=y.find(u=>u.sessionId===A))==null?void 0:c.projectPath)||M;if(console.log("[SpawnModal] Effective CWD:",e),console.log("[SpawnModal] Agent name:",m),console.log("[SpawnModal] Agent class:",i),console.log("[SpawnModal] Permission mode:",q),console.log("[SpawnModal] Provider:",o),console.log("[SpawnModal] Use Chrome:",U),console.log("[SpawnModal] Session ID:",A||"none"),!e.trim()){console.error("[SpawnModal] Empty CWD, showing error"),z(!0);return}if(!m.trim()){console.log("[SpawnModal] Empty name, regenerating");const u=new Set(Array.from(S.getState().agents.values()).map(f=>f.name));v(Ee(u,H));return}rs(ne.LAST_CWD,e),E(!0),b();const n=Array.from(xe),l=je.trim()||void 0;console.log("[SpawnModal] Calling store.spawnAgent with:",{name:m.trim(),class:i,cwd:e.trim(),sessionId:A||void 0,useChrome:o==="claude"?U:!1,permissionMode:q,provider:o,codexConfig:o==="codex"?j:void 0,codexModel:o==="codex"?ee:void 0,opencodeModel:o==="opencode"?se:void 0,initialSkillIds:n,model:o==="claude"?V:void 0,customInstructions:l?`${l.length} chars`:void 0,spawnAreaId:N||void 0}),window.__spawnModalAreaContext=N?{areaId:N}:null,S.spawnAgent(m.trim(),i,e.trim(),Ie||void 0,A||void 0,o==="claude"?U:!1,q,n,o,o==="codex"?j:void 0,o==="codex"?ee:void 0,o==="claude"?V:void 0,l,o==="claude"?Z:void 0,o==="opencode"?se:void 0)},be=()=>{console.log("[SpawnModal] Agent creation successful"),E(!1),v(""),Q(new Set),_(),C(),g()},Ce=()=>{console.error("[SpawnModal] Agent creation failed"),E(!1),z(!0),_(),C()},Me=e=>{console.log("[SpawnModal] Directory not found:",e),E(!1),ue(e),J(!0),C()},ke=()=>{J(!1),E(!0),b(),S.createDirectoryAndSpawn(me,m.trim(),i)},ae=()=>{J(!1),ue(""),_()};t.useEffect(()=>(window.__spawnModalSuccess=be,window.__spawnModalError=Ce,window.__spawnModalDirNotFound=Me,()=>{_(),delete window.__spawnModalSuccess,delete window.__spawnModalError,delete window.__spawnModalDirNotFound}),[m,i,be,Ce,Me,_]);const{handleMouseDown:Ye,handleClick:Xe}=ts(g),Qe=e=>{e.key==="Escape"&&g()};return!r&&!pe?null:pe?s.jsx("div",{className:"modal-overlay visible",onClick:ae,onKeyDown:e=>{e.key==="Escape"&&ae(),e.key==="Enter"&&ke()},children:s.jsxs("div",{className:"modal confirm-modal",onClick:e=>e.stopPropagation(),children:[s.jsx("div",{className:"modal-header",children:a("terminal:spawn.directoryNotFound")}),s.jsxs("div",{className:"modal-body confirm-modal-body",children:[s.jsx("p",{children:a("terminal:spawn.directoryNotExist")}),s.jsx("code",{className:"confirm-modal-path",children:me}),s.jsx("p",{children:a("terminal:spawn.wouldYouCreate")})]}),s.jsxs("div",{className:"modal-footer",children:[s.jsx("button",{className:"btn btn-secondary",onClick:ae,children:a("common:buttons.cancel")}),s.jsx("button",{className:"btn btn-primary",onClick:ke,autoFocus:!0,children:a("terminal:spawn.createDirectory")})]})]})}):s.jsx("div",{className:`modal-overlay ${r?"visible":""}`,onMouseDown:Ye,onClick:Xe,onKeyDown:Qe,children:s.jsxs("div",{className:"modal spawn-modal",children:[s.jsx("div",{className:"modal-header",children:a("terminal:spawn.deployTitle")}),s.jsxs("div",{className:"modal-body spawn-modal-body",children:[s.jsxs("div",{className:"spawn-top-section",children:[s.jsx("div",{className:"spawn-preview-compact",children:s.jsx(ls,{agentClass:He,modelFile:Be,customModelUrl:Ge,modelScale:Ke,width:100,height:120})}),s.jsxs("div",{className:"spawn-class-section",children:[s.jsx("div",{className:"spawn-class-label",children:a("terminal:spawn.agentClass")}),p.length+te.length>6&&s.jsx("input",{type:"text",className:"spawn-input class-search-input",placeholder:a("terminal:spawn.filterClasses"),value:h,onChange:e=>$e(e.target.value)}),s.jsxs("div",{className:"class-selector-inline",children:[W.map(e=>s.jsxs("button",{className:`class-chip ${i===e.id?"selected":""}`,onClick:()=>k(e.id),title:e.description,children:[s.jsx(De,{classId:e.id,size:18,className:"class-chip-icon"}),s.jsx("span",{className:"class-chip-name",children:e.name})]},e.id)),B.map(e=>{const n=Ae[e.id];return s.jsxs("button",{className:`class-chip ${i===e.id?"selected":""}`,onClick:()=>k(e.id),title:n.description,children:[s.jsx(De,{classId:e.id,size:18,className:"class-chip-icon"}),s.jsx("span",{className:"class-chip-name",children:e.name})]},e.id)}),h&&W.length===0&&B.length===0&&s.jsx("div",{className:"class-search-empty",children:a("terminal:spawn.noClassesMatch",{query:h})})]})]})]}),s.jsxs("div",{className:"spawn-form-section",children:[s.jsxs("div",{className:"spawn-form-row",children:[s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:a("common:labels.name")}),s.jsx("input",{ref:O,type:"text",className:"spawn-input",placeholder:a("terminal:spawn.agentNamePlaceholder"),value:m,onChange:e=>v(e.target.value)})]}),s.jsxs("div",{className:"spawn-field spawn-field-wide",children:[s.jsxs("label",{className:"spawn-label",children:[a("terminal:spawn.workingDir"),s.jsx(x,{text:a("terminal:spawn.helpWorkingDir"),title:a("terminal:spawn.workingDir"),position:"top",size:"sm"})]}),s.jsx(os,{value:M,onChange:e=>{F(e),z(!1)},placeholder:a("terminal:spawn.workingDirPlaceholder"),className:`spawn-input ${Le?"error":""}`,directoriesOnly:!0})]})]}),s.jsxs("div",{className:"spawn-form-row",children:[s.jsxs("div",{className:"spawn-field",children:[s.jsxs("label",{className:"spawn-label",children:[a("terminal:spawn.selectRuntime"),s.jsx(x,{text:a("terminal:spawn.helpRuntime"),title:a("terminal:spawn.runtimeTitle"),position:"top",size:"sm"})]}),s.jsxs("div",{className:"spawn-select-row",children:[s.jsxs("button",{className:`spawn-select-btn ${o==="claude"?"selected":""}`,onClick:()=>X("claude"),title:a("terminal:spawn.useClaudeCli"),children:[s.jsx("img",{src:"/assets/claude.ico",alt:"Claude",className:"spawn-provider-icon"}),s.jsx("span",{children:"Claude"})]}),s.jsxs("button",{className:`spawn-select-btn ${o==="codex"?"selected":""}`,onClick:()=>X("codex"),title:a("terminal:spawn.useCodexCli"),children:[s.jsx("img",{src:"/assets/codex.ico",alt:"Codex",className:"spawn-provider-icon"}),s.jsx("span",{children:"Codex"})]}),s.jsxs("button",{className:`spawn-select-btn spawn-select-btn--opencode ${o==="opencode"?"selected":""}`,onClick:()=>X("opencode"),title:"Use OpenCode CLI (multi-provider)",children:[s.jsx("img",{src:"/assets/opencode.svg",alt:"OpenCode",className:"spawn-provider-icon"}),s.jsx("span",{children:"OpenCode"})]})]})]}),s.jsxs("div",{className:"spawn-field",children:[s.jsxs("label",{className:"spawn-label",children:[a("common:labels.permissions"),s.jsx(x,{text:a("terminal:spawn.helpPermission"),title:a("terminal:spawn.permissionMode"),position:"top",size:"sm"})]}),s.jsx("div",{className:"spawn-select-row",children:Object.keys(oe).map(e=>s.jsxs("button",{className:`spawn-select-btn ${q===e?"selected":""}`,onClick:()=>Pe(e),title:oe[e].description,children:[s.jsx("span",{children:s.jsx(ie,{name:e==="bypass"?"bolt":"lock",size:12})}),s.jsx("span",{children:oe[e].label})]},e))})]})]}),s.jsx("div",{className:"spawn-form-row",children:s.jsxs("div",{className:"spawn-field",children:[s.jsxs("label",{className:"spawn-label",children:[a("common:labels.model"),s.jsx(x,{text:a("terminal:spawn.helpModel"),title:a("terminal:spawn.modelTitle"),position:"top",size:"sm"})]}),o==="claude"?s.jsx("div",{className:"spawn-select-row spawn-select-row--wrap",children:Object.keys(T).filter(e=>!T[e].deprecated).map(e=>s.jsxs("button",{className:`spawn-select-btn ${V===e?"selected":""}`,onClick:()=>fe(e),title:T[e].description,children:[s.jsx("span",{children:T[e].icon}),s.jsx("span",{children:T[e].label})]},e))}):o==="codex"?s.jsx("div",{className:"spawn-select-row spawn-select-row--codex-models",children:Object.keys(K).map(e=>s.jsxs("button",{className:`spawn-select-btn ${ee===e?"selected":""}`,onClick:()=>Fe(e),title:K[e].description,children:[s.jsx("span",{children:K[e].icon}),s.jsx("span",{children:K[e].label})]},e))}):o==="opencode"?s.jsx(is,{value:se,onChange:ze,inputId:"spawn-opencode-model"}):s.jsx("div",{className:"spawn-inline-hint",children:a("terminal:spawn.chooseCodexModel")})]})}),s.jsxs("div",{className:"spawn-form-row",children:[o==="claude"&&s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:"Effort"}),s.jsxs("div",{className:"spawn-select-row spawn-select-row--effort",children:[s.jsx("button",{className:`spawn-select-btn spawn-select-btn--compact ${Z===void 0?"selected":""}`,onClick:()=>ge(void 0),title:"Use default effort level",children:s.jsx("span",{children:"Default"})}),Object.keys(ce).map(e=>s.jsx("button",{className:`spawn-select-btn spawn-select-btn--compact ${Z===e?"selected":""}`,onClick:()=>ge(e),title:ce[e].description,children:s.jsx("span",{children:ce[e].label})},e))]})]}),s.jsxs("div",{className:"spawn-field",children:[s.jsx("label",{className:"spawn-label",children:a("terminal:spawn.browser")}),s.jsxs("label",{className:"spawn-checkbox",children:[s.jsx("input",{type:"checkbox",checked:U,onChange:e=>Te(e.target.checked),disabled:o!=="claude"}),s.jsxs("span",{children:[s.jsx(ie,{name:"globe",size:12})," ",a("terminal:spawn.chromeBrowser")]}),s.jsx(x,{text:a(o==="claude"?"terminal:spawn.helpChrome":"terminal:spawn.helpChromeDisabled"),title:a("terminal:spawn.chromeBrowser"),position:"top",size:"sm"})]})]})]}),o==="codex"&&s.jsxs("div",{className:"codex-config-section",children:[s.jsx("div",{className:"codex-config-title",children:a("terminal:spawn.codex.configuration")}),s.jsxs("div",{className:"codex-config-options",children:[s.jsxs("div",{className:"codex-option-group",children:[s.jsxs("label",{className:"spawn-checkbox",children:[s.jsx("input",{type:"checkbox",checked:j.fullAuto!==!1,onChange:e=>L(n=>({...n,fullAuto:e.target.checked}))}),s.jsx("span",{children:a("terminal:spawn.codex.fullAuto")}),s.jsx(x,{text:a("terminal:spawn.helpFullAuto"),title:a("terminal:spawn.fullAutoTitle"),position:"top",size:"sm"})]}),s.jsxs("label",{className:"spawn-checkbox",children:[s.jsx("input",{type:"checkbox",checked:!!j.search,onChange:e=>L(n=>({...n,search:e.target.checked}))}),s.jsx("span",{children:a("terminal:spawn.codex.search")}),s.jsx(x,{text:a("terminal:spawn.helpSearch"),title:a("terminal:spawn.searchTitle"),position:"top",size:"sm"})]})]}),j.fullAuto===!1&&s.jsxs("div",{className:"codex-option-group",children:[s.jsx("div",{className:"codex-option-header",children:a("terminal:spawn.codex.restrictions")}),s.jsxs("select",{className:"spawn-input codex-select",value:j.sandbox||"workspace-write",onChange:e=>L(n=>({...n,sandbox:e.target.value})),children:[s.jsxs("option",{value:"read-only",children:["📖 ",a("terminal:spawn.codex.sandboxReadOnly")]}),s.jsxs("option",{value:"workspace-write",children:["✏️ ",a("terminal:spawn.codex.sandboxWorkspaceWrite")]}),s.jsxs("option",{value:"danger-full-access",children:["⚡ ",a("terminal:spawn.codex.sandboxDangerFullAccess")]})]}),s.jsxs("select",{className:"spawn-input codex-select",value:j.approvalMode||"on-request",onChange:e=>L(n=>({...n,approvalMode:e.target.value})),children:[s.jsxs("option",{value:"untrusted",children:["🔒 ",a("terminal:spawn.codex.approvalsUntrusted")]}),s.jsxs("option",{value:"on-failure",children:["⚠️ ",a("terminal:spawn.codex.approvalsOnFailure")]}),s.jsxs("option",{value:"on-request",children:["🤔 ",a("terminal:spawn.codex.approvalsOnRequest")]}),s.jsxs("option",{value:"never",children:["✅ ",a("terminal:spawn.codex.approvalsNever")]})]})]}),s.jsxs("div",{className:"codex-option-group",children:[s.jsx("div",{className:"codex-option-header",children:a("terminal:spawn.codex.profile")}),s.jsx("input",{type:"text",className:"spawn-input codex-profile-input",placeholder:a("terminal:spawn.codex.profilePlaceholder"),value:j.profile||"",onChange:e=>L(n=>({...n,profile:e.target.value||void 0}))})]})]})]}),w.length>0&&s.jsxs("div",{className:"spawn-skills-section",children:[s.jsxs("label",{className:"spawn-label",children:[a("terminal:spawn.skills")," ",s.jsxs("span",{className:"spawn-label-hint",children:["(",a("common:labels.optional"),")"]}),s.jsx(x,{text:a("terminal:spawn.helpSkills"),title:a("terminal:spawn.skillsTitle"),position:"top",size:"sm"})]}),w.length>6&&s.jsx("input",{type:"text",className:"spawn-input skill-search-input",placeholder:a("terminal:spawn.filterSkills"),value:D,onChange:e=>Ue(e.target.value)}),s.jsxs("div",{className:"spawn-skills-inline",children:[ve.map(e=>{const n=xe.has(e.id);return We.some(c=>c.id===e.id)?null:s.jsxs("button",{className:`spawn-skill-chip ${n?"selected":""}`,onClick:()=>Oe(e.id),title:e.description,children:[n&&s.jsx("span",{className:"spawn-skill-check",children:s.jsx(ie,{name:"check",size:10})}),s.jsx("span",{children:e.name}),e.builtin&&s.jsx("span",{className:"spawn-skill-builtin",children:"TC"})]},e.id)}),D&&ve.length===0&&s.jsx("div",{className:"skill-search-empty",children:a("terminal:spawn.noSkillsMatch",{query:D})})]})]}),s.jsxs("div",{className:"spawn-custom-instructions-section",children:[s.jsxs("label",{className:"spawn-label",children:[a("terminal:spawn.customInstructions")," ",s.jsxs("span",{className:"spawn-label-hint",children:["(",a("common:labels.optional"),")"]}),s.jsx(x,{text:a("terminal:spawn.helpCustomInstructions"),title:a("terminal:spawn.customInstructions"),position:"top",size:"sm"})]}),s.jsx("textarea",{className:"spawn-input spawn-textarea",placeholder:a("terminal:spawn.customInstructionsPlaceholder"),value:je,onChange:e=>Re(e.target.value),rows:3})]}),s.jsxs("div",{className:"spawn-sessions-section",children:[s.jsxs("label",{className:"spawn-label",children:[a("terminal:spawn.linkSession")," ",s.jsxs("span",{className:"spawn-label-hint",children:["(",a("common:labels.optional"),")"]}),s.jsx(x,{text:a("terminal:spawn.helpLinkSession"),title:a("terminal:spawn.linkSessionTitle"),position:"top",size:"sm"})]}),y.length>0&&s.jsx("input",{type:"text",className:"spawn-input session-search-input",placeholder:a("terminal:spawn.searchSessions"),value:I,onChange:e=>we(e.target.value)}),s.jsx("div",{className:"sessions-list",children:_e?s.jsx("div",{className:"sessions-loading",children:a("terminal:spawn.loadingSessions")}):y.length===0?s.jsx("div",{className:"sessions-empty",children:a("terminal:spawn.noSessions")}):Se.length===0?s.jsx("div",{className:"sessions-empty",children:a("terminal:spawn.noSessionsMatch",{query:I})}):Se.map(e=>{const n=A===e.sessionId,l=Date.now()-new Date(e.lastModified).getTime(),c=l<6e4?a("common:time.justNow"):l<36e5?a("common:time.minutesAgo",{count:Math.floor(l/6e4)}):l<864e5?a("common:time.hoursAgo",{count:Math.floor(l/36e5)}):a("common:time.daysAgo",{count:Math.floor(l/864e5)});return s.jsxs("div",{className:`session-item ${n?"selected":""}`,onClick:()=>{n?R(null):(R(e.sessionId),F(e.projectPath))},children:[s.jsxs("div",{className:"session-item-header",children:[s.jsx("span",{className:"session-item-path",children:e.projectPath}),s.jsx("span",{className:"session-item-age",children:c})]}),s.jsx("div",{className:"session-item-preview",children:e.firstMessage||a("terminal:spawn.messagesCount",{count:e.messageCount})})]},e.sessionId)})})]})]})]}),s.jsxs("div",{className:"modal-footer",children:[s.jsx("button",{className:"btn btn-secondary",onClick:g,children:a("common:buttons.cancel")}),s.jsx("button",{className:"btn btn-primary",onClick:Je,disabled:de,children:a(de?"common:buttons.deploying":"common:buttons2.deploy")})]})]})})}export{us as SpawnModal};
@@ -1 +0,0 @@
1
- import{z as et,B as tt,r as s,C as We,S as N,E as Ue,G as De,H as ae,J as at,s as _,K as Ke,L as nt,v as st,w as rt,j as e,I as m,M as lt,N as qe,O as Ye,P as it,U as ot,V as ct,W as dt,X as pt,Y as mt,Z as ut,_ as ht,$ as ft,a0 as gt,a1 as _t,a2 as xt,a3 as bt,a4 as wt,a5 as jt,a6 as Nt,a7 as Ct,a8 as vt,a9 as kt,aa as At,ab as St,ac as Et}from"./main--_0rf6yB.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";const Mt=["simple","chat","advanced"],It={simple:"Simple",chat:"Chat",advanced:"Advanced"},yt={simple:"○",chat:"◐",advanced:"◉"},zt={simple:"Simple view — clean messages only",chat:"Chat view — assistant replies (no tool calls)",advanced:"Advanced view — everything including tools"},Xe="flat-clear-context";function Rt(u){const o=u.split("/").filter(Boolean);return o.length===0?u:o.slice(-2).join("/")}function Tt(u){if(u.provider==="codex"){const X=u.codexModel||"gpt-5.3-codex",b=At[X];return{model:(b==null?void 0:b.label)||X}}if(u.provider==="opencode")return{model:u.opencodeModel||"opencode"};const o=u.model||"sonnet",x=Et[o],k=u.effort,M=k?St[k]:void 0;return{model:(x==null?void 0:x.label)||o,effort:M==null?void 0:M.label}}function Pt(u,o){if(o.type==="rectangle"&&o.width&&o.height){const x=o.width/2,k=o.height/2;return u.x>=o.center.x-x&&u.x<=o.center.x+x&&u.z>=o.center.z-k&&u.z<=o.center.z+k}if(o.type==="circle"&&o.radius){const x=u.x-o.center.x,k=u.z-o.center.z;return x*x+k*k<=o.radius*o.radius}return!1}const $t=ht.memo(function({agentId:o,terminalViewMode:x,onTerminalViewModeChange:k,inspectorOpen:M,onToggleInspector:X,onImageClick:b,onFileClick:ne,onBashClick:se,onViewMarkdown:he,onRequestClearSubordinates:fe,onOpenBuilding:re,keyboard:le,canNavigateBack:ge,canNavigateForward:I,onNavigateBack:K,onNavigateForward:q,agentInfoOpen:G,onToggleAgentInfo:Ie}){var l,d,S,C;const p=ft(o),y=gt(),V=s.useRef(null),_e=s.useRef(null);s.useEffect(()=>{const a=_e.current;if(!a)return;const c=n=>{n.button===3?(n.preventDefault(),n.stopPropagation(),K()):n.button===4&&(n.preventDefault(),n.stopPropagation(),q())},i=n=>{(n.button===3||n.button===4)&&n.preventDefault()};return a.addEventListener("mouseup",c),a.addEventListener("mousedown",i),()=>{a.removeEventListener("mouseup",c),a.removeEventListener("mousedown",i)}},[K,q]);const Y=Ke(),Z=s.useMemo(()=>{if(!p)return null;const a=new Set,c=[];for(const i of Y.values())i.archived||i.directories.length===0||i.assignedAgentIds.includes(o)&&(a.add(i.id),c.push(i));for(const i of Y.values())i.archived||i.directories.length===0||a.has(i.id)||Pt({x:p.position.x,z:p.position.z},i)&&(a.add(i.id),c.push(i));return c.length===0?null:c.flatMap(i=>i.directories.filter(n=>n&&n.trim().length>0).map(n=>({areaId:i.id,areaName:i.name,dir:n})))},[p,o,Y]),{branches:$,fetchRemote:xe,fetchingDirs:ie}=_t(Z),J=s.useMemo(()=>{var i;const a=_.getAreaForAgent(o);if(!a)return[];const c=[];for(const n of y.values())n.type==="terminal"&&_.isPositionInArea(n.position,a)&&c.push({id:n.id,name:n.name,hasUrl:!!((i=n.terminalStatus)!=null&&i.url)});return c},[o,y]),be=s.useMemo(()=>{var i;const a=_.getAreaForAgent(o);if(!a)return[];const c=[];for(const n of y.values())n.type==="server"&&((i=n.pm2)!=null&&i.enabled)&&_.isPositionInArea(n.position,a)&&c.push({id:n.id,name:n.name});return c},[o,y]),we=s.useMemo(()=>{const a=_.getAreaForAgent(o);if(!a)return[];const c=[];for(const i of y.values())i.type==="database"&&i.database&&_.isPositionInArea(i.position,a)&&c.push({id:i.id,name:i.name});return c},[o,y]),[,ye]=s.useReducer(a=>a+1,0),Q=((l=V.current)==null?void 0:l.search.searchMode)??!1,ze=s.useCallback(()=>{var a;(a=V.current)==null||a.search.toggleSearch(),ye()},[]),je=xt(),oe=je.isPending(Xe),[O,f]=s.useState(null),A=O?y.get(O):null,{height:L,onResizeStart:ce}=bt(),[F,Ne]=s.useState(()=>De(N.GIT_PANEL_OPEN,!1)),[H,Ce]=s.useState(()=>De(N.BUILDINGS_PANEL_OPEN,!1)),Re=s.useCallback(()=>{Ne(a=>{const c=!a;return ae(N.GIT_PANEL_OPEN,c),c})},[]),ee=s.useCallback(()=>{Ce(a=>{const c=!a;return ae(N.BUILDINGS_PANEL_OPEN,c),c})},[]),z=s.useCallback(()=>{Ne(!1),ae(N.GIT_PANEL_OPEN,!1)},[]),te=s.useCallback(()=>{Ce(!1),ae(N.BUILDINGS_PANEL_OPEN,!1)},[]),Te=wt();s.useEffect(()=>{if(!O)return;J.some(c=>c.id===O)||f(null)},[O,J]);const[W,B]=s.useState(!1),de=s.useRef(null);if(s.useEffect(()=>{if(!W)return;const a=c=>{de.current&&!de.current.contains(c.target)&&B(!1)};return document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[W]),!p)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 R=p.contextStats,ve=!!R,pe=R?R.totalTokens:p.contextUsed||0,me=R?R.contextWindow:p.contextLimit||2e5,Pe=R?R.usedPercent:Math.round(pe/me*100),T=Math.max(0,Math.min(100,Pe)),$e=Math.max(0,100-T),ue=T>=80?"#ff4a4a":T>=60?"#ff9e4a":T>=40?"#ffd700":"#4aff9e",ke=(pe/1e3).toFixed(1),P=(me/1e3).toFixed(1),U=p.cwd,Ae=U?Rt(U):null,t=((d=p.subordinateIds)==null?void 0:d.length)||0,r=t>0;return e.jsxs("div",{ref:_e,className:`flat-terminal-wrapper ${F||H?"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 ${G?"flat-terminal-wrapper__header-main--active":""}`,onClick:Ie,title:G?"Hide agent info":"Show agent info","aria-pressed":G,children:[e.jsx(qe,{agent:p,size:28}),e.jsxs("span",{className:"flat-terminal-wrapper__header-info",children:[e.jsx("span",{className:"flat-terminal-wrapper__header-name",children:p.name}),e.jsx("span",{className:"flat-terminal-wrapper__header-status",style:{color:Ye(p.status)},children:p.status})]}),p.taskLabel&&e.jsxs("span",{className:"flat-terminal-wrapper__header-task",title:p.taskLabel,children:["📋 ",p.taskLabel]}),e.jsxs("span",{className:"flat-terminal-wrapper__header-model",children:[e.jsx("img",{src:p.provider==="codex"?"/assets/codex.png":p.provider==="opencode"?"/assets/opencode.png":"/assets/claude.png",alt:p.provider,className:"flat-terminal-wrapper__header-provider-icon",title:p.provider==="codex"?"Codex Agent":p.provider==="opencode"?"OpenCode Agent":"Claude Agent"}),(()=>{const{model:a,effort:c}=Tt(p);return e.jsxs("span",{className:"flat-terminal-wrapper__header-model-chip",title:c?`Model: ${a} · Effort: ${c}`:`Model: ${a}`,children:[e.jsx("span",{className:"flat-terminal-wrapper__header-model-name",children:a}),c&&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:c})]})]})})()]})]}),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:Mt.map(a=>e.jsxs("button",{type:"button",className:`flat-terminal-wrapper__view-mode-btn ${x===a?"flat-terminal-wrapper__view-mode-btn--active":""}`,onClick:()=>k(a),title:zt[a],"aria-pressed":x===a,children:[e.jsx("span",{className:"flat-terminal-wrapper__view-mode-icon","aria-hidden":"true",children:yt[a]}),e.jsx("span",{className:"flat-terminal-wrapper__view-mode-label",children:It[a]})]},a))}),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:K,disabled:!ge,title:"Back to previous agent","aria-label":"Back to previous agent",children:e.jsx(m,{name:"arrow-left",size:14})}),e.jsx("button",{type:"button",className:"flat-terminal-wrapper__action-btn",onClick:q,disabled:!I,title:"Forward to next agent","aria-label":"Forward to next agent",children:e.jsx(m,{name:"arrow-right",size:14})}),e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn ${Q?"flat-terminal-wrapper__action-btn--active":""}`,onClick:ze,title:Q?"Close search":"Search messages","aria-pressed":Q,children:e.jsx(m,{name:Q?"cross":"search",size:14})}),e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn flat-terminal-wrapper__action-btn--danger ${oe?"flat-terminal-wrapper__action-btn--confirm":""}`,onClick:()=>je.handleClick(Xe,()=>{var a;_.clearContext(o),(a=V.current)==null||a.historyLoader.clearHistory()}),title:oe?"Click again to confirm clear context":"Clear context",children:e.jsx(m,{name:oe?"question":"clear",size:14})}),e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn ${F?"flat-terminal-wrapper__action-btn--active":""}`,onClick:Re,title:F?"Hide git panel":"Show git changes","aria-pressed":F,children:e.jsx(m,{name:"git-branch",size:14})}),e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn ${H?"flat-terminal-wrapper__action-btn--active":""}`,onClick:ee,title:H?"Hide buildings panel":"Show area buildings","aria-pressed":H,children:e.jsx(m,{name:"buildings",size:14})}),e.jsxs("div",{className:"flat-terminal-wrapper__more",ref:de,children:[e.jsx("button",{type:"button",className:`flat-terminal-wrapper__action-btn ${W?"flat-terminal-wrapper__action-btn--active":""}`,onClick:()=>B(a=>!a),title:"More actions","aria-expanded":W,children:"⋮"}),W&&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",onClick:()=>{_.collapseContext(o),B(!1)},disabled:p.status!=="idle",title:p.status!=="idle"?"Agent must be idle to collapse context":"Collapse context",children:[e.jsx(m,{name:"package",size:14}),e.jsx("span",{children:"Collapse context"})]}),r&&e.jsxs("button",{type:"button",role:"menuitem",className:"flat-terminal-wrapper__more-item flat-terminal-wrapper__more-item--danger",onClick:()=>{fe(o,t),B(!1)},children:[e.jsx(m,{name:"crown",size:14}),e.jsxs("span",{children:["Clear ",t," subordinate",t===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:()=>{_.killAgent(o),B(!1)},children:[e.jsx(m,{name:"cross",size:14}),e.jsx("span",{children:"Remove agent"})]})]})]})]}),e.jsxs("button",{type:"button",className:`flat-terminal-wrapper__inspector-toggle ${M?"flat-terminal-wrapper__inspector-toggle--active":""}`,onClick:X,title:M?"Hide inspector panel":"Show inspector panel","aria-label":M?"Hide inspector panel":"Show inspector panel","aria-pressed":M,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:()=>_.deselectAll(),title:"Close chat","aria-label":"Close chat",children:e.jsx(m,{name:"cross",size:14})})]})]}),e.jsx(jt,{ref:V,agentId:o,agent:p,viewMode:x,isOpen:!0,onImageClick:b,onFileClick:ne,onBashClick:se,onViewMarkdown:he,keyboard:le,hasModalOpen:!1}),A&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"guake-bottom-terminal-resize",onMouseDown:ce,role:"separator","aria-orientation":"horizontal","aria-label":"Resize embedded terminal"}),e.jsxs("div",{className:"flat-bottom-panel",role:"region","aria-label":`Embedded terminal: ${A.name}`,style:{height:L},children:[e.jsxs("div",{className:"flat-bottom-panel__header",children:[e.jsxs("span",{className:"flat-bottom-panel__title",children:[e.jsx(m,{name:"terminal",size:12}),e.jsx("span",{children:A.name}),!((S=A.terminalStatus)!=null&&S.url)&&e.jsx("span",{className:"flat-bottom-panel__muted",children:"(starting...)"})]}),e.jsx("button",{type:"button",className:"flat-bottom-panel__close",onClick:()=>f(null),title:"Close embedded terminal","aria-label":"Close embedded terminal",children:e.jsx(m,{name:"cross",size:12})})]}),e.jsx("div",{className:"flat-bottom-panel__body",children:(C=A.terminalStatus)!=null&&C.url?e.jsx(Nt,{terminalUrl:A.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:[p.isDetached&&e.jsxs("span",{className:"flat-terminal-wrapper__detached",title:"Reattaching session...",children:[e.jsx(m,{name:"refresh",size:12}),e.jsx("span",{children:"Reattaching"})]}),U&&Ae&&e.jsxs("span",{className:"flat-terminal-wrapper__cwd",title:U,onClick:()=>_.setFileViewerPath(U),children:[e.jsx("span",{className:"flat-terminal-wrapper__cwd-icon",children:e.jsx(m,{name:"folder",size:12})}),e.jsx("span",{className:"flat-terminal-wrapper__cwd-text",children:Ae})]}),Z&&Z.map(({areaId:a,areaName:c,dir:i})=>{const n=$.get(i),g=ie.has(i),E=i.split("/").filter(Boolean).pop()||i;return e.jsxs("span",{className:"flat-terminal-wrapper__area-dir",title:`${c}: ${i}${n?` (${n.branch}${n.ahead?` ↑${n.ahead}`:""}${n.behind?` ↓${n.behind}`:""})`:""}`,onClick:()=>_.openFileExplorerForAreaFolder(a,i),children:[e.jsx(m,{name:"folder-open",size:12}),e.jsx("span",{className:"flat-terminal-wrapper__area-dir-name",children:E}),n&&e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"flat-terminal-wrapper__area-dir-branch",children:[e.jsx(m,{name:"git-branch",size:10})," ",n.branch]}),n.ahead>0&&e.jsxs("span",{className:"flat-terminal-wrapper__branch-ahead",title:`${n.ahead} ahead`,children:[e.jsx(m,{name:"arrow-up",size:9}),n.ahead]}),n.behind>0&&e.jsxs("span",{className:"flat-terminal-wrapper__branch-behind",title:`${n.behind} behind`,children:[e.jsx(m,{name:"arrow-down",size:9}),n.behind]}),e.jsx("span",{className:`flat-terminal-wrapper__area-fetch ${g?"flat-terminal-wrapper__area-fetch--fetching":""}`,title:"Git fetch",onClick:D=>{D.stopPropagation(),xe(i)},children:e.jsx(m,{name:g?"hourglass":"download",size:12})})]})]},`${a}:${i}`)}),e.jsxs("span",{className:"flat-terminal-wrapper__context",onClick:()=>_.setContextModalAgentId(o),title:ve?`Context usage: ${ke}k / ${P}k tokens (${T}% used). Click to view stats.`:"Click to fetch context stats",children:[e.jsx("span",{className:"flat-terminal-wrapper__context-icon",children:e.jsx(m,{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:`${T}%`,backgroundColor:ue}})}),e.jsxs("span",{className:"flat-terminal-wrapper__context-tokens",style:{color:ue},children:[ke,"k/",P,"k"]}),e.jsxs("span",{className:"flat-terminal-wrapper__context-free",children:["(",$e,"% free)"]}),!ve&&e.jsx("span",{className:"flat-terminal-wrapper__context-warning",title:"No context stats yet",children:e.jsx(m,{name:"warn",size:12})})]}),e.jsx("div",{className:"flat-terminal-wrapper__statusbar-spacer","aria-hidden":"true"}),J.length>0&&e.jsx("span",{className:"flat-terminal-wrapper__buildings",role:"group","aria-label":"Area terminals",children:J.map(a=>{const c=O===a.id;return e.jsx("button",{type:"button",className:`flat-terminal-wrapper__building-btn ${c?"flat-terminal-wrapper__building-btn--active":""} ${a.hasUrl?"":"flat-terminal-wrapper__building-btn--offline"}`,title:`${c?"Hide":"Show"} terminal: ${a.name}${a.hasUrl?"":" (starting...)"}`,onClick:()=>{if(c){f(null);return}a.hasUrl||_.sendBuildingCommand(a.id,"start"),f(a.id)},children:e.jsx(m,{name:"terminal",size:14})},a.id)})}),be.length>0&&e.jsx("span",{className:"flat-terminal-wrapper__buildings",role:"group","aria-label":"Area PM2 logs",children:be.map(a=>e.jsx("button",{type:"button",className:"flat-terminal-wrapper__building-btn",title:`Open logs: ${a.name}`,onClick:()=>re(a.id),children:e.jsx(m,{name:"scroll",size:14})},a.id))}),we.length>0&&e.jsx("span",{className:"flat-terminal-wrapper__buildings",role:"group","aria-label":"Area databases",children:we.map(a=>e.jsx("button",{type:"button",className:"flat-terminal-wrapper__building-btn",title:`Open database: ${a.name}`,onClick:()=>re(a.id),children:e.jsx(m,{name:"hard-drives",size:14})},a.id))}),e.jsx("div",{className:"flat-terminal-wrapper__theme",children:e.jsx(Ct,{})})]}),F&&e.jsx(vt,{agentId:o,agents:Te,onClose:z,branchInfoMap:$,fetchRemote:xe,fetchingDirs:ie}),H&&e.jsx(kt,{agentId:o,onClose:te})]})});function Bt({onAgentClick:u,onBuildingClick:o,onBuildingDoubleClick:x,onOpenSpawnModal:k,onOpenBossSpawnModal:M,onOpenAreaModal:X}){const b=et(),ne=tt(),[se,he]=s.useState(null),[fe,re]=s.useState(null),[le,ge]=s.useState(null),[I,K]=s.useState(null),[q,G]=s.useState(!1),Ie=s.useCallback(()=>{G(t=>!t)},[]),p=s.useCallback(()=>{G(!1)},[]),[y,V]=s.useState(()=>{const t=We(N.VIEW_MODE);return t==="simple"||t==="chat"||t==="advanced"?t:"simple"}),_e=s.useCallback(t=>{V(t),Ue(N.VIEW_MODE,t)},[]);s.useEffect(()=>{const t=r=>{if(r.key!==N.VIEW_MODE)return;const l=r.newValue;(l==="simple"||l==="chat"||l==="advanced")&&V(l)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)},[]);const[Y,Z]=s.useState(()=>De(N.FLAT_INSPECTOR_OPEN,!1)),[$,xe]=s.useState(()=>We(N.FLAT_INSPECTOR_VIEW)==="tracking"?"tracking":"agent"),ie=s.useCallback(t=>{xe(t),Ue(N.FLAT_INSPECTOR_VIEW,t)},[]),J=s.useCallback(()=>{Z(t=>{const r=!t;return ae(N.FLAT_INSPECTOR_OPEN,r),r})},[]),be=s.useCallback(()=>{Z(!1),ae(N.FLAT_INSPECTOR_OPEN,!1)},[]),we=at(),ye=s.useCallback((t,r)=>{he({url:t,name:r})},[]),Q=s.useCallback((t,r)=>{re({command:t,output:r,isLive:!1})},[]),ze=s.useCallback((t,r)=>{_.setFileViewerPath(t,r)},[]),je=s.useCallback(t=>{},[]),oe=s.useCallback((t,r)=>{ge({agentId:t,count:r})},[]),O=s.useCallback(t=>{x?x(t):o(t)},[o,x]),f=s.useMemo(()=>ne.size>0?Array.from(ne)[0]:null,[ne]);s.useEffect(()=>{G(!1)},[f]);const A=s.useRef([]),L=s.useRef(-1),ce=s.useRef(!1),F=s.useRef(null),[Ne,H]=s.useState(!1),[Ce,Re]=s.useState(!1),ee=s.useMemo(()=>new Set(b.map(t=>t.id)),[b]),z=s.useCallback(()=>{const t=A.current,r=L.current;H(r>0),Re(r>=0&&r<t.length-1)},[]),te=s.useCallback(t=>{const r=A.current;if(r.length===0)return;let l=L.current+t;for(;l>=0&&l<r.length;){const d=r[l];if(ee.has(d)){ce.current=!0,L.current=l,z(),_.selectAgent(d);return}l+=t}},[ee,z]),Te=s.useCallback(()=>te(-1),[te]),W=s.useCallback(()=>te(1),[te]);s.useEffect(()=>{if(!f){A.current=[],L.current=-1,z();return}if(F.current=f,ce.current){ce.current=!1,z();return}const t=A.current,r=L.current;if(r>=0&&t[r]===f){z();return}const l=r<t.length-1?t.slice(0,r+1):t.slice();l.push(f),l.length>100&&l.shift(),A.current=l,L.current=l.length-1,z()},[f,z]);const B=s.useCallback(t=>{u(t)},[u]),de=f??"",R=s.useCallback(()=>{},[]),ve=s.useCallback(t=>{B(t)},[B]),pe=Y&&!!f,me=s.useRef(null);s.useEffect(()=>{if(f)return;const t=r=>{if(r.key!==" "&&r.key!=="Backspace")return;const l=r.target;if(l.tagName==="INPUT"||l.tagName==="TEXTAREA"||l.isContentEditable)return;const d=F.current;!d||!ee.has(d)||(r.preventDefault(),_.selectAgent(d))};return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[f,ee]);const[Pe,T]=s.useState(new Set),$e=s.useCallback(t=>{T(r=>{const l=new Set(r);return l.has(t)?l.delete(t):l.add(t),l})},[]),ue=Ke(),[ke]=nt(),P=s.useMemo(()=>{const t=new Map,r=[];for(const n of b){const g=_.getAreaForAgent(n.id);if(!st((g==null?void 0:g.id)??null))continue;if(!g||g.archived){r.push(n);continue}const E=t.get(g.id);E?E.push(n):t.set(g.id,[n])}const l=[];for(const[,n]of ue){if(n.archived||!rt(n.id))continue;const g=t.get(n.id);g&&g.length>0&&l.push({area:n,agents:g})}r.length>0&&l.push({area:{id:"__unassigned__",name:"Unassigned",color:"#6272a4",center:{x:0,z:0},type:"circle",radius:0,directories:[],archived:!1,assignedAgentIds:[],zIndex:0},agents:r});const d=l.filter(n=>n.area.id!=="__unassigned__"),S=l.filter(n=>n.area.id==="__unassigned__");let C=1,a=1;const c=new Map;if(d.length>1){let n=1/0,g=-1/0,E=1/0,D=-1/0;for(const w of d)n=Math.min(n,w.area.center.x),g=Math.max(g,w.area.center.x),E=Math.min(E,w.area.center.z),D=Math.max(D,w.area.center.z);const Se=g-n||1,Ee=D-E||1;if(d.length<=4){C=d.length,a=1;const w=[...d].sort((j,Oe)=>j.area.center.x-Oe.area.center.x);for(let j=0;j<w.length;j++)c.set(w[j].area.id,{row:1,col:j+1})}else{const w=[...d].sort((h,v)=>h.area.center.x-v.area.center.x),j=[];for(let h=1;h<w.length;h++)j.push(w[h].area.center.x-w[h-1].area.center.x);const Oe=j.reduce((h,v)=>h+v,0)/j.length||1;let Ge=1;for(const h of j)h>Oe*1.3&&Ge++;C=Math.max(2,Math.min(Ge,d.length));const Le=[...d].sort((h,v)=>h.area.center.z-v.area.center.z),Me=[];for(let h=1;h<Le.length;h++)Me.push(Le[h].area.center.z-Le[h-1].area.center.z);const Ze=Me.reduce((h,v)=>h+v,0)/Me.length||1;let Ve=1;for(const h of Me)h>Ze*1.3&&Ve++;a=Math.max(2,Math.min(Ve,d.length)),C=Math.max(C,Math.ceil(d.length/a)),a=Math.max(a,Math.ceil(d.length/C));const Je=Se/C,Qe=Ee/a,He=new Set;for(const h of d){let v=Math.min(C-1,Math.max(0,Math.floor((h.area.center.x-n)/Je))),Fe=Math.min(a-1,Math.max(0,Math.floor((h.area.center.z-E)/Qe))),Be=`${Fe},${v}`;for(;He.has(Be)&&v<C-1;)v++,Be=`${Fe},${v}`;He.add(Be),c.set(h.area.id,{row:Fe+1,col:v+1})}}}const i=n=>{n.sort((g,E)=>{var Se,Ee,w,j;const D=(((Se=g.position)==null?void 0:Se.z)??0)-(((Ee=E.position)==null?void 0:Ee.z)??0);return D!==0?D:(((w=g.position)==null?void 0:w.x)??0)-(((j=E.position)==null?void 0:j.x)??0)})};for(const n of d)i(n.agents);for(const n of S)i(n.agents);return{groups:[...d,...S],gridCols:C,gridRows:a,positions:c}},[b,ue,ke]),U=s.useMemo(()=>{if(!I)return[];const t=b.find(r=>r.id===I.agentId);return t?[{id:"edit-agent",label:"Edit Agent",icon:e.jsx(m,{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(m,{name:"chat",size:14}),onClick:()=>u(t.id)},{id:"delete-agent",label:"Delete Agent",icon:e.jsx(m,{name:"trash",size:14}),danger:!0,onClick:()=>{window.confirm(`Remove ${t.name} from view?`)&&_.removeAgentFromServer(t.id)}}]:[]},[I,b,u]),Ae=s.useCallback(t=>{const r=new Set(P.groups.map(l=>l.area.id));r.delete(t),T(r),requestAnimationFrame(()=>{const l=me.current;if(!l)return;const d=l.querySelector(`[data-area-id="${t}"]`);if(!d)return;const S=l.getBoundingClientRect(),a=d.getBoundingClientRect().top-S.top+l.scrollTop-8;l.scrollTo({top:Math.max(0,a),behavior:"smooth"})})},[P]);return e.jsxs("div",{className:`flat-view ${pe?"flat-view--with-inspector":""}`,children:[e.jsxs("div",{className:"flat-middle",children:[e.jsxs("div",{className:"flat-middle__header",children:[e.jsx("h2",{className:"flat-middle__title",children:"👥 Agents"}),e.jsxs("div",{className:"flat-middle__actions",children:[e.jsx("button",{className:"flat-cta-btn flat-cta-btn--agent",onClick:k,title:"Create new agent",children:"+ Agent"}),e.jsx("button",{className:"flat-cta-btn flat-cta-btn--boss",onClick:M,title:"Create new boss agent",children:"+ Boss"}),e.jsx("button",{className:"flat-cta-btn flat-cta-btn--area",onClick:X,title:"Create new area",children:"+ Area"})]})]}),e.jsx("div",{className:"flat-middle__content",children:e.jsx(lt,{activeAgentId:de,onClose:R,onSelectAgent:ve,collapsedAreas:Pe,onToggleArea:$e,agentListRef:me})})]}),e.jsx("div",{className:"flat-right",children:f?e.jsx($t,{agentId:f,terminalViewMode:y,onTerminalViewModeChange:_e,inspectorOpen:Y,onToggleInspector:J,onImageClick:ye,onFileClick:ze,onBashClick:Q,onViewMarkdown:je,onRequestClearSubordinates:oe,onOpenBuilding:O,keyboard:we,canNavigateBack:Ne,canNavigateForward:Ce,onNavigateBack:Te,onNavigateForward:W,agentInfoOpen:q,onToggleAgentInfo:Ie}):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("div",{className:"flat-map__grid",style:{gridTemplateColumns:`repeat(${P.gridCols}, 1fr)`},children:P.groups.length===0?e.jsx("div",{className:"flat-map__empty",children:e.jsx("span",{children:"No areas or agents yet"})}):P.groups.map(t=>{const r=t.area.id,l=P.positions.get(r);return e.jsxs("div",{className:"flat-map-area-card",style:{"--area-color":t.area.color,gridRow:l==null?void 0:l.row,gridColumn:l==null?void 0:l.col},children:[e.jsxs("button",{type:"button",className:"flat-map-area-card__header",onClick:()=>Ae(r),title:`Focus ${t.area.name} in left panel`,children:[e.jsx("span",{className:"flat-map-area-card__color",style:{background:t.area.color}}),e.jsx("span",{className:"flat-map-area-card__name",children:t.area.name}),e.jsx("span",{className:"flat-map-area-card__count",children:t.agents.length})]}),e.jsx("div",{className:"flat-map-area-card__agents",children:t.agents.map(d=>e.jsxs("button",{type:"button",className:`flat-map-agent-chip ${d.status}`,onClick:()=>u(d.id),onContextMenu:S=>{S.preventDefault(),S.stopPropagation(),K({agentId:d.id,position:{x:S.clientX,y:S.clientY}})},title:`Open chat with ${d.name}`,children:[e.jsx(qe,{agent:d,size:16}),e.jsx("span",{className:"flat-map-agent-chip__name",children:d.name}),e.jsx("span",{className:"flat-map-agent-chip__dot",style:{backgroundColor:Ye(d.status)}})]},d.id))})]},r)})})]})})}),pe&&f&&e.jsxs("aside",{className:"flat-inspector","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":$==="agent",className:`flat-inspector__tab ${$==="agent"?"flat-inspector__tab--active":""}`,onClick:()=>ie("agent"),children:"Agent"}),e.jsx("button",{type:"button",role:"tab","aria-selected":$==="tracking",className:`flat-inspector__tab ${$==="tracking"?"flat-inspector__tab--active":""}`,onClick:()=>ie("tracking"),children:"Tracking"})]}),e.jsx("button",{type:"button",className:"flat-inspector__close",onClick:be,title:"Close inspector","aria-label":"Close inspector",children:"✕"})]}),e.jsx("div",{className:"flat-inspector__body",children:$==="tracking"?e.jsx(it,{activeAgentId:f??"",onSelectAgent:t=>u(t)}):(()=>{const t=b.find(r=>r.id===f);return t?e.jsx(ot,{agent:t,onFocusAgent:r=>u(r),onKillAgent:r=>_.killAgent(r)}):e.jsx("div",{className:"flat-inspector__empty",children:e.jsx("span",{children:"Agent not found"})})})()})]}),se&&e.jsx(ct,{url:se.url,name:se.name,onClose:()=>he(null)}),fe&&e.jsx(dt,{state:fe,onClose:()=>re(null)}),le&&e.jsx(pt,{action:"clear-subordinates",selectedAgentId:le.agentId,subordinateCount:le.count,onClose:()=>ge(null),onClearHistory:()=>{}}),e.jsx(mt,{agent:f?b.find(t=>t.id===f)??null:null,isOpen:q&&!!f,onClose:p}),e.jsx(ut,{isOpen:I!==null,position:(I==null?void 0:I.position)??{x:0,y:0},worldPosition:{x:0,z:0},actions:U,onClose:()=>K(null)})]})}export{Bt as FlatView};
@@ -1 +0,0 @@
1
- .app.view-mode-flat .guake-terminal{display:none}.flat-view{display:grid;grid-template-columns:1fr 1fr;height:100%;width:100%;background:#282a36;overflow:hidden;padding-left:64px;box-sizing:border-box;transition:grid-template-columns .25s ease}.flat-view--with-inspector{grid-template-columns:1fr 1fr 320px}.flat-middle{display:flex;flex-direction:column;background:#282a36;border-right:1px solid rgba(255,255,255,.06);overflow:hidden;min-width:280px}.flat-middle__header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid rgba(255,255,255,.06);flex-shrink:0;gap:12px}.flat-middle__title{font-size:14px;font-weight:600;color:#f8f8f2;margin:0}.flat-middle__actions{display:flex;gap:6px;flex-shrink:0}.flat-middle__content{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px}.flat-middle__content::-webkit-scrollbar{width:6px}.flat-middle__content::-webkit-scrollbar-track{background:transparent}.flat-middle__content::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:3px}.flat-middle__content::-webkit-scrollbar-thumb:hover{background:#fff3}.flat-cta-btn{padding:4px 10px;font-size:11px;font-weight:500;border:none;border-radius:4px;cursor:pointer;transition:all .15s ease;white-space:nowrap}.flat-cta-btn--agent{background:#50fa7b26;color:#50fa7b}.flat-cta-btn--agent:hover{background:#50fa7b40}.flat-cta-btn--boss{background:#ffd70026;color:gold}.flat-cta-btn--boss:hover{background:#ffd70040}.flat-cta-btn--building{background:#8be9fd26;color:#8be9fd}.flat-cta-btn--building:hover{background:#8be9fd40}.flat-cta-btn--area{background:#bd93f926;color:#bd93f9}.flat-cta-btn--area:hover{background:#bd93f940}.flat-middle .agent-overview-panel{position:relative;inset:auto;width:100%;height:100%;border-right:none;flex:1;min-height:0;z-index:auto}.flat-middle .agent-overview-panel .aop-row-controls .close-btn{display:none}.flat-middle__content:has(>.agent-overview-panel){padding:0;overflow:hidden}.flat-right{display:flex;flex-direction:column;background:#21222c;overflow:hidden}.flat-chat{display:flex;flex-direction:column;height:100%}.flat-chat--empty{align-items:center;justify-content:center}.flat-chat__placeholder{display:flex;flex-direction:column;align-items:center;gap:12px;color:#6272a4}.flat-chat__placeholder-icon{font-size:48px;opacity:.5}.flat-chat__placeholder-text{font-size:14px}.flat-map{display:flex;flex-direction:column;height:100%;padding:12px 16px;gap:10px;overflow-y:auto}.flat-map::-webkit-scrollbar{width:6px}.flat-map::-webkit-scrollbar-track{background:transparent}.flat-map::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:3px}.flat-map::-webkit-scrollbar-thumb:hover{background:#fff3}.flat-map__header{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-shrink:0}.flat-map__title{font-size:13px;font-weight:600;color:#f8f8f2}.flat-map__hint{font-size:11px;color:#6272a4}.flat-map__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px;align-content:start}@media(max-width:768px){.flat-map__grid{grid-template-columns:1fr}}.flat-map__empty{grid-column:1/-1;display:flex;align-items:center;justify-content:center;padding:40px;color:#6272a4;font-size:13px}.flat-map-area-card{display:flex;flex-direction:column;background:#363848;border:1px solid rgba(255,255,255,.06);border-radius:8px;overflow:hidden;transition:border-color .15s ease,box-shadow .15s ease}.flat-map-area-card:hover{border-color:#ffffff1a;box-shadow:0 2px 8px #00000040}.flat-map-area-card__header{display:flex;align-items:center;gap:6px;padding:6px 8px;background:transparent;border:none;cursor:pointer;width:100%;text-align:left;color:#f8f8f2;font-size:12px;font-weight:600;transition:background .15s ease}.flat-map-area-card__header:hover{background:#ffffff0a}.flat-map-area-card__color{width:8px;height:8px;border-radius:50%;flex-shrink:0}.flat-map-area-card__name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.flat-map-area-card__count{font-size:10px;font-weight:500;color:#6272a4;background:#ffffff0f;padding:1px 5px;border-radius:8px;flex-shrink:0}.flat-map-area-card__caret{font-size:10px;color:#6272a4;flex-shrink:0;width:12px;text-align:center}.flat-map-area-card__agents{display:flex;flex-wrap:wrap;gap:4px;padding:0 8px 8px}.flat-map-agent-chip{display:inline-flex;align-items:center;gap:5px;padding:3px 7px;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:10px;cursor:pointer;color:#9a9caa;font-size:11px;text-align:left;transition:background .15s ease,color .15s ease,border-color .15s ease;white-space:nowrap;min-width:0}.flat-map-agent-chip:hover{background:#ffffff14;border-color:#ffffff1f;color:#f8f8f2}.flat-map-agent-chip.working{background-color:#4a9eff24;background-image:linear-gradient(110deg,transparent 35%,rgba(139,233,253,.55) 50%,transparent 65%);background-size:250% 100%;background-repeat:no-repeat;background-position:150% 0;border-color:#4a9eff8c;color:#f8f8f2;box-shadow:0 0 8px #4a9eff59;animation:flat-map-agent-working-shimmer 1.6s linear infinite}.flat-map-agent-chip.working .flat-map-agent-chip__dot{box-shadow:0 0 6px #4a9effb3}@keyframes flat-map-agent-working-shimmer{0%{background-position:150% 0}to{background-position:-50% 0}}@media(prefers-reduced-motion:reduce){.flat-map-agent-chip.working{animation-duration:5s;background-image:linear-gradient(110deg,transparent 40%,rgba(139,233,253,.3) 50%,transparent 60%)}}.flat-map-agent-chip__name{min-width:0;overflow:hidden;text-overflow:ellipsis}.flat-map-agent-chip__dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.flat-terminal-wrapper{display:flex;flex-direction:column;height:100%;min-height:0;position:relative;background:#21222c;overflow:hidden;--guake-side-panel-width: 380px}.flat-terminal-wrapper--with-side-panel>*:not(.guake-git-panel):not(.guake-buildings-panel):not(.guake-workflow-panel){margin-right:var(--guake-side-panel-width);transition:margin-right .2s ease}.flat-terminal-wrapper__header{display:flex;flex-direction:row;align-items:center;gap:12px;padding:6px 12px;border-bottom:1px solid rgba(255,255,255,.06);background:#1e1f29;flex-shrink:0;min-height:40px}.flat-terminal-wrapper__header-main{display:flex;align-items:center;gap:10px;min-width:0;flex:1 1 auto;overflow:hidden;padding:4px 6px;margin:0;background:transparent;border:1px solid transparent;border-radius:8px;color:inherit;font:inherit;text-align:left;cursor:pointer;transition:background .15s ease,border-color .15s ease}.flat-terminal-wrapper__header-main:hover{background:#ffffff0a;border-color:#ffffff0f}.flat-terminal-wrapper__header-main--active{background:#bd93f92e;border-color:#bd93f973}.flat-terminal-wrapper__header-main--active:hover{background:#bd93f942}.flat-terminal-wrapper__header-meta{display:flex;align-items:center;justify-content:flex-end;gap:6px;flex:0 0 auto;flex-wrap:nowrap}.flat-terminal-wrapper__statusbar{display:flex;align-items:center;gap:10px;padding:6px 12px;flex-shrink:0;background:#1e1f29;border-top:1px solid rgba(255,255,255,.06);min-height:32px;box-sizing:border-box}.flat-terminal-wrapper__statusbar .flat-terminal-wrapper__cwd,.flat-terminal-wrapper__statusbar .flat-terminal-wrapper__context{background:transparent;border-color:#ffffff0a}.flat-terminal-wrapper__statusbar-spacer{flex:1 1 auto}.flat-terminal-wrapper__buildings{display:inline-flex;align-items:center;gap:4px;padding:2px;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:10px}.flat-terminal-wrapper__building-btn{display:inline-flex;align-items:center;justify-content:center;width:26px;height:22px;padding:0;color:#6272a4;background:transparent;border:none;border-radius:7px;cursor:pointer;transition:background .15s ease,color .15s ease}.flat-terminal-wrapper__building-btn:hover{color:#f8f8f2;background:#ffffff14}.flat-terminal-wrapper__building-btn--offline{color:#ffb86cbf}.flat-terminal-wrapper__building-btn--offline:hover{color:#ffb86c}.flat-terminal-wrapper__building-btn--active{color:#f8f8f2;background:#bd93f947;box-shadow:0 0 0 1px #bd93f973}.flat-terminal-wrapper__building-btn--active:hover{background:#bd93f95c}.flat-terminal-wrapper__detached{display:inline-flex;align-items:center;gap:6px;padding:3px 9px;font-size:11px;font-weight:500;color:#ffb86c;background:#ffb86c1f;border:1px solid rgba(255,184,108,.35);border-radius:10px;animation:blink 1.6s ease-in-out infinite}.flat-terminal-wrapper__area-dir{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;font-size:11px;font-family:SF Mono,Menlo,Consolas,monospace;color:#9a9caa;background:#ffffff08;border:1px solid rgba(255,255,255,.05);border-radius:10px;cursor:pointer;max-width:240px;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .15s ease,color .15s ease,border-color .15s ease}.flat-terminal-wrapper__area-dir:hover{background:#ffffff14;color:#f8f8f2;border-color:#ffffff24}.flat-terminal-wrapper__area-dir-name{overflow:hidden;text-overflow:ellipsis}.flat-terminal-wrapper__area-dir-branch{display:inline-flex;align-items:center;gap:3px;color:#8be9fd;opacity:.85}.flat-terminal-wrapper__branch-ahead{display:inline-flex;align-items:center;color:#50fa7b}.flat-terminal-wrapper__branch-behind{display:inline-flex;align-items:center;color:#ffb86c}.flat-terminal-wrapper__area-fetch{display:inline-flex;align-items:center;padding:1px 3px;border-radius:4px;color:#6272a4;cursor:pointer;transition:background .15s ease,color .15s ease}.flat-terminal-wrapper__area-fetch:hover{background:#ffffff14;color:#f8f8f2}.flat-terminal-wrapper__area-fetch--fetching{animation:blink 1s ease-in-out infinite}.flat-terminal-wrapper__context-label{color:#6272a4;margin-right:2px}.flat-terminal-wrapper__context-free{color:#6272a4;font-size:10px}.flat-terminal-wrapper__actions{display:inline-flex;align-items:center;gap:4px;padding:2px;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:10px}.flat-terminal-wrapper__action-btn{display:inline-flex;align-items:center;justify-content:center;width:26px;height:24px;padding:0;font-size:12px;line-height:1;color:#6272a4;background:transparent;border:none;border-radius:7px;cursor:pointer;transition:background .15s ease,color .15s ease,box-shadow .15s ease}.flat-terminal-wrapper__action-btn:hover:not(:disabled){color:#f8f8f2;background:#ffffff0f}.flat-terminal-wrapper__action-btn:disabled{opacity:.35;cursor:not-allowed}.flat-terminal-wrapper__action-btn--active{color:#f8f8f2;background:#bd93f947;box-shadow:0 0 0 1px #bd93f973}.flat-terminal-wrapper__action-btn--active:hover{background:#bd93f95c}.flat-terminal-wrapper__action-btn--danger{color:#ff5555d9}.flat-terminal-wrapper__action-btn--danger:hover{color:#f55;background:#ff55551f}.flat-terminal-wrapper__action-btn--confirm{color:#f55;background:#ff55552e;box-shadow:0 0 0 1px #ff555580;animation:blink 1s ease-in-out infinite}.flat-terminal-wrapper__more{position:relative;display:inline-flex}.flat-terminal-wrapper__more-menu{position:absolute;top:calc(100% + 4px);right:0;min-width:220px;padding:4px;background:#363848;border:1px solid rgba(255,255,255,.08);border-radius:8px;box-shadow:0 8px 28px #00000073;z-index:100}.flat-terminal-wrapper__more-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 10px;font-size:12px;color:#f8f8f2;background:transparent;border:none;border-radius:6px;cursor:pointer;text-align:left;transition:background .15s ease,color .15s ease}.flat-terminal-wrapper__more-item:hover:not(:disabled){background:#ffffff0f}.flat-terminal-wrapper__more-item:disabled{opacity:.45;cursor:not-allowed}.flat-terminal-wrapper__more-item--danger{color:#ff5555e6}.flat-terminal-wrapper__more-item--danger:hover:not(:disabled){color:#f55;background:#ff55551f}.flat-terminal-wrapper__more-divider{height:1px;margin:4px 2px;background:#ffffff0f}.flat-terminal-wrapper__header-info{display:flex;flex-direction:row;align-items:baseline;gap:8px;min-width:0;overflow:hidden}.flat-terminal-wrapper__header-name{font-size:13px;font-weight:600;color:#f8f8f2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.flat-terminal-wrapper__header-status{font-size:10px;text-transform:capitalize;flex-shrink:0}.flat-terminal-wrapper__header-task{font-size:11px;color:#6272a4;max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:2px 8px;border-radius:10px;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);flex-shrink:1}.flat-terminal-wrapper__header-model{display:inline-flex;align-items:center;gap:6px;flex-shrink:0;min-width:0}.flat-terminal-wrapper__header-provider-icon{width:16px;height:16px;object-fit:contain;flex-shrink:0;filter:drop-shadow(0 1px 2px rgba(0,0,0,.25))}.flat-terminal-wrapper__header-model-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:10px;font-family:SF Mono,Menlo,Consolas,monospace;font-weight:600;color:#9a9caa;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:999px;white-space:nowrap;max-width:180px;overflow:hidden;text-overflow:ellipsis;line-height:1.4}.flat-terminal-wrapper__header-model-name{color:#f8f8f2;text-transform:lowercase;overflow:hidden;text-overflow:ellipsis}.flat-terminal-wrapper__header-model-sep{opacity:.6}.flat-terminal-wrapper__header-model-effort{color:#bd93f9;text-transform:lowercase}.flat-terminal-wrapper__cwd{display:inline-flex;align-items:center;gap:6px;padding:4px 9px;font-size:11px;color:#9a9caa;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:10px;cursor:pointer;max-width:240px;transition:background .15s ease,border-color .15s ease,color .15s ease}.flat-terminal-wrapper__cwd:hover{background:#ffffff14;border-color:#ffffff24;color:#f8f8f2}.flat-terminal-wrapper__cwd-icon{font-size:12px;line-height:1}.flat-terminal-wrapper__cwd-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:SF Mono,Menlo,Consolas,monospace}.flat-terminal-wrapper__context{display:inline-flex;align-items:center;gap:6px;padding:4px 9px;font-size:11px;color:#9a9caa;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:10px;cursor:pointer;transition:background .15s ease,border-color .15s ease}.flat-terminal-wrapper__context:hover{background:#ffffff14;border-color:#ffffff24}.flat-terminal-wrapper__context-icon{font-size:12px;line-height:1}.flat-terminal-wrapper__context-bar{position:relative;width:56px;height:5px;border-radius:3px;background:#ffffff14;overflow:hidden}.flat-terminal-wrapper__context-bar-fill{position:absolute;left:0;top:0;height:100%;border-radius:3px;transition:width .2s ease,background-color .2s ease}.flat-terminal-wrapper__context-tokens{font-family:SF Mono,Menlo,Consolas,monospace;font-size:11px;font-weight:600;font-variant-numeric:tabular-nums}.flat-terminal-wrapper__context-warning{font-size:11px;opacity:.8}.flat-terminal-wrapper__view-mode{display:inline-flex;align-items:center;padding:2px;gap:2px;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:10px}.flat-terminal-wrapper__view-mode-btn{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;font-size:11px;font-weight:500;color:#6272a4;background:transparent;border:none;border-radius:8px;cursor:pointer;transition:background .15s ease,color .15s ease,box-shadow .15s ease}.flat-terminal-wrapper__view-mode-btn:hover{color:#f8f8f2;background:#ffffff0a}.flat-terminal-wrapper__view-mode-btn--active{color:#f8f8f2;background:#bd93f947;box-shadow:0 0 0 1px #bd93f980,0 1px 3px #00000040}.flat-terminal-wrapper__view-mode-btn--active:hover{background:#bd93f95c}.flat-terminal-wrapper__view-mode-icon{font-size:13px;line-height:1}.flat-terminal-wrapper__view-mode-label{line-height:1}.flat-terminal-wrapper__theme{display:inline-flex;align-items:center}.flat-terminal-wrapper__theme .theme-selector-trigger{padding:4px 9px;font-size:11px;border-radius:10px;background:#ffffff0a;border:1px solid rgba(255,255,255,.06)}.flat-terminal-wrapper__theme .theme-selector-trigger:hover{background:#ffffff14;border-color:#ffffff24}.flat-terminal-wrapper__inspector-toggle{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;font-size:11px;font-weight:500;color:#9a9caa;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:10px;cursor:pointer;transition:background .15s ease,border-color .15s ease,color .15s ease,box-shadow .15s ease}.flat-terminal-wrapper__inspector-toggle:hover{color:#f8f8f2;background:#ffffff14;border-color:#ffffff24}.flat-terminal-wrapper__inspector-toggle--active{color:#f8f8f2;background:#bd93f938;border-color:#bd93f98c;box-shadow:0 0 0 1px #bd93f959,0 1px 3px #00000040}.flat-terminal-wrapper__inspector-toggle--active:hover{background:#bd93f952}.flat-terminal-wrapper__inspector-icon{display:inline-flex;align-items:center;justify-content:center;line-height:1}.flat-terminal-wrapper__inspector-label{line-height:1}.flat-terminal-wrapper__close{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;padding:0;color:#6272a4;background:#ffffff0a;border:1px solid rgba(255,255,255,.06);border-radius:10px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}.flat-terminal-wrapper__close:hover{color:#f55;background:#ff55551f;border-color:#f556}@media(max-width:1100px){.flat-terminal-wrapper__view-mode-label,.flat-terminal-wrapper__inspector-label{display:none}.flat-terminal-wrapper__cwd{max-width:160px}}.flat-terminal-wrapper .guake-output{flex:1 1 auto;min-height:0;overflow-y:auto;padding:14px 18px}.flat-terminal-wrapper .guake-output::-webkit-scrollbar{width:6px}.flat-terminal-wrapper .guake-output::-webkit-scrollbar-track{background:transparent}.flat-terminal-wrapper .guake-output::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:3px}.flat-terminal-wrapper .guake-input-container{position:relative;flex-shrink:0;border-top:1px solid rgba(255,255,255,.06);background:#1e1f29}.flat-terminal-wrapper .guake-search-bar,.flat-terminal-wrapper .atp-search-bar{position:sticky;top:0;z-index:10;background:#1e1f29}.flat-terminal-wrapper .guake-handle,.flat-terminal-wrapper .guake-side-panel-resize,.flat-terminal-wrapper .atp-resize-handle{display:none}.flat-terminal-wrapper .compacting-indicator{padding:12px;margin:8px}@keyframes blink{0%,to{opacity:1}50%{opacity:.3}}.flat-inspector{display:flex;flex-direction:column;min-width:0;min-height:0;height:100%;background:#1e1f29;border-left:1px solid rgba(255,255,255,.06);overflow:hidden;animation:flat-inspector-slide-in .22s ease}.flat-inspector__header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid rgba(255,255,255,.06);background:#21222c;flex-shrink:0}.flat-inspector__tabs{display:inline-flex;align-items:center;gap:4px;padding:2px;background:#00000040;border:1px solid rgba(255,255,255,.06);border-radius:6px}.flat-inspector__tab{padding:4px 10px;font-size:12px;font-weight:500;color:#6272a4;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background .15s ease,color .15s ease}.flat-inspector__tab:hover{color:#f8f8f2}.flat-inspector__tab--active{color:#f8f8f2;background:#ffffff14}.flat-inspector__close{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;font-size:13px;color:#6272a4;background:transparent;border:1px solid transparent;border-radius:6px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}.flat-inspector__close:hover{color:#f8f8f2;background:#ffffff0f;border-color:#ffffff1a}.flat-inspector__body{flex:1 1 auto;min-height:0;min-width:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column}.flat-inspector__body .unit-panel{flex:1 1 auto;min-height:0;min-width:0;padding:10px}.flat-inspector__empty{display:flex;align-items:center;justify-content:center;flex:1;color:#6272a4;font-size:13px}@keyframes flat-inspector-slide-in{0%{opacity:0;transform:translate(12px)}to{opacity:1;transform:translate(0)}}@media(max-width:1024px){.flat-view,.flat-view--with-inspector{grid-template-columns:1fr}.flat-right,.flat-inspector{display:none}}@media(min-width:1400px){.flat-view{grid-template-columns:minmax(280px,400px) 1fr}.flat-view--with-inspector{grid-template-columns:minmax(280px,400px) 1fr 360px}}.flat-bottom-panel{display:flex;flex-direction:column;flex-shrink:0;height:250px;min-height:0;background:#1e1f29;border-top:1px solid rgba(255,255,255,.08);overflow:hidden}.flat-bottom-panel__header{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:4px 10px;background:#21222c;border-bottom:1px solid rgba(255,255,255,.06);flex-shrink:0;min-height:28px}.flat-bottom-panel__title{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:500;color:#f8f8f2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.flat-bottom-panel__muted{color:#6272a4;font-weight:400;font-size:10px}.flat-bottom-panel__close{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;color:#6272a4;background:transparent;border:none;border-radius:6px;cursor:pointer;transition:background .15s ease,color .15s ease}.flat-bottom-panel__close:hover{color:#f8f8f2;background:#ffffff14}.flat-bottom-panel__body{flex:1 1 auto;min-height:0;display:flex;background:#282a36}.flat-bottom-panel__body>*{flex:1 1 auto;min-height:0}.flat-bottom-panel__placeholder{flex:1 1 auto;display:flex;align-items:center;justify-content:center;color:#6272a4;font-size:12px}