copilotoffice 1.0.4 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/electron/main.js +21 -3
- package/dist/electron/terminal/ipc-relay.js +19 -2
- package/dist/electron/terminal/preload.js +3 -0
- package/dist/electron/terminal/server.js +46 -18
- package/dist/game.bundle.js +1888 -369
- package/package.json +1 -1
package/dist/game.bundle.js
CHANGED
|
@@ -140044,6 +140044,18 @@ var CopilotOffice = (() => {
|
|
|
140044
140044
|
CORE_AGENT_IDS.clear();
|
|
140045
140045
|
for (const a of AGENTS) CORE_AGENT_IDS.add(a.id);
|
|
140046
140046
|
}
|
|
140047
|
+
function restoreSeatedReserveAgents(seatedAgents) {
|
|
140048
|
+
const valid = [];
|
|
140049
|
+
for (const seated of seatedAgents) {
|
|
140050
|
+
const reserveConfig = RESERVE_AGENTS[seated.deskId];
|
|
140051
|
+
if (!reserveConfig || reserveConfig.id !== seated.agentId) continue;
|
|
140052
|
+
valid.push(seated);
|
|
140053
|
+
if (!AGENTS.find((a) => a.id === seated.agentId)) {
|
|
140054
|
+
AGENTS.push(reserveConfig);
|
|
140055
|
+
}
|
|
140056
|
+
}
|
|
140057
|
+
return valid;
|
|
140058
|
+
}
|
|
140047
140059
|
var FLEET_NAMES, FLEET_COLORS, FLEET_SEAT_POSITIONS, ARTHUR_FLEET_SEAT_INDEX, FLEET_AGENTS, RESERVE_AGENTS, SHOW_ARCHITECT_IN_DEFAULT_OFFICE, CORE_AGENT_IDS, RESERVE_AGENT_DESK, AGENTS, DEFAULT_AGENTS, DEFAULT_RESERVE_MAP, RANDOM_POOL_CONFIGS, RANDOM_SPRITE_COUNT, CORE_POSITIONS, RESERVE_DESK_IDS, RESERVE_POSITIONS, ROLE_TITLES;
|
|
140048
140060
|
var init_agents = __esm({
|
|
140049
140061
|
"src/config/agents.ts"() {
|
|
@@ -148603,10 +148615,17 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148603
148615
|
this.resizeHandler = null;
|
|
148604
148616
|
this.resizeObserver = null;
|
|
148605
148617
|
this.refitTimers = [];
|
|
148618
|
+
this.refitGeneration = 0;
|
|
148606
148619
|
this.attachedOfficeId = null;
|
|
148607
148620
|
this.isReadOnly = false;
|
|
148608
148621
|
this.isReplaying = false;
|
|
148609
148622
|
this.launchMode = "copilot";
|
|
148623
|
+
this.pendingInputLine = "";
|
|
148624
|
+
this.awaitingSessionIdRefresh = false;
|
|
148625
|
+
this.sessionRefreshCommandTimer = null;
|
|
148626
|
+
this.sessionRefreshExpiryTimer = null;
|
|
148627
|
+
this.currentSessionTitle = null;
|
|
148628
|
+
this.isEditingSessionTitle = false;
|
|
148610
148629
|
this.scene = scene;
|
|
148611
148630
|
this.inputManager = inputManager;
|
|
148612
148631
|
this.getOfficeId = getOfficeId;
|
|
@@ -148635,6 +148654,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148635
148654
|
[Process exited with code ${exitCode}]`);
|
|
148636
148655
|
}
|
|
148637
148656
|
});
|
|
148657
|
+
window.copilotBridge.onSessionMetaUpdated((agentId, meta) => {
|
|
148658
|
+
if (agentId === this.currentAgentId) {
|
|
148659
|
+
this.updateSessionTitleDisplay(meta?.title || null);
|
|
148660
|
+
}
|
|
148661
|
+
});
|
|
148638
148662
|
}
|
|
148639
148663
|
}
|
|
148640
148664
|
/**
|
|
@@ -148647,7 +148671,84 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148647
148671
|
this.setupTerminalListeners();
|
|
148648
148672
|
console.log("[TerminalOverlay] Re-attached terminal IPC listeners");
|
|
148649
148673
|
}
|
|
148650
|
-
|
|
148674
|
+
clearSessionRefreshTimers() {
|
|
148675
|
+
if (this.sessionRefreshCommandTimer) {
|
|
148676
|
+
clearTimeout(this.sessionRefreshCommandTimer);
|
|
148677
|
+
this.sessionRefreshCommandTimer = null;
|
|
148678
|
+
}
|
|
148679
|
+
if (this.sessionRefreshExpiryTimer) {
|
|
148680
|
+
clearTimeout(this.sessionRefreshExpiryTimer);
|
|
148681
|
+
this.sessionRefreshExpiryTimer = null;
|
|
148682
|
+
}
|
|
148683
|
+
}
|
|
148684
|
+
scheduleSessionIdRefresh(agentId) {
|
|
148685
|
+
if (!window.copilotBridge) return;
|
|
148686
|
+
const officeId = this.getActiveOfficeId();
|
|
148687
|
+
this.awaitingSessionIdRefresh = true;
|
|
148688
|
+
this.clearSessionRefreshTimers();
|
|
148689
|
+
const el = this.spriteCardElement?.querySelector(".session-id-display");
|
|
148690
|
+
if (el) {
|
|
148691
|
+
el.textContent = "syncing...";
|
|
148692
|
+
}
|
|
148693
|
+
this.sessionRefreshCommandTimer = setTimeout(() => {
|
|
148694
|
+
this.sessionRefreshCommandTimer = null;
|
|
148695
|
+
void window.copilotBridge.terminalWrite(officeId, agentId, "/session\r").catch(() => {
|
|
148696
|
+
});
|
|
148697
|
+
}, 400);
|
|
148698
|
+
this.sessionRefreshExpiryTimer = setTimeout(() => {
|
|
148699
|
+
this.sessionRefreshExpiryTimer = null;
|
|
148700
|
+
this.awaitingSessionIdRefresh = false;
|
|
148701
|
+
this.updateSessionDisplay();
|
|
148702
|
+
}, 12e3);
|
|
148703
|
+
}
|
|
148704
|
+
parseSessionId(data) {
|
|
148705
|
+
if (!this.awaitingSessionIdRefresh || !this.currentAgentId || !window.copilotBridge) return;
|
|
148706
|
+
const match = data.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);
|
|
148707
|
+
if (!match) return;
|
|
148708
|
+
const nextSessionId = match[0].toLowerCase();
|
|
148709
|
+
this.awaitingSessionIdRefresh = false;
|
|
148710
|
+
this.clearSessionRefreshTimers();
|
|
148711
|
+
this.sessionId = nextSessionId;
|
|
148712
|
+
this.updateSessionDisplay();
|
|
148713
|
+
const officeId = this.getActiveOfficeId();
|
|
148714
|
+
void window.copilotBridge.setSessionId(officeId, this.currentAgentId, nextSessionId).catch(() => {
|
|
148715
|
+
});
|
|
148716
|
+
}
|
|
148717
|
+
getActiveOfficeId() {
|
|
148718
|
+
return this.attachedOfficeId ?? this.getOfficeId();
|
|
148719
|
+
}
|
|
148720
|
+
clearRefitTimers() {
|
|
148721
|
+
for (const timer of this.refitTimers) {
|
|
148722
|
+
clearTimeout(timer);
|
|
148723
|
+
}
|
|
148724
|
+
this.refitTimers.length = 0;
|
|
148725
|
+
}
|
|
148726
|
+
resolveTerminalDimensions() {
|
|
148727
|
+
if (!this.terminal || !this.fitAddon) return null;
|
|
148728
|
+
this.fitAddon.fit();
|
|
148729
|
+
const proposed = this.fitAddon.proposeDimensions();
|
|
148730
|
+
const fallbackCols = this.terminal.cols || 80;
|
|
148731
|
+
const fallbackRows = this.terminal.rows || 24;
|
|
148732
|
+
const colsRaw = proposed?.cols ?? fallbackCols;
|
|
148733
|
+
const rowsRaw = proposed?.rows ?? fallbackRows;
|
|
148734
|
+
if (!Number.isFinite(colsRaw) || !Number.isFinite(rowsRaw)) return null;
|
|
148735
|
+
const cols = Math.max(2, Math.floor(colsRaw));
|
|
148736
|
+
const rows = Math.max(1, Math.floor(rowsRaw));
|
|
148737
|
+
return { cols, rows };
|
|
148738
|
+
}
|
|
148739
|
+
fitAndResizeTerminal(options) {
|
|
148740
|
+
if (!this.terminal || !this.fitAddon) return null;
|
|
148741
|
+
const dims = this.resolveTerminalDimensions();
|
|
148742
|
+
if (!dims) return null;
|
|
148743
|
+
const agentId = options?.agentId ?? this.currentAgentId;
|
|
148744
|
+
if (!agentId || !window.copilotBridge) return dims;
|
|
148745
|
+
const officeId = options?.officeId ?? this.getActiveOfficeId();
|
|
148746
|
+
void window.copilotBridge.terminalResize(officeId, agentId, dims.cols, dims.rows).catch(() => {
|
|
148747
|
+
});
|
|
148748
|
+
if (options?.refreshVisibleRows) {
|
|
148749
|
+
this.terminal.refresh(0, Math.max(0, dims.rows - 1));
|
|
148750
|
+
}
|
|
148751
|
+
return dims;
|
|
148651
148752
|
}
|
|
148652
148753
|
acknowledgeCompletedWork(officeId, agentId) {
|
|
148653
148754
|
if (agentId === "pc-terminal") return;
|
|
@@ -148659,10 +148760,92 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148659
148760
|
const el = this.spriteCardElement?.querySelector(".session-id-display");
|
|
148660
148761
|
if (el && this.sessionId) {
|
|
148661
148762
|
el.textContent = this.sessionId;
|
|
148662
|
-
el.title = `Click to copy. Resume with: copilot --
|
|
148763
|
+
el.title = `Click to copy. Resume with: copilot --session-id ${this.sessionId}`;
|
|
148663
148764
|
el.onclick = () => this.copySessionId();
|
|
148664
148765
|
}
|
|
148665
148766
|
}
|
|
148767
|
+
updateSessionTitleDisplay(title) {
|
|
148768
|
+
this.currentSessionTitle = title && title.trim().length > 0 ? title : null;
|
|
148769
|
+
if (this.isEditingSessionTitle) return;
|
|
148770
|
+
const el = this.spriteCardElement?.querySelector(".session-title-display");
|
|
148771
|
+
if (!el) return;
|
|
148772
|
+
if (this.currentSessionTitle) {
|
|
148773
|
+
el.textContent = this.currentSessionTitle;
|
|
148774
|
+
el.title = this.currentSessionTitle;
|
|
148775
|
+
el.style.color = "#c8d4ff";
|
|
148776
|
+
return;
|
|
148777
|
+
}
|
|
148778
|
+
el.textContent = "Untitled session";
|
|
148779
|
+
el.title = "Click to set title";
|
|
148780
|
+
el.style.color = "#77839f";
|
|
148781
|
+
}
|
|
148782
|
+
async startSessionTitleEdit() {
|
|
148783
|
+
if (this.isReadOnly || !this.currentAgentId || this.isEditingSessionTitle || !this.spriteCardElement || !window.copilotBridge?.setSessionMeta) return;
|
|
148784
|
+
const titleEl = this.spriteCardElement.querySelector(".session-title-display");
|
|
148785
|
+
if (!titleEl) return;
|
|
148786
|
+
this.isEditingSessionTitle = true;
|
|
148787
|
+
const previousTitle = this.currentSessionTitle || "";
|
|
148788
|
+
const input = document.createElement("input");
|
|
148789
|
+
input.type = "text";
|
|
148790
|
+
input.value = previousTitle;
|
|
148791
|
+
input.maxLength = 120;
|
|
148792
|
+
input.className = "session-title-input";
|
|
148793
|
+
input.style.cssText = `
|
|
148794
|
+
width: min(520px, 52vw);
|
|
148795
|
+
max-width: 100%;
|
|
148796
|
+
background: #101629;
|
|
148797
|
+
color: #dbe6ff;
|
|
148798
|
+
border: 1px solid #3f5c92;
|
|
148799
|
+
border-radius: 6px;
|
|
148800
|
+
padding: 6px 10px;
|
|
148801
|
+
font-size: 15px;
|
|
148802
|
+
font-weight: 700;
|
|
148803
|
+
font-family: 'Cascadia Code', Consolas, monospace;
|
|
148804
|
+
line-height: 1.25;
|
|
148805
|
+
outline: none;
|
|
148806
|
+
`;
|
|
148807
|
+
titleEl.replaceWith(input);
|
|
148808
|
+
input.focus();
|
|
148809
|
+
input.select();
|
|
148810
|
+
const agentId = this.currentAgentId;
|
|
148811
|
+
let finalized = false;
|
|
148812
|
+
const finalize = async (save) => {
|
|
148813
|
+
if (finalized) return;
|
|
148814
|
+
finalized = true;
|
|
148815
|
+
const nextTitle = save ? input.value.trim() : previousTitle;
|
|
148816
|
+
if (save) {
|
|
148817
|
+
try {
|
|
148818
|
+
await withTimeout(
|
|
148819
|
+
window.copilotBridge.setSessionMeta(this.getActiveOfficeId(), agentId, { title: nextTitle }),
|
|
148820
|
+
IPC_TIMEOUT,
|
|
148821
|
+
"setSessionMeta"
|
|
148822
|
+
);
|
|
148823
|
+
} catch (error) {
|
|
148824
|
+
console.warn("[TerminalOverlay] Failed to save session title", error);
|
|
148825
|
+
}
|
|
148826
|
+
}
|
|
148827
|
+
this.isEditingSessionTitle = false;
|
|
148828
|
+
this.currentSessionTitle = nextTitle || null;
|
|
148829
|
+
if (!input.isConnected || !this.spriteCardElement) {
|
|
148830
|
+
this.updateSessionTitleDisplay(this.currentSessionTitle);
|
|
148831
|
+
return;
|
|
148832
|
+
}
|
|
148833
|
+
input.replaceWith(titleEl);
|
|
148834
|
+
this.updateSessionTitleDisplay(this.currentSessionTitle);
|
|
148835
|
+
};
|
|
148836
|
+
input.addEventListener("keydown", (event) => {
|
|
148837
|
+
if (event.key === "Enter") {
|
|
148838
|
+
event.preventDefault();
|
|
148839
|
+
void finalize(true);
|
|
148840
|
+
} else if (event.key === "Escape") {
|
|
148841
|
+
event.preventDefault();
|
|
148842
|
+
void finalize(false);
|
|
148843
|
+
}
|
|
148844
|
+
});
|
|
148845
|
+
input.addEventListener("blur", () => {
|
|
148846
|
+
void finalize(true);
|
|
148847
|
+
});
|
|
148848
|
+
}
|
|
148666
148849
|
async show(agent, onClose, options) {
|
|
148667
148850
|
const previousAgentId = this.currentAgentId;
|
|
148668
148851
|
const previousOfficeId = this.attachedOfficeId ?? this.getOfficeId();
|
|
@@ -148674,24 +148857,26 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148674
148857
|
this.isReadOnly = options?.readOnly ?? false;
|
|
148675
148858
|
this.launchMode = options?.launchMode ?? "copilot";
|
|
148676
148859
|
this.attachedOfficeId = this.getOfficeId();
|
|
148860
|
+
const officeId = this.getActiveOfficeId();
|
|
148677
148861
|
this.currentAgent = agent;
|
|
148678
148862
|
if (!this.container) {
|
|
148679
148863
|
this.createContainer();
|
|
148680
148864
|
}
|
|
148681
148865
|
const inceptionBadge = agent.id === "admin" ? " \u{1F3AD} INCEPTION MODE" : "";
|
|
148682
|
-
let
|
|
148866
|
+
let sessionTitle = null;
|
|
148683
148867
|
if (window.copilotBridge?.getSessionMeta) {
|
|
148684
148868
|
try {
|
|
148685
|
-
const meta = await window.copilotBridge.getSessionMeta(
|
|
148869
|
+
const meta = await window.copilotBridge.getSessionMeta(officeId, agent.id);
|
|
148686
148870
|
if (meta?.title) {
|
|
148687
|
-
|
|
148871
|
+
sessionTitle = meta.title;
|
|
148688
148872
|
}
|
|
148689
148873
|
} catch (_) {
|
|
148690
148874
|
}
|
|
148691
148875
|
}
|
|
148876
|
+
const sessionTitleHtml = sessionTitle ? ` <span style="color: #aab; font-size: 15px;">\u2014 ${sessionTitle.replace(/</g, "<")}</span>` : "";
|
|
148692
148877
|
if (this.headerElement) {
|
|
148693
148878
|
const readOnlyBadge = this.isReadOnly ? ' <span style="color: #ffb86c; font-size: 12px; background: #332200; padding: 2px 8px; border-radius: 4px;">\u{1F512} READ-ONLY</span>' : "";
|
|
148694
|
-
const shortcutsText = this.isReadOnly ? "[F10] Close [Ctrl+F] Fullscreen" : "[F10] Close [Ctrl+Shift+N] New Session [Ctrl+F] Fullscreen";
|
|
148879
|
+
const shortcutsText = this.isReadOnly ? "[F10] Close [Ctrl+F] Fullscreen" : "[F10] Close [/new or Ctrl+Shift+N] New Session [Ctrl+F] Fullscreen";
|
|
148695
148880
|
const headerLabel = this.isReadOnly ? `\u{1F4DC} Meeting with ${agent.name}` : `\u{1F4AC} Talking to ${agent.name}`;
|
|
148696
148881
|
this.headerElement.innerHTML = `
|
|
148697
148882
|
<div style="display: flex; align-items: center; gap: 15px;">
|
|
@@ -148714,6 +148899,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148714
148899
|
if (this.container) {
|
|
148715
148900
|
this.container.style.display = "flex";
|
|
148716
148901
|
}
|
|
148902
|
+
this.awaitingSessionIdRefresh = false;
|
|
148903
|
+
this.clearSessionRefreshTimers();
|
|
148717
148904
|
if (this.spriteCardElement) {
|
|
148718
148905
|
this.spriteCardElement.style.display = "flex";
|
|
148719
148906
|
}
|
|
@@ -148727,27 +148914,39 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148727
148914
|
agentNameDisplay.textContent = agent.name;
|
|
148728
148915
|
agentNameDisplay.style.color = colorHex;
|
|
148729
148916
|
}
|
|
148917
|
+
const agentDescriptionDisplay = this.spriteCardElement?.querySelector(".agent-description-display");
|
|
148918
|
+
if (agentDescriptionDisplay) {
|
|
148919
|
+
agentDescriptionDisplay.textContent = agent.description;
|
|
148920
|
+
}
|
|
148921
|
+
this.updateSessionTitleDisplay(sessionTitle);
|
|
148730
148922
|
this.drawAgentSprite(agent);
|
|
148923
|
+
this.pendingInputLine = "";
|
|
148924
|
+
this.awaitingSessionIdRefresh = false;
|
|
148925
|
+
this.clearSessionRefreshTimers();
|
|
148926
|
+
this.clearRefitTimers();
|
|
148927
|
+
this.refitGeneration += 1;
|
|
148731
148928
|
if (!this.terminal) {
|
|
148732
148929
|
this.createTerminal();
|
|
148733
148930
|
} else {
|
|
148734
148931
|
this.isReplaying = true;
|
|
148932
|
+
this.terminal.reset();
|
|
148735
148933
|
this.terminal.clear();
|
|
148736
148934
|
}
|
|
148737
148935
|
this.sessionId = null;
|
|
148738
148936
|
if (window.copilotBridge) {
|
|
148739
148937
|
try {
|
|
148740
148938
|
const exists = await withTimeout(
|
|
148741
|
-
window.copilotBridge.terminalExists(
|
|
148939
|
+
window.copilotBridge.terminalExists(officeId, agent.id),
|
|
148742
148940
|
IPC_TIMEOUT,
|
|
148743
148941
|
"terminalExists"
|
|
148744
148942
|
);
|
|
148745
148943
|
if (!exists) {
|
|
148746
148944
|
this.isReplaying = false;
|
|
148747
|
-
await this.startNewSession(agent.id, agent.workingDir || officeManager.getCurrentWorkingDirectory());
|
|
148945
|
+
await this.startNewSession(agent.id, agent.workingDir || officeManager.getCurrentWorkingDirectory(), officeId);
|
|
148748
148946
|
} else {
|
|
148947
|
+
this.fitAndResizeTerminal({ officeId, agentId: agent.id });
|
|
148749
148948
|
const attachResult = await withTimeout(
|
|
148750
|
-
window.copilotBridge.terminalAttach(
|
|
148949
|
+
window.copilotBridge.terminalAttach(officeId, agent.id),
|
|
148751
148950
|
IPC_TIMEOUT,
|
|
148752
148951
|
"terminalAttach"
|
|
148753
148952
|
);
|
|
@@ -148758,7 +148957,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148758
148957
|
this.isReplaying = false;
|
|
148759
148958
|
this.scene.game.events.emit("agent:reattached", agent.id);
|
|
148760
148959
|
const savedId = await withTimeout(
|
|
148761
|
-
window.copilotBridge.getSessionId(
|
|
148960
|
+
window.copilotBridge.getSessionId(officeId, agent.id),
|
|
148762
148961
|
IPC_TIMEOUT,
|
|
148763
148962
|
"getSessionId"
|
|
148764
148963
|
);
|
|
@@ -148806,18 +149005,20 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148806
149005
|
}
|
|
148807
149006
|
}, 50);
|
|
148808
149007
|
}
|
|
148809
|
-
async startNewSession(agentId, workingDir) {
|
|
149008
|
+
async startNewSession(agentId, workingDir, officeId) {
|
|
149009
|
+
this.awaitingSessionIdRefresh = false;
|
|
149010
|
+
this.clearSessionRefreshTimers();
|
|
148810
149011
|
this.sessionId = null;
|
|
148811
149012
|
this.updateSessionDisplay();
|
|
148812
149013
|
const el = this.spriteCardElement?.querySelector(".session-id-display");
|
|
148813
149014
|
if (el) {
|
|
148814
149015
|
el.textContent = "starting...";
|
|
148815
149016
|
}
|
|
148816
|
-
this.
|
|
148817
|
-
const dims = this.
|
|
149017
|
+
const targetOfficeId = officeId ?? this.getActiveOfficeId();
|
|
149018
|
+
const dims = this.fitAndResizeTerminal({ officeId: targetOfficeId, agentId });
|
|
148818
149019
|
const result = await withTimeout(
|
|
148819
149020
|
this.launchMode === "shell" ? window.copilotBridge.terminalStart(
|
|
148820
|
-
|
|
149021
|
+
targetOfficeId,
|
|
148821
149022
|
agentId,
|
|
148822
149023
|
workingDir,
|
|
148823
149024
|
dims?.cols,
|
|
@@ -148825,7 +149026,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148825
149026
|
void 0,
|
|
148826
149027
|
"shell"
|
|
148827
149028
|
) : window.copilotBridge.terminalStart(
|
|
148828
|
-
|
|
149029
|
+
targetOfficeId,
|
|
148829
149030
|
agentId,
|
|
148830
149031
|
workingDir,
|
|
148831
149032
|
dims?.cols,
|
|
@@ -148842,15 +149043,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148842
149043
|
}
|
|
148843
149044
|
}
|
|
148844
149045
|
fetchSessionId(agentId) {
|
|
148845
|
-
|
|
148846
|
-
const el = this.spriteCardElement?.querySelector(".session-id-display");
|
|
148847
|
-
if (el) {
|
|
148848
|
-
el.textContent = "fetching...";
|
|
148849
|
-
}
|
|
148850
|
-
setTimeout(() => {
|
|
148851
|
-
window.copilotBridge.terminalWrite(this.getOfficeId(), agentId, "/session\r");
|
|
148852
|
-
}, 200);
|
|
148853
|
-
}
|
|
149046
|
+
this.scheduleSessionIdRefresh(agentId);
|
|
148854
149047
|
}
|
|
148855
149048
|
createContainer() {
|
|
148856
149049
|
this.container = document.createElement("div");
|
|
@@ -148925,8 +149118,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148925
149118
|
this.spriteCardElement.id = "sprite-card";
|
|
148926
149119
|
this.spriteCardElement.style.cssText = `
|
|
148927
149120
|
width: 100%;
|
|
148928
|
-
background: #
|
|
148929
|
-
border-top: 1px solid #
|
|
149121
|
+
background: #13131f;
|
|
149122
|
+
border-top: 1px solid #252540;
|
|
148930
149123
|
font-family: 'Cascadia Code', Consolas, monospace;
|
|
148931
149124
|
font-size: 14px;
|
|
148932
149125
|
color: #888;
|
|
@@ -148934,7 +149127,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148934
149127
|
flex-shrink: 0;
|
|
148935
149128
|
justify-content: space-between;
|
|
148936
149129
|
align-items: center;
|
|
148937
|
-
padding:
|
|
149130
|
+
padding: 16px 24px;
|
|
148938
149131
|
box-sizing: border-box;
|
|
148939
149132
|
position: relative;
|
|
148940
149133
|
z-index: 10001;
|
|
@@ -148947,13 +149140,32 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148947
149140
|
gap: 20px;
|
|
148948
149141
|
`;
|
|
148949
149142
|
agentDisplay.innerHTML = `
|
|
148950
|
-
<
|
|
148951
|
-
|
|
148952
|
-
|
|
148953
|
-
|
|
149143
|
+
<div style="width: 72px; background: #2a2a40; border: 1px solid #3a3a58; border-radius: 8px; display: flex; align-items: center; justify-content: center; overflow: hidden; flex-shrink: 0;">
|
|
149144
|
+
<canvas class="agent-sprite-canvas" width="32" height="34" style="image-rendering: pixelated; width: 64px; height: 68px; display: block;"></canvas>
|
|
149145
|
+
</div>
|
|
149146
|
+
<div style="display: flex; flex-direction: column; gap: 4px; min-width: 0;">
|
|
149147
|
+
<span class="agent-name-display" style="font-weight: 700; font-size: 18px; color: #dde;"></span>
|
|
149148
|
+
<span class="agent-description-display" style="color: #778; font-size: 13px; line-height: 1.25;"></span>
|
|
149149
|
+
<span class="session-title-display" style="color: #c8d4ff; font-size: 14px; font-weight: 700; line-height: 1.25; cursor: text; max-width: min(520px, 52vw); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">Untitled session</span>
|
|
149150
|
+
<span style="color: #666; font-size: 11px;">Session ID: <span class="session-id-display" style="color: #4a9eff; cursor: pointer;">--</span></span>
|
|
148954
149151
|
</div>
|
|
148955
149152
|
`;
|
|
148956
149153
|
this.spriteCardElement.appendChild(agentDisplay);
|
|
149154
|
+
const sessionTitleDisplay = this.spriteCardElement.querySelector(".session-title-display");
|
|
149155
|
+
if (sessionTitleDisplay) {
|
|
149156
|
+
sessionTitleDisplay.onclick = () => {
|
|
149157
|
+
void this.startSessionTitleEdit();
|
|
149158
|
+
};
|
|
149159
|
+
sessionTitleDisplay.onkeydown = (event) => {
|
|
149160
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
149161
|
+
event.preventDefault();
|
|
149162
|
+
void this.startSessionTitleEdit();
|
|
149163
|
+
}
|
|
149164
|
+
};
|
|
149165
|
+
sessionTitleDisplay.tabIndex = 0;
|
|
149166
|
+
sessionTitleDisplay.setAttribute("role", "button");
|
|
149167
|
+
sessionTitleDisplay.setAttribute("aria-label", "Edit session title");
|
|
149168
|
+
}
|
|
148957
149169
|
const controlsColumn = document.createElement("div");
|
|
148958
149170
|
controlsColumn.style.cssText = `
|
|
148959
149171
|
display: flex;
|
|
@@ -148979,28 +149191,28 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
148979
149191
|
white-space: nowrap;
|
|
148980
149192
|
`;
|
|
148981
149193
|
const historyBtn = document.createElement("button");
|
|
148982
|
-
historyBtn.textContent = "
|
|
149194
|
+
historyBtn.textContent = "Session History";
|
|
148983
149195
|
historyBtn.style.cssText = btnStyle;
|
|
148984
149196
|
historyBtn.onmouseover = () => historyBtn.style.background = "#3a4a5a";
|
|
148985
149197
|
historyBtn.onmouseout = () => historyBtn.style.background = "#2a3a4a";
|
|
148986
149198
|
historyBtn.onclick = () => this.toggleSessionHistory(historyBtn);
|
|
148987
149199
|
buttonGrid.appendChild(historyBtn);
|
|
148988
149200
|
const newSessionBtn = document.createElement("button");
|
|
148989
|
-
newSessionBtn.textContent = "
|
|
149201
|
+
newSessionBtn.textContent = "New Session";
|
|
148990
149202
|
newSessionBtn.style.cssText = btnStyle;
|
|
148991
149203
|
newSessionBtn.onmouseover = () => newSessionBtn.style.background = "#3a4a5a";
|
|
148992
149204
|
newSessionBtn.onmouseout = () => newSessionBtn.style.background = "#2a3a4a";
|
|
148993
149205
|
newSessionBtn.onclick = () => this.handleNewSession();
|
|
148994
149206
|
buttonGrid.appendChild(newSessionBtn);
|
|
148995
149207
|
const clearHistoryBtn = document.createElement("button");
|
|
148996
|
-
clearHistoryBtn.textContent = "
|
|
149208
|
+
clearHistoryBtn.textContent = "Clear History";
|
|
148997
149209
|
clearHistoryBtn.style.cssText = btnStyle;
|
|
148998
149210
|
clearHistoryBtn.onmouseover = () => clearHistoryBtn.style.background = "#3a4a5a";
|
|
148999
149211
|
clearHistoryBtn.onmouseout = () => clearHistoryBtn.style.background = "#2a3a4a";
|
|
149000
149212
|
clearHistoryBtn.onclick = () => this.handleClearHistory();
|
|
149001
149213
|
buttonGrid.appendChild(clearHistoryBtn);
|
|
149002
149214
|
const closeSessionBtn = document.createElement("button");
|
|
149003
|
-
closeSessionBtn.textContent = "
|
|
149215
|
+
closeSessionBtn.textContent = "Close Session";
|
|
149004
149216
|
closeSessionBtn.style.cssText = btnStyle + "color: #ff8888;";
|
|
149005
149217
|
closeSessionBtn.onmouseover = () => {
|
|
149006
149218
|
closeSessionBtn.style.background = "#4a2a2a";
|
|
@@ -149011,7 +149223,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149011
149223
|
closeSessionBtn.onclick = () => this.handleCloseSession();
|
|
149012
149224
|
buttonGrid.appendChild(closeSessionBtn);
|
|
149013
149225
|
this.fullscreenBtn = document.createElement("button");
|
|
149014
|
-
this.fullscreenBtn.textContent = this.isFullWidth ? "
|
|
149226
|
+
this.fullscreenBtn.textContent = this.isFullWidth ? "Half Width" : "Full Width";
|
|
149015
149227
|
this.fullscreenBtn.style.cssText = btnStyle + "color: #88ccff;";
|
|
149016
149228
|
this.fullscreenBtn.onmouseover = () => {
|
|
149017
149229
|
if (this.fullscreenBtn) this.fullscreenBtn.style.background = "#2a3a5a";
|
|
@@ -149023,7 +149235,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149023
149235
|
this.fullscreenBtn.title = "Toggle fullscreen (Ctrl+F)";
|
|
149024
149236
|
buttonGrid.appendChild(this.fullscreenBtn);
|
|
149025
149237
|
const refreshFocusBtn = document.createElement("button");
|
|
149026
|
-
refreshFocusBtn.textContent = "
|
|
149238
|
+
refreshFocusBtn.textContent = "Refresh Focus";
|
|
149027
149239
|
refreshFocusBtn.style.cssText = btnStyle + "color: #88ffaa;";
|
|
149028
149240
|
refreshFocusBtn.onmouseover = () => {
|
|
149029
149241
|
refreshFocusBtn.style.background = "#2a4a3a";
|
|
@@ -149031,8 +149243,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149031
149243
|
refreshFocusBtn.onmouseout = () => {
|
|
149032
149244
|
refreshFocusBtn.style.background = "#2a3a4a";
|
|
149033
149245
|
};
|
|
149034
|
-
refreshFocusBtn.onclick = () => this.
|
|
149035
|
-
refreshFocusBtn.title = "Re-focus terminal
|
|
149246
|
+
refreshFocusBtn.onclick = () => this.refreshFocusAndGeometry();
|
|
149247
|
+
refreshFocusBtn.title = "Re-focus terminal and force geometry self-heal";
|
|
149036
149248
|
buttonGrid.appendChild(refreshFocusBtn);
|
|
149037
149249
|
this.mobileKeyboardBtn = document.createElement("button");
|
|
149038
149250
|
this.mobileKeyboardBtn.textContent = "\u2328 Open Keyboard";
|
|
@@ -149083,8 +149295,13 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149083
149295
|
}
|
|
149084
149296
|
async handleNewSession() {
|
|
149085
149297
|
if (!this.currentAgentId || !this.currentAgent || this.isReadOnly) return;
|
|
149298
|
+
this.awaitingSessionIdRefresh = false;
|
|
149299
|
+
this.clearSessionRefreshTimers();
|
|
149086
149300
|
const officeId = this.attachedOfficeId ?? this.getOfficeId();
|
|
149087
149301
|
console.log(`[TerminalOverlay] handleNewSession: agent=${this.currentAgentId}, office=${officeId}`);
|
|
149302
|
+
this.clearRefitTimers();
|
|
149303
|
+
this.refitGeneration += 1;
|
|
149304
|
+
this.pendingInputLine = "";
|
|
149088
149305
|
this.terminal?.clear();
|
|
149089
149306
|
this.terminal?.writeln("\x1B[33m[Starting new session...]\x1B[0m\r\n");
|
|
149090
149307
|
await withTimeout(
|
|
@@ -149097,8 +149314,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149097
149314
|
if (el) el.textContent = "starting...";
|
|
149098
149315
|
this.sessionId = null;
|
|
149099
149316
|
this.updateSessionDisplay();
|
|
149100
|
-
this.
|
|
149101
|
-
const dims = this.
|
|
149317
|
+
this.updateSessionTitleDisplay(null);
|
|
149318
|
+
const dims = this.fitAndResizeTerminal({ officeId, agentId: this.currentAgentId });
|
|
149102
149319
|
const result = await withTimeout(
|
|
149103
149320
|
this.launchMode === "shell" ? window.copilotBridge.terminalStart(
|
|
149104
149321
|
officeId,
|
|
@@ -149138,6 +149355,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149138
149355
|
if (result.success && result.sessionId) {
|
|
149139
149356
|
this.sessionId = result.sessionId;
|
|
149140
149357
|
this.updateSessionDisplay();
|
|
149358
|
+
this.updateSessionTitleDisplay(null);
|
|
149141
149359
|
}
|
|
149142
149360
|
} catch {
|
|
149143
149361
|
}
|
|
@@ -149240,9 +149458,6 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149240
149458
|
.xterm-viewport {
|
|
149241
149459
|
background-color: #0a0a14 !important;
|
|
149242
149460
|
}
|
|
149243
|
-
.xterm-screen {
|
|
149244
|
-
height: 100%;
|
|
149245
|
-
}
|
|
149246
149461
|
#terminal-container .xterm {
|
|
149247
149462
|
height: 100%;
|
|
149248
149463
|
}
|
|
@@ -149286,10 +149501,27 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149286
149501
|
this.fitAddon = new import_addon_fit.FitAddon();
|
|
149287
149502
|
this.terminal.loadAddon(this.fitAddon);
|
|
149288
149503
|
this.terminal.open(this.terminalDiv);
|
|
149289
|
-
this.
|
|
149504
|
+
this.fitAndResizeTerminal();
|
|
149290
149505
|
this.terminal.attachCustomKeyEventHandler((event) => {
|
|
149291
|
-
|
|
149506
|
+
const isModifierPressed = event.ctrlKey || event.metaKey;
|
|
149507
|
+
const key = event.key.toLowerCase();
|
|
149508
|
+
if (event.type !== "keydown" || !isModifierPressed) return true;
|
|
149509
|
+
if (key === "c") {
|
|
149510
|
+
const selectedText = this.terminal?.hasSelection() ? this.terminal.getSelection() : "";
|
|
149511
|
+
if (!selectedText) {
|
|
149512
|
+
return true;
|
|
149513
|
+
}
|
|
149514
|
+
event.preventDefault();
|
|
149515
|
+
event.stopPropagation();
|
|
149516
|
+
navigator.clipboard.writeText(selectedText).catch((err) => {
|
|
149517
|
+
console.warn("[Terminal] Clipboard write failed:", err);
|
|
149518
|
+
});
|
|
149519
|
+
return false;
|
|
149520
|
+
}
|
|
149521
|
+
if (key === "v") {
|
|
149292
149522
|
if (this.isReadOnly) return false;
|
|
149523
|
+
event.preventDefault();
|
|
149524
|
+
event.stopPropagation();
|
|
149293
149525
|
navigator.clipboard.readText().then((text) => {
|
|
149294
149526
|
if (text) this.terminal.paste(text);
|
|
149295
149527
|
}).catch((err) => {
|
|
@@ -149301,8 +149533,34 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149301
149533
|
});
|
|
149302
149534
|
this.terminal.onData((data) => {
|
|
149303
149535
|
if (this.isReadOnly) return;
|
|
149304
|
-
if (this.currentAgentId
|
|
149305
|
-
|
|
149536
|
+
if (!this.currentAgentId || !window.copilotBridge) return;
|
|
149537
|
+
let outbound = "";
|
|
149538
|
+
let shouldStartSlashNewSession = false;
|
|
149539
|
+
for (const ch of data) {
|
|
149540
|
+
if (ch === "\r" || ch === "\n") {
|
|
149541
|
+
const command = this.pendingInputLine.trim();
|
|
149542
|
+
this.pendingInputLine = "";
|
|
149543
|
+
if (command === "/new") {
|
|
149544
|
+
shouldStartSlashNewSession = true;
|
|
149545
|
+
}
|
|
149546
|
+
outbound += ch;
|
|
149547
|
+
continue;
|
|
149548
|
+
}
|
|
149549
|
+
if (ch === "\x7F") {
|
|
149550
|
+
this.pendingInputLine = this.pendingInputLine.slice(0, -1);
|
|
149551
|
+
outbound += ch;
|
|
149552
|
+
continue;
|
|
149553
|
+
}
|
|
149554
|
+
if (ch >= " ") {
|
|
149555
|
+
this.pendingInputLine += ch;
|
|
149556
|
+
}
|
|
149557
|
+
outbound += ch;
|
|
149558
|
+
}
|
|
149559
|
+
if (outbound.length > 0) {
|
|
149560
|
+
window.copilotBridge.terminalWrite(this.getOfficeId(), this.currentAgentId, outbound);
|
|
149561
|
+
}
|
|
149562
|
+
if (shouldStartSlashNewSession) {
|
|
149563
|
+
this.fetchSessionId(this.currentAgentId);
|
|
149306
149564
|
}
|
|
149307
149565
|
});
|
|
149308
149566
|
this.resizeHandler = () => {
|
|
@@ -149370,18 +149628,27 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149370
149628
|
officePanel.style.width = "50%";
|
|
149371
149629
|
terminalPanel.style.width = "50%";
|
|
149372
149630
|
}
|
|
149631
|
+
refreshFocusAndGeometry() {
|
|
149632
|
+
this.clearRefitTimers();
|
|
149633
|
+
this.refitGeneration += 1;
|
|
149634
|
+
this.fitAndResizeTerminal({ refreshVisibleRows: true });
|
|
149635
|
+
this.focusTerminal();
|
|
149636
|
+
this.debouncedRefit();
|
|
149637
|
+
}
|
|
149373
149638
|
/** Re-fit xterm after panel resize and notify PTY of new dimensions.
|
|
149374
149639
|
* Multi-stage: immediate → 150ms → 350ms to catch late layout shifts. */
|
|
149375
149640
|
debouncedRefit() {
|
|
149376
149641
|
if (!this.fitAddon || !this.terminal || !this.currentAgentId) return;
|
|
149377
|
-
|
|
149378
|
-
|
|
149642
|
+
const generation = ++this.refitGeneration;
|
|
149643
|
+
const agentId = this.currentAgentId;
|
|
149644
|
+
const officeId = this.getActiveOfficeId();
|
|
149645
|
+
this.clearRefitTimers();
|
|
149379
149646
|
const doFit = () => {
|
|
149380
|
-
this.
|
|
149381
|
-
|
|
149382
|
-
if (
|
|
149383
|
-
|
|
149384
|
-
}
|
|
149647
|
+
if (!this.isVisible) return;
|
|
149648
|
+
if (generation !== this.refitGeneration) return;
|
|
149649
|
+
if (this.currentAgentId !== agentId) return;
|
|
149650
|
+
if (this.getActiveOfficeId() !== officeId) return;
|
|
149651
|
+
this.fitAndResizeTerminal({ officeId, agentId });
|
|
149385
149652
|
};
|
|
149386
149653
|
requestAnimationFrame(() => {
|
|
149387
149654
|
doFit();
|
|
@@ -149405,14 +149672,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149405
149672
|
}
|
|
149406
149673
|
applySpriteCardResponsiveStyles() {
|
|
149407
149674
|
if (!this.spriteCardElement) return;
|
|
149408
|
-
const isMobile = window.__copilotOfficeMobileModeActive?.() === true;
|
|
149409
|
-
if (isMobile) {
|
|
149410
|
-
this.spriteCardElement.style.minHeight = "416px";
|
|
149411
|
-
this.spriteCardElement.style.padding = "39px";
|
|
149412
|
-
return;
|
|
149413
|
-
}
|
|
149414
149675
|
this.spriteCardElement.style.minHeight = "";
|
|
149415
|
-
this.spriteCardElement.style.padding = "
|
|
149676
|
+
this.spriteCardElement.style.padding = "16px 24px";
|
|
149416
149677
|
}
|
|
149417
149678
|
updateMobileKeyboardButtonVisibility() {
|
|
149418
149679
|
if (!this.mobileKeyboardBtn) return;
|
|
@@ -149467,8 +149728,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149467
149728
|
setTerminalFocusVisual(focused) {
|
|
149468
149729
|
this.isFocused = focused;
|
|
149469
149730
|
if (this.spriteCardElement && this.spriteCardElement.style.display !== "none") {
|
|
149470
|
-
this.spriteCardElement.style.background = focused ? "#
|
|
149471
|
-
this.spriteCardElement.style.borderTopColor = focused ? "#
|
|
149731
|
+
this.spriteCardElement.style.background = focused ? "#13131f" : "#101019";
|
|
149732
|
+
this.spriteCardElement.style.borderTopColor = focused ? "#252540" : "#1c1c2f";
|
|
149472
149733
|
}
|
|
149473
149734
|
}
|
|
149474
149735
|
setupKeyboardHandler() {
|
|
@@ -149483,6 +149744,9 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149483
149744
|
this.updateMobileKeyboardButtonVisibility();
|
|
149484
149745
|
this.isVisible = false;
|
|
149485
149746
|
this.isReadOnly = false;
|
|
149747
|
+
this.pendingInputLine = "";
|
|
149748
|
+
this.awaitingSessionIdRefresh = false;
|
|
149749
|
+
this.clearSessionRefreshTimers();
|
|
149486
149750
|
this.closeHistoryPopover();
|
|
149487
149751
|
this.restorePanelLayout();
|
|
149488
149752
|
this.inputManager.deactivateTerminalF10();
|
|
@@ -149521,8 +149785,9 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149521
149785
|
return false;
|
|
149522
149786
|
}
|
|
149523
149787
|
destroy() {
|
|
149524
|
-
|
|
149525
|
-
this.
|
|
149788
|
+
this.clearRefitTimers();
|
|
149789
|
+
this.awaitingSessionIdRefresh = false;
|
|
149790
|
+
this.clearSessionRefreshTimers();
|
|
149526
149791
|
if (this.resizeHandler) {
|
|
149527
149792
|
window.removeEventListener("resize", this.resizeHandler);
|
|
149528
149793
|
this.resizeHandler = null;
|
|
@@ -150477,8 +150742,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150477
150742
|
"use strict";
|
|
150478
150743
|
DESKTOP_DASHBOARD_TYPOGRAPHY = {
|
|
150479
150744
|
cardTitle: "15px",
|
|
150745
|
+
cardTitleLg: "18px",
|
|
150480
150746
|
cardDescription: "11px",
|
|
150481
150747
|
statusText: "11px",
|
|
150748
|
+
statusPanelText: "13px",
|
|
150749
|
+
statusPanelIcon: "26px",
|
|
150482
150750
|
statusDot: "8px",
|
|
150483
150751
|
elapsed: "10px",
|
|
150484
150752
|
badge: "10px",
|
|
@@ -150489,14 +150757,18 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150489
150757
|
taskSummary: "10px",
|
|
150490
150758
|
sessionLabel: "9px",
|
|
150491
150759
|
sessionTitle: "13px",
|
|
150760
|
+
sessionTitleLg: "15px",
|
|
150492
150761
|
sessionButton: "11px",
|
|
150493
150762
|
emptyState: "11px",
|
|
150494
150763
|
arthurHint: "10px"
|
|
150495
150764
|
};
|
|
150496
150765
|
MOBILE_DASHBOARD_TYPOGRAPHY = {
|
|
150497
150766
|
cardTitle: "19px",
|
|
150767
|
+
cardTitleLg: "24px",
|
|
150498
150768
|
cardDescription: "15px",
|
|
150499
150769
|
statusText: "16px",
|
|
150770
|
+
statusPanelText: "18px",
|
|
150771
|
+
statusPanelIcon: "34px",
|
|
150500
150772
|
statusDot: "11px",
|
|
150501
150773
|
elapsed: "14px",
|
|
150502
150774
|
badge: "13px",
|
|
@@ -150507,6 +150779,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150507
150779
|
taskSummary: "14px",
|
|
150508
150780
|
sessionLabel: "13px",
|
|
150509
150781
|
sessionTitle: "17px",
|
|
150782
|
+
sessionTitleLg: "20px",
|
|
150510
150783
|
sessionButton: "14px",
|
|
150511
150784
|
emptyState: "14px",
|
|
150512
150785
|
arthurHint: "14px"
|
|
@@ -150538,6 +150811,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150538
150811
|
display: flex;
|
|
150539
150812
|
align-items: center;
|
|
150540
150813
|
gap: 12px;
|
|
150814
|
+
min-height: 108px;
|
|
150541
150815
|
">
|
|
150542
150816
|
<div style="
|
|
150543
150817
|
width: 64px;
|
|
@@ -150626,11 +150900,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150626
150900
|
padding: 0 4px;
|
|
150627
150901
|
box-shadow: 0 1px 4px rgba(0,0,0,0.4);
|
|
150628
150902
|
">${unread}</div>` : "";
|
|
150629
|
-
const elapsedHtml = elapsed ? `<
|
|
150630
|
-
const queueHtml = toolCount > 1 ? `<
|
|
150903
|
+
const elapsedHtml = elapsed ? `<div data-elapsed-agent="${agent.id}" style="color: #8a8; font-size: ${t.elapsed}; margin-top: 4px;">\u23F1 ${elapsed}</div>` : "";
|
|
150904
|
+
const queueHtml = toolCount > 1 ? `<div style="
|
|
150631
150905
|
background: #334; color: #aac; font-size: ${t.queue};
|
|
150632
|
-
padding:
|
|
150633
|
-
">${toolCount} tools</
|
|
150906
|
+
padding: 2px 8px; border-radius: 8px; margin-top: 4px;
|
|
150907
|
+
">${toolCount} tools queued</div>` : "";
|
|
150634
150908
|
let toolPipelineHtml = "";
|
|
150635
150909
|
if (tools.length > 0) {
|
|
150636
150910
|
const toolRows = tools.map((t2, i) => {
|
|
@@ -150686,12 +150960,19 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150686
150960
|
">
|
|
150687
150961
|
<div style="font-size: ${t.sessionLabel}; color: #3a3a5a; text-transform: uppercase; letter-spacing: 0.5px;">Session Info</div>
|
|
150688
150962
|
<div class="session-title-display" data-agent="${agent.id}" style="
|
|
150689
|
-
font-weight: bold; color: ${metaTitle ? "#ccd" : "#444"}; font-size: ${t.
|
|
150963
|
+
font-weight: bold; color: ${metaTitle ? "#ccd" : "#444"}; font-size: ${t.sessionTitleLg};
|
|
150690
150964
|
cursor: text; min-height: 18px; line-height: 1.4;
|
|
150691
150965
|
overflow: hidden; text-overflow: ellipsis;
|
|
150692
150966
|
display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
|
|
150693
150967
|
" title="${metaTitle ? metaTitle.replace(/"/g, """) : "Click to set title"}">${metaTitle || "Untitled session"}</div>
|
|
150694
|
-
<
|
|
150968
|
+
<button class="session-new-btn" data-agent="${agent.id}" style="
|
|
150969
|
+
margin-top: 2px;
|
|
150970
|
+
align-self: flex-start;
|
|
150971
|
+
background: #2a3a4a; border: 1px solid #4a5a6a; color: #a9cff7;
|
|
150972
|
+
font-size: ${t.sessionButton}; padding: 4px 10px; border-radius: 4px;
|
|
150973
|
+
cursor: pointer; transition: background 0.15s, border-color 0.15s;
|
|
150974
|
+
" title="Start a new session for this agent">\u{1F504} New Session</button>
|
|
150975
|
+
<div style="display: flex; justify-content: flex-end;">
|
|
150695
150976
|
<button class="session-edit-btn" data-agent="${agent.id}" style="
|
|
150696
150977
|
background: none; border: 1px solid #333; color: #667;
|
|
150697
150978
|
font-size: ${t.sessionButton}; padding: 2px 8px; border-radius: 4px;
|
|
@@ -150725,46 +151006,60 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150725
151006
|
align-items: flex-start;
|
|
150726
151007
|
gap: 14px;
|
|
150727
151008
|
position: relative;
|
|
150728
|
-
min-height:
|
|
151009
|
+
min-height: 236px;
|
|
150729
151010
|
">
|
|
150730
151011
|
${badgeHtml}
|
|
150731
|
-
<div style="
|
|
150732
|
-
|
|
150733
|
-
|
|
150734
|
-
|
|
150735
|
-
|
|
150736
|
-
|
|
150737
|
-
|
|
150738
|
-
|
|
150739
|
-
|
|
150740
|
-
|
|
150741
|
-
|
|
150742
|
-
|
|
150743
|
-
|
|
150744
|
-
|
|
150745
|
-
|
|
150746
|
-
|
|
150747
|
-
|
|
150748
|
-
|
|
151012
|
+
<div style="flex-shrink: 0; width: 96px; display: flex; flex-direction: column; align-items: stretch; gap: 10px;">
|
|
151013
|
+
<div style="
|
|
151014
|
+
width: 96px;
|
|
151015
|
+
background: ${colorHex}22;
|
|
151016
|
+
border: 1px solid ${colorHex}44;
|
|
151017
|
+
border-radius: 10px;
|
|
151018
|
+
display: flex;
|
|
151019
|
+
align-items: center;
|
|
151020
|
+
justify-content: center;
|
|
151021
|
+
overflow: hidden;
|
|
151022
|
+
align-self: flex-start;
|
|
151023
|
+
padding: 6px 0;
|
|
151024
|
+
">
|
|
151025
|
+
<canvas
|
|
151026
|
+
id="overview-sprite-${agent.id}"
|
|
151027
|
+
width="32" height="34"
|
|
151028
|
+
style="image-rendering: pixelated; width: 72px; height: 76px; display: block;"
|
|
151029
|
+
></canvas>
|
|
151030
|
+
</div>
|
|
151031
|
+
<div style="
|
|
151032
|
+
border: 1px solid ${statusDot}66;
|
|
151033
|
+
background: ${statusDot}22;
|
|
151034
|
+
border-radius: 10px;
|
|
151035
|
+
padding: 8px 6px;
|
|
151036
|
+
display: flex;
|
|
151037
|
+
flex-direction: column;
|
|
151038
|
+
align-items: center;
|
|
151039
|
+
text-align: center;
|
|
151040
|
+
min-height: 96px;
|
|
151041
|
+
justify-content: center;
|
|
151042
|
+
">
|
|
151043
|
+
<div style="font-size: ${t.statusPanelIcon}; line-height: 1;">${statusIcon}</div>
|
|
151044
|
+
<div style="
|
|
151045
|
+
margin-top: 6px;
|
|
151046
|
+
font-size: ${t.statusPanelText};
|
|
151047
|
+
color: ${statusDot};
|
|
151048
|
+
line-height: 1.15;
|
|
151049
|
+
font-weight: 700;
|
|
151050
|
+
white-space: normal;
|
|
151051
|
+
word-break: break-word;
|
|
151052
|
+
">${statusLabel}</div>
|
|
151053
|
+
${elapsedHtml}
|
|
151054
|
+
${queueHtml}
|
|
151055
|
+
</div>
|
|
150749
151056
|
</div>
|
|
150750
151057
|
<div style="flex: 3; min-width: 0; display: flex; flex-direction: column; gap: 4px;">
|
|
150751
151058
|
<div>
|
|
150752
|
-
<div style="font-weight: bold; color: #dde; font-size: ${t.
|
|
151059
|
+
<div style="font-weight: bold; color: #dde; font-size: ${t.cardTitleLg};">${agent.name}</div>
|
|
150753
151060
|
<div style="color: #778; font-size: ${t.cardDescription}; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;">${agent.description}</div>
|
|
150754
151061
|
</div>
|
|
150755
151062
|
<div>
|
|
150756
|
-
<div style="display: flex; align-items: center; flex-wrap: wrap; margin-top: 4px;">
|
|
150757
|
-
<div style="
|
|
150758
|
-
font-size: ${t.statusText};
|
|
150759
|
-
color: ${statusDot};
|
|
150760
|
-
display: flex; align-items: center; gap: 4px;
|
|
150761
|
-
">
|
|
150762
|
-
<span style="font-size: ${t.statusDot};">\u25CF</span>
|
|
150763
|
-
<span>${statusIcon} ${statusLabel}</span>
|
|
150764
|
-
</div>
|
|
150765
|
-
${elapsedHtml}
|
|
150766
|
-
${queueHtml}
|
|
150767
|
-
</div>
|
|
150768
151063
|
${taskSummaryHtml}
|
|
150769
151064
|
</div>
|
|
150770
151065
|
${toolPipelineHtml}
|
|
@@ -150795,6 +151090,10 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150795
151090
|
context.emitOpenTerminal(agentId);
|
|
150796
151091
|
},
|
|
150797
151092
|
handleMetaPanelClick(target, agentId, context) {
|
|
151093
|
+
if (target.closest(".session-new-btn")) {
|
|
151094
|
+
context.startNewSession(agentId);
|
|
151095
|
+
return;
|
|
151096
|
+
}
|
|
150798
151097
|
if (target.closest(".session-edit-btn") || target.closest(".session-title-display")) {
|
|
150799
151098
|
context.startSessionMetaEdit(agentId);
|
|
150800
151099
|
}
|
|
@@ -150896,7 +151195,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150896
151195
|
background: ${bgColor};
|
|
150897
151196
|
border: 1.5px solid ${borderColor};
|
|
150898
151197
|
border-radius: 10px;
|
|
150899
|
-
padding:
|
|
151198
|
+
padding: 18px 16px;
|
|
150900
151199
|
margin-bottom: 8px;
|
|
150901
151200
|
cursor: ${cursor};
|
|
150902
151201
|
transition: border-color 0.15s;
|
|
@@ -150904,6 +151203,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150904
151203
|
align-items: flex-start;
|
|
150905
151204
|
gap: 12px;
|
|
150906
151205
|
position: relative;
|
|
151206
|
+
min-height: 124px;
|
|
150907
151207
|
">
|
|
150908
151208
|
<div style="
|
|
150909
151209
|
flex-shrink: 0;
|
|
@@ -153555,12 +153855,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
153555
153855
|
if (this.currentLayout === "default") {
|
|
153556
153856
|
const officeId = officeManager.currentOfficeId;
|
|
153557
153857
|
if (officeId) {
|
|
153558
|
-
const
|
|
153559
|
-
for (const { deskId, agentId } of
|
|
153560
|
-
const reserveConfig = RESERVE_AGENTS[deskId];
|
|
153561
|
-
if (!reserveConfig || reserveConfig.id !== agentId) continue;
|
|
153562
|
-
if (AGENTS.find((a) => a.id === agentId)) continue;
|
|
153563
|
-
AGENTS.push(reserveConfig);
|
|
153858
|
+
const restoredSeatedAgents = restoreSeatedReserveAgents(officeManager.getSeatedAgents(officeId));
|
|
153859
|
+
for (const { deskId, agentId } of restoredSeatedAgents) {
|
|
153564
153860
|
const desk = this.desks.find((d) => d.agentId === deskId);
|
|
153565
153861
|
if (desk) {
|
|
153566
153862
|
desk.agentId = agentId;
|
|
@@ -155443,151 +155739,969 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155443
155739
|
}
|
|
155444
155740
|
});
|
|
155445
155741
|
|
|
155446
|
-
// src/
|
|
155447
|
-
var
|
|
155448
|
-
|
|
155449
|
-
|
|
155450
|
-
|
|
155451
|
-
|
|
155452
|
-
|
|
155453
|
-
|
|
155454
|
-
|
|
155455
|
-
|
|
155456
|
-
|
|
155457
|
-
|
|
155458
|
-
|
|
155459
|
-
|
|
155460
|
-
|
|
155461
|
-
|
|
155462
|
-
|
|
155463
|
-
|
|
155464
|
-
|
|
155465
|
-
|
|
155466
|
-
|
|
155467
|
-
|
|
155468
|
-
|
|
155469
|
-
|
|
155470
|
-
|
|
155471
|
-
|
|
155472
|
-
|
|
155473
|
-
|
|
155474
|
-
|
|
155475
|
-
|
|
155476
|
-
|
|
155477
|
-
|
|
155478
|
-
|
|
155479
|
-
|
|
155480
|
-
|
|
155481
|
-
|
|
155482
|
-
|
|
155483
|
-
|
|
155484
|
-
|
|
155485
|
-
|
|
155486
|
-
|
|
155487
|
-
|
|
155488
|
-
|
|
155489
|
-
|
|
155490
|
-
|
|
155491
|
-
|
|
155492
|
-
|
|
155493
|
-
|
|
155494
|
-
|
|
155495
|
-
|
|
155496
|
-
|
|
155497
|
-
|
|
155498
|
-
|
|
155499
|
-
|
|
155500
|
-
|
|
155501
|
-
|
|
155502
|
-
|
|
155503
|
-
|
|
155504
|
-
|
|
155505
|
-
|
|
155506
|
-
|
|
155507
|
-
|
|
155508
|
-
|
|
155509
|
-
|
|
155510
|
-
|
|
155511
|
-
|
|
155512
|
-
|
|
155513
|
-
|
|
155514
|
-
|
|
155515
|
-
|
|
155516
|
-
|
|
155517
|
-
|
|
155518
|
-
|
|
155519
|
-
|
|
155520
|
-
|
|
155521
|
-
|
|
155522
|
-
|
|
155523
|
-
|
|
155524
|
-
|
|
155525
|
-
|
|
155526
|
-
|
|
155527
|
-
|
|
155528
|
-
|
|
155529
|
-
|
|
155530
|
-
|
|
155531
|
-
|
|
155532
|
-
|
|
155533
|
-
|
|
155534
|
-
|
|
155535
|
-
|
|
155536
|
-
|
|
155537
|
-
|
|
155538
|
-
|
|
155539
|
-
|
|
155540
|
-
|
|
155541
|
-
|
|
155542
|
-
|
|
155543
|
-
|
|
155544
|
-
|
|
155545
|
-
|
|
155546
|
-
|
|
155547
|
-
|
|
155548
|
-
|
|
155549
|
-
|
|
155550
|
-
|
|
155551
|
-
|
|
155552
|
-
|
|
155553
|
-
|
|
155554
|
-
|
|
155555
|
-
|
|
155556
|
-
|
|
155557
|
-
|
|
155558
|
-
|
|
155559
|
-
|
|
155560
|
-
|
|
155561
|
-
|
|
155562
|
-
|
|
155563
|
-
|
|
155564
|
-
|
|
155565
|
-
|
|
155566
|
-
|
|
155567
|
-
|
|
155568
|
-
|
|
155569
|
-
|
|
155570
|
-
|
|
155571
|
-
|
|
155572
|
-
|
|
155573
|
-
|
|
155574
|
-
|
|
155575
|
-
|
|
155576
|
-
|
|
155577
|
-
|
|
155578
|
-
|
|
155579
|
-
|
|
155580
|
-
|
|
155581
|
-
|
|
155582
|
-
|
|
155583
|
-
|
|
155584
|
-
|
|
155585
|
-
|
|
155586
|
-
|
|
155587
|
-
|
|
155588
|
-
|
|
155589
|
-
|
|
155590
|
-
|
|
155742
|
+
// src/ui/SeriousTerminalController.ts
|
|
155743
|
+
var import_xterm2, import_addon_fit2, SeriousTerminalController;
|
|
155744
|
+
var init_SeriousTerminalController = __esm({
|
|
155745
|
+
"src/ui/SeriousTerminalController.ts"() {
|
|
155746
|
+
"use strict";
|
|
155747
|
+
import_xterm2 = __toESM(require_xterm());
|
|
155748
|
+
import_addon_fit2 = __toESM(require_addon_fit());
|
|
155749
|
+
SeriousTerminalController = class _SeriousTerminalController {
|
|
155750
|
+
constructor(host, options = {}) {
|
|
155751
|
+
this.historyPopover = null;
|
|
155752
|
+
this.terminal = null;
|
|
155753
|
+
this.fitAddon = null;
|
|
155754
|
+
this.resizeObserver = null;
|
|
155755
|
+
this.resizeHandler = null;
|
|
155756
|
+
this.refitTimers = [];
|
|
155757
|
+
this.activeOfficeId = null;
|
|
155758
|
+
this.activeAgentId = null;
|
|
155759
|
+
this.visible = false;
|
|
155760
|
+
this.openedAt = 0;
|
|
155761
|
+
this.sessionId = null;
|
|
155762
|
+
this.activeOptions = null;
|
|
155763
|
+
this.isFullWidth = false;
|
|
155764
|
+
this.host = host;
|
|
155765
|
+
this.onClose = options.onClose;
|
|
155766
|
+
this.isFullWidth = localStorage.getItem(_SeriousTerminalController.FULL_WIDTH_STORAGE_KEY) === "true";
|
|
155767
|
+
this.container = document.createElement("div");
|
|
155768
|
+
this.container.style.cssText = `
|
|
155769
|
+
display: none;
|
|
155770
|
+
flex-direction: column;
|
|
155771
|
+
flex: 1;
|
|
155772
|
+
min-height: 0;
|
|
155773
|
+
background: #11131c;
|
|
155774
|
+
color: #d7defa;
|
|
155775
|
+
border-left: 2px solid #2f3f62;
|
|
155776
|
+
font-family: 'Cascadia Code', Consolas, monospace;
|
|
155777
|
+
`;
|
|
155778
|
+
const header = document.createElement("div");
|
|
155779
|
+
header.style.cssText = `
|
|
155780
|
+
display: flex;
|
|
155781
|
+
align-items: center;
|
|
155782
|
+
justify-content: space-between;
|
|
155783
|
+
gap: 8px;
|
|
155784
|
+
padding: 12px 14px;
|
|
155785
|
+
border-bottom: 1px solid #27314e;
|
|
155786
|
+
background: #171b2a;
|
|
155787
|
+
flex-shrink: 0;
|
|
155788
|
+
`;
|
|
155789
|
+
const leftHeader = document.createElement("div");
|
|
155790
|
+
leftHeader.style.cssText = "min-width: 0;";
|
|
155791
|
+
this.titleEl = document.createElement("div");
|
|
155792
|
+
this.titleEl.style.cssText = "font-size: 14px; font-weight: 700; color: #9fc2ff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;";
|
|
155793
|
+
this.subtitleEl = document.createElement("div");
|
|
155794
|
+
this.subtitleEl.style.cssText = "font-size: 11px; color: #7f8bad; margin-top: 3px;";
|
|
155795
|
+
leftHeader.appendChild(this.titleEl);
|
|
155796
|
+
leftHeader.appendChild(this.subtitleEl);
|
|
155797
|
+
const rightHeader = document.createElement("div");
|
|
155798
|
+
rightHeader.style.cssText = "display: flex; align-items: center; gap: 6px;";
|
|
155799
|
+
this.statusEl = document.createElement("div");
|
|
155800
|
+
this.statusEl.style.cssText = "font-size: 11px; color: #8ca2db; margin-right: 4px;";
|
|
155801
|
+
const detachBtn = document.createElement("button");
|
|
155802
|
+
detachBtn.textContent = "Detach";
|
|
155803
|
+
detachBtn.style.cssText = this.buttonCss("#2f3754", "#6f8ed8");
|
|
155804
|
+
detachBtn.addEventListener("click", () => {
|
|
155805
|
+
void this.closeView({ detach: true });
|
|
155806
|
+
});
|
|
155807
|
+
const closeBtn = document.createElement("button");
|
|
155808
|
+
closeBtn.textContent = "Close";
|
|
155809
|
+
closeBtn.style.cssText = this.buttonCss("#3a2534", "#c98fbb");
|
|
155810
|
+
closeBtn.addEventListener("click", () => {
|
|
155811
|
+
void this.closeView({ detach: true });
|
|
155812
|
+
});
|
|
155813
|
+
rightHeader.appendChild(this.statusEl);
|
|
155814
|
+
rightHeader.appendChild(detachBtn);
|
|
155815
|
+
rightHeader.appendChild(closeBtn);
|
|
155816
|
+
header.appendChild(leftHeader);
|
|
155817
|
+
header.appendChild(rightHeader);
|
|
155818
|
+
this.terminalOuterEl = document.createElement("div");
|
|
155819
|
+
this.terminalOuterEl.style.cssText = `
|
|
155820
|
+
flex: 1;
|
|
155821
|
+
min-height: 0;
|
|
155822
|
+
overflow: hidden;
|
|
155823
|
+
background: #0d111b;
|
|
155824
|
+
padding: 10px;
|
|
155825
|
+
box-sizing: border-box;
|
|
155826
|
+
`;
|
|
155827
|
+
this.terminalDivEl = document.createElement("div");
|
|
155828
|
+
this.terminalDivEl.style.cssText = "width: 100%; height: 100%; overflow: hidden;";
|
|
155829
|
+
this.terminalOuterEl.appendChild(this.terminalDivEl);
|
|
155830
|
+
this.terminalOuterEl.addEventListener("mousedown", () => this.terminal?.focus());
|
|
155831
|
+
this.spriteCardEl = document.createElement("div");
|
|
155832
|
+
this.spriteCardEl.style.cssText = `
|
|
155833
|
+
width: 100%;
|
|
155834
|
+
background: #13131f;
|
|
155835
|
+
border-top: 1px solid #252540;
|
|
155836
|
+
font-family: 'Cascadia Code', Consolas, monospace;
|
|
155837
|
+
color: #c8d4ff;
|
|
155838
|
+
display: flex;
|
|
155839
|
+
flex-shrink: 0;
|
|
155840
|
+
justify-content: space-between;
|
|
155841
|
+
align-items: stretch;
|
|
155842
|
+
gap: 24px;
|
|
155843
|
+
min-height: 148px;
|
|
155844
|
+
padding: 16px 24px;
|
|
155845
|
+
box-sizing: border-box;
|
|
155846
|
+
`;
|
|
155847
|
+
const spriteCardLeft = document.createElement("div");
|
|
155848
|
+
spriteCardLeft.style.cssText = "display: flex; align-items: center; gap: 18px; min-width: 0; flex: 1;";
|
|
155849
|
+
const spriteFrame = document.createElement("div");
|
|
155850
|
+
spriteFrame.style.cssText = `
|
|
155851
|
+
width: 72px;
|
|
155852
|
+
background: #2a2a40;
|
|
155853
|
+
border: 1px solid #3a3a58;
|
|
155854
|
+
border-radius: 8px;
|
|
155855
|
+
display: flex;
|
|
155856
|
+
align-items: center;
|
|
155857
|
+
justify-content: center;
|
|
155858
|
+
overflow: hidden;
|
|
155859
|
+
flex-shrink: 0;
|
|
155860
|
+
`;
|
|
155861
|
+
this.spriteCanvasEl = document.createElement("canvas");
|
|
155862
|
+
this.spriteCanvasEl.width = 32;
|
|
155863
|
+
this.spriteCanvasEl.height = 34;
|
|
155864
|
+
this.spriteCanvasEl.style.cssText = `
|
|
155865
|
+
image-rendering: pixelated;
|
|
155866
|
+
width: 64px;
|
|
155867
|
+
height: 68px;
|
|
155868
|
+
display: block;
|
|
155869
|
+
`;
|
|
155870
|
+
spriteFrame.appendChild(this.spriteCanvasEl);
|
|
155871
|
+
const spriteCardText = document.createElement("div");
|
|
155872
|
+
spriteCardText.style.cssText = "display: flex; flex-direction: column; gap: 4px; min-width: 0;";
|
|
155873
|
+
this.spriteNameEl = document.createElement("span");
|
|
155874
|
+
this.spriteNameEl.style.cssText = "font-size: 18px; font-weight: 700; color: #dde; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;";
|
|
155875
|
+
this.spriteSubtitleEl = document.createElement("span");
|
|
155876
|
+
this.spriteSubtitleEl.style.cssText = "font-size: 13px; color: #778; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;";
|
|
155877
|
+
this.sessionTitleEl = document.createElement("span");
|
|
155878
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
155879
|
+
this.sessionTitleEl.style.cssText = "font-size: 14px; font-weight: 700; color: #77839f; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;";
|
|
155880
|
+
spriteCardText.appendChild(this.spriteNameEl);
|
|
155881
|
+
spriteCardText.appendChild(this.spriteSubtitleEl);
|
|
155882
|
+
spriteCardText.appendChild(this.sessionTitleEl);
|
|
155883
|
+
spriteCardLeft.appendChild(spriteFrame);
|
|
155884
|
+
spriteCardLeft.appendChild(spriteCardText);
|
|
155885
|
+
const spriteCardRight = document.createElement("div");
|
|
155886
|
+
spriteCardRight.style.cssText = "display: flex; flex-direction: column; justify-content: center; align-items: flex-end; gap: 8px;";
|
|
155887
|
+
const sessionLabel = document.createElement("span");
|
|
155888
|
+
sessionLabel.textContent = "Session ID";
|
|
155889
|
+
sessionLabel.style.cssText = "font-size: 11px; color: #6f7fa9;";
|
|
155890
|
+
this.sessionIdEl = document.createElement("span");
|
|
155891
|
+
this.sessionIdEl.textContent = "--";
|
|
155892
|
+
this.sessionIdEl.style.cssText = "font-size: 12px; color: #8ec3ff; cursor: pointer;";
|
|
155893
|
+
this.sessionIdEl.title = "Copy session ID";
|
|
155894
|
+
this.sessionIdEl.onclick = () => this.copySessionId();
|
|
155895
|
+
spriteCardRight.appendChild(sessionLabel);
|
|
155896
|
+
spriteCardRight.appendChild(this.sessionIdEl);
|
|
155897
|
+
const buttonGrid = document.createElement("div");
|
|
155898
|
+
buttonGrid.style.cssText = `
|
|
155899
|
+
display: grid;
|
|
155900
|
+
grid-template-columns: repeat(2, max-content);
|
|
155901
|
+
gap: 6px;
|
|
155902
|
+
margin-top: 2px;
|
|
155903
|
+
`;
|
|
155904
|
+
const footerBtnCss = this.buttonCss("#2a3a4a", "#4a5a6a");
|
|
155905
|
+
const historyBtn = document.createElement("button");
|
|
155906
|
+
historyBtn.textContent = "Session History";
|
|
155907
|
+
historyBtn.style.cssText = footerBtnCss;
|
|
155908
|
+
historyBtn.onclick = () => {
|
|
155909
|
+
void this.toggleSessionHistory(historyBtn);
|
|
155910
|
+
};
|
|
155911
|
+
buttonGrid.appendChild(historyBtn);
|
|
155912
|
+
const newSessionBtn = document.createElement("button");
|
|
155913
|
+
newSessionBtn.textContent = "New Session";
|
|
155914
|
+
newSessionBtn.style.cssText = footerBtnCss;
|
|
155915
|
+
newSessionBtn.onclick = () => {
|
|
155916
|
+
void this.handleNewSession();
|
|
155917
|
+
};
|
|
155918
|
+
buttonGrid.appendChild(newSessionBtn);
|
|
155919
|
+
const clearHistoryBtn = document.createElement("button");
|
|
155920
|
+
clearHistoryBtn.textContent = "Clear History";
|
|
155921
|
+
clearHistoryBtn.style.cssText = footerBtnCss;
|
|
155922
|
+
clearHistoryBtn.onclick = () => {
|
|
155923
|
+
void this.handleClearHistory();
|
|
155924
|
+
};
|
|
155925
|
+
buttonGrid.appendChild(clearHistoryBtn);
|
|
155926
|
+
const closeSessionBtn = document.createElement("button");
|
|
155927
|
+
closeSessionBtn.textContent = "Close Session";
|
|
155928
|
+
closeSessionBtn.style.cssText = this.buttonCss("#3a2a2a", "#8f5d5d");
|
|
155929
|
+
closeSessionBtn.onclick = () => {
|
|
155930
|
+
void this.handleCloseSession();
|
|
155931
|
+
};
|
|
155932
|
+
buttonGrid.appendChild(closeSessionBtn);
|
|
155933
|
+
this.fullscreenBtn = document.createElement("button");
|
|
155934
|
+
this.fullscreenBtn.textContent = this.isFullWidth ? "Half Width" : "Full Width";
|
|
155935
|
+
this.fullscreenBtn.style.cssText = this.buttonCss("#2a2f4a", "#5a6aa0");
|
|
155936
|
+
this.fullscreenBtn.onclick = () => this.toggleFullWidth();
|
|
155937
|
+
buttonGrid.appendChild(this.fullscreenBtn);
|
|
155938
|
+
const refreshFocusBtn = document.createElement("button");
|
|
155939
|
+
refreshFocusBtn.textContent = "Refresh Focus";
|
|
155940
|
+
refreshFocusBtn.style.cssText = this.buttonCss("#2a3a2a", "#4f7b63");
|
|
155941
|
+
refreshFocusBtn.onclick = () => this.refreshFocusAndGeometry();
|
|
155942
|
+
buttonGrid.appendChild(refreshFocusBtn);
|
|
155943
|
+
spriteCardRight.appendChild(buttonGrid);
|
|
155944
|
+
this.spriteCardEl.appendChild(spriteCardLeft);
|
|
155945
|
+
this.spriteCardEl.appendChild(spriteCardRight);
|
|
155946
|
+
this.ensureXtermStyles();
|
|
155947
|
+
this.container.appendChild(header);
|
|
155948
|
+
this.container.appendChild(this.terminalOuterEl);
|
|
155949
|
+
this.container.appendChild(this.spriteCardEl);
|
|
155950
|
+
this.host.appendChild(this.container);
|
|
155951
|
+
this.createTerminal();
|
|
155952
|
+
if (window.copilotBridge) {
|
|
155953
|
+
window.copilotBridge.onTerminalData((agentId, data) => {
|
|
155954
|
+
if (!this.visible || this.activeAgentId !== agentId) return;
|
|
155955
|
+
this.terminal?.write(data);
|
|
155956
|
+
});
|
|
155957
|
+
window.copilotBridge.onTerminalExit((agentId, exitCode) => {
|
|
155958
|
+
if (!this.visible || this.activeAgentId !== agentId) return;
|
|
155959
|
+
this.terminal?.writeln(`\r
|
|
155960
|
+
[terminal exited with code ${exitCode}]`);
|
|
155961
|
+
this.setStatus("Exited");
|
|
155962
|
+
});
|
|
155963
|
+
window.copilotBridge.onSessionMetaUpdated((agentId) => {
|
|
155964
|
+
if (!this.visible || !this.activeOfficeId || this.activeAgentId !== agentId) return;
|
|
155965
|
+
void this.updateSessionTitle(this.activeOfficeId, agentId);
|
|
155966
|
+
});
|
|
155967
|
+
}
|
|
155968
|
+
}
|
|
155969
|
+
static {
|
|
155970
|
+
this.FULL_WIDTH_STORAGE_KEY = "agencyOffice:seriousTerminalFullWidth";
|
|
155971
|
+
}
|
|
155972
|
+
isVisible() {
|
|
155973
|
+
return this.visible;
|
|
155974
|
+
}
|
|
155975
|
+
refreshCardFromOverview() {
|
|
155976
|
+
if (!this.visible || !this.activeAgentId) return;
|
|
155977
|
+
this.renderExactOverviewCard(this.activeAgentId);
|
|
155978
|
+
}
|
|
155979
|
+
async openAgentTerminal(options) {
|
|
155980
|
+
if (!window.copilotBridge || !this.terminal) return;
|
|
155981
|
+
const switchingTarget = this.activeOfficeId !== options.officeId || this.activeAgentId !== options.agentId;
|
|
155982
|
+
if (switchingTarget) {
|
|
155983
|
+
await this.closeView({ detach: true, silent: true });
|
|
155984
|
+
}
|
|
155985
|
+
this.activeOfficeId = options.officeId;
|
|
155986
|
+
this.activeAgentId = options.agentId;
|
|
155987
|
+
this.activeOptions = { ...options };
|
|
155988
|
+
this.visible = true;
|
|
155989
|
+
this.openedAt = Date.now();
|
|
155990
|
+
this.sessionId = null;
|
|
155991
|
+
this.container.style.display = "flex";
|
|
155992
|
+
this.terminal.clear();
|
|
155993
|
+
this.titleEl.textContent = `${options.name} (${options.agentId})`;
|
|
155994
|
+
this.subtitleEl.textContent = options.description;
|
|
155995
|
+
this.updateSpriteCard(options);
|
|
155996
|
+
void this.updateSessionTitle(options.officeId, options.agentId);
|
|
155997
|
+
this.updateSessionIdDisplay();
|
|
155998
|
+
this.setStatus("Opening...");
|
|
155999
|
+
this.applyPanelLayout();
|
|
156000
|
+
this.refitAndResize(options.officeId, options.agentId);
|
|
156001
|
+
try {
|
|
156002
|
+
const exists = await window.copilotBridge.terminalExists(options.officeId, options.agentId);
|
|
156003
|
+
if (!exists) {
|
|
156004
|
+
const dims = this.fitAddon?.proposeDimensions();
|
|
156005
|
+
const startResult = await window.copilotBridge.terminalStart(
|
|
156006
|
+
options.officeId,
|
|
156007
|
+
options.agentId,
|
|
156008
|
+
options.workingDir,
|
|
156009
|
+
dims?.cols,
|
|
156010
|
+
dims?.rows,
|
|
156011
|
+
void 0,
|
|
156012
|
+
options.launchMode || "copilot"
|
|
156013
|
+
);
|
|
156014
|
+
if (!startResult.success) {
|
|
156015
|
+
this.terminal.writeln(`\r
|
|
156016
|
+
Failed to start terminal: ${startResult.error || "unknown error"}`);
|
|
156017
|
+
this.setStatus("Start failed");
|
|
156018
|
+
return;
|
|
156019
|
+
}
|
|
156020
|
+
if (startResult.sessionId) {
|
|
156021
|
+
this.sessionId = startResult.sessionId;
|
|
156022
|
+
this.updateSessionIdDisplay();
|
|
156023
|
+
}
|
|
156024
|
+
}
|
|
156025
|
+
const attachResult = await window.copilotBridge.terminalAttach(options.officeId, options.agentId);
|
|
156026
|
+
if (!attachResult.success) {
|
|
156027
|
+
this.terminal.writeln("\r\nFailed to attach terminal session.");
|
|
156028
|
+
this.setStatus("Attach failed");
|
|
156029
|
+
return;
|
|
156030
|
+
}
|
|
156031
|
+
if (attachResult.scrollback) {
|
|
156032
|
+
this.terminal.write(attachResult.scrollback);
|
|
156033
|
+
}
|
|
156034
|
+
const attachedSessionId = await window.copilotBridge.getSessionId(options.officeId, options.agentId);
|
|
156035
|
+
if (attachedSessionId) {
|
|
156036
|
+
this.sessionId = attachedSessionId;
|
|
156037
|
+
this.updateSessionIdDisplay();
|
|
156038
|
+
}
|
|
156039
|
+
this.setStatus(`Attached \xB7 ${this.formatElapsed(this.openedAt)}`);
|
|
156040
|
+
this.terminal.focus();
|
|
156041
|
+
this.debouncedRefit(options.officeId, options.agentId);
|
|
156042
|
+
this.refreshCardFromOverview();
|
|
156043
|
+
} catch (error) {
|
|
156044
|
+
this.terminal.writeln(`\r
|
|
156045
|
+
Terminal error: ${error?.message || String(error)}`);
|
|
156046
|
+
this.setStatus("Error");
|
|
156047
|
+
this.refreshCardFromOverview();
|
|
156048
|
+
}
|
|
156049
|
+
}
|
|
156050
|
+
async startNewSession(options) {
|
|
156051
|
+
if (!window.copilotBridge) return;
|
|
156052
|
+
try {
|
|
156053
|
+
await window.copilotBridge.resetSession(options.officeId, options.agentId);
|
|
156054
|
+
} catch {
|
|
156055
|
+
}
|
|
156056
|
+
const isCurrentView = this.visible && this.activeOfficeId === options.officeId && this.activeAgentId === options.agentId;
|
|
156057
|
+
if (isCurrentView) {
|
|
156058
|
+
await this.openAgentTerminal(options);
|
|
156059
|
+
return;
|
|
156060
|
+
}
|
|
156061
|
+
const startResult = await window.copilotBridge.terminalStart(
|
|
156062
|
+
options.officeId,
|
|
156063
|
+
options.agentId,
|
|
156064
|
+
options.workingDir,
|
|
156065
|
+
void 0,
|
|
156066
|
+
void 0,
|
|
156067
|
+
void 0,
|
|
156068
|
+
options.launchMode || "copilot"
|
|
156069
|
+
);
|
|
156070
|
+
if (!startResult.success) {
|
|
156071
|
+
console.warn(
|
|
156072
|
+
`[SeriousTerminalController] Failed to start new session for ${options.agentId}: ${startResult.error || "unknown error"}`
|
|
156073
|
+
);
|
|
156074
|
+
}
|
|
156075
|
+
}
|
|
156076
|
+
async closeView(options = {}) {
|
|
156077
|
+
const { detach = true, silent = false } = options;
|
|
156078
|
+
if (detach && this.activeOfficeId && this.activeAgentId && window.copilotBridge) {
|
|
156079
|
+
try {
|
|
156080
|
+
await window.copilotBridge.terminalDetach(this.activeOfficeId, this.activeAgentId);
|
|
156081
|
+
} catch {
|
|
156082
|
+
}
|
|
156083
|
+
}
|
|
156084
|
+
this.visible = false;
|
|
156085
|
+
this.container.style.display = "none";
|
|
156086
|
+
this.activeOfficeId = null;
|
|
156087
|
+
this.activeAgentId = null;
|
|
156088
|
+
this.activeOptions = null;
|
|
156089
|
+
this.sessionId = null;
|
|
156090
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
156091
|
+
this.sessionTitleEl.style.color = "#77839f";
|
|
156092
|
+
this.updateSessionIdDisplay();
|
|
156093
|
+
this.setStatus("");
|
|
156094
|
+
this.clearRefitTimers();
|
|
156095
|
+
this.closeSessionHistoryPopover();
|
|
156096
|
+
this.applyPanelLayout();
|
|
156097
|
+
if (!silent) {
|
|
156098
|
+
this.onClose?.();
|
|
156099
|
+
}
|
|
156100
|
+
}
|
|
156101
|
+
setStatus(text) {
|
|
156102
|
+
this.statusEl.textContent = text;
|
|
156103
|
+
}
|
|
156104
|
+
updateSpriteCard(options) {
|
|
156105
|
+
this.spriteNameEl.textContent = options.name;
|
|
156106
|
+
this.spriteSubtitleEl.textContent = options.description;
|
|
156107
|
+
const colorHex = `#${(options.color ?? 7311064).toString(16).padStart(6, "0")}`;
|
|
156108
|
+
this.spriteNameEl.style.color = colorHex;
|
|
156109
|
+
this.renderAgentSprite(options.agentId, options.color ?? 7311064);
|
|
156110
|
+
}
|
|
156111
|
+
updateSessionIdDisplay() {
|
|
156112
|
+
this.sessionIdEl.textContent = this.sessionId || "--";
|
|
156113
|
+
}
|
|
156114
|
+
renderExactOverviewCard(agentId) {
|
|
156115
|
+
const sourceCard = document.querySelector(`#overview-content .agent-card[data-agent="${agentId}"]`);
|
|
156116
|
+
if (!sourceCard) return;
|
|
156117
|
+
const clonedCard = sourceCard.cloneNode(true);
|
|
156118
|
+
clonedCard.style.marginBottom = "0";
|
|
156119
|
+
clonedCard.style.cursor = "default";
|
|
156120
|
+
const sourceCanvases = sourceCard.querySelectorAll("canvas");
|
|
156121
|
+
const cloneCanvases = clonedCard.querySelectorAll("canvas");
|
|
156122
|
+
cloneCanvases.forEach((node, i) => {
|
|
156123
|
+
const canvas = node;
|
|
156124
|
+
canvas.removeAttribute("id");
|
|
156125
|
+
const src = sourceCanvases[i];
|
|
156126
|
+
const ctx = canvas.getContext("2d");
|
|
156127
|
+
if (!src || !ctx) return;
|
|
156128
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
156129
|
+
ctx.drawImage(src, 0, 0);
|
|
156130
|
+
});
|
|
156131
|
+
this.spriteCardEl.style.display = "block";
|
|
156132
|
+
this.spriteCardEl.style.padding = "10px 10px 12px";
|
|
156133
|
+
this.spriteCardEl.style.minHeight = "0";
|
|
156134
|
+
this.spriteCardEl.style.gap = "0";
|
|
156135
|
+
this.spriteCardEl.style.alignItems = "stretch";
|
|
156136
|
+
this.spriteCardEl.style.justifyContent = "stretch";
|
|
156137
|
+
this.spriteCardEl.innerHTML = "";
|
|
156138
|
+
this.spriteCardEl.appendChild(clonedCard);
|
|
156139
|
+
}
|
|
156140
|
+
async updateSessionTitle(officeId, agentId) {
|
|
156141
|
+
if (!window.copilotBridge?.getSessionMeta) {
|
|
156142
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
156143
|
+
this.sessionTitleEl.style.color = "#77839f";
|
|
156144
|
+
return;
|
|
156145
|
+
}
|
|
156146
|
+
try {
|
|
156147
|
+
const meta = await window.copilotBridge.getSessionMeta(officeId, agentId);
|
|
156148
|
+
const title = meta?.title?.trim();
|
|
156149
|
+
if (title) {
|
|
156150
|
+
this.sessionTitleEl.textContent = title;
|
|
156151
|
+
this.sessionTitleEl.style.color = "#c8d4ff";
|
|
156152
|
+
} else {
|
|
156153
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
156154
|
+
this.sessionTitleEl.style.color = "#77839f";
|
|
156155
|
+
}
|
|
156156
|
+
} catch {
|
|
156157
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
156158
|
+
this.sessionTitleEl.style.color = "#77839f";
|
|
156159
|
+
}
|
|
156160
|
+
}
|
|
156161
|
+
async handleNewSession() {
|
|
156162
|
+
if (!this.activeOptions) return;
|
|
156163
|
+
await this.startNewSession(this.activeOptions);
|
|
156164
|
+
this.closeSessionHistoryPopover();
|
|
156165
|
+
}
|
|
156166
|
+
async handleClearHistory() {
|
|
156167
|
+
if (!window.copilotBridge || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156168
|
+
try {
|
|
156169
|
+
await window.copilotBridge.clearSessionHistory(this.activeOfficeId, this.activeAgentId);
|
|
156170
|
+
this.terminal?.writeln("\r\n[session history cleared]");
|
|
156171
|
+
this.closeSessionHistoryPopover();
|
|
156172
|
+
} catch {
|
|
156173
|
+
this.terminal?.writeln("\r\n[failed to clear session history]");
|
|
156174
|
+
}
|
|
156175
|
+
}
|
|
156176
|
+
async handleCloseSession() {
|
|
156177
|
+
if (!window.copilotBridge || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156178
|
+
try {
|
|
156179
|
+
await window.copilotBridge.resetSession(this.activeOfficeId, this.activeAgentId);
|
|
156180
|
+
this.terminal?.writeln("\r\n[session closed]");
|
|
156181
|
+
} catch {
|
|
156182
|
+
this.terminal?.writeln("\r\n[failed to close session]");
|
|
156183
|
+
}
|
|
156184
|
+
await this.closeView({ detach: true });
|
|
156185
|
+
}
|
|
156186
|
+
async toggleSessionHistory(anchor) {
|
|
156187
|
+
if (!window.copilotBridge || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156188
|
+
if (this.historyPopover) {
|
|
156189
|
+
this.closeSessionHistoryPopover();
|
|
156190
|
+
return;
|
|
156191
|
+
}
|
|
156192
|
+
let history = [];
|
|
156193
|
+
try {
|
|
156194
|
+
history = await window.copilotBridge.getSessionHistory(this.activeOfficeId, this.activeAgentId);
|
|
156195
|
+
} catch {
|
|
156196
|
+
history = [];
|
|
156197
|
+
}
|
|
156198
|
+
const pop = document.createElement("div");
|
|
156199
|
+
pop.style.cssText = `
|
|
156200
|
+
position: absolute;
|
|
156201
|
+
right: 12px;
|
|
156202
|
+
bottom: calc(100% + 8px);
|
|
156203
|
+
width: min(620px, 88vw);
|
|
156204
|
+
max-height: 280px;
|
|
156205
|
+
overflow: auto;
|
|
156206
|
+
background: #101629;
|
|
156207
|
+
border: 1px solid #2f3f62;
|
|
156208
|
+
border-radius: 8px;
|
|
156209
|
+
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
|
|
156210
|
+
padding: 10px 12px;
|
|
156211
|
+
z-index: 10003;
|
|
156212
|
+
color: #c8d4ff;
|
|
156213
|
+
font-size: 12px;
|
|
156214
|
+
white-space: pre-wrap;
|
|
156215
|
+
line-height: 1.4;
|
|
156216
|
+
`;
|
|
156217
|
+
const title = document.createElement("div");
|
|
156218
|
+
title.textContent = `Session History (${history.length})`;
|
|
156219
|
+
title.style.cssText = "font-weight: 700; margin-bottom: 8px; color: #9fc2ff;";
|
|
156220
|
+
pop.appendChild(title);
|
|
156221
|
+
const body = document.createElement("div");
|
|
156222
|
+
if (history.length === 0) {
|
|
156223
|
+
body.textContent = "No history yet.";
|
|
156224
|
+
body.style.cssText = "color: #77839f; font-style: italic;";
|
|
156225
|
+
} else {
|
|
156226
|
+
body.textContent = history.join("\n");
|
|
156227
|
+
}
|
|
156228
|
+
pop.appendChild(body);
|
|
156229
|
+
const closeBtn = document.createElement("button");
|
|
156230
|
+
closeBtn.textContent = "Close";
|
|
156231
|
+
closeBtn.style.cssText = `${this.buttonCss("#2a2f4a", "#5a6aa0")} margin-top: 10px;`;
|
|
156232
|
+
closeBtn.onclick = () => this.closeSessionHistoryPopover();
|
|
156233
|
+
pop.appendChild(closeBtn);
|
|
156234
|
+
this.historyPopover = pop;
|
|
156235
|
+
this.spriteCardEl.style.position = "relative";
|
|
156236
|
+
this.spriteCardEl.appendChild(pop);
|
|
156237
|
+
anchor.blur();
|
|
156238
|
+
}
|
|
156239
|
+
closeSessionHistoryPopover() {
|
|
156240
|
+
if (this.historyPopover?.parentElement) {
|
|
156241
|
+
this.historyPopover.parentElement.removeChild(this.historyPopover);
|
|
156242
|
+
}
|
|
156243
|
+
this.historyPopover = null;
|
|
156244
|
+
}
|
|
156245
|
+
copySessionId() {
|
|
156246
|
+
if (!this.sessionId) return;
|
|
156247
|
+
navigator.clipboard.writeText(this.sessionId).then(() => {
|
|
156248
|
+
const original = this.sessionIdEl.textContent;
|
|
156249
|
+
this.sessionIdEl.textContent = "Copied!";
|
|
156250
|
+
this.sessionIdEl.style.color = "#61d394";
|
|
156251
|
+
setTimeout(() => {
|
|
156252
|
+
this.sessionIdEl.textContent = original;
|
|
156253
|
+
this.sessionIdEl.style.color = "#8ec3ff";
|
|
156254
|
+
}, 900);
|
|
156255
|
+
}).catch(() => {
|
|
156256
|
+
});
|
|
156257
|
+
}
|
|
156258
|
+
renderAgentSprite(seed, baseColor) {
|
|
156259
|
+
const ctx = this.spriteCanvasEl.getContext("2d");
|
|
156260
|
+
if (!ctx) return;
|
|
156261
|
+
ctx.clearRect(0, 0, 32, 34);
|
|
156262
|
+
ctx.imageSmoothingEnabled = false;
|
|
156263
|
+
const color = this.toHex(baseColor);
|
|
156264
|
+
const shade = this.toHex(this.scaleColor(baseColor, 0.72));
|
|
156265
|
+
const accent = this.toHex(this.scaleColor(baseColor, 1.22));
|
|
156266
|
+
const skin = "#f3cfa7";
|
|
156267
|
+
ctx.fillStyle = "#0f1425";
|
|
156268
|
+
ctx.fillRect(0, 0, 32, 34);
|
|
156269
|
+
ctx.fillStyle = shade;
|
|
156270
|
+
ctx.fillRect(8, 16, 16, 14);
|
|
156271
|
+
ctx.fillStyle = color;
|
|
156272
|
+
ctx.fillRect(9, 16, 14, 13);
|
|
156273
|
+
ctx.fillStyle = skin;
|
|
156274
|
+
ctx.fillRect(10, 8, 12, 9);
|
|
156275
|
+
ctx.fillStyle = accent;
|
|
156276
|
+
ctx.fillRect(10, 5, 12, 4);
|
|
156277
|
+
ctx.fillStyle = "#182033";
|
|
156278
|
+
ctx.fillRect(13, 11, 2, 2);
|
|
156279
|
+
ctx.fillRect(17, 11, 2, 2);
|
|
156280
|
+
const seedValue = [...seed].reduce((acc, ch) => acc + ch.charCodeAt(0), 0);
|
|
156281
|
+
const badgeX = seedValue % 2 === 0 ? 5 : 24;
|
|
156282
|
+
ctx.fillStyle = accent;
|
|
156283
|
+
ctx.fillRect(badgeX, 19, 3, 3);
|
|
156284
|
+
}
|
|
156285
|
+
toHex(color) {
|
|
156286
|
+
return `#${color.toString(16).padStart(6, "0")}`;
|
|
156287
|
+
}
|
|
156288
|
+
scaleColor(color, multiplier) {
|
|
156289
|
+
const r = Math.min(255, Math.max(0, Math.round((color >> 16 & 255) * multiplier)));
|
|
156290
|
+
const g = Math.min(255, Math.max(0, Math.round((color >> 8 & 255) * multiplier)));
|
|
156291
|
+
const b = Math.min(255, Math.max(0, Math.round((color & 255) * multiplier)));
|
|
156292
|
+
return r << 16 | g << 8 | b;
|
|
156293
|
+
}
|
|
156294
|
+
ensureXtermStyles() {
|
|
156295
|
+
if (document.getElementById("xterm-styles")) return;
|
|
156296
|
+
const style = document.createElement("style");
|
|
156297
|
+
style.id = "xterm-styles";
|
|
156298
|
+
style.textContent = `
|
|
156299
|
+
.xterm { height: 100%; }
|
|
156300
|
+
.xterm-viewport { overflow-y: auto !important; }
|
|
156301
|
+
#serious-terminal-container .xterm { height: 100%; }
|
|
156302
|
+
`;
|
|
156303
|
+
document.head.appendChild(style);
|
|
156304
|
+
}
|
|
156305
|
+
createTerminal() {
|
|
156306
|
+
this.terminal = new import_xterm2.Terminal({
|
|
156307
|
+
theme: {
|
|
156308
|
+
background: "#0d111b",
|
|
156309
|
+
foreground: "#e0e0e0",
|
|
156310
|
+
cursor: "#00ff88",
|
|
156311
|
+
cursorAccent: "#0d111b",
|
|
156312
|
+
selectionBackground: "#3a5a8a"
|
|
156313
|
+
},
|
|
156314
|
+
fontFamily: "Cascadia Code, Consolas, Monaco, monospace",
|
|
156315
|
+
fontSize: 16,
|
|
156316
|
+
lineHeight: 1.2,
|
|
156317
|
+
cursorBlink: true,
|
|
156318
|
+
cursorStyle: "block",
|
|
156319
|
+
scrollback: 1e4,
|
|
156320
|
+
allowProposedApi: true
|
|
156321
|
+
});
|
|
156322
|
+
this.fitAddon = new import_addon_fit2.FitAddon();
|
|
156323
|
+
this.terminal.loadAddon(this.fitAddon);
|
|
156324
|
+
this.terminalDivEl.id = "serious-terminal-container";
|
|
156325
|
+
this.terminal.open(this.terminalDivEl);
|
|
156326
|
+
this.terminal.attachCustomKeyEventHandler((event) => {
|
|
156327
|
+
const isModifierPressed = event.ctrlKey || event.metaKey;
|
|
156328
|
+
const key = event.key.toLowerCase();
|
|
156329
|
+
if (event.type !== "keydown" || !isModifierPressed) return true;
|
|
156330
|
+
if (key === "c") {
|
|
156331
|
+
const selectedText = this.terminal?.hasSelection() ? this.terminal.getSelection() : "";
|
|
156332
|
+
if (!selectedText) {
|
|
156333
|
+
return true;
|
|
156334
|
+
}
|
|
156335
|
+
event.preventDefault();
|
|
156336
|
+
event.stopPropagation();
|
|
156337
|
+
navigator.clipboard.writeText(selectedText).catch(() => {
|
|
156338
|
+
});
|
|
156339
|
+
return false;
|
|
156340
|
+
}
|
|
156341
|
+
if (key === "v") {
|
|
156342
|
+
event.preventDefault();
|
|
156343
|
+
event.stopPropagation();
|
|
156344
|
+
navigator.clipboard.readText().then((text) => {
|
|
156345
|
+
if (text) this.terminal?.paste(text);
|
|
156346
|
+
}).catch(() => {
|
|
156347
|
+
});
|
|
156348
|
+
return false;
|
|
156349
|
+
}
|
|
156350
|
+
if (key === "f") {
|
|
156351
|
+
event.preventDefault();
|
|
156352
|
+
event.stopPropagation();
|
|
156353
|
+
this.toggleFullWidth();
|
|
156354
|
+
return false;
|
|
156355
|
+
}
|
|
156356
|
+
return true;
|
|
156357
|
+
});
|
|
156358
|
+
this.terminal.onData((data) => {
|
|
156359
|
+
if (!window.copilotBridge || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156360
|
+
void window.copilotBridge.terminalWrite(this.activeOfficeId, this.activeAgentId, data);
|
|
156361
|
+
});
|
|
156362
|
+
this.resizeHandler = () => {
|
|
156363
|
+
if (!this.visible || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156364
|
+
this.debouncedRefit(this.activeOfficeId, this.activeAgentId);
|
|
156365
|
+
};
|
|
156366
|
+
window.addEventListener("resize", this.resizeHandler);
|
|
156367
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
156368
|
+
if (!this.visible || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156369
|
+
this.debouncedRefit(this.activeOfficeId, this.activeAgentId);
|
|
156370
|
+
});
|
|
156371
|
+
this.resizeObserver.observe(this.terminalDivEl);
|
|
156372
|
+
}
|
|
156373
|
+
refitAndResize(officeId, agentId) {
|
|
156374
|
+
if (!this.fitAddon || !window.copilotBridge) return;
|
|
156375
|
+
this.fitAddon.fit();
|
|
156376
|
+
const dims = this.fitAddon.proposeDimensions();
|
|
156377
|
+
if (!dims) return;
|
|
156378
|
+
void window.copilotBridge.terminalResize(officeId, agentId, dims.cols, dims.rows);
|
|
156379
|
+
}
|
|
156380
|
+
debouncedRefit(officeId, agentId) {
|
|
156381
|
+
this.clearRefitTimers();
|
|
156382
|
+
requestAnimationFrame(() => {
|
|
156383
|
+
this.refitAndResize(officeId, agentId);
|
|
156384
|
+
this.refitTimers.push(setTimeout(() => {
|
|
156385
|
+
this.refitAndResize(officeId, agentId);
|
|
156386
|
+
this.refitTimers.push(setTimeout(() => this.refitAndResize(officeId, agentId), 200));
|
|
156387
|
+
}, 150));
|
|
156388
|
+
});
|
|
156389
|
+
}
|
|
156390
|
+
refreshFocusAndGeometry() {
|
|
156391
|
+
if (!this.visible || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156392
|
+
this.terminal?.focus();
|
|
156393
|
+
this.debouncedRefit(this.activeOfficeId, this.activeAgentId);
|
|
156394
|
+
}
|
|
156395
|
+
toggleFullWidth() {
|
|
156396
|
+
this.isFullWidth = !this.isFullWidth;
|
|
156397
|
+
localStorage.setItem(_SeriousTerminalController.FULL_WIDTH_STORAGE_KEY, String(this.isFullWidth));
|
|
156398
|
+
this.fullscreenBtn.textContent = this.isFullWidth ? "Half Width" : "Full Width";
|
|
156399
|
+
this.applyPanelLayout();
|
|
156400
|
+
}
|
|
156401
|
+
applyPanelLayout() {
|
|
156402
|
+
const officePanel = document.getElementById("office-panel");
|
|
156403
|
+
const terminalPanel = document.getElementById("terminal-panel");
|
|
156404
|
+
const isMobile = window.__copilotOfficeMobileModeActive?.() === true;
|
|
156405
|
+
if (!officePanel || !terminalPanel || isMobile) return;
|
|
156406
|
+
const appMode = document.getElementById("game-container")?.dataset.appMode;
|
|
156407
|
+
if (appMode !== "serious" || !this.visible || !this.isFullWidth) {
|
|
156408
|
+
officePanel.style.display = "flex";
|
|
156409
|
+
officePanel.style.flexDirection = "column";
|
|
156410
|
+
terminalPanel.style.width = "50%";
|
|
156411
|
+
terminalPanel.style.borderLeft = "2px solid #333";
|
|
156412
|
+
return;
|
|
156413
|
+
}
|
|
156414
|
+
officePanel.style.display = "none";
|
|
156415
|
+
terminalPanel.style.width = "100%";
|
|
156416
|
+
terminalPanel.style.borderLeft = "none";
|
|
156417
|
+
}
|
|
156418
|
+
clearRefitTimers() {
|
|
156419
|
+
for (const timer of this.refitTimers) clearTimeout(timer);
|
|
156420
|
+
this.refitTimers.length = 0;
|
|
156421
|
+
}
|
|
156422
|
+
formatElapsed(startTime) {
|
|
156423
|
+
const seconds = Math.floor((Date.now() - startTime) / 1e3);
|
|
156424
|
+
if (seconds < 60) return `${seconds}s`;
|
|
156425
|
+
const mins = Math.floor(seconds / 60);
|
|
156426
|
+
const secs = seconds % 60;
|
|
156427
|
+
return `${mins}m ${secs}s`;
|
|
156428
|
+
}
|
|
156429
|
+
buttonCss(background, border) {
|
|
156430
|
+
return `
|
|
156431
|
+
background: ${background};
|
|
156432
|
+
border: 1px solid ${border};
|
|
156433
|
+
color: #d4dbf9;
|
|
156434
|
+
border-radius: 5px;
|
|
156435
|
+
padding: 6px 10px;
|
|
156436
|
+
font-family: inherit;
|
|
156437
|
+
font-size: 12px;
|
|
156438
|
+
cursor: pointer;
|
|
156439
|
+
white-space: nowrap;
|
|
156440
|
+
`;
|
|
156441
|
+
}
|
|
156442
|
+
};
|
|
156443
|
+
}
|
|
156444
|
+
});
|
|
156445
|
+
|
|
156446
|
+
// src/main.ts
|
|
156447
|
+
var require_main = __commonJS({
|
|
156448
|
+
"src/main.ts"() {
|
|
156449
|
+
var import_phaser10 = __toESM(require_phaser());
|
|
156450
|
+
init_BootScene();
|
|
156451
|
+
init_OfficeScene();
|
|
156452
|
+
init_MeetingScene();
|
|
156453
|
+
init_officeManager();
|
|
156454
|
+
init_agents();
|
|
156455
|
+
init_responsiveLayout();
|
|
156456
|
+
init_layouts();
|
|
156457
|
+
init_ToastNotification();
|
|
156458
|
+
init_NotificationService();
|
|
156459
|
+
init_SettingsPanel();
|
|
156460
|
+
init_SpriteCustomizerPanel();
|
|
156461
|
+
init_SeriousTerminalController();
|
|
156462
|
+
init_SpriteGenerator();
|
|
156463
|
+
officeManager.ensureDefaultOffice();
|
|
156464
|
+
function getCurrentLayout() {
|
|
156465
|
+
return officeManager.currentOffice?.config.layout ?? "default";
|
|
156466
|
+
}
|
|
156467
|
+
function getCurrentAgents() {
|
|
156468
|
+
return getLayout(getCurrentLayout()).agents;
|
|
156469
|
+
}
|
|
156470
|
+
function getCurrentAgentTools() {
|
|
156471
|
+
return officeManager.currentOffice?.agentTools || /* @__PURE__ */ new Map();
|
|
156472
|
+
}
|
|
156473
|
+
function syncActiveRosterForCurrentOffice() {
|
|
156474
|
+
const office = officeManager.currentOffice;
|
|
156475
|
+
if (!office) return;
|
|
156476
|
+
swapActiveAgents(office.config);
|
|
156477
|
+
if (office.config.layout === "default") {
|
|
156478
|
+
restoreSeatedReserveAgents(officeManager.getSeatedAgents(office.config.id));
|
|
156479
|
+
}
|
|
156480
|
+
}
|
|
156481
|
+
function normalizeToolName(toolName) {
|
|
156482
|
+
return (toolName ?? "").trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
156483
|
+
}
|
|
156484
|
+
function isAskUserTool(toolName, status) {
|
|
156485
|
+
const normalized = normalizeToolName(toolName);
|
|
156486
|
+
if (normalized === "ask_user" || normalized === "askuser") return true;
|
|
156487
|
+
const statusText = (status ?? "").toLowerCase();
|
|
156488
|
+
return statusText.includes("waiting for your answer") || statusText.includes("waiting on user input");
|
|
156489
|
+
}
|
|
156490
|
+
function isDonePendingAck(status) {
|
|
156491
|
+
return !!status?.completionPendingAck;
|
|
156492
|
+
}
|
|
156493
|
+
var selectedAgentId = null;
|
|
156494
|
+
var phaserGameRef;
|
|
156495
|
+
var debugMode = false;
|
|
156496
|
+
var currentZoom = parseFloat(localStorage.getItem("agencyOffice:zoomLevel") ?? "0.8");
|
|
156497
|
+
currentZoom = isNaN(currentZoom) || currentZoom < 0.5 || currentZoom > 2 ? 0.8 : currentZoom;
|
|
156498
|
+
var RESIZE_DEBOUNCE_MS = 200;
|
|
156499
|
+
var APP_MODE_STORAGE_KEY = "agencyOffice:appMode";
|
|
156500
|
+
var SESSION_META_CACHE_STORAGE_KEY = "agencyOffice:sessionMetaCacheByOffice";
|
|
156501
|
+
var OVERVIEW_SPRITE_CACHE_STORAGE_KEY = "agencyOffice:overviewSpriteCache";
|
|
156502
|
+
var PC_TERMINAL_ID2 = "pc-terminal";
|
|
156503
|
+
function sanitizeAppMode(value) {
|
|
156504
|
+
return value === "serious" ? "serious" : "game";
|
|
156505
|
+
}
|
|
156506
|
+
var appMode = sanitizeAppMode(localStorage.getItem(APP_MODE_STORAGE_KEY));
|
|
156507
|
+
function persistAppMode(mode) {
|
|
156508
|
+
try {
|
|
156509
|
+
localStorage.setItem(APP_MODE_STORAGE_KEY, mode);
|
|
156510
|
+
} catch {
|
|
156511
|
+
}
|
|
156512
|
+
}
|
|
156513
|
+
function loadSessionMetaCacheByOffice() {
|
|
156514
|
+
try {
|
|
156515
|
+
const raw = localStorage.getItem(SESSION_META_CACHE_STORAGE_KEY);
|
|
156516
|
+
if (!raw) return {};
|
|
156517
|
+
const parsed = JSON.parse(raw);
|
|
156518
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
156519
|
+
} catch {
|
|
156520
|
+
return {};
|
|
156521
|
+
}
|
|
156522
|
+
}
|
|
156523
|
+
function saveSessionMetaCacheByOffice(cache) {
|
|
156524
|
+
try {
|
|
156525
|
+
localStorage.setItem(SESSION_META_CACHE_STORAGE_KEY, JSON.stringify(cache));
|
|
156526
|
+
} catch {
|
|
156527
|
+
}
|
|
156528
|
+
}
|
|
156529
|
+
function getSessionMetaCacheForOffice(officeId) {
|
|
156530
|
+
const all = loadSessionMetaCacheByOffice();
|
|
156531
|
+
return all[officeId] || {};
|
|
156532
|
+
}
|
|
156533
|
+
function setSessionMetaCacheForOffice(officeId, meta) {
|
|
156534
|
+
const all = loadSessionMetaCacheByOffice();
|
|
156535
|
+
all[officeId] = meta;
|
|
156536
|
+
saveSessionMetaCacheByOffice(all);
|
|
156537
|
+
}
|
|
156538
|
+
function loadOverviewSpriteCache() {
|
|
156539
|
+
try {
|
|
156540
|
+
const raw = localStorage.getItem(OVERVIEW_SPRITE_CACHE_STORAGE_KEY);
|
|
156541
|
+
if (!raw) return {};
|
|
156542
|
+
const parsed = JSON.parse(raw);
|
|
156543
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
156544
|
+
} catch {
|
|
156545
|
+
return {};
|
|
156546
|
+
}
|
|
156547
|
+
}
|
|
156548
|
+
function saveOverviewSpriteCache(cache) {
|
|
156549
|
+
try {
|
|
156550
|
+
localStorage.setItem(OVERVIEW_SPRITE_CACHE_STORAGE_KEY, JSON.stringify(cache));
|
|
156551
|
+
} catch {
|
|
156552
|
+
}
|
|
156553
|
+
}
|
|
156554
|
+
var agentPreloadStatus = /* @__PURE__ */ new Map();
|
|
156555
|
+
var pendingStatusBarUpdate = false;
|
|
156556
|
+
var pendingTerminalContentUpdate = false;
|
|
156557
|
+
var OVERVIEW_SPRITE_MAX_RETRY_ATTEMPTS = 5;
|
|
156558
|
+
var OVERVIEW_SPRITE_RETRY_DELAY_MS = 120;
|
|
156559
|
+
var overviewSpriteRetryTimer = null;
|
|
156560
|
+
var overviewSpriteCache = loadOverviewSpriteCache();
|
|
156561
|
+
var overviewSpriteImageCache = /* @__PURE__ */ new Map();
|
|
156562
|
+
function scheduleUiUpdateWithFallback(callback) {
|
|
156563
|
+
let done = false;
|
|
156564
|
+
const runOnce = () => {
|
|
156565
|
+
if (done) return;
|
|
156566
|
+
done = true;
|
|
156567
|
+
callback();
|
|
156568
|
+
};
|
|
156569
|
+
requestAnimationFrame(runOnce);
|
|
156570
|
+
const fallbackDelayMs = document.hidden ? 80 : 200;
|
|
156571
|
+
setTimeout(runOnce, fallbackDelayMs);
|
|
156572
|
+
}
|
|
156573
|
+
function scheduleStatusBarUpdate() {
|
|
156574
|
+
if (pendingStatusBarUpdate) return;
|
|
156575
|
+
pendingStatusBarUpdate = true;
|
|
156576
|
+
scheduleUiUpdateWithFallback(() => {
|
|
156577
|
+
pendingStatusBarUpdate = false;
|
|
156578
|
+
updateStatusBarNow();
|
|
156579
|
+
});
|
|
156580
|
+
}
|
|
156581
|
+
function scheduleTerminalContentUpdate() {
|
|
156582
|
+
if (pendingTerminalContentUpdate) return;
|
|
156583
|
+
pendingTerminalContentUpdate = true;
|
|
156584
|
+
scheduleUiUpdateWithFallback(() => {
|
|
156585
|
+
pendingTerminalContentUpdate = false;
|
|
156586
|
+
updateTerminalContentNow();
|
|
156587
|
+
});
|
|
156588
|
+
}
|
|
156589
|
+
var container = document.getElementById("game-container");
|
|
156590
|
+
container.innerHTML = "";
|
|
156591
|
+
container.style.cssText = "display: flex; flex-direction: column; width: 100%; height: calc(100% - 58px);";
|
|
156592
|
+
var tabsBar = document.createElement("div");
|
|
156593
|
+
tabsBar.id = "office-tabs";
|
|
156594
|
+
tabsBar.style.cssText = `
|
|
156595
|
+
display: flex;
|
|
156596
|
+
align-items: center;
|
|
156597
|
+
background: #1a1a2a;
|
|
156598
|
+
border-bottom: 2px solid #333;
|
|
156599
|
+
padding: 0 16px;
|
|
156600
|
+
height: 72px;
|
|
156601
|
+
flex-shrink: 0;
|
|
156602
|
+
font-size: 22px;
|
|
156603
|
+
`;
|
|
156604
|
+
container.appendChild(tabsBar);
|
|
156605
|
+
var mainContent = document.createElement("div");
|
|
156606
|
+
mainContent.style.cssText = "display: flex; flex: 1; min-height: 0;";
|
|
156607
|
+
container.appendChild(mainContent);
|
|
156608
|
+
var officePanel = document.createElement("div");
|
|
156609
|
+
officePanel.id = "office-panel";
|
|
156610
|
+
officePanel.style.cssText = "width: 50%; height: 100%; position: relative;";
|
|
156611
|
+
mainContent.appendChild(officePanel);
|
|
156612
|
+
var terminalPanel = document.createElement("div");
|
|
156613
|
+
terminalPanel.id = "terminal-panel";
|
|
156614
|
+
terminalPanel.style.cssText = `
|
|
156615
|
+
width: 50%;
|
|
156616
|
+
height: 100%;
|
|
156617
|
+
background: #1e1e2e;
|
|
156618
|
+
border-left: 2px solid #333;
|
|
156619
|
+
display: flex;
|
|
156620
|
+
flex-direction: column;
|
|
156621
|
+
position: relative;
|
|
156622
|
+
`;
|
|
156623
|
+
mainContent.appendChild(terminalPanel);
|
|
156624
|
+
var overviewHost = document.createElement("div");
|
|
156625
|
+
overviewHost.id = "overview-host";
|
|
156626
|
+
overviewHost.style.cssText = `
|
|
156627
|
+
display: flex;
|
|
156628
|
+
flex-direction: column;
|
|
156629
|
+
flex: 1;
|
|
156630
|
+
min-height: 0;
|
|
156631
|
+
position: relative;
|
|
156632
|
+
`;
|
|
156633
|
+
terminalPanel.appendChild(overviewHost);
|
|
156634
|
+
var terminalHost = document.createElement("div");
|
|
156635
|
+
terminalHost.id = "terminal-host";
|
|
156636
|
+
terminalHost.style.cssText = "display: none; flex: 1; min-height: 0;";
|
|
156637
|
+
terminalPanel.appendChild(terminalHost);
|
|
156638
|
+
var seriousPlaceholder = document.createElement("div");
|
|
156639
|
+
seriousPlaceholder.id = "serious-terminal-placeholder";
|
|
156640
|
+
seriousPlaceholder.style.cssText = `
|
|
156641
|
+
display: none;
|
|
156642
|
+
flex: 1;
|
|
156643
|
+
min-height: 0;
|
|
156644
|
+
align-items: center;
|
|
156645
|
+
justify-content: center;
|
|
156646
|
+
padding: 24px;
|
|
156647
|
+
font-family: 'Cascadia Code', Consolas, monospace;
|
|
156648
|
+
text-align: center;
|
|
156649
|
+
color: #95a7d7;
|
|
156650
|
+
background: radial-gradient(circle at top, #222846 0%, #171c2f 50%, #13192a 100%);
|
|
156651
|
+
`;
|
|
156652
|
+
seriousPlaceholder.innerHTML = `
|
|
156653
|
+
<div style="max-width: 380px;">
|
|
156654
|
+
<div style="font-size: 34px; margin-bottom: 10px;">\u{1F4BB}</div>
|
|
156655
|
+
<div style="font-size: 18px; color: #c7d7ff; font-weight: 700; margin-bottom: 8px;">No terminal selected</div>
|
|
156656
|
+
<div style="font-size: 12px; line-height: 1.45; color: #8fa3d6;">
|
|
156657
|
+
Select an agent or office PC from the overview on the left to open a command line session.
|
|
156658
|
+
</div>
|
|
156659
|
+
</div>
|
|
156660
|
+
`;
|
|
156661
|
+
terminalHost.appendChild(seriousPlaceholder);
|
|
156662
|
+
var currentResponsiveLayout = "default";
|
|
156663
|
+
var resizeDebounceTimer = null;
|
|
156664
|
+
function isMobileModeActive() {
|
|
156665
|
+
return currentResponsiveLayout === "portrait-dashboard";
|
|
156666
|
+
}
|
|
156667
|
+
function applyMobileTopBarVisibility() {
|
|
156668
|
+
const hidden = isMobileModeActive();
|
|
156669
|
+
const ids = ["zoom-bar", "sprite-customizer-btn", "debug-toggle-btn"];
|
|
156670
|
+
for (const id of ids) {
|
|
156671
|
+
const el = document.getElementById(id);
|
|
156672
|
+
if (!el) continue;
|
|
156673
|
+
el.style.display = hidden ? "none" : "";
|
|
156674
|
+
}
|
|
156675
|
+
}
|
|
156676
|
+
function syncMainPanelLayout() {
|
|
156677
|
+
const hideOfficePanel = currentResponsiveLayout === "portrait-dashboard";
|
|
156678
|
+
if (hideOfficePanel) {
|
|
156679
|
+
officePanel.style.display = "none";
|
|
156680
|
+
officePanel.style.flexDirection = "";
|
|
156681
|
+
terminalPanel.style.width = "100%";
|
|
156682
|
+
terminalPanel.style.borderLeft = "none";
|
|
156683
|
+
return;
|
|
156684
|
+
}
|
|
156685
|
+
officePanel.style.display = appMode === "serious" ? "flex" : "";
|
|
156686
|
+
officePanel.style.flexDirection = appMode === "serious" ? "column" : "";
|
|
156687
|
+
terminalPanel.style.width = "50%";
|
|
156688
|
+
terminalPanel.style.borderLeft = "2px solid #333";
|
|
156689
|
+
}
|
|
156690
|
+
function applyResponsiveLayout(layoutKey) {
|
|
156691
|
+
if (layoutKey === currentResponsiveLayout) return;
|
|
156692
|
+
currentResponsiveLayout = layoutKey;
|
|
156693
|
+
syncMainPanelLayout();
|
|
156694
|
+
refreshRightPanelMode();
|
|
156695
|
+
if (phaserGameRef && appMode === "game") {
|
|
156696
|
+
phaserGameRef.events.emit("layout:change", { layoutKey });
|
|
156697
|
+
if (layoutKey === "default") {
|
|
156698
|
+
const width = officePanel.clientWidth || window.innerWidth / 2;
|
|
156699
|
+
const height = officePanel.clientHeight || window.innerHeight;
|
|
156700
|
+
phaserGameRef.scale.resize(width, height);
|
|
156701
|
+
}
|
|
156702
|
+
}
|
|
156703
|
+
applyMobileTopBarVisibility();
|
|
156704
|
+
}
|
|
155591
156705
|
function onWindowResize() {
|
|
155592
156706
|
if (resizeDebounceTimer !== null) {
|
|
155593
156707
|
window.clearTimeout(resizeDebounceTimer);
|
|
@@ -155595,13 +156709,55 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155595
156709
|
resizeDebounceTimer = window.setTimeout(() => {
|
|
155596
156710
|
const next = computeResponsiveLayout(window.innerWidth, window.innerHeight);
|
|
155597
156711
|
applyResponsiveLayout(next);
|
|
155598
|
-
if (phaserGameRef && currentResponsiveLayout === "default") {
|
|
156712
|
+
if (phaserGameRef && appMode === "game" && currentResponsiveLayout === "default") {
|
|
155599
156713
|
const width = officePanel.clientWidth || window.innerWidth / 2;
|
|
155600
156714
|
const height = officePanel.clientHeight || window.innerHeight;
|
|
155601
156715
|
phaserGameRef.scale.resize(width, height);
|
|
155602
156716
|
}
|
|
155603
156717
|
}, RESIZE_DEBOUNCE_MS);
|
|
155604
156718
|
}
|
|
156719
|
+
function applyAppMode(nextMode, options = {}) {
|
|
156720
|
+
const { persist = false, refreshTabs = true, force = false } = options;
|
|
156721
|
+
if (!force && nextMode === appMode) return;
|
|
156722
|
+
const previousMode = appMode;
|
|
156723
|
+
appMode = nextMode;
|
|
156724
|
+
const selectedAgentBeforeModeSwitch = selectedAgentId;
|
|
156725
|
+
if (previousMode === "serious" && appMode === "game") {
|
|
156726
|
+
void seriousTerminalController?.closeView({ detach: true, silent: true });
|
|
156727
|
+
}
|
|
156728
|
+
if (appMode === "serious") {
|
|
156729
|
+
prewarmOverviewSpriteCacheFromTextures();
|
|
156730
|
+
teardownPhaserGame();
|
|
156731
|
+
} else {
|
|
156732
|
+
ensurePhaserGame();
|
|
156733
|
+
}
|
|
156734
|
+
container.dataset.appMode = appMode;
|
|
156735
|
+
tabsBar.dataset.appMode = appMode;
|
|
156736
|
+
mainContent.dataset.appMode = appMode;
|
|
156737
|
+
officePanel.dataset.appMode = appMode;
|
|
156738
|
+
terminalPanel.dataset.appMode = appMode;
|
|
156739
|
+
overviewHost.dataset.appMode = appMode;
|
|
156740
|
+
terminalHost.dataset.appMode = appMode;
|
|
156741
|
+
syncMainPanelLayout();
|
|
156742
|
+
if (phaserGameRef && appMode === "game" && currentResponsiveLayout === "default") {
|
|
156743
|
+
const width = officePanel.clientWidth || window.innerWidth / 2;
|
|
156744
|
+
const height = officePanel.clientHeight || window.innerHeight;
|
|
156745
|
+
phaserGameRef.scale.resize(width, height);
|
|
156746
|
+
}
|
|
156747
|
+
if (persist) persistAppMode(appMode);
|
|
156748
|
+
if (refreshTabs) renderOfficeTabs();
|
|
156749
|
+
refreshRightPanelMode();
|
|
156750
|
+
updateTerminalContent();
|
|
156751
|
+
updateStatusBar();
|
|
156752
|
+
phaserGameRef?.events.emit("app:mode:changed", { mode: appMode, previousMode });
|
|
156753
|
+
if (appMode === "serious" && selectedAgentBeforeModeSwitch && getSeriousLaunchConfig(selectedAgentBeforeModeSwitch)) {
|
|
156754
|
+
void openAgentTerminal(selectedAgentBeforeModeSwitch);
|
|
156755
|
+
}
|
|
156756
|
+
}
|
|
156757
|
+
function toggleAppMode() {
|
|
156758
|
+
const nextMode = appMode === "game" ? "serious" : "game";
|
|
156759
|
+
applyAppMode(nextMode, { persist: true, refreshTabs: true });
|
|
156760
|
+
}
|
|
155605
156761
|
applyResponsiveLayout(computeResponsiveLayout(window.innerWidth, window.innerHeight));
|
|
155606
156762
|
window.addEventListener("resize", onWindowResize);
|
|
155607
156763
|
if (typeof window !== "undefined") {
|
|
@@ -155651,6 +156807,21 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155651
156807
|
color: #4a4;
|
|
155652
156808
|
">+ New Office</div>
|
|
155653
156809
|
<div style="flex: 1;"></div>
|
|
156810
|
+
<div id="app-mode-toggle-btn" style="
|
|
156811
|
+
padding: 8px 14px;
|
|
156812
|
+
background: ${appMode === "serious" ? "#2f2638" : "#252538"};
|
|
156813
|
+
border: 2px solid ${appMode === "serious" ? "#a66be0" : "#444"};
|
|
156814
|
+
border-radius: 6px;
|
|
156815
|
+
cursor: pointer;
|
|
156816
|
+
font-family: monospace;
|
|
156817
|
+
color: ${appMode === "serious" ? "#d4b6ff" : "#8fb7ff"};
|
|
156818
|
+
font-size: 14px;
|
|
156819
|
+
user-select: none;
|
|
156820
|
+
transition: all 0.2s;
|
|
156821
|
+
margin-right: 8px;
|
|
156822
|
+
" title="Toggle app mode (game/serious)">
|
|
156823
|
+
${appMode === "serious" ? "\u{1F9E0} Serious Mode" : "\u{1F3AE} Game Mode"}
|
|
156824
|
+
</div>
|
|
155654
156825
|
<div id="sprite-customizer-btn" style="
|
|
155655
156826
|
padding: 8px 16px;
|
|
155656
156827
|
background: #252538;
|
|
@@ -155749,12 +156920,16 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155749
156920
|
});
|
|
155750
156921
|
});
|
|
155751
156922
|
document.getElementById("new-office-btn")?.addEventListener("click", showNewOfficeDialog);
|
|
156923
|
+
document.getElementById("app-mode-toggle-btn")?.addEventListener("click", (e) => {
|
|
156924
|
+
e.stopPropagation();
|
|
156925
|
+
toggleAppMode();
|
|
156926
|
+
});
|
|
155752
156927
|
document.getElementById("debug-toggle-btn")?.addEventListener("click", () => {
|
|
155753
156928
|
debugMode = !debugMode;
|
|
155754
|
-
|
|
156929
|
+
phaserGameRef?.events.emit("debug:toggle", debugMode);
|
|
155755
156930
|
renderOfficeTabs();
|
|
155756
156931
|
if (!isMobileModeActive()) {
|
|
155757
|
-
|
|
156932
|
+
phaserGameRef?.events.emit("game:panel:clicked");
|
|
155758
156933
|
}
|
|
155759
156934
|
console.log(`[Debug] Debug mode ${debugMode ? "ON" : "OFF"}`);
|
|
155760
156935
|
});
|
|
@@ -155794,19 +156969,20 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155794
156969
|
applyMobileTopBarVisibility();
|
|
155795
156970
|
}
|
|
155796
156971
|
function switchToOffice(officeId) {
|
|
155797
|
-
if (
|
|
156972
|
+
if (phaserGameRef?.registry.get("animating")) {
|
|
155798
156973
|
console.log("[Office] Blocked: animation in progress");
|
|
155799
156974
|
return;
|
|
155800
156975
|
}
|
|
155801
156976
|
selectedAgentId = null;
|
|
156977
|
+
void seriousTerminalController?.closeView({ detach: true });
|
|
155802
156978
|
officeManager.switchOffice(officeId);
|
|
155803
|
-
|
|
155804
|
-
|
|
155805
|
-
|
|
156979
|
+
cachedSessionMeta = getSessionMetaCacheForOffice(officeId);
|
|
156980
|
+
syncActiveRosterForCurrentOffice();
|
|
156981
|
+
phaserGameRef?.events.emit("office:switch", officeId, officeManager.currentOffice?.config.workingDirectory);
|
|
155806
156982
|
renderOfficeTabs();
|
|
155807
156983
|
updateTerminalContent();
|
|
155808
156984
|
updateStatusBar();
|
|
155809
|
-
|
|
156985
|
+
void reconnectAgentStatuses();
|
|
155810
156986
|
fetchSessionMeta();
|
|
155811
156987
|
console.log(`[Office] Switched to office: ${officeManager.currentOffice?.config.name}`);
|
|
155812
156988
|
}
|
|
@@ -156001,8 +157177,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156001
157177
|
nameInput.select();
|
|
156002
157178
|
}
|
|
156003
157179
|
renderOfficeTabs();
|
|
156004
|
-
var
|
|
156005
|
-
|
|
157180
|
+
var overviewHeader = document.createElement("div");
|
|
157181
|
+
overviewHeader.style.cssText = `
|
|
156006
157182
|
padding: 14px 20px;
|
|
156007
157183
|
background: #141424;
|
|
156008
157184
|
border-bottom: 2px solid #2a2a4a;
|
|
@@ -156012,7 +157188,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156012
157188
|
justify-content: space-between;
|
|
156013
157189
|
align-items: center;
|
|
156014
157190
|
`;
|
|
156015
|
-
|
|
157191
|
+
overviewHeader.innerHTML = `
|
|
156016
157192
|
<div>
|
|
156017
157193
|
<div id="terminal-title" style="font-size: 18px; font-weight: bold; color: #8af; margin-bottom: 4px;">\u{1F3E2} Office Overview</div>
|
|
156018
157194
|
<div id="terminal-subtitle" style="font-size: 12px; color: #555;"></div>
|
|
@@ -156030,7 +157206,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156030
157206
|
white-space: nowrap;
|
|
156031
157207
|
">\u2715 Close Office</button>
|
|
156032
157208
|
`;
|
|
156033
|
-
|
|
157209
|
+
overviewHost.appendChild(overviewHeader);
|
|
156034
157210
|
document.getElementById("close-office-btn").addEventListener("click", () => {
|
|
156035
157211
|
const currentId = officeManager.currentOfficeId;
|
|
156036
157212
|
const office = officeManager.currentOffice;
|
|
@@ -156040,9 +157216,9 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156040
157216
|
switchToOffice("office-0");
|
|
156041
157217
|
}
|
|
156042
157218
|
});
|
|
156043
|
-
var
|
|
156044
|
-
|
|
156045
|
-
|
|
157219
|
+
var overviewContent = document.createElement("div");
|
|
157220
|
+
overviewContent.id = "terminal-content";
|
|
157221
|
+
overviewContent.style.cssText = `
|
|
156046
157222
|
flex: 1;
|
|
156047
157223
|
padding: 16px;
|
|
156048
157224
|
overflow-y: auto;
|
|
@@ -156051,7 +157227,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156051
157227
|
color: #ccc;
|
|
156052
157228
|
position: relative;
|
|
156053
157229
|
`;
|
|
156054
|
-
|
|
157230
|
+
overviewHost.appendChild(overviewContent);
|
|
156055
157231
|
var statusBar = document.createElement("div");
|
|
156056
157232
|
statusBar.id = "status-bar";
|
|
156057
157233
|
statusBar.style.cssText = `
|
|
@@ -156097,6 +157273,86 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156097
157273
|
function getAgentConfig(agentId) {
|
|
156098
157274
|
return getCurrentAgents().find((a) => a.id === agentId) || AGENTS.find((a) => a.id === agentId);
|
|
156099
157275
|
}
|
|
157276
|
+
var seriousTerminalController = null;
|
|
157277
|
+
function getSeriousLaunchConfig(agentId) {
|
|
157278
|
+
if (agentId === PC_TERMINAL_ID2) {
|
|
157279
|
+
return {
|
|
157280
|
+
name: "PC TERMINAL",
|
|
157281
|
+
description: "Local Shell",
|
|
157282
|
+
color: 7311064,
|
|
157283
|
+
workingDir: officeManager.getCurrentWorkingDirectory(),
|
|
157284
|
+
launchMode: "shell"
|
|
157285
|
+
};
|
|
157286
|
+
}
|
|
157287
|
+
const agent = getAgentConfig(agentId);
|
|
157288
|
+
if (!agent) return null;
|
|
157289
|
+
return {
|
|
157290
|
+
name: agent.name,
|
|
157291
|
+
description: agent.description,
|
|
157292
|
+
color: agent.color,
|
|
157293
|
+
workingDir: agent.workingDir || officeManager.getCurrentWorkingDirectory(),
|
|
157294
|
+
launchMode: "copilot"
|
|
157295
|
+
};
|
|
157296
|
+
}
|
|
157297
|
+
function refreshRightPanelMode() {
|
|
157298
|
+
const seriousDesktop = appMode === "serious" && currentResponsiveLayout === "default";
|
|
157299
|
+
const desiredOverviewParent = seriousDesktop ? officePanel : terminalPanel;
|
|
157300
|
+
if (overviewHost.parentElement !== desiredOverviewParent) {
|
|
157301
|
+
desiredOverviewParent.appendChild(overviewHost);
|
|
157302
|
+
}
|
|
157303
|
+
if (appMode === "serious") {
|
|
157304
|
+
const seriousVisible = !!seriousTerminalController?.isVisible();
|
|
157305
|
+
if (seriousDesktop) {
|
|
157306
|
+
overviewHost.style.display = "flex";
|
|
157307
|
+
terminalHost.style.display = "flex";
|
|
157308
|
+
seriousPlaceholder.style.display = seriousVisible ? "none" : "flex";
|
|
157309
|
+
return;
|
|
157310
|
+
}
|
|
157311
|
+
if (seriousVisible) {
|
|
157312
|
+
overviewHost.style.display = "none";
|
|
157313
|
+
terminalHost.style.display = "flex";
|
|
157314
|
+
seriousPlaceholder.style.display = "none";
|
|
157315
|
+
return;
|
|
157316
|
+
}
|
|
157317
|
+
overviewHost.style.display = "flex";
|
|
157318
|
+
terminalHost.style.display = "none";
|
|
157319
|
+
seriousPlaceholder.style.display = "none";
|
|
157320
|
+
return;
|
|
157321
|
+
}
|
|
157322
|
+
overviewHost.style.display = "flex";
|
|
157323
|
+
terminalHost.style.display = "none";
|
|
157324
|
+
seriousPlaceholder.style.display = "none";
|
|
157325
|
+
}
|
|
157326
|
+
async function openAgentTerminal(agentId) {
|
|
157327
|
+
if (appMode === "game") {
|
|
157328
|
+
phaserGameRef?.events.emit("open:agent:terminal", agentId);
|
|
157329
|
+
return;
|
|
157330
|
+
}
|
|
157331
|
+
const launchConfig = getSeriousLaunchConfig(agentId);
|
|
157332
|
+
if (!launchConfig || !window.copilotBridge) return;
|
|
157333
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
157334
|
+
const officeStatus = officeManager.getAgentStatus(officeId, agentId);
|
|
157335
|
+
if (officeStatus?.state === "slacking") {
|
|
157336
|
+
officeManager.setAgentStarting(officeId, agentId);
|
|
157337
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
157338
|
+
updateStatusBar();
|
|
157339
|
+
updateTerminalContent();
|
|
157340
|
+
}
|
|
157341
|
+
await seriousTerminalController?.openAgentTerminal({
|
|
157342
|
+
officeId,
|
|
157343
|
+
agentId,
|
|
157344
|
+
...launchConfig
|
|
157345
|
+
});
|
|
157346
|
+
refreshRightPanelMode();
|
|
157347
|
+
}
|
|
157348
|
+
seriousTerminalController = new SeriousTerminalController(terminalHost, {
|
|
157349
|
+
onClose: () => {
|
|
157350
|
+
selectedAgentId = null;
|
|
157351
|
+
refreshRightPanelMode();
|
|
157352
|
+
updateStatusBar();
|
|
157353
|
+
updateTerminalContent();
|
|
157354
|
+
}
|
|
157355
|
+
});
|
|
156100
157356
|
var notificationService = new NotificationService(
|
|
156101
157357
|
toastManager,
|
|
156102
157358
|
(agentId) => {
|
|
@@ -156109,7 +157365,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156109
157365
|
const oId = officeManager.currentOfficeId;
|
|
156110
157366
|
if (oId) officeManager.clearUnread(oId, agentId);
|
|
156111
157367
|
updateTerminalContent();
|
|
156112
|
-
|
|
157368
|
+
void openAgentTerminal(agentId);
|
|
156113
157369
|
}
|
|
156114
157370
|
);
|
|
156115
157371
|
function notifyAgent(agentId, eventType, context) {
|
|
@@ -156158,9 +157414,16 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156158
157414
|
var lastStatusBarHtml = "";
|
|
156159
157415
|
var cachedSessionMeta = {};
|
|
156160
157416
|
function fetchSessionMeta() {
|
|
157417
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
157418
|
+
const cached = getSessionMetaCacheForOffice(officeId);
|
|
157419
|
+
if (Object.keys(cached).length > 0) {
|
|
157420
|
+
cachedSessionMeta = cached;
|
|
157421
|
+
updateTerminalContent();
|
|
157422
|
+
}
|
|
156161
157423
|
if (!window.copilotBridge?.getAllSessionMeta) return;
|
|
156162
|
-
window.copilotBridge.getAllSessionMeta(
|
|
157424
|
+
window.copilotBridge.getAllSessionMeta(officeId).then((meta) => {
|
|
156163
157425
|
cachedSessionMeta = meta || {};
|
|
157426
|
+
setSessionMetaCacheForOffice(officeId, cachedSessionMeta);
|
|
156164
157427
|
updateTerminalContent();
|
|
156165
157428
|
}).catch(() => {
|
|
156166
157429
|
});
|
|
@@ -156169,6 +157432,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156169
157432
|
scheduleTerminalContentUpdate();
|
|
156170
157433
|
}
|
|
156171
157434
|
function updateTerminalContentNow() {
|
|
157435
|
+
syncActiveRosterForCurrentOffice();
|
|
156172
157436
|
const agentTools = getCurrentAgentTools();
|
|
156173
157437
|
const office = officeManager.currentOffice;
|
|
156174
157438
|
const closeBtn = document.getElementById("close-office-btn");
|
|
@@ -156193,47 +157457,135 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156193
157457
|
});
|
|
156194
157458
|
if (html !== lastTerminalContentHtml) {
|
|
156195
157459
|
lastTerminalContentHtml = html;
|
|
156196
|
-
|
|
156197
|
-
|
|
157460
|
+
overviewContent.innerHTML = html;
|
|
157461
|
+
}
|
|
157462
|
+
drawOverviewSprites();
|
|
157463
|
+
if (appMode === "serious") {
|
|
157464
|
+
seriousTerminalController?.refreshCardFromOverview();
|
|
156198
157465
|
}
|
|
156199
157466
|
}
|
|
156200
157467
|
function updateStatusBar() {
|
|
156201
157468
|
scheduleStatusBarUpdate();
|
|
156202
157469
|
}
|
|
156203
|
-
function
|
|
156204
|
-
|
|
156205
|
-
|
|
157470
|
+
function clearOverviewSpriteRetry() {
|
|
157471
|
+
if (overviewSpriteRetryTimer) {
|
|
157472
|
+
clearTimeout(overviewSpriteRetryTimer);
|
|
157473
|
+
overviewSpriteRetryTimer = null;
|
|
157474
|
+
}
|
|
157475
|
+
}
|
|
157476
|
+
function drawCachedOverviewSprite(canvas, textureKey) {
|
|
157477
|
+
const dataUrl = overviewSpriteCache[textureKey];
|
|
157478
|
+
if (!dataUrl) return false;
|
|
157479
|
+
let img = overviewSpriteImageCache.get(textureKey);
|
|
157480
|
+
if (!img || img.src !== dataUrl) {
|
|
157481
|
+
img = new Image();
|
|
157482
|
+
img.src = dataUrl;
|
|
157483
|
+
overviewSpriteImageCache.set(textureKey, img);
|
|
157484
|
+
}
|
|
157485
|
+
const ctx = canvas.getContext("2d");
|
|
157486
|
+
if (!ctx) return true;
|
|
157487
|
+
const drawNow = () => {
|
|
157488
|
+
if (!img) return;
|
|
157489
|
+
ctx.imageSmoothingEnabled = false;
|
|
157490
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
157491
|
+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
157492
|
+
};
|
|
157493
|
+
if (!img.complete || img.naturalWidth === 0) {
|
|
157494
|
+
img.onload = () => drawNow();
|
|
157495
|
+
return true;
|
|
157496
|
+
}
|
|
157497
|
+
drawNow();
|
|
157498
|
+
return true;
|
|
157499
|
+
}
|
|
157500
|
+
function updateOverviewSpriteCacheFromCanvas(canvas, textureKey) {
|
|
157501
|
+
try {
|
|
157502
|
+
const dataUrl = canvas.toDataURL("image/png");
|
|
157503
|
+
if (overviewSpriteCache[textureKey] !== dataUrl) {
|
|
157504
|
+
overviewSpriteCache = { ...overviewSpriteCache, [textureKey]: dataUrl };
|
|
157505
|
+
saveOverviewSpriteCache(overviewSpriteCache);
|
|
157506
|
+
const img = new Image();
|
|
157507
|
+
img.src = dataUrl;
|
|
157508
|
+
overviewSpriteImageCache.set(textureKey, img);
|
|
157509
|
+
}
|
|
157510
|
+
} catch {
|
|
157511
|
+
}
|
|
157512
|
+
}
|
|
157513
|
+
function drawTextureToOverviewCanvas(canvas, textureKey) {
|
|
157514
|
+
if (!phaserGameRef) {
|
|
157515
|
+
return drawCachedOverviewSprite(canvas, textureKey);
|
|
157516
|
+
}
|
|
157517
|
+
const texture = phaserGameRef.textures.get(textureKey);
|
|
157518
|
+
if (!texture || texture.key === "__MISSING") {
|
|
157519
|
+
return drawCachedOverviewSprite(canvas, textureKey);
|
|
157520
|
+
}
|
|
157521
|
+
const source = texture.getSourceImage();
|
|
157522
|
+
if (!source) {
|
|
157523
|
+
return drawCachedOverviewSprite(canvas, textureKey);
|
|
157524
|
+
}
|
|
157525
|
+
const ctx = canvas.getContext("2d");
|
|
157526
|
+
if (!ctx) return true;
|
|
157527
|
+
const sourceWidth = source instanceof HTMLImageElement ? source.naturalWidth || source.width : source.width;
|
|
157528
|
+
const sourceHeight = source instanceof HTMLImageElement ? source.naturalHeight || source.height : source.height;
|
|
157529
|
+
ctx.imageSmoothingEnabled = false;
|
|
157530
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
157531
|
+
if (sourceWidth > canvas.width || sourceHeight > canvas.height) {
|
|
157532
|
+
ctx.drawImage(source, 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
|
|
157533
|
+
} else {
|
|
157534
|
+
ctx.drawImage(source, 0, 0);
|
|
157535
|
+
}
|
|
157536
|
+
updateOverviewSpriteCacheFromCanvas(canvas, textureKey);
|
|
157537
|
+
return true;
|
|
157538
|
+
}
|
|
157539
|
+
function prewarmOverviewSpriteCacheFromTextures() {
|
|
157540
|
+
if (!phaserGameRef) return;
|
|
157541
|
+
const textureKeys = getCurrentAgents().map((agent) => agent.sprite);
|
|
157542
|
+
if (!textureKeys.includes("desktop_pc")) textureKeys.push("desktop_pc");
|
|
157543
|
+
for (const textureKey of textureKeys) {
|
|
157544
|
+
const texture = phaserGameRef.textures.get(textureKey);
|
|
157545
|
+
if (!texture || texture.key === "__MISSING") continue;
|
|
157546
|
+
const source = texture.getSourceImage();
|
|
157547
|
+
if (!source) continue;
|
|
157548
|
+
const scratch = document.createElement("canvas");
|
|
157549
|
+
scratch.width = textureKey === "desktop_pc" ? 32 : 32;
|
|
157550
|
+
scratch.height = textureKey === "desktop_pc" ? 32 : 34;
|
|
157551
|
+
const ctx = scratch.getContext("2d");
|
|
157552
|
+
if (!ctx) continue;
|
|
157553
|
+
const sourceWidth = source instanceof HTMLImageElement ? source.naturalWidth || source.width : source.width;
|
|
157554
|
+
const sourceHeight = source instanceof HTMLImageElement ? source.naturalHeight || source.height : source.height;
|
|
157555
|
+
ctx.imageSmoothingEnabled = false;
|
|
157556
|
+
ctx.clearRect(0, 0, scratch.width, scratch.height);
|
|
157557
|
+
if (sourceWidth > scratch.width || sourceHeight > scratch.height) {
|
|
157558
|
+
ctx.drawImage(source, 0, 0, scratch.width, scratch.height, 0, 0, scratch.width, scratch.height);
|
|
157559
|
+
} else {
|
|
157560
|
+
ctx.drawImage(source, 0, 0);
|
|
157561
|
+
}
|
|
157562
|
+
updateOverviewSpriteCacheFromCanvas(scratch, textureKey);
|
|
157563
|
+
}
|
|
157564
|
+
}
|
|
157565
|
+
function drawOverviewSprites(attempt = 0) {
|
|
157566
|
+
clearOverviewSpriteRetry();
|
|
157567
|
+
requestAnimationFrame(() => {
|
|
157568
|
+
let missingTexture = false;
|
|
156206
157569
|
for (const agent of getCurrentAgents()) {
|
|
156207
157570
|
const canvas = document.getElementById(`overview-sprite-${agent.id}`);
|
|
156208
157571
|
if (!canvas) continue;
|
|
156209
|
-
const
|
|
156210
|
-
if (!
|
|
156211
|
-
const texture = phaserGameRef.textures.get(agent.sprite);
|
|
156212
|
-
if (!texture || texture.key === "__MISSING") continue;
|
|
156213
|
-
const source = texture.getSourceImage();
|
|
156214
|
-
if (source) {
|
|
156215
|
-
ctx.imageSmoothingEnabled = false;
|
|
156216
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
156217
|
-
ctx.drawImage(source, 0, 0);
|
|
156218
|
-
}
|
|
157572
|
+
const drawn = drawTextureToOverviewCanvas(canvas, agent.sprite);
|
|
157573
|
+
if (!drawn) missingTexture = true;
|
|
156219
157574
|
}
|
|
156220
157575
|
const pcCanvas = document.getElementById("overview-sprite-pc-terminal");
|
|
156221
157576
|
if (pcCanvas) {
|
|
156222
|
-
const
|
|
156223
|
-
if (!
|
|
156224
|
-
const texture = phaserGameRef.textures.get("desktop_pc");
|
|
156225
|
-
if (!texture || texture.key === "__MISSING") return;
|
|
156226
|
-
const source = texture.getSourceImage();
|
|
156227
|
-
if (source) {
|
|
156228
|
-
ctx.imageSmoothingEnabled = false;
|
|
156229
|
-
ctx.clearRect(0, 0, pcCanvas.width, pcCanvas.height);
|
|
156230
|
-
ctx.drawImage(source, 0, 0);
|
|
156231
|
-
}
|
|
157577
|
+
const drawn = drawTextureToOverviewCanvas(pcCanvas, "desktop_pc");
|
|
157578
|
+
if (!drawn) missingTexture = true;
|
|
156232
157579
|
}
|
|
156233
|
-
|
|
157580
|
+
if (missingTexture && phaserGameRef && attempt < OVERVIEW_SPRITE_MAX_RETRY_ATTEMPTS) {
|
|
157581
|
+
overviewSpriteRetryTimer = setTimeout(() => {
|
|
157582
|
+
drawOverviewSprites(attempt + 1);
|
|
157583
|
+
}, OVERVIEW_SPRITE_RETRY_DELAY_MS);
|
|
157584
|
+
}
|
|
157585
|
+
});
|
|
156234
157586
|
}
|
|
156235
157587
|
function setupTerminalClickHandler() {
|
|
156236
|
-
|
|
157588
|
+
overviewHost.addEventListener("click", (e) => {
|
|
156237
157589
|
const target = e.target;
|
|
156238
157590
|
const layout = getLayout(getCurrentLayout());
|
|
156239
157591
|
const metaPanel = target.closest(".session-meta-panel");
|
|
@@ -156242,7 +157594,10 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156242
157594
|
const agentId = metaPanel.dataset.agent;
|
|
156243
157595
|
if (!agentId) return;
|
|
156244
157596
|
layout.clickHandler.handleMetaPanelClick(target, agentId, {
|
|
156245
|
-
startSessionMetaEdit
|
|
157597
|
+
startSessionMetaEdit,
|
|
157598
|
+
startNewSession: (id) => {
|
|
157599
|
+
void startSessionFromOverview(id);
|
|
157600
|
+
}
|
|
156246
157601
|
});
|
|
156247
157602
|
return;
|
|
156248
157603
|
}
|
|
@@ -156260,21 +157615,58 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156260
157615
|
},
|
|
156261
157616
|
updateContent: updateTerminalContent,
|
|
156262
157617
|
emitOpenTerminal: (id) => {
|
|
156263
|
-
|
|
157618
|
+
void openAgentTerminal(id);
|
|
156264
157619
|
}
|
|
156265
157620
|
});
|
|
156266
157621
|
}
|
|
156267
157622
|
});
|
|
156268
157623
|
}
|
|
157624
|
+
async function startSessionFromOverview(agentId) {
|
|
157625
|
+
if (!window.copilotBridge) return;
|
|
157626
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
157627
|
+
const launchConfig = getSeriousLaunchConfig(agentId);
|
|
157628
|
+
if (!launchConfig) return;
|
|
157629
|
+
cachedSessionMeta[agentId] = { title: "" };
|
|
157630
|
+
setSessionMetaCacheForOffice(officeId, cachedSessionMeta);
|
|
157631
|
+
updateTerminalContent();
|
|
157632
|
+
try {
|
|
157633
|
+
if (appMode === "serious" && seriousTerminalController) {
|
|
157634
|
+
await seriousTerminalController.startNewSession({
|
|
157635
|
+
officeId,
|
|
157636
|
+
agentId,
|
|
157637
|
+
...launchConfig
|
|
157638
|
+
});
|
|
157639
|
+
} else {
|
|
157640
|
+
await window.copilotBridge.resetSession(officeId, agentId);
|
|
157641
|
+
await window.copilotBridge.terminalStart(
|
|
157642
|
+
officeId,
|
|
157643
|
+
agentId,
|
|
157644
|
+
launchConfig.workingDir,
|
|
157645
|
+
void 0,
|
|
157646
|
+
void 0,
|
|
157647
|
+
void 0,
|
|
157648
|
+
launchConfig.launchMode
|
|
157649
|
+
);
|
|
157650
|
+
}
|
|
157651
|
+
} catch (error) {
|
|
157652
|
+
console.warn(`[Office] Failed to start new session from overview for ${agentId}:`, error);
|
|
157653
|
+
}
|
|
157654
|
+
officeManager.setAgentStarting(officeId, agentId);
|
|
157655
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
157656
|
+
updateStatusBar();
|
|
157657
|
+
updateTerminalContent();
|
|
157658
|
+
}
|
|
156269
157659
|
function startSessionMetaEdit(agentId) {
|
|
156270
|
-
const panel =
|
|
157660
|
+
const panel = overviewHost.querySelector(`.session-meta-panel[data-agent="${agentId}"]`);
|
|
156271
157661
|
if (!panel) return;
|
|
156272
157662
|
const meta = cachedSessionMeta[agentId] || { title: "" };
|
|
156273
157663
|
const titleEl = panel.querySelector(".session-title-display");
|
|
156274
157664
|
if (titleEl) {
|
|
156275
157665
|
replaceWithInput(titleEl, meta.title, "Session title...", 80, async (value) => {
|
|
156276
|
-
|
|
157666
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
157667
|
+
await window.copilotBridge.setSessionMeta(officeId, agentId, { title: value });
|
|
156277
157668
|
cachedSessionMeta[agentId] = { title: value };
|
|
157669
|
+
setSessionMetaCacheForOffice(officeId, cachedSessionMeta);
|
|
156278
157670
|
updateTerminalContent();
|
|
156279
157671
|
});
|
|
156280
157672
|
}
|
|
@@ -156347,7 +157739,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156347
157739
|
console.log(`[Office] Status: ${agentId} \u2192 thinking (${toolName})`);
|
|
156348
157740
|
notifyAgent(agentId, "toolStart", { toolName });
|
|
156349
157741
|
}
|
|
156350
|
-
|
|
157742
|
+
phaserGameRef?.events.emit("agent:tool:start", agentId, toolName, status);
|
|
156351
157743
|
updateTerminalContent();
|
|
156352
157744
|
updateStatusBar();
|
|
156353
157745
|
});
|
|
@@ -156366,7 +157758,12 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156366
157758
|
officeManager.pushRecentAction(officeId, agentId, completedToolName, "completed");
|
|
156367
157759
|
notifyAgent(agentId, "toolComplete", { toolName: completedToolName });
|
|
156368
157760
|
if (remaining.length === 0) {
|
|
156369
|
-
officeManager.
|
|
157761
|
+
const currentStatus = officeManager.getAgentStatus(officeId, agentId);
|
|
157762
|
+
if (currentStatus?.subState === "thinking") {
|
|
157763
|
+
officeManager.setAgentThinking(officeId, agentId, currentStatus.thinkingDetail ?? "Processing...");
|
|
157764
|
+
} else {
|
|
157765
|
+
officeManager.setAgentReady(officeId, agentId);
|
|
157766
|
+
}
|
|
156370
157767
|
} else if (remaining.some((t) => isAskUserTool(t.name, t.status))) {
|
|
156371
157768
|
officeManager.setAgentWaiting(officeId, agentId);
|
|
156372
157769
|
} else {
|
|
@@ -156374,7 +157771,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156374
157771
|
officeManager.setAgentThinking(officeId, agentId, `${last.name}`);
|
|
156375
157772
|
}
|
|
156376
157773
|
}
|
|
156377
|
-
|
|
157774
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156378
157775
|
updateTerminalContent();
|
|
156379
157776
|
updateStatusBar();
|
|
156380
157777
|
});
|
|
@@ -156396,7 +157793,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156396
157793
|
}
|
|
156397
157794
|
notifyAgent(agentId, "turnEnd");
|
|
156398
157795
|
}
|
|
156399
|
-
|
|
157796
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156400
157797
|
updateTerminalContent();
|
|
156401
157798
|
updateStatusBar();
|
|
156402
157799
|
});
|
|
@@ -156413,7 +157810,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156413
157810
|
officeManager.setAgentThinking(officeId, agentId, "Processing...");
|
|
156414
157811
|
console.log(`[Office] Status: ${agentId} \u2192 thinking (turn start)`);
|
|
156415
157812
|
notifyAgent(agentId, "turnStart");
|
|
156416
|
-
|
|
157813
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156417
157814
|
updateTerminalContent();
|
|
156418
157815
|
updateStatusBar();
|
|
156419
157816
|
});
|
|
@@ -156428,12 +157825,14 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156428
157825
|
}
|
|
156429
157826
|
officeManager.setAgentThinking(officeId, agentId, "Processing...");
|
|
156430
157827
|
console.log(`[Office] Status: ${agentId} \u2192 thinking (user message)`);
|
|
156431
|
-
|
|
157828
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156432
157829
|
updateTerminalContent();
|
|
156433
157830
|
});
|
|
156434
157831
|
window.copilotBridge.onSessionMetaUpdated((agentId, meta) => {
|
|
156435
157832
|
console.log(`[Office] Session meta updated for ${agentId}: "${meta.title}"`);
|
|
157833
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
156436
157834
|
cachedSessionMeta[agentId] = meta;
|
|
157835
|
+
setSessionMetaCacheForOffice(officeId, cachedSessionMeta);
|
|
156437
157836
|
updateTerminalContent();
|
|
156438
157837
|
});
|
|
156439
157838
|
window.copilotBridge.onTerminalPreloadStatus((agentId, status) => {
|
|
@@ -156459,17 +157858,45 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156459
157858
|
notifyAgent(agentId, "sessionError");
|
|
156460
157859
|
}
|
|
156461
157860
|
}
|
|
156462
|
-
|
|
157861
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156463
157862
|
updateStatusBar();
|
|
156464
157863
|
updateTerminalContent();
|
|
156465
157864
|
});
|
|
156466
157865
|
}
|
|
156467
157866
|
var syncInProgress = false;
|
|
156468
|
-
|
|
156469
|
-
|
|
157867
|
+
var syncStartedAt = 0;
|
|
157868
|
+
var SYNC_LOCK_TIMEOUT_MS = 15e3;
|
|
157869
|
+
var STALE_IN_TURN_THINKING_TIMEOUT_MS = 9e4;
|
|
157870
|
+
var THINKING_TO_READY_GRACE_MS = 7e3;
|
|
157871
|
+
var SYNC_WAIT_POLL_MS = 50;
|
|
157872
|
+
async function waitForSyncIdle(timeoutMs = SYNC_LOCK_TIMEOUT_MS) {
|
|
157873
|
+
const startedAt = Date.now();
|
|
157874
|
+
while (syncInProgress && Date.now() - startedAt < timeoutMs) {
|
|
157875
|
+
await new Promise((resolve) => setTimeout(resolve, SYNC_WAIT_POLL_MS));
|
|
157876
|
+
}
|
|
157877
|
+
}
|
|
157878
|
+
async function syncAgentStatuses(force = false) {
|
|
157879
|
+
if (!window.copilotBridge) return;
|
|
157880
|
+
if (syncInProgress) {
|
|
157881
|
+
if (force) {
|
|
157882
|
+
await waitForSyncIdle();
|
|
157883
|
+
if (syncInProgress) {
|
|
157884
|
+
console.warn(`[Office] syncAgentStatuses lock held for >${SYNC_LOCK_TIMEOUT_MS / 1e3}s during forced sync \u2014 force-releasing`);
|
|
157885
|
+
syncInProgress = false;
|
|
157886
|
+
}
|
|
157887
|
+
} else {
|
|
157888
|
+
if (syncStartedAt && Date.now() - syncStartedAt > SYNC_LOCK_TIMEOUT_MS) {
|
|
157889
|
+
console.warn(`[Office] syncAgentStatuses lock held for >${SYNC_LOCK_TIMEOUT_MS / 1e3}s \u2014 force-releasing`);
|
|
157890
|
+
syncInProgress = false;
|
|
157891
|
+
} else {
|
|
157892
|
+
return;
|
|
157893
|
+
}
|
|
157894
|
+
}
|
|
157895
|
+
}
|
|
156470
157896
|
const officeId = officeManager.currentOfficeId;
|
|
156471
157897
|
if (!officeId) return;
|
|
156472
157898
|
syncInProgress = true;
|
|
157899
|
+
syncStartedAt = Date.now();
|
|
156473
157900
|
try {
|
|
156474
157901
|
const statuses = await window.copilotBridge.queryAgentStatuses(officeId);
|
|
156475
157902
|
let changed = false;
|
|
@@ -156480,6 +157907,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156480
157907
|
const current = officeManager.getAgentStatus(officeId, agent.id);
|
|
156481
157908
|
const activeTools = getCurrentAgentTools().get(agent.id) || [];
|
|
156482
157909
|
const waitingToolActive = activeTools.some((t) => isAskUserTool(t.name, t.status));
|
|
157910
|
+
const thinkingSince = current?.subState === "thinking" ? current.activityStartTime : null;
|
|
157911
|
+
const thinkingAgeMs = thinkingSince ? now - thinkingSince : null;
|
|
157912
|
+
const staleInTurnThinking = Boolean(
|
|
157913
|
+
current?.subState === "thinking" && thinkingSince && now - thinkingSince > STALE_IN_TURN_THINKING_TIMEOUT_MS && activeTools.length === 0
|
|
157914
|
+
);
|
|
156483
157915
|
if (current?.subState === "starting" && current.activityStartTime && now - current.activityStartTime > STARTING_TIMEOUT_MS) {
|
|
156484
157916
|
console.warn(`[Office] Agent ${agent.id} stuck in starting for >${STARTING_TIMEOUT_MS / 1e3}s \u2014 transitioning to error`);
|
|
156485
157917
|
officeManager.setAgentError(officeId, agent.id, "Startup timed out");
|
|
@@ -156494,7 +157926,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156494
157926
|
changed = true;
|
|
156495
157927
|
}
|
|
156496
157928
|
} else if (serverStatus.inTurn) {
|
|
156497
|
-
if (
|
|
157929
|
+
if (staleInTurnThinking) {
|
|
157930
|
+
console.warn(`[Office] Agent ${agent.id} stale inTurn for >${STALE_IN_TURN_THINKING_TIMEOUT_MS / 1e3}s \u2014 resetting to ready`);
|
|
157931
|
+
officeManager.setAgentReady(officeId, agent.id);
|
|
157932
|
+
changed = true;
|
|
157933
|
+
} else if (!current || current.subState !== "thinking" && current.subState !== "waiting") {
|
|
156498
157934
|
officeManager.setTaskSummary(officeId, agent.id, "Processing...");
|
|
156499
157935
|
officeManager.setAgentThinking(officeId, agent.id, "Processing...");
|
|
156500
157936
|
changed = true;
|
|
@@ -156506,6 +157942,9 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156506
157942
|
officeManager.setAgentReady(officeId, agent.id);
|
|
156507
157943
|
changed = true;
|
|
156508
157944
|
} else if (current.subState === "thinking" && !serverStatus.inTurn) {
|
|
157945
|
+
if (thinkingAgeMs !== null && thinkingAgeMs < THINKING_TO_READY_GRACE_MS) {
|
|
157946
|
+
continue;
|
|
157947
|
+
}
|
|
156509
157948
|
console.warn(`[Office] Agent ${agent.id} stuck in thinking but server reports idle \u2014 resetting to ready`);
|
|
156510
157949
|
const agentTools = getCurrentAgentTools();
|
|
156511
157950
|
if (agentTools.has(agent.id)) {
|
|
@@ -156529,7 +157968,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156529
157968
|
}
|
|
156530
157969
|
if (changed) {
|
|
156531
157970
|
for (const agent of getCurrentAgents()) {
|
|
156532
|
-
|
|
157971
|
+
phaserGameRef?.events.emit("agent:status:changed", agent.id);
|
|
156533
157972
|
}
|
|
156534
157973
|
updateTerminalContent();
|
|
156535
157974
|
updateStatusBar();
|
|
@@ -156549,8 +157988,27 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156549
157988
|
pendingTerminalContentUpdate = false;
|
|
156550
157989
|
updateStatusBarNow();
|
|
156551
157990
|
updateTerminalContentNow();
|
|
157991
|
+
drawOverviewSprites();
|
|
156552
157992
|
phaserGameRef?.events.emit("agent:status:changed");
|
|
156553
|
-
void
|
|
157993
|
+
void reconnectAgentStatuses();
|
|
157994
|
+
}
|
|
157995
|
+
async function reconnectAgentStatuses() {
|
|
157996
|
+
if (!window.copilotBridge) return;
|
|
157997
|
+
const officeId = officeManager.currentOfficeId;
|
|
157998
|
+
if (!officeId) return;
|
|
157999
|
+
await waitForSyncIdle();
|
|
158000
|
+
try {
|
|
158001
|
+
const statuses = await window.copilotBridge.queryAgentStatuses(officeId);
|
|
158002
|
+
for (const [agentId, info] of Object.entries(statuses)) {
|
|
158003
|
+
if (info.alive) {
|
|
158004
|
+
await window.copilotBridge.terminalAttach(officeId, agentId).catch(() => {
|
|
158005
|
+
});
|
|
158006
|
+
}
|
|
158007
|
+
}
|
|
158008
|
+
} catch (e) {
|
|
158009
|
+
console.warn("[Office] Failed to reconnect agent viewers:", e);
|
|
158010
|
+
}
|
|
158011
|
+
await syncAgentStatuses(true);
|
|
156554
158012
|
}
|
|
156555
158013
|
var ELAPSED_TICK_MS = 1e3;
|
|
156556
158014
|
setInterval(() => {
|
|
@@ -156579,6 +158037,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156579
158037
|
}
|
|
156580
158038
|
}, ELAPSED_TICK_MS);
|
|
156581
158039
|
function updateStatusBarNow() {
|
|
158040
|
+
syncActiveRosterForCurrentOffice();
|
|
156582
158041
|
const office = officeManager.currentOffice;
|
|
156583
158042
|
const agents = office ? Array.from(office.agents.values()) : [];
|
|
156584
158043
|
const officeName = officeManager.currentOffice?.config.name || "No Office";
|
|
@@ -156610,6 +158069,17 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156610
158069
|
cursor: pointer;
|
|
156611
158070
|
margin-right: 24px;
|
|
156612
158071
|
">\u27F3 Reset All Sessions</button>
|
|
158072
|
+
<button id="reconnect-statuses-btn" style="
|
|
158073
|
+
background: #1a2a2a;
|
|
158074
|
+
border: 1px solid #4a8;
|
|
158075
|
+
color: #8f8;
|
|
158076
|
+
font-family: monospace;
|
|
158077
|
+
font-size: 14px;
|
|
158078
|
+
padding: 4px 16px;
|
|
158079
|
+
border-radius: 4px;
|
|
158080
|
+
cursor: pointer;
|
|
158081
|
+
margin-right: 24px;
|
|
158082
|
+
">\u{1F50C} Re-connect Statuses</button>
|
|
156613
158083
|
<span style="color: #666; font-size: 10px;">WASD: Walk | Shift: Run | Space: Talk | F10: Close terminal</span>
|
|
156614
158084
|
`;
|
|
156615
158085
|
if (html !== lastStatusBarHtml) {
|
|
@@ -156629,60 +158099,37 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156629
158099
|
btn.textContent = "\u27F3 Reset All Sessions";
|
|
156630
158100
|
}
|
|
156631
158101
|
});
|
|
158102
|
+
document.getElementById("reconnect-statuses-btn")?.addEventListener("click", async () => {
|
|
158103
|
+
const btn = document.getElementById("reconnect-statuses-btn");
|
|
158104
|
+
if (btn) {
|
|
158105
|
+
btn.disabled = true;
|
|
158106
|
+
btn.textContent = "\u{1F50C} Reconnecting...";
|
|
158107
|
+
}
|
|
158108
|
+
await reconnectAgentStatuses();
|
|
158109
|
+
if (btn) {
|
|
158110
|
+
btn.disabled = false;
|
|
158111
|
+
btn.textContent = "\u{1F50C} Re-connect Statuses";
|
|
158112
|
+
}
|
|
158113
|
+
});
|
|
156632
158114
|
}
|
|
156633
158115
|
}
|
|
156634
|
-
updateStatusBar();
|
|
156635
158116
|
setupTerminalClickHandler();
|
|
156636
|
-
|
|
156637
|
-
fetchSessionMeta();
|
|
156638
|
-
var phaserGame = new import_phaser10.default.Game({
|
|
156639
|
-
type: import_phaser10.default.AUTO,
|
|
156640
|
-
parent: officePanel,
|
|
156641
|
-
width: officePanel.clientWidth || window.innerWidth / 2,
|
|
156642
|
-
height: officePanel.clientHeight || window.innerHeight,
|
|
156643
|
-
backgroundColor: "#1a1a2e",
|
|
156644
|
-
physics: { default: "arcade", arcade: { debug: false } },
|
|
156645
|
-
scene: [BootScene, OfficeScene, MeetingScene]
|
|
156646
|
-
});
|
|
156647
|
-
phaserGameRef = phaserGame;
|
|
156648
|
-
officePanel.addEventListener("click", () => {
|
|
156649
|
-
const canvas = officePanel.querySelector("canvas");
|
|
156650
|
-
canvas?.focus();
|
|
156651
|
-
});
|
|
156652
|
-
officePanel.addEventListener("mousedown", () => {
|
|
156653
|
-
if (isMobileModeActive()) return;
|
|
156654
|
-
console.log("[main] game panel mousedown \u2014 emitting game:panel:clicked");
|
|
156655
|
-
phaserGame?.events.emit("game:panel:clicked");
|
|
156656
|
-
});
|
|
156657
|
-
phaserGame.events.once("ready", () => {
|
|
156658
|
-
drawOverviewSprites();
|
|
156659
|
-
phaserGame.events.emit("layout:change", { layoutKey: currentResponsiveLayout });
|
|
156660
|
-
});
|
|
156661
|
-
window.addEventListener("focus", () => {
|
|
156662
|
-
catchUpStatusViews("window focus");
|
|
156663
|
-
});
|
|
156664
|
-
document.addEventListener("visibilitychange", () => {
|
|
156665
|
-
if (!document.hidden) {
|
|
156666
|
-
catchUpStatusViews("document visible");
|
|
156667
|
-
}
|
|
156668
|
-
});
|
|
156669
|
-
phaserGame.events.on("agent:session:closed", (agentId) => {
|
|
158117
|
+
function onAgentSessionClosed(agentId) {
|
|
156670
158118
|
const officeId = officeManager.currentOfficeId;
|
|
156671
158119
|
if (officeId) officeManager.setAgentSlacking(officeId, agentId);
|
|
156672
|
-
|
|
158120
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156673
158121
|
updateTerminalContent();
|
|
156674
158122
|
updateStatusBar();
|
|
156675
|
-
}
|
|
156676
|
-
|
|
158123
|
+
}
|
|
158124
|
+
function onAgentStatusChanged() {
|
|
156677
158125
|
updateTerminalContent();
|
|
156678
158126
|
updateStatusBar();
|
|
156679
|
-
}
|
|
156680
|
-
|
|
158127
|
+
}
|
|
158128
|
+
function onAgentReattached(agentId) {
|
|
156681
158129
|
console.log(`[Office] Agent reattached: ${agentId}`);
|
|
156682
|
-
syncAgentStatuses();
|
|
156683
|
-
}
|
|
156684
|
-
|
|
156685
|
-
phaserGame.events.on("fleet:office:created", async (officeId, sourceOfficeId) => {
|
|
158130
|
+
void syncAgentStatuses();
|
|
158131
|
+
}
|
|
158132
|
+
async function onFleetOfficeCreated(officeId, sourceOfficeId) {
|
|
156686
158133
|
console.log(`[Office] Fleet V-Team office created: ${officeId} (source: ${sourceOfficeId ?? "none"})`);
|
|
156687
158134
|
if (sourceOfficeId && window.copilotBridge?.transferSession) {
|
|
156688
158135
|
try {
|
|
@@ -156693,11 +158140,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156693
158140
|
}
|
|
156694
158141
|
}
|
|
156695
158142
|
if (sourceOfficeId) {
|
|
156696
|
-
|
|
158143
|
+
phaserGameRef?.events.emit("fleet:source-office", { sourceOfficeId });
|
|
156697
158144
|
}
|
|
156698
158145
|
switchToOffice(officeId);
|
|
156699
|
-
}
|
|
156700
|
-
|
|
158146
|
+
}
|
|
158147
|
+
async function onFleetDeployRequested(data) {
|
|
156701
158148
|
console.log(`[Fleet] Deploy requested: "${data.officeName}" from office ${data.sourceOfficeId}`);
|
|
156702
158149
|
const fleetOffice = officeManager.createOffice(data.officeName, ".", "fleet-vteam");
|
|
156703
158150
|
const officeId = fleetOffice.config.id;
|
|
@@ -156713,24 +158160,96 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156713
158160
|
console.warn("[Fleet] copilotBridge.transferSession not available");
|
|
156714
158161
|
}
|
|
156715
158162
|
data.resolve?.();
|
|
156716
|
-
|
|
158163
|
+
phaserGameRef?.events.emit("fleet:source-office", { sourceOfficeId: data.sourceOfficeId, prompt: data.prompt });
|
|
156717
158164
|
switchToOffice(officeId);
|
|
156718
|
-
}
|
|
156719
|
-
|
|
158165
|
+
}
|
|
158166
|
+
function onFleetStatus(status) {
|
|
156720
158167
|
const subtitle = document.getElementById("terminal-subtitle");
|
|
156721
158168
|
if (subtitle && officeManager.currentOffice?.config.layout === "fleet-vteam") {
|
|
156722
158169
|
subtitle.textContent = `Fleet: ${status.active} active \xB7 ${status.completed} done \xB7 ${status.failed} failed / ${status.total} total`;
|
|
156723
158170
|
}
|
|
156724
158171
|
updateTerminalContent();
|
|
156725
|
-
}
|
|
156726
|
-
|
|
158172
|
+
}
|
|
158173
|
+
function onFleetComplete() {
|
|
156727
158174
|
console.log("[Fleet] All sub-agents complete");
|
|
156728
158175
|
const subtitle = document.getElementById("terminal-subtitle");
|
|
156729
158176
|
if (subtitle) {
|
|
156730
158177
|
subtitle.textContent = "\u2705 Fleet complete!";
|
|
156731
158178
|
}
|
|
156732
158179
|
updateTerminalContent();
|
|
158180
|
+
}
|
|
158181
|
+
var officePanelListenersBound = false;
|
|
158182
|
+
function bindOfficePanelListeners() {
|
|
158183
|
+
if (officePanelListenersBound) return;
|
|
158184
|
+
officePanelListenersBound = true;
|
|
158185
|
+
officePanel.addEventListener("click", () => {
|
|
158186
|
+
const canvas = officePanel.querySelector("canvas");
|
|
158187
|
+
canvas?.focus();
|
|
158188
|
+
});
|
|
158189
|
+
officePanel.addEventListener("mousedown", () => {
|
|
158190
|
+
if (isMobileModeActive()) return;
|
|
158191
|
+
console.log("[main] game panel mousedown \u2014 emitting game:panel:clicked");
|
|
158192
|
+
phaserGameRef?.events.emit("game:panel:clicked");
|
|
158193
|
+
});
|
|
158194
|
+
}
|
|
158195
|
+
function getPhaserDimensions() {
|
|
158196
|
+
return {
|
|
158197
|
+
width: officePanel.clientWidth || window.innerWidth / 2,
|
|
158198
|
+
height: officePanel.clientHeight || window.innerHeight
|
|
158199
|
+
};
|
|
158200
|
+
}
|
|
158201
|
+
function bindPhaserEventListeners(game) {
|
|
158202
|
+
game.events.once("ready", () => {
|
|
158203
|
+
drawOverviewSprites();
|
|
158204
|
+
game.events.emit("layout:change", { layoutKey: currentResponsiveLayout });
|
|
158205
|
+
});
|
|
158206
|
+
game.events.on("agent:session:closed", onAgentSessionClosed);
|
|
158207
|
+
game.events.on("agent:status:changed", onAgentStatusChanged);
|
|
158208
|
+
game.events.on("agent:reattached", onAgentReattached);
|
|
158209
|
+
game.events.on("bgm:started", onBgmStarted);
|
|
158210
|
+
game.events.on("fleet:office:created", onFleetOfficeCreated);
|
|
158211
|
+
game.events.on("fleet:deploy-requested", onFleetDeployRequested);
|
|
158212
|
+
game.events.on("fleet:status", onFleetStatus);
|
|
158213
|
+
game.events.on("fleet:complete", onFleetComplete);
|
|
158214
|
+
}
|
|
158215
|
+
function ensurePhaserGame() {
|
|
158216
|
+
if (phaserGameRef) return;
|
|
158217
|
+
const { width, height } = getPhaserDimensions();
|
|
158218
|
+
const game = new import_phaser10.default.Game({
|
|
158219
|
+
type: import_phaser10.default.AUTO,
|
|
158220
|
+
parent: officePanel,
|
|
158221
|
+
width,
|
|
158222
|
+
height,
|
|
158223
|
+
backgroundColor: "#1a1a2e",
|
|
158224
|
+
physics: { default: "arcade", arcade: { debug: false } },
|
|
158225
|
+
scene: [BootScene, OfficeScene, MeetingScene]
|
|
158226
|
+
});
|
|
158227
|
+
phaserGameRef = game;
|
|
158228
|
+
bindPhaserEventListeners(game);
|
|
158229
|
+
}
|
|
158230
|
+
function teardownPhaserGame() {
|
|
158231
|
+
if (!phaserGameRef) return;
|
|
158232
|
+
const game = phaserGameRef;
|
|
158233
|
+
phaserGameRef = void 0;
|
|
158234
|
+
try {
|
|
158235
|
+
game.destroy(true);
|
|
158236
|
+
} catch (error) {
|
|
158237
|
+
console.warn("[main] Failed to destroy Phaser game cleanly:", error);
|
|
158238
|
+
}
|
|
158239
|
+
officePanel.innerHTML = "";
|
|
158240
|
+
}
|
|
158241
|
+
bindOfficePanelListeners();
|
|
158242
|
+
window.addEventListener("focus", () => {
|
|
158243
|
+
catchUpStatusViews("window focus");
|
|
158244
|
+
});
|
|
158245
|
+
document.addEventListener("visibilitychange", () => {
|
|
158246
|
+
if (!document.hidden) {
|
|
158247
|
+
catchUpStatusViews("document visible");
|
|
158248
|
+
}
|
|
156733
158249
|
});
|
|
158250
|
+
syncActiveRosterForCurrentOffice();
|
|
158251
|
+
applyAppMode(appMode, { force: true, refreshTabs: false });
|
|
158252
|
+
fetchSessionMeta();
|
|
156734
158253
|
}
|
|
156735
158254
|
});
|
|
156736
158255
|
return require_main();
|