copilotoffice 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- 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 +43 -15
- package/dist/game.bundle.js +1857 -373
- 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;
|
|
@@ -148663,6 +148764,88 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
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,12 @@ 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
|
-
if ((event.ctrlKey || event.metaKey) && event.key === "v" && event.type === "keydown") {
|
|
149506
|
+
if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "v" && event.type === "keydown") {
|
|
149292
149507
|
if (this.isReadOnly) return false;
|
|
149508
|
+
event.preventDefault();
|
|
149509
|
+
event.stopPropagation();
|
|
149293
149510
|
navigator.clipboard.readText().then((text) => {
|
|
149294
149511
|
if (text) this.terminal.paste(text);
|
|
149295
149512
|
}).catch((err) => {
|
|
@@ -149301,8 +149518,34 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149301
149518
|
});
|
|
149302
149519
|
this.terminal.onData((data) => {
|
|
149303
149520
|
if (this.isReadOnly) return;
|
|
149304
|
-
if (this.currentAgentId
|
|
149305
|
-
|
|
149521
|
+
if (!this.currentAgentId || !window.copilotBridge) return;
|
|
149522
|
+
let outbound = "";
|
|
149523
|
+
let shouldStartSlashNewSession = false;
|
|
149524
|
+
for (const ch of data) {
|
|
149525
|
+
if (ch === "\r" || ch === "\n") {
|
|
149526
|
+
const command = this.pendingInputLine.trim();
|
|
149527
|
+
this.pendingInputLine = "";
|
|
149528
|
+
if (command === "/new") {
|
|
149529
|
+
shouldStartSlashNewSession = true;
|
|
149530
|
+
}
|
|
149531
|
+
outbound += ch;
|
|
149532
|
+
continue;
|
|
149533
|
+
}
|
|
149534
|
+
if (ch === "\x7F") {
|
|
149535
|
+
this.pendingInputLine = this.pendingInputLine.slice(0, -1);
|
|
149536
|
+
outbound += ch;
|
|
149537
|
+
continue;
|
|
149538
|
+
}
|
|
149539
|
+
if (ch >= " ") {
|
|
149540
|
+
this.pendingInputLine += ch;
|
|
149541
|
+
}
|
|
149542
|
+
outbound += ch;
|
|
149543
|
+
}
|
|
149544
|
+
if (outbound.length > 0) {
|
|
149545
|
+
window.copilotBridge.terminalWrite(this.getOfficeId(), this.currentAgentId, outbound);
|
|
149546
|
+
}
|
|
149547
|
+
if (shouldStartSlashNewSession) {
|
|
149548
|
+
this.fetchSessionId(this.currentAgentId);
|
|
149306
149549
|
}
|
|
149307
149550
|
});
|
|
149308
149551
|
this.resizeHandler = () => {
|
|
@@ -149370,18 +149613,27 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149370
149613
|
officePanel.style.width = "50%";
|
|
149371
149614
|
terminalPanel.style.width = "50%";
|
|
149372
149615
|
}
|
|
149616
|
+
refreshFocusAndGeometry() {
|
|
149617
|
+
this.clearRefitTimers();
|
|
149618
|
+
this.refitGeneration += 1;
|
|
149619
|
+
this.fitAndResizeTerminal({ refreshVisibleRows: true });
|
|
149620
|
+
this.focusTerminal();
|
|
149621
|
+
this.debouncedRefit();
|
|
149622
|
+
}
|
|
149373
149623
|
/** Re-fit xterm after panel resize and notify PTY of new dimensions.
|
|
149374
149624
|
* Multi-stage: immediate → 150ms → 350ms to catch late layout shifts. */
|
|
149375
149625
|
debouncedRefit() {
|
|
149376
149626
|
if (!this.fitAddon || !this.terminal || !this.currentAgentId) return;
|
|
149377
|
-
|
|
149378
|
-
|
|
149627
|
+
const generation = ++this.refitGeneration;
|
|
149628
|
+
const agentId = this.currentAgentId;
|
|
149629
|
+
const officeId = this.getActiveOfficeId();
|
|
149630
|
+
this.clearRefitTimers();
|
|
149379
149631
|
const doFit = () => {
|
|
149380
|
-
this.
|
|
149381
|
-
|
|
149382
|
-
if (
|
|
149383
|
-
|
|
149384
|
-
}
|
|
149632
|
+
if (!this.isVisible) return;
|
|
149633
|
+
if (generation !== this.refitGeneration) return;
|
|
149634
|
+
if (this.currentAgentId !== agentId) return;
|
|
149635
|
+
if (this.getActiveOfficeId() !== officeId) return;
|
|
149636
|
+
this.fitAndResizeTerminal({ officeId, agentId });
|
|
149385
149637
|
};
|
|
149386
149638
|
requestAnimationFrame(() => {
|
|
149387
149639
|
doFit();
|
|
@@ -149405,14 +149657,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149405
149657
|
}
|
|
149406
149658
|
applySpriteCardResponsiveStyles() {
|
|
149407
149659
|
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
149660
|
this.spriteCardElement.style.minHeight = "";
|
|
149415
|
-
this.spriteCardElement.style.padding = "
|
|
149661
|
+
this.spriteCardElement.style.padding = "16px 24px";
|
|
149416
149662
|
}
|
|
149417
149663
|
updateMobileKeyboardButtonVisibility() {
|
|
149418
149664
|
if (!this.mobileKeyboardBtn) return;
|
|
@@ -149467,8 +149713,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149467
149713
|
setTerminalFocusVisual(focused) {
|
|
149468
149714
|
this.isFocused = focused;
|
|
149469
149715
|
if (this.spriteCardElement && this.spriteCardElement.style.display !== "none") {
|
|
149470
|
-
this.spriteCardElement.style.background = focused ? "#
|
|
149471
|
-
this.spriteCardElement.style.borderTopColor = focused ? "#
|
|
149716
|
+
this.spriteCardElement.style.background = focused ? "#13131f" : "#101019";
|
|
149717
|
+
this.spriteCardElement.style.borderTopColor = focused ? "#252540" : "#1c1c2f";
|
|
149472
149718
|
}
|
|
149473
149719
|
}
|
|
149474
149720
|
setupKeyboardHandler() {
|
|
@@ -149483,6 +149729,9 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149483
149729
|
this.updateMobileKeyboardButtonVisibility();
|
|
149484
149730
|
this.isVisible = false;
|
|
149485
149731
|
this.isReadOnly = false;
|
|
149732
|
+
this.pendingInputLine = "";
|
|
149733
|
+
this.awaitingSessionIdRefresh = false;
|
|
149734
|
+
this.clearSessionRefreshTimers();
|
|
149486
149735
|
this.closeHistoryPopover();
|
|
149487
149736
|
this.restorePanelLayout();
|
|
149488
149737
|
this.inputManager.deactivateTerminalF10();
|
|
@@ -149521,8 +149770,9 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
149521
149770
|
return false;
|
|
149522
149771
|
}
|
|
149523
149772
|
destroy() {
|
|
149524
|
-
|
|
149525
|
-
this.
|
|
149773
|
+
this.clearRefitTimers();
|
|
149774
|
+
this.awaitingSessionIdRefresh = false;
|
|
149775
|
+
this.clearSessionRefreshTimers();
|
|
149526
149776
|
if (this.resizeHandler) {
|
|
149527
149777
|
window.removeEventListener("resize", this.resizeHandler);
|
|
149528
149778
|
this.resizeHandler = null;
|
|
@@ -150477,8 +150727,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150477
150727
|
"use strict";
|
|
150478
150728
|
DESKTOP_DASHBOARD_TYPOGRAPHY = {
|
|
150479
150729
|
cardTitle: "15px",
|
|
150730
|
+
cardTitleLg: "18px",
|
|
150480
150731
|
cardDescription: "11px",
|
|
150481
150732
|
statusText: "11px",
|
|
150733
|
+
statusPanelText: "13px",
|
|
150734
|
+
statusPanelIcon: "26px",
|
|
150482
150735
|
statusDot: "8px",
|
|
150483
150736
|
elapsed: "10px",
|
|
150484
150737
|
badge: "10px",
|
|
@@ -150489,14 +150742,18 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150489
150742
|
taskSummary: "10px",
|
|
150490
150743
|
sessionLabel: "9px",
|
|
150491
150744
|
sessionTitle: "13px",
|
|
150745
|
+
sessionTitleLg: "15px",
|
|
150492
150746
|
sessionButton: "11px",
|
|
150493
150747
|
emptyState: "11px",
|
|
150494
150748
|
arthurHint: "10px"
|
|
150495
150749
|
};
|
|
150496
150750
|
MOBILE_DASHBOARD_TYPOGRAPHY = {
|
|
150497
150751
|
cardTitle: "19px",
|
|
150752
|
+
cardTitleLg: "24px",
|
|
150498
150753
|
cardDescription: "15px",
|
|
150499
150754
|
statusText: "16px",
|
|
150755
|
+
statusPanelText: "18px",
|
|
150756
|
+
statusPanelIcon: "34px",
|
|
150500
150757
|
statusDot: "11px",
|
|
150501
150758
|
elapsed: "14px",
|
|
150502
150759
|
badge: "13px",
|
|
@@ -150507,6 +150764,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150507
150764
|
taskSummary: "14px",
|
|
150508
150765
|
sessionLabel: "13px",
|
|
150509
150766
|
sessionTitle: "17px",
|
|
150767
|
+
sessionTitleLg: "20px",
|
|
150510
150768
|
sessionButton: "14px",
|
|
150511
150769
|
emptyState: "14px",
|
|
150512
150770
|
arthurHint: "14px"
|
|
@@ -150538,6 +150796,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150538
150796
|
display: flex;
|
|
150539
150797
|
align-items: center;
|
|
150540
150798
|
gap: 12px;
|
|
150799
|
+
min-height: 108px;
|
|
150541
150800
|
">
|
|
150542
150801
|
<div style="
|
|
150543
150802
|
width: 64px;
|
|
@@ -150626,11 +150885,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150626
150885
|
padding: 0 4px;
|
|
150627
150886
|
box-shadow: 0 1px 4px rgba(0,0,0,0.4);
|
|
150628
150887
|
">${unread}</div>` : "";
|
|
150629
|
-
const elapsedHtml = elapsed ? `<
|
|
150630
|
-
const queueHtml = toolCount > 1 ? `<
|
|
150888
|
+
const elapsedHtml = elapsed ? `<div data-elapsed-agent="${agent.id}" style="color: #8a8; font-size: ${t.elapsed}; margin-top: 4px;">\u23F1 ${elapsed}</div>` : "";
|
|
150889
|
+
const queueHtml = toolCount > 1 ? `<div style="
|
|
150631
150890
|
background: #334; color: #aac; font-size: ${t.queue};
|
|
150632
|
-
padding:
|
|
150633
|
-
">${toolCount} tools</
|
|
150891
|
+
padding: 2px 8px; border-radius: 8px; margin-top: 4px;
|
|
150892
|
+
">${toolCount} tools queued</div>` : "";
|
|
150634
150893
|
let toolPipelineHtml = "";
|
|
150635
150894
|
if (tools.length > 0) {
|
|
150636
150895
|
const toolRows = tools.map((t2, i) => {
|
|
@@ -150686,12 +150945,19 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150686
150945
|
">
|
|
150687
150946
|
<div style="font-size: ${t.sessionLabel}; color: #3a3a5a; text-transform: uppercase; letter-spacing: 0.5px;">Session Info</div>
|
|
150688
150947
|
<div class="session-title-display" data-agent="${agent.id}" style="
|
|
150689
|
-
font-weight: bold; color: ${metaTitle ? "#ccd" : "#444"}; font-size: ${t.
|
|
150948
|
+
font-weight: bold; color: ${metaTitle ? "#ccd" : "#444"}; font-size: ${t.sessionTitleLg};
|
|
150690
150949
|
cursor: text; min-height: 18px; line-height: 1.4;
|
|
150691
150950
|
overflow: hidden; text-overflow: ellipsis;
|
|
150692
150951
|
display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
|
|
150693
150952
|
" title="${metaTitle ? metaTitle.replace(/"/g, """) : "Click to set title"}">${metaTitle || "Untitled session"}</div>
|
|
150694
|
-
<
|
|
150953
|
+
<button class="session-new-btn" data-agent="${agent.id}" style="
|
|
150954
|
+
margin-top: 2px;
|
|
150955
|
+
align-self: flex-start;
|
|
150956
|
+
background: #2a3a4a; border: 1px solid #4a5a6a; color: #a9cff7;
|
|
150957
|
+
font-size: ${t.sessionButton}; padding: 4px 10px; border-radius: 4px;
|
|
150958
|
+
cursor: pointer; transition: background 0.15s, border-color 0.15s;
|
|
150959
|
+
" title="Start a new session for this agent">\u{1F504} New Session</button>
|
|
150960
|
+
<div style="display: flex; justify-content: flex-end;">
|
|
150695
150961
|
<button class="session-edit-btn" data-agent="${agent.id}" style="
|
|
150696
150962
|
background: none; border: 1px solid #333; color: #667;
|
|
150697
150963
|
font-size: ${t.sessionButton}; padding: 2px 8px; border-radius: 4px;
|
|
@@ -150725,46 +150991,60 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150725
150991
|
align-items: flex-start;
|
|
150726
150992
|
gap: 14px;
|
|
150727
150993
|
position: relative;
|
|
150728
|
-
min-height:
|
|
150994
|
+
min-height: 236px;
|
|
150729
150995
|
">
|
|
150730
150996
|
${badgeHtml}
|
|
150731
|
-
<div style="
|
|
150732
|
-
|
|
150733
|
-
|
|
150734
|
-
|
|
150735
|
-
|
|
150736
|
-
|
|
150737
|
-
|
|
150738
|
-
|
|
150739
|
-
|
|
150740
|
-
|
|
150741
|
-
|
|
150742
|
-
|
|
150743
|
-
|
|
150744
|
-
|
|
150745
|
-
|
|
150746
|
-
|
|
150747
|
-
|
|
150748
|
-
|
|
150997
|
+
<div style="flex-shrink: 0; width: 96px; display: flex; flex-direction: column; align-items: stretch; gap: 10px;">
|
|
150998
|
+
<div style="
|
|
150999
|
+
width: 96px;
|
|
151000
|
+
background: ${colorHex}22;
|
|
151001
|
+
border: 1px solid ${colorHex}44;
|
|
151002
|
+
border-radius: 10px;
|
|
151003
|
+
display: flex;
|
|
151004
|
+
align-items: center;
|
|
151005
|
+
justify-content: center;
|
|
151006
|
+
overflow: hidden;
|
|
151007
|
+
align-self: flex-start;
|
|
151008
|
+
padding: 6px 0;
|
|
151009
|
+
">
|
|
151010
|
+
<canvas
|
|
151011
|
+
id="overview-sprite-${agent.id}"
|
|
151012
|
+
width="32" height="34"
|
|
151013
|
+
style="image-rendering: pixelated; width: 72px; height: 76px; display: block;"
|
|
151014
|
+
></canvas>
|
|
151015
|
+
</div>
|
|
151016
|
+
<div style="
|
|
151017
|
+
border: 1px solid ${statusDot}66;
|
|
151018
|
+
background: ${statusDot}22;
|
|
151019
|
+
border-radius: 10px;
|
|
151020
|
+
padding: 8px 6px;
|
|
151021
|
+
display: flex;
|
|
151022
|
+
flex-direction: column;
|
|
151023
|
+
align-items: center;
|
|
151024
|
+
text-align: center;
|
|
151025
|
+
min-height: 96px;
|
|
151026
|
+
justify-content: center;
|
|
151027
|
+
">
|
|
151028
|
+
<div style="font-size: ${t.statusPanelIcon}; line-height: 1;">${statusIcon}</div>
|
|
151029
|
+
<div style="
|
|
151030
|
+
margin-top: 6px;
|
|
151031
|
+
font-size: ${t.statusPanelText};
|
|
151032
|
+
color: ${statusDot};
|
|
151033
|
+
line-height: 1.15;
|
|
151034
|
+
font-weight: 700;
|
|
151035
|
+
white-space: normal;
|
|
151036
|
+
word-break: break-word;
|
|
151037
|
+
">${statusLabel}</div>
|
|
151038
|
+
${elapsedHtml}
|
|
151039
|
+
${queueHtml}
|
|
151040
|
+
</div>
|
|
150749
151041
|
</div>
|
|
150750
151042
|
<div style="flex: 3; min-width: 0; display: flex; flex-direction: column; gap: 4px;">
|
|
150751
151043
|
<div>
|
|
150752
|
-
<div style="font-weight: bold; color: #dde; font-size: ${t.
|
|
151044
|
+
<div style="font-weight: bold; color: #dde; font-size: ${t.cardTitleLg};">${agent.name}</div>
|
|
150753
151045
|
<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
151046
|
</div>
|
|
150755
151047
|
<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
151048
|
${taskSummaryHtml}
|
|
150769
151049
|
</div>
|
|
150770
151050
|
${toolPipelineHtml}
|
|
@@ -150795,6 +151075,10 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150795
151075
|
context.emitOpenTerminal(agentId);
|
|
150796
151076
|
},
|
|
150797
151077
|
handleMetaPanelClick(target, agentId, context) {
|
|
151078
|
+
if (target.closest(".session-new-btn")) {
|
|
151079
|
+
context.startNewSession(agentId);
|
|
151080
|
+
return;
|
|
151081
|
+
}
|
|
150798
151082
|
if (target.closest(".session-edit-btn") || target.closest(".session-title-display")) {
|
|
150799
151083
|
context.startSessionMetaEdit(agentId);
|
|
150800
151084
|
}
|
|
@@ -150896,7 +151180,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150896
151180
|
background: ${bgColor};
|
|
150897
151181
|
border: 1.5px solid ${borderColor};
|
|
150898
151182
|
border-radius: 10px;
|
|
150899
|
-
padding:
|
|
151183
|
+
padding: 18px 16px;
|
|
150900
151184
|
margin-bottom: 8px;
|
|
150901
151185
|
cursor: ${cursor};
|
|
150902
151186
|
transition: border-color 0.15s;
|
|
@@ -150904,6 +151188,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
150904
151188
|
align-items: flex-start;
|
|
150905
151189
|
gap: 12px;
|
|
150906
151190
|
position: relative;
|
|
151191
|
+
min-height: 124px;
|
|
150907
151192
|
">
|
|
150908
151193
|
<div style="
|
|
150909
151194
|
flex-shrink: 0;
|
|
@@ -153555,12 +153840,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
153555
153840
|
if (this.currentLayout === "default") {
|
|
153556
153841
|
const officeId = officeManager.currentOfficeId;
|
|
153557
153842
|
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);
|
|
153843
|
+
const restoredSeatedAgents = restoreSeatedReserveAgents(officeManager.getSeatedAgents(officeId));
|
|
153844
|
+
for (const { deskId, agentId } of restoredSeatedAgents) {
|
|
153564
153845
|
const desk = this.desks.find((d) => d.agentId === deskId);
|
|
153565
153846
|
if (desk) {
|
|
153566
153847
|
desk.agentId = agentId;
|
|
@@ -155443,165 +155724,1005 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155443
155724
|
}
|
|
155444
155725
|
});
|
|
155445
155726
|
|
|
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
|
-
|
|
155591
|
-
|
|
155592
|
-
|
|
155593
|
-
|
|
155594
|
-
|
|
155595
|
-
|
|
155727
|
+
// src/ui/SeriousTerminalController.ts
|
|
155728
|
+
var import_xterm2, import_addon_fit2, SeriousTerminalController;
|
|
155729
|
+
var init_SeriousTerminalController = __esm({
|
|
155730
|
+
"src/ui/SeriousTerminalController.ts"() {
|
|
155731
|
+
"use strict";
|
|
155732
|
+
import_xterm2 = __toESM(require_xterm());
|
|
155733
|
+
import_addon_fit2 = __toESM(require_addon_fit());
|
|
155734
|
+
SeriousTerminalController = class _SeriousTerminalController {
|
|
155735
|
+
constructor(host, options = {}) {
|
|
155736
|
+
this.historyPopover = null;
|
|
155737
|
+
this.terminal = null;
|
|
155738
|
+
this.fitAddon = null;
|
|
155739
|
+
this.resizeObserver = null;
|
|
155740
|
+
this.resizeHandler = null;
|
|
155741
|
+
this.refitTimers = [];
|
|
155742
|
+
this.activeOfficeId = null;
|
|
155743
|
+
this.activeAgentId = null;
|
|
155744
|
+
this.visible = false;
|
|
155745
|
+
this.openedAt = 0;
|
|
155746
|
+
this.sessionId = null;
|
|
155747
|
+
this.activeOptions = null;
|
|
155748
|
+
this.isFullWidth = false;
|
|
155749
|
+
this.host = host;
|
|
155750
|
+
this.onClose = options.onClose;
|
|
155751
|
+
this.isFullWidth = localStorage.getItem(_SeriousTerminalController.FULL_WIDTH_STORAGE_KEY) === "true";
|
|
155752
|
+
this.container = document.createElement("div");
|
|
155753
|
+
this.container.style.cssText = `
|
|
155754
|
+
display: none;
|
|
155755
|
+
flex-direction: column;
|
|
155756
|
+
flex: 1;
|
|
155757
|
+
min-height: 0;
|
|
155758
|
+
background: #11131c;
|
|
155759
|
+
color: #d7defa;
|
|
155760
|
+
border-left: 2px solid #2f3f62;
|
|
155761
|
+
font-family: 'Cascadia Code', Consolas, monospace;
|
|
155762
|
+
`;
|
|
155763
|
+
const header = document.createElement("div");
|
|
155764
|
+
header.style.cssText = `
|
|
155765
|
+
display: flex;
|
|
155766
|
+
align-items: center;
|
|
155767
|
+
justify-content: space-between;
|
|
155768
|
+
gap: 8px;
|
|
155769
|
+
padding: 12px 14px;
|
|
155770
|
+
border-bottom: 1px solid #27314e;
|
|
155771
|
+
background: #171b2a;
|
|
155772
|
+
flex-shrink: 0;
|
|
155773
|
+
`;
|
|
155774
|
+
const leftHeader = document.createElement("div");
|
|
155775
|
+
leftHeader.style.cssText = "min-width: 0;";
|
|
155776
|
+
this.titleEl = document.createElement("div");
|
|
155777
|
+
this.titleEl.style.cssText = "font-size: 14px; font-weight: 700; color: #9fc2ff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;";
|
|
155778
|
+
this.subtitleEl = document.createElement("div");
|
|
155779
|
+
this.subtitleEl.style.cssText = "font-size: 11px; color: #7f8bad; margin-top: 3px;";
|
|
155780
|
+
leftHeader.appendChild(this.titleEl);
|
|
155781
|
+
leftHeader.appendChild(this.subtitleEl);
|
|
155782
|
+
const rightHeader = document.createElement("div");
|
|
155783
|
+
rightHeader.style.cssText = "display: flex; align-items: center; gap: 6px;";
|
|
155784
|
+
this.statusEl = document.createElement("div");
|
|
155785
|
+
this.statusEl.style.cssText = "font-size: 11px; color: #8ca2db; margin-right: 4px;";
|
|
155786
|
+
const detachBtn = document.createElement("button");
|
|
155787
|
+
detachBtn.textContent = "Detach";
|
|
155788
|
+
detachBtn.style.cssText = this.buttonCss("#2f3754", "#6f8ed8");
|
|
155789
|
+
detachBtn.addEventListener("click", () => {
|
|
155790
|
+
void this.closeView({ detach: true });
|
|
155791
|
+
});
|
|
155792
|
+
const closeBtn = document.createElement("button");
|
|
155793
|
+
closeBtn.textContent = "Close";
|
|
155794
|
+
closeBtn.style.cssText = this.buttonCss("#3a2534", "#c98fbb");
|
|
155795
|
+
closeBtn.addEventListener("click", () => {
|
|
155796
|
+
void this.closeView({ detach: true });
|
|
155797
|
+
});
|
|
155798
|
+
rightHeader.appendChild(this.statusEl);
|
|
155799
|
+
rightHeader.appendChild(detachBtn);
|
|
155800
|
+
rightHeader.appendChild(closeBtn);
|
|
155801
|
+
header.appendChild(leftHeader);
|
|
155802
|
+
header.appendChild(rightHeader);
|
|
155803
|
+
this.terminalOuterEl = document.createElement("div");
|
|
155804
|
+
this.terminalOuterEl.style.cssText = `
|
|
155805
|
+
flex: 1;
|
|
155806
|
+
min-height: 0;
|
|
155807
|
+
overflow: hidden;
|
|
155808
|
+
background: #0d111b;
|
|
155809
|
+
padding: 10px;
|
|
155810
|
+
box-sizing: border-box;
|
|
155811
|
+
`;
|
|
155812
|
+
this.terminalDivEl = document.createElement("div");
|
|
155813
|
+
this.terminalDivEl.style.cssText = "width: 100%; height: 100%; overflow: hidden;";
|
|
155814
|
+
this.terminalOuterEl.appendChild(this.terminalDivEl);
|
|
155815
|
+
this.terminalOuterEl.addEventListener("mousedown", () => this.terminal?.focus());
|
|
155816
|
+
this.spriteCardEl = document.createElement("div");
|
|
155817
|
+
this.spriteCardEl.style.cssText = `
|
|
155818
|
+
width: 100%;
|
|
155819
|
+
background: #13131f;
|
|
155820
|
+
border-top: 1px solid #252540;
|
|
155821
|
+
font-family: 'Cascadia Code', Consolas, monospace;
|
|
155822
|
+
color: #c8d4ff;
|
|
155823
|
+
display: flex;
|
|
155824
|
+
flex-shrink: 0;
|
|
155825
|
+
justify-content: space-between;
|
|
155826
|
+
align-items: stretch;
|
|
155827
|
+
gap: 24px;
|
|
155828
|
+
min-height: 148px;
|
|
155829
|
+
padding: 16px 24px;
|
|
155830
|
+
box-sizing: border-box;
|
|
155831
|
+
`;
|
|
155832
|
+
const spriteCardLeft = document.createElement("div");
|
|
155833
|
+
spriteCardLeft.style.cssText = "display: flex; align-items: center; gap: 18px; min-width: 0; flex: 1;";
|
|
155834
|
+
const spriteFrame = document.createElement("div");
|
|
155835
|
+
spriteFrame.style.cssText = `
|
|
155836
|
+
width: 72px;
|
|
155837
|
+
background: #2a2a40;
|
|
155838
|
+
border: 1px solid #3a3a58;
|
|
155839
|
+
border-radius: 8px;
|
|
155840
|
+
display: flex;
|
|
155841
|
+
align-items: center;
|
|
155842
|
+
justify-content: center;
|
|
155843
|
+
overflow: hidden;
|
|
155844
|
+
flex-shrink: 0;
|
|
155845
|
+
`;
|
|
155846
|
+
this.spriteCanvasEl = document.createElement("canvas");
|
|
155847
|
+
this.spriteCanvasEl.width = 32;
|
|
155848
|
+
this.spriteCanvasEl.height = 34;
|
|
155849
|
+
this.spriteCanvasEl.style.cssText = `
|
|
155850
|
+
image-rendering: pixelated;
|
|
155851
|
+
width: 64px;
|
|
155852
|
+
height: 68px;
|
|
155853
|
+
display: block;
|
|
155854
|
+
`;
|
|
155855
|
+
spriteFrame.appendChild(this.spriteCanvasEl);
|
|
155856
|
+
const spriteCardText = document.createElement("div");
|
|
155857
|
+
spriteCardText.style.cssText = "display: flex; flex-direction: column; gap: 4px; min-width: 0;";
|
|
155858
|
+
this.spriteNameEl = document.createElement("span");
|
|
155859
|
+
this.spriteNameEl.style.cssText = "font-size: 18px; font-weight: 700; color: #dde; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;";
|
|
155860
|
+
this.spriteSubtitleEl = document.createElement("span");
|
|
155861
|
+
this.spriteSubtitleEl.style.cssText = "font-size: 13px; color: #778; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;";
|
|
155862
|
+
this.sessionTitleEl = document.createElement("span");
|
|
155863
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
155864
|
+
this.sessionTitleEl.style.cssText = "font-size: 14px; font-weight: 700; color: #77839f; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;";
|
|
155865
|
+
spriteCardText.appendChild(this.spriteNameEl);
|
|
155866
|
+
spriteCardText.appendChild(this.spriteSubtitleEl);
|
|
155867
|
+
spriteCardText.appendChild(this.sessionTitleEl);
|
|
155868
|
+
spriteCardLeft.appendChild(spriteFrame);
|
|
155869
|
+
spriteCardLeft.appendChild(spriteCardText);
|
|
155870
|
+
const spriteCardRight = document.createElement("div");
|
|
155871
|
+
spriteCardRight.style.cssText = "display: flex; flex-direction: column; justify-content: center; align-items: flex-end; gap: 8px;";
|
|
155872
|
+
const sessionLabel = document.createElement("span");
|
|
155873
|
+
sessionLabel.textContent = "Session ID";
|
|
155874
|
+
sessionLabel.style.cssText = "font-size: 11px; color: #6f7fa9;";
|
|
155875
|
+
this.sessionIdEl = document.createElement("span");
|
|
155876
|
+
this.sessionIdEl.textContent = "--";
|
|
155877
|
+
this.sessionIdEl.style.cssText = "font-size: 12px; color: #8ec3ff; cursor: pointer;";
|
|
155878
|
+
this.sessionIdEl.title = "Copy session ID";
|
|
155879
|
+
this.sessionIdEl.onclick = () => this.copySessionId();
|
|
155880
|
+
spriteCardRight.appendChild(sessionLabel);
|
|
155881
|
+
spriteCardRight.appendChild(this.sessionIdEl);
|
|
155882
|
+
const buttonGrid = document.createElement("div");
|
|
155883
|
+
buttonGrid.style.cssText = `
|
|
155884
|
+
display: grid;
|
|
155885
|
+
grid-template-columns: repeat(2, max-content);
|
|
155886
|
+
gap: 6px;
|
|
155887
|
+
margin-top: 2px;
|
|
155888
|
+
`;
|
|
155889
|
+
const footerBtnCss = this.buttonCss("#2a3a4a", "#4a5a6a");
|
|
155890
|
+
const historyBtn = document.createElement("button");
|
|
155891
|
+
historyBtn.textContent = "Session History";
|
|
155892
|
+
historyBtn.style.cssText = footerBtnCss;
|
|
155893
|
+
historyBtn.onclick = () => {
|
|
155894
|
+
void this.toggleSessionHistory(historyBtn);
|
|
155895
|
+
};
|
|
155896
|
+
buttonGrid.appendChild(historyBtn);
|
|
155897
|
+
const newSessionBtn = document.createElement("button");
|
|
155898
|
+
newSessionBtn.textContent = "New Session";
|
|
155899
|
+
newSessionBtn.style.cssText = footerBtnCss;
|
|
155900
|
+
newSessionBtn.onclick = () => {
|
|
155901
|
+
void this.handleNewSession();
|
|
155902
|
+
};
|
|
155903
|
+
buttonGrid.appendChild(newSessionBtn);
|
|
155904
|
+
const clearHistoryBtn = document.createElement("button");
|
|
155905
|
+
clearHistoryBtn.textContent = "Clear History";
|
|
155906
|
+
clearHistoryBtn.style.cssText = footerBtnCss;
|
|
155907
|
+
clearHistoryBtn.onclick = () => {
|
|
155908
|
+
void this.handleClearHistory();
|
|
155909
|
+
};
|
|
155910
|
+
buttonGrid.appendChild(clearHistoryBtn);
|
|
155911
|
+
const closeSessionBtn = document.createElement("button");
|
|
155912
|
+
closeSessionBtn.textContent = "Close Session";
|
|
155913
|
+
closeSessionBtn.style.cssText = this.buttonCss("#3a2a2a", "#8f5d5d");
|
|
155914
|
+
closeSessionBtn.onclick = () => {
|
|
155915
|
+
void this.handleCloseSession();
|
|
155916
|
+
};
|
|
155917
|
+
buttonGrid.appendChild(closeSessionBtn);
|
|
155918
|
+
this.fullscreenBtn = document.createElement("button");
|
|
155919
|
+
this.fullscreenBtn.textContent = this.isFullWidth ? "Half Width" : "Full Width";
|
|
155920
|
+
this.fullscreenBtn.style.cssText = this.buttonCss("#2a2f4a", "#5a6aa0");
|
|
155921
|
+
this.fullscreenBtn.onclick = () => this.toggleFullWidth();
|
|
155922
|
+
buttonGrid.appendChild(this.fullscreenBtn);
|
|
155923
|
+
const refreshFocusBtn = document.createElement("button");
|
|
155924
|
+
refreshFocusBtn.textContent = "Refresh Focus";
|
|
155925
|
+
refreshFocusBtn.style.cssText = this.buttonCss("#2a3a2a", "#4f7b63");
|
|
155926
|
+
refreshFocusBtn.onclick = () => this.refreshFocusAndGeometry();
|
|
155927
|
+
buttonGrid.appendChild(refreshFocusBtn);
|
|
155928
|
+
spriteCardRight.appendChild(buttonGrid);
|
|
155929
|
+
this.spriteCardEl.appendChild(spriteCardLeft);
|
|
155930
|
+
this.spriteCardEl.appendChild(spriteCardRight);
|
|
155931
|
+
this.ensureXtermStyles();
|
|
155932
|
+
this.container.appendChild(header);
|
|
155933
|
+
this.container.appendChild(this.terminalOuterEl);
|
|
155934
|
+
this.container.appendChild(this.spriteCardEl);
|
|
155935
|
+
this.host.appendChild(this.container);
|
|
155936
|
+
this.createTerminal();
|
|
155937
|
+
if (window.copilotBridge) {
|
|
155938
|
+
window.copilotBridge.onTerminalData((agentId, data) => {
|
|
155939
|
+
if (!this.visible || this.activeAgentId !== agentId) return;
|
|
155940
|
+
this.terminal?.write(data);
|
|
155941
|
+
});
|
|
155942
|
+
window.copilotBridge.onTerminalExit((agentId, exitCode) => {
|
|
155943
|
+
if (!this.visible || this.activeAgentId !== agentId) return;
|
|
155944
|
+
this.terminal?.writeln(`\r
|
|
155945
|
+
[terminal exited with code ${exitCode}]`);
|
|
155946
|
+
this.setStatus("Exited");
|
|
155947
|
+
});
|
|
155948
|
+
window.copilotBridge.onSessionMetaUpdated((agentId) => {
|
|
155949
|
+
if (!this.visible || !this.activeOfficeId || this.activeAgentId !== agentId) return;
|
|
155950
|
+
void this.updateSessionTitle(this.activeOfficeId, agentId);
|
|
155951
|
+
});
|
|
155952
|
+
}
|
|
155953
|
+
}
|
|
155954
|
+
static {
|
|
155955
|
+
this.FULL_WIDTH_STORAGE_KEY = "agencyOffice:seriousTerminalFullWidth";
|
|
155956
|
+
}
|
|
155957
|
+
isVisible() {
|
|
155958
|
+
return this.visible;
|
|
155959
|
+
}
|
|
155960
|
+
refreshCardFromOverview() {
|
|
155961
|
+
if (!this.visible || !this.activeAgentId) return;
|
|
155962
|
+
this.renderExactOverviewCard(this.activeAgentId);
|
|
155963
|
+
}
|
|
155964
|
+
async openAgentTerminal(options) {
|
|
155965
|
+
if (!window.copilotBridge || !this.terminal) return;
|
|
155966
|
+
const switchingTarget = this.activeOfficeId !== options.officeId || this.activeAgentId !== options.agentId;
|
|
155967
|
+
if (switchingTarget) {
|
|
155968
|
+
await this.closeView({ detach: true, silent: true });
|
|
155969
|
+
}
|
|
155970
|
+
this.activeOfficeId = options.officeId;
|
|
155971
|
+
this.activeAgentId = options.agentId;
|
|
155972
|
+
this.activeOptions = { ...options };
|
|
155973
|
+
this.visible = true;
|
|
155974
|
+
this.openedAt = Date.now();
|
|
155975
|
+
this.sessionId = null;
|
|
155976
|
+
this.container.style.display = "flex";
|
|
155977
|
+
this.terminal.clear();
|
|
155978
|
+
this.titleEl.textContent = `${options.name} (${options.agentId})`;
|
|
155979
|
+
this.subtitleEl.textContent = options.description;
|
|
155980
|
+
this.updateSpriteCard(options);
|
|
155981
|
+
void this.updateSessionTitle(options.officeId, options.agentId);
|
|
155982
|
+
this.updateSessionIdDisplay();
|
|
155983
|
+
this.setStatus("Opening...");
|
|
155984
|
+
this.applyPanelLayout();
|
|
155985
|
+
this.refitAndResize(options.officeId, options.agentId);
|
|
155986
|
+
try {
|
|
155987
|
+
const exists = await window.copilotBridge.terminalExists(options.officeId, options.agentId);
|
|
155988
|
+
if (!exists) {
|
|
155989
|
+
const dims = this.fitAddon?.proposeDimensions();
|
|
155990
|
+
const startResult = await window.copilotBridge.terminalStart(
|
|
155991
|
+
options.officeId,
|
|
155992
|
+
options.agentId,
|
|
155993
|
+
options.workingDir,
|
|
155994
|
+
dims?.cols,
|
|
155995
|
+
dims?.rows,
|
|
155996
|
+
void 0,
|
|
155997
|
+
options.launchMode || "copilot"
|
|
155998
|
+
);
|
|
155999
|
+
if (!startResult.success) {
|
|
156000
|
+
this.terminal.writeln(`\r
|
|
156001
|
+
Failed to start terminal: ${startResult.error || "unknown error"}`);
|
|
156002
|
+
this.setStatus("Start failed");
|
|
156003
|
+
return;
|
|
156004
|
+
}
|
|
156005
|
+
if (startResult.sessionId) {
|
|
156006
|
+
this.sessionId = startResult.sessionId;
|
|
156007
|
+
this.updateSessionIdDisplay();
|
|
156008
|
+
}
|
|
156009
|
+
}
|
|
156010
|
+
const attachResult = await window.copilotBridge.terminalAttach(options.officeId, options.agentId);
|
|
156011
|
+
if (!attachResult.success) {
|
|
156012
|
+
this.terminal.writeln("\r\nFailed to attach terminal session.");
|
|
156013
|
+
this.setStatus("Attach failed");
|
|
156014
|
+
return;
|
|
156015
|
+
}
|
|
156016
|
+
if (attachResult.scrollback) {
|
|
156017
|
+
this.terminal.write(attachResult.scrollback);
|
|
156018
|
+
}
|
|
156019
|
+
const attachedSessionId = await window.copilotBridge.getSessionId(options.officeId, options.agentId);
|
|
156020
|
+
if (attachedSessionId) {
|
|
156021
|
+
this.sessionId = attachedSessionId;
|
|
156022
|
+
this.updateSessionIdDisplay();
|
|
156023
|
+
}
|
|
156024
|
+
this.setStatus(`Attached \xB7 ${this.formatElapsed(this.openedAt)}`);
|
|
156025
|
+
this.terminal.focus();
|
|
156026
|
+
this.debouncedRefit(options.officeId, options.agentId);
|
|
156027
|
+
this.refreshCardFromOverview();
|
|
156028
|
+
} catch (error) {
|
|
156029
|
+
this.terminal.writeln(`\r
|
|
156030
|
+
Terminal error: ${error?.message || String(error)}`);
|
|
156031
|
+
this.setStatus("Error");
|
|
156032
|
+
this.refreshCardFromOverview();
|
|
156033
|
+
}
|
|
156034
|
+
}
|
|
156035
|
+
async startNewSession(options) {
|
|
156036
|
+
if (!window.copilotBridge) return;
|
|
156037
|
+
try {
|
|
156038
|
+
await window.copilotBridge.resetSession(options.officeId, options.agentId);
|
|
156039
|
+
} catch {
|
|
156040
|
+
}
|
|
156041
|
+
const isCurrentView = this.visible && this.activeOfficeId === options.officeId && this.activeAgentId === options.agentId;
|
|
156042
|
+
if (isCurrentView) {
|
|
156043
|
+
await this.openAgentTerminal(options);
|
|
156044
|
+
return;
|
|
156045
|
+
}
|
|
156046
|
+
const startResult = await window.copilotBridge.terminalStart(
|
|
156047
|
+
options.officeId,
|
|
156048
|
+
options.agentId,
|
|
156049
|
+
options.workingDir,
|
|
156050
|
+
void 0,
|
|
156051
|
+
void 0,
|
|
156052
|
+
void 0,
|
|
156053
|
+
options.launchMode || "copilot"
|
|
156054
|
+
);
|
|
156055
|
+
if (!startResult.success) {
|
|
156056
|
+
console.warn(
|
|
156057
|
+
`[SeriousTerminalController] Failed to start new session for ${options.agentId}: ${startResult.error || "unknown error"}`
|
|
156058
|
+
);
|
|
156059
|
+
}
|
|
156060
|
+
}
|
|
156061
|
+
async closeView(options = {}) {
|
|
156062
|
+
const { detach = true, silent = false } = options;
|
|
156063
|
+
if (detach && this.activeOfficeId && this.activeAgentId && window.copilotBridge) {
|
|
156064
|
+
try {
|
|
156065
|
+
await window.copilotBridge.terminalDetach(this.activeOfficeId, this.activeAgentId);
|
|
156066
|
+
} catch {
|
|
156067
|
+
}
|
|
156068
|
+
}
|
|
156069
|
+
this.visible = false;
|
|
156070
|
+
this.container.style.display = "none";
|
|
156071
|
+
this.activeOfficeId = null;
|
|
156072
|
+
this.activeAgentId = null;
|
|
156073
|
+
this.activeOptions = null;
|
|
156074
|
+
this.sessionId = null;
|
|
156075
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
156076
|
+
this.sessionTitleEl.style.color = "#77839f";
|
|
156077
|
+
this.updateSessionIdDisplay();
|
|
156078
|
+
this.setStatus("");
|
|
156079
|
+
this.clearRefitTimers();
|
|
156080
|
+
this.closeSessionHistoryPopover();
|
|
156081
|
+
this.applyPanelLayout();
|
|
156082
|
+
if (!silent) {
|
|
156083
|
+
this.onClose?.();
|
|
156084
|
+
}
|
|
156085
|
+
}
|
|
156086
|
+
setStatus(text) {
|
|
156087
|
+
this.statusEl.textContent = text;
|
|
156088
|
+
}
|
|
156089
|
+
updateSpriteCard(options) {
|
|
156090
|
+
this.spriteNameEl.textContent = options.name;
|
|
156091
|
+
this.spriteSubtitleEl.textContent = options.description;
|
|
156092
|
+
const colorHex = `#${(options.color ?? 7311064).toString(16).padStart(6, "0")}`;
|
|
156093
|
+
this.spriteNameEl.style.color = colorHex;
|
|
156094
|
+
this.renderAgentSprite(options.agentId, options.color ?? 7311064);
|
|
156095
|
+
}
|
|
156096
|
+
updateSessionIdDisplay() {
|
|
156097
|
+
this.sessionIdEl.textContent = this.sessionId || "--";
|
|
156098
|
+
}
|
|
156099
|
+
renderExactOverviewCard(agentId) {
|
|
156100
|
+
const sourceCard = document.querySelector(`#overview-content .agent-card[data-agent="${agentId}"]`);
|
|
156101
|
+
if (!sourceCard) return;
|
|
156102
|
+
const clonedCard = sourceCard.cloneNode(true);
|
|
156103
|
+
clonedCard.style.marginBottom = "0";
|
|
156104
|
+
clonedCard.style.cursor = "default";
|
|
156105
|
+
const sourceCanvases = sourceCard.querySelectorAll("canvas");
|
|
156106
|
+
const cloneCanvases = clonedCard.querySelectorAll("canvas");
|
|
156107
|
+
cloneCanvases.forEach((node, i) => {
|
|
156108
|
+
const canvas = node;
|
|
156109
|
+
canvas.removeAttribute("id");
|
|
156110
|
+
const src = sourceCanvases[i];
|
|
156111
|
+
const ctx = canvas.getContext("2d");
|
|
156112
|
+
if (!src || !ctx) return;
|
|
156113
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
156114
|
+
ctx.drawImage(src, 0, 0);
|
|
156115
|
+
});
|
|
156116
|
+
this.spriteCardEl.style.display = "block";
|
|
156117
|
+
this.spriteCardEl.style.padding = "10px 10px 12px";
|
|
156118
|
+
this.spriteCardEl.style.minHeight = "0";
|
|
156119
|
+
this.spriteCardEl.style.gap = "0";
|
|
156120
|
+
this.spriteCardEl.style.alignItems = "stretch";
|
|
156121
|
+
this.spriteCardEl.style.justifyContent = "stretch";
|
|
156122
|
+
this.spriteCardEl.innerHTML = "";
|
|
156123
|
+
this.spriteCardEl.appendChild(clonedCard);
|
|
156124
|
+
}
|
|
156125
|
+
async updateSessionTitle(officeId, agentId) {
|
|
156126
|
+
if (!window.copilotBridge?.getSessionMeta) {
|
|
156127
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
156128
|
+
this.sessionTitleEl.style.color = "#77839f";
|
|
156129
|
+
return;
|
|
156130
|
+
}
|
|
156131
|
+
try {
|
|
156132
|
+
const meta = await window.copilotBridge.getSessionMeta(officeId, agentId);
|
|
156133
|
+
const title = meta?.title?.trim();
|
|
156134
|
+
if (title) {
|
|
156135
|
+
this.sessionTitleEl.textContent = title;
|
|
156136
|
+
this.sessionTitleEl.style.color = "#c8d4ff";
|
|
156137
|
+
} else {
|
|
156138
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
156139
|
+
this.sessionTitleEl.style.color = "#77839f";
|
|
156140
|
+
}
|
|
156141
|
+
} catch {
|
|
156142
|
+
this.sessionTitleEl.textContent = "Untitled session";
|
|
156143
|
+
this.sessionTitleEl.style.color = "#77839f";
|
|
156144
|
+
}
|
|
156145
|
+
}
|
|
156146
|
+
async handleNewSession() {
|
|
156147
|
+
if (!this.activeOptions) return;
|
|
156148
|
+
await this.startNewSession(this.activeOptions);
|
|
156149
|
+
this.closeSessionHistoryPopover();
|
|
156150
|
+
}
|
|
156151
|
+
async handleClearHistory() {
|
|
156152
|
+
if (!window.copilotBridge || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156153
|
+
try {
|
|
156154
|
+
await window.copilotBridge.clearSessionHistory(this.activeOfficeId, this.activeAgentId);
|
|
156155
|
+
this.terminal?.writeln("\r\n[session history cleared]");
|
|
156156
|
+
this.closeSessionHistoryPopover();
|
|
156157
|
+
} catch {
|
|
156158
|
+
this.terminal?.writeln("\r\n[failed to clear session history]");
|
|
156159
|
+
}
|
|
156160
|
+
}
|
|
156161
|
+
async handleCloseSession() {
|
|
156162
|
+
if (!window.copilotBridge || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156163
|
+
try {
|
|
156164
|
+
await window.copilotBridge.resetSession(this.activeOfficeId, this.activeAgentId);
|
|
156165
|
+
this.terminal?.writeln("\r\n[session closed]");
|
|
156166
|
+
} catch {
|
|
156167
|
+
this.terminal?.writeln("\r\n[failed to close session]");
|
|
156168
|
+
}
|
|
156169
|
+
await this.closeView({ detach: true });
|
|
156170
|
+
}
|
|
156171
|
+
async toggleSessionHistory(anchor) {
|
|
156172
|
+
if (!window.copilotBridge || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156173
|
+
if (this.historyPopover) {
|
|
156174
|
+
this.closeSessionHistoryPopover();
|
|
156175
|
+
return;
|
|
156176
|
+
}
|
|
156177
|
+
let history = [];
|
|
156178
|
+
try {
|
|
156179
|
+
history = await window.copilotBridge.getSessionHistory(this.activeOfficeId, this.activeAgentId);
|
|
156180
|
+
} catch {
|
|
156181
|
+
history = [];
|
|
156182
|
+
}
|
|
156183
|
+
const pop = document.createElement("div");
|
|
156184
|
+
pop.style.cssText = `
|
|
156185
|
+
position: absolute;
|
|
156186
|
+
right: 12px;
|
|
156187
|
+
bottom: calc(100% + 8px);
|
|
156188
|
+
width: min(620px, 88vw);
|
|
156189
|
+
max-height: 280px;
|
|
156190
|
+
overflow: auto;
|
|
156191
|
+
background: #101629;
|
|
156192
|
+
border: 1px solid #2f3f62;
|
|
156193
|
+
border-radius: 8px;
|
|
156194
|
+
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
|
|
156195
|
+
padding: 10px 12px;
|
|
156196
|
+
z-index: 10003;
|
|
156197
|
+
color: #c8d4ff;
|
|
156198
|
+
font-size: 12px;
|
|
156199
|
+
white-space: pre-wrap;
|
|
156200
|
+
line-height: 1.4;
|
|
156201
|
+
`;
|
|
156202
|
+
const title = document.createElement("div");
|
|
156203
|
+
title.textContent = `Session History (${history.length})`;
|
|
156204
|
+
title.style.cssText = "font-weight: 700; margin-bottom: 8px; color: #9fc2ff;";
|
|
156205
|
+
pop.appendChild(title);
|
|
156206
|
+
const body = document.createElement("div");
|
|
156207
|
+
if (history.length === 0) {
|
|
156208
|
+
body.textContent = "No history yet.";
|
|
156209
|
+
body.style.cssText = "color: #77839f; font-style: italic;";
|
|
156210
|
+
} else {
|
|
156211
|
+
body.textContent = history.join("\n");
|
|
156212
|
+
}
|
|
156213
|
+
pop.appendChild(body);
|
|
156214
|
+
const closeBtn = document.createElement("button");
|
|
156215
|
+
closeBtn.textContent = "Close";
|
|
156216
|
+
closeBtn.style.cssText = `${this.buttonCss("#2a2f4a", "#5a6aa0")} margin-top: 10px;`;
|
|
156217
|
+
closeBtn.onclick = () => this.closeSessionHistoryPopover();
|
|
156218
|
+
pop.appendChild(closeBtn);
|
|
156219
|
+
this.historyPopover = pop;
|
|
156220
|
+
this.spriteCardEl.style.position = "relative";
|
|
156221
|
+
this.spriteCardEl.appendChild(pop);
|
|
156222
|
+
anchor.blur();
|
|
156223
|
+
}
|
|
156224
|
+
closeSessionHistoryPopover() {
|
|
156225
|
+
if (this.historyPopover?.parentElement) {
|
|
156226
|
+
this.historyPopover.parentElement.removeChild(this.historyPopover);
|
|
156227
|
+
}
|
|
156228
|
+
this.historyPopover = null;
|
|
156229
|
+
}
|
|
156230
|
+
copySessionId() {
|
|
156231
|
+
if (!this.sessionId) return;
|
|
156232
|
+
navigator.clipboard.writeText(this.sessionId).then(() => {
|
|
156233
|
+
const original = this.sessionIdEl.textContent;
|
|
156234
|
+
this.sessionIdEl.textContent = "Copied!";
|
|
156235
|
+
this.sessionIdEl.style.color = "#61d394";
|
|
156236
|
+
setTimeout(() => {
|
|
156237
|
+
this.sessionIdEl.textContent = original;
|
|
156238
|
+
this.sessionIdEl.style.color = "#8ec3ff";
|
|
156239
|
+
}, 900);
|
|
156240
|
+
}).catch(() => {
|
|
156241
|
+
});
|
|
156242
|
+
}
|
|
156243
|
+
renderAgentSprite(seed, baseColor) {
|
|
156244
|
+
const ctx = this.spriteCanvasEl.getContext("2d");
|
|
156245
|
+
if (!ctx) return;
|
|
156246
|
+
ctx.clearRect(0, 0, 32, 34);
|
|
156247
|
+
ctx.imageSmoothingEnabled = false;
|
|
156248
|
+
const color = this.toHex(baseColor);
|
|
156249
|
+
const shade = this.toHex(this.scaleColor(baseColor, 0.72));
|
|
156250
|
+
const accent = this.toHex(this.scaleColor(baseColor, 1.22));
|
|
156251
|
+
const skin = "#f3cfa7";
|
|
156252
|
+
ctx.fillStyle = "#0f1425";
|
|
156253
|
+
ctx.fillRect(0, 0, 32, 34);
|
|
156254
|
+
ctx.fillStyle = shade;
|
|
156255
|
+
ctx.fillRect(8, 16, 16, 14);
|
|
156256
|
+
ctx.fillStyle = color;
|
|
156257
|
+
ctx.fillRect(9, 16, 14, 13);
|
|
156258
|
+
ctx.fillStyle = skin;
|
|
156259
|
+
ctx.fillRect(10, 8, 12, 9);
|
|
156260
|
+
ctx.fillStyle = accent;
|
|
156261
|
+
ctx.fillRect(10, 5, 12, 4);
|
|
156262
|
+
ctx.fillStyle = "#182033";
|
|
156263
|
+
ctx.fillRect(13, 11, 2, 2);
|
|
156264
|
+
ctx.fillRect(17, 11, 2, 2);
|
|
156265
|
+
const seedValue = [...seed].reduce((acc, ch) => acc + ch.charCodeAt(0), 0);
|
|
156266
|
+
const badgeX = seedValue % 2 === 0 ? 5 : 24;
|
|
156267
|
+
ctx.fillStyle = accent;
|
|
156268
|
+
ctx.fillRect(badgeX, 19, 3, 3);
|
|
156269
|
+
}
|
|
156270
|
+
toHex(color) {
|
|
156271
|
+
return `#${color.toString(16).padStart(6, "0")}`;
|
|
156272
|
+
}
|
|
156273
|
+
scaleColor(color, multiplier) {
|
|
156274
|
+
const r = Math.min(255, Math.max(0, Math.round((color >> 16 & 255) * multiplier)));
|
|
156275
|
+
const g = Math.min(255, Math.max(0, Math.round((color >> 8 & 255) * multiplier)));
|
|
156276
|
+
const b = Math.min(255, Math.max(0, Math.round((color & 255) * multiplier)));
|
|
156277
|
+
return r << 16 | g << 8 | b;
|
|
156278
|
+
}
|
|
156279
|
+
ensureXtermStyles() {
|
|
156280
|
+
if (document.getElementById("xterm-styles")) return;
|
|
156281
|
+
const style = document.createElement("style");
|
|
156282
|
+
style.id = "xterm-styles";
|
|
156283
|
+
style.textContent = `
|
|
156284
|
+
.xterm { height: 100%; }
|
|
156285
|
+
.xterm-viewport { overflow-y: auto !important; }
|
|
156286
|
+
#serious-terminal-container .xterm { height: 100%; }
|
|
156287
|
+
`;
|
|
156288
|
+
document.head.appendChild(style);
|
|
156289
|
+
}
|
|
156290
|
+
createTerminal() {
|
|
156291
|
+
this.terminal = new import_xterm2.Terminal({
|
|
156292
|
+
theme: {
|
|
156293
|
+
background: "#0d111b",
|
|
156294
|
+
foreground: "#e0e0e0",
|
|
156295
|
+
cursor: "#00ff88",
|
|
156296
|
+
cursorAccent: "#0d111b",
|
|
156297
|
+
selectionBackground: "#3a5a8a"
|
|
156298
|
+
},
|
|
156299
|
+
fontFamily: "Cascadia Code, Consolas, Monaco, monospace",
|
|
156300
|
+
fontSize: 16,
|
|
156301
|
+
lineHeight: 1.2,
|
|
156302
|
+
cursorBlink: true,
|
|
156303
|
+
cursorStyle: "block",
|
|
156304
|
+
scrollback: 1e4,
|
|
156305
|
+
allowProposedApi: true
|
|
156306
|
+
});
|
|
156307
|
+
this.fitAddon = new import_addon_fit2.FitAddon();
|
|
156308
|
+
this.terminal.loadAddon(this.fitAddon);
|
|
156309
|
+
this.terminalDivEl.id = "serious-terminal-container";
|
|
156310
|
+
this.terminal.open(this.terminalDivEl);
|
|
156311
|
+
this.terminal.attachCustomKeyEventHandler((event) => {
|
|
156312
|
+
if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "v" && event.type === "keydown") {
|
|
156313
|
+
event.preventDefault();
|
|
156314
|
+
event.stopPropagation();
|
|
156315
|
+
navigator.clipboard.readText().then((text) => {
|
|
156316
|
+
if (text) this.terminal?.paste(text);
|
|
156317
|
+
}).catch(() => {
|
|
156318
|
+
});
|
|
156319
|
+
return false;
|
|
156320
|
+
}
|
|
156321
|
+
return true;
|
|
156322
|
+
});
|
|
156323
|
+
this.terminal.onData((data) => {
|
|
156324
|
+
if (!window.copilotBridge || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156325
|
+
void window.copilotBridge.terminalWrite(this.activeOfficeId, this.activeAgentId, data);
|
|
156326
|
+
});
|
|
156327
|
+
this.resizeHandler = () => {
|
|
156328
|
+
if (!this.visible || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156329
|
+
this.debouncedRefit(this.activeOfficeId, this.activeAgentId);
|
|
156330
|
+
};
|
|
156331
|
+
window.addEventListener("resize", this.resizeHandler);
|
|
156332
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
156333
|
+
if (!this.visible || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156334
|
+
this.debouncedRefit(this.activeOfficeId, this.activeAgentId);
|
|
156335
|
+
});
|
|
156336
|
+
this.resizeObserver.observe(this.terminalDivEl);
|
|
156337
|
+
}
|
|
156338
|
+
refitAndResize(officeId, agentId) {
|
|
156339
|
+
if (!this.fitAddon || !window.copilotBridge) return;
|
|
156340
|
+
this.fitAddon.fit();
|
|
156341
|
+
const dims = this.fitAddon.proposeDimensions();
|
|
156342
|
+
if (!dims) return;
|
|
156343
|
+
void window.copilotBridge.terminalResize(officeId, agentId, dims.cols, dims.rows);
|
|
156344
|
+
}
|
|
156345
|
+
debouncedRefit(officeId, agentId) {
|
|
156346
|
+
this.clearRefitTimers();
|
|
156347
|
+
requestAnimationFrame(() => {
|
|
156348
|
+
this.refitAndResize(officeId, agentId);
|
|
156349
|
+
this.refitTimers.push(setTimeout(() => {
|
|
156350
|
+
this.refitAndResize(officeId, agentId);
|
|
156351
|
+
this.refitTimers.push(setTimeout(() => this.refitAndResize(officeId, agentId), 200));
|
|
156352
|
+
}, 150));
|
|
156353
|
+
});
|
|
156354
|
+
}
|
|
156355
|
+
refreshFocusAndGeometry() {
|
|
156356
|
+
if (!this.visible || !this.activeOfficeId || !this.activeAgentId) return;
|
|
156357
|
+
this.terminal?.focus();
|
|
156358
|
+
this.debouncedRefit(this.activeOfficeId, this.activeAgentId);
|
|
156359
|
+
}
|
|
156360
|
+
toggleFullWidth() {
|
|
156361
|
+
this.isFullWidth = !this.isFullWidth;
|
|
156362
|
+
localStorage.setItem(_SeriousTerminalController.FULL_WIDTH_STORAGE_KEY, String(this.isFullWidth));
|
|
156363
|
+
this.fullscreenBtn.textContent = this.isFullWidth ? "Half Width" : "Full Width";
|
|
156364
|
+
this.applyPanelLayout();
|
|
156365
|
+
}
|
|
156366
|
+
applyPanelLayout() {
|
|
156367
|
+
const officePanel = document.getElementById("office-panel");
|
|
156368
|
+
const terminalPanel = document.getElementById("terminal-panel");
|
|
156369
|
+
const isMobile = window.__copilotOfficeMobileModeActive?.() === true;
|
|
156370
|
+
if (!officePanel || !terminalPanel || isMobile) return;
|
|
156371
|
+
const appMode = document.getElementById("game-container")?.dataset.appMode;
|
|
156372
|
+
if (appMode !== "serious" || !this.visible || !this.isFullWidth) {
|
|
156373
|
+
officePanel.style.display = "flex";
|
|
156374
|
+
officePanel.style.flexDirection = "column";
|
|
156375
|
+
terminalPanel.style.width = "50%";
|
|
156376
|
+
terminalPanel.style.borderLeft = "2px solid #333";
|
|
156377
|
+
return;
|
|
156378
|
+
}
|
|
156379
|
+
officePanel.style.display = "none";
|
|
156380
|
+
terminalPanel.style.width = "100%";
|
|
156381
|
+
terminalPanel.style.borderLeft = "none";
|
|
156382
|
+
}
|
|
156383
|
+
clearRefitTimers() {
|
|
156384
|
+
for (const timer of this.refitTimers) clearTimeout(timer);
|
|
156385
|
+
this.refitTimers.length = 0;
|
|
156386
|
+
}
|
|
156387
|
+
formatElapsed(startTime) {
|
|
156388
|
+
const seconds = Math.floor((Date.now() - startTime) / 1e3);
|
|
156389
|
+
if (seconds < 60) return `${seconds}s`;
|
|
156390
|
+
const mins = Math.floor(seconds / 60);
|
|
156391
|
+
const secs = seconds % 60;
|
|
156392
|
+
return `${mins}m ${secs}s`;
|
|
156393
|
+
}
|
|
156394
|
+
buttonCss(background, border) {
|
|
156395
|
+
return `
|
|
156396
|
+
background: ${background};
|
|
156397
|
+
border: 1px solid ${border};
|
|
156398
|
+
color: #d4dbf9;
|
|
156399
|
+
border-radius: 5px;
|
|
156400
|
+
padding: 6px 10px;
|
|
156401
|
+
font-family: inherit;
|
|
156402
|
+
font-size: 12px;
|
|
156403
|
+
cursor: pointer;
|
|
156404
|
+
white-space: nowrap;
|
|
156405
|
+
`;
|
|
156406
|
+
}
|
|
156407
|
+
};
|
|
156408
|
+
}
|
|
156409
|
+
});
|
|
156410
|
+
|
|
156411
|
+
// src/main.ts
|
|
156412
|
+
var require_main = __commonJS({
|
|
156413
|
+
"src/main.ts"() {
|
|
156414
|
+
var import_phaser10 = __toESM(require_phaser());
|
|
156415
|
+
init_BootScene();
|
|
156416
|
+
init_OfficeScene();
|
|
156417
|
+
init_MeetingScene();
|
|
156418
|
+
init_officeManager();
|
|
156419
|
+
init_agents();
|
|
156420
|
+
init_responsiveLayout();
|
|
156421
|
+
init_layouts();
|
|
156422
|
+
init_ToastNotification();
|
|
156423
|
+
init_NotificationService();
|
|
156424
|
+
init_SettingsPanel();
|
|
156425
|
+
init_SpriteCustomizerPanel();
|
|
156426
|
+
init_SeriousTerminalController();
|
|
156427
|
+
init_SpriteGenerator();
|
|
156428
|
+
officeManager.ensureDefaultOffice();
|
|
156429
|
+
function getCurrentLayout() {
|
|
156430
|
+
return officeManager.currentOffice?.config.layout ?? "default";
|
|
156431
|
+
}
|
|
156432
|
+
function getCurrentAgents() {
|
|
156433
|
+
return getLayout(getCurrentLayout()).agents;
|
|
156434
|
+
}
|
|
156435
|
+
function getCurrentAgentTools() {
|
|
156436
|
+
return officeManager.currentOffice?.agentTools || /* @__PURE__ */ new Map();
|
|
156437
|
+
}
|
|
156438
|
+
function syncActiveRosterForCurrentOffice() {
|
|
156439
|
+
const office = officeManager.currentOffice;
|
|
156440
|
+
if (!office) return;
|
|
156441
|
+
swapActiveAgents(office.config);
|
|
156442
|
+
if (office.config.layout === "default") {
|
|
156443
|
+
restoreSeatedReserveAgents(officeManager.getSeatedAgents(office.config.id));
|
|
156444
|
+
}
|
|
156445
|
+
}
|
|
156446
|
+
function normalizeToolName(toolName) {
|
|
156447
|
+
return (toolName ?? "").trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
156448
|
+
}
|
|
156449
|
+
function isAskUserTool(toolName, status) {
|
|
156450
|
+
const normalized = normalizeToolName(toolName);
|
|
156451
|
+
if (normalized === "ask_user" || normalized === "askuser") return true;
|
|
156452
|
+
const statusText = (status ?? "").toLowerCase();
|
|
156453
|
+
return statusText.includes("waiting for your answer") || statusText.includes("waiting on user input");
|
|
156454
|
+
}
|
|
156455
|
+
function isDonePendingAck(status) {
|
|
156456
|
+
return !!status?.completionPendingAck;
|
|
156457
|
+
}
|
|
156458
|
+
var selectedAgentId = null;
|
|
156459
|
+
var phaserGameRef;
|
|
156460
|
+
var debugMode = false;
|
|
156461
|
+
var currentZoom = parseFloat(localStorage.getItem("agencyOffice:zoomLevel") ?? "0.8");
|
|
156462
|
+
currentZoom = isNaN(currentZoom) || currentZoom < 0.5 || currentZoom > 2 ? 0.8 : currentZoom;
|
|
156463
|
+
var RESIZE_DEBOUNCE_MS = 200;
|
|
156464
|
+
var APP_MODE_STORAGE_KEY = "agencyOffice:appMode";
|
|
156465
|
+
var SESSION_META_CACHE_STORAGE_KEY = "agencyOffice:sessionMetaCacheByOffice";
|
|
156466
|
+
var OVERVIEW_SPRITE_CACHE_STORAGE_KEY = "agencyOffice:overviewSpriteCache";
|
|
156467
|
+
var PC_TERMINAL_ID2 = "pc-terminal";
|
|
156468
|
+
function sanitizeAppMode(value) {
|
|
156469
|
+
return value === "serious" ? "serious" : "game";
|
|
156470
|
+
}
|
|
156471
|
+
var appMode = sanitizeAppMode(localStorage.getItem(APP_MODE_STORAGE_KEY));
|
|
156472
|
+
function persistAppMode(mode) {
|
|
156473
|
+
try {
|
|
156474
|
+
localStorage.setItem(APP_MODE_STORAGE_KEY, mode);
|
|
156475
|
+
} catch {
|
|
156476
|
+
}
|
|
156477
|
+
}
|
|
156478
|
+
function loadSessionMetaCacheByOffice() {
|
|
156479
|
+
try {
|
|
156480
|
+
const raw = localStorage.getItem(SESSION_META_CACHE_STORAGE_KEY);
|
|
156481
|
+
if (!raw) return {};
|
|
156482
|
+
const parsed = JSON.parse(raw);
|
|
156483
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
156484
|
+
} catch {
|
|
156485
|
+
return {};
|
|
156486
|
+
}
|
|
156487
|
+
}
|
|
156488
|
+
function saveSessionMetaCacheByOffice(cache) {
|
|
156489
|
+
try {
|
|
156490
|
+
localStorage.setItem(SESSION_META_CACHE_STORAGE_KEY, JSON.stringify(cache));
|
|
156491
|
+
} catch {
|
|
156492
|
+
}
|
|
156493
|
+
}
|
|
156494
|
+
function getSessionMetaCacheForOffice(officeId) {
|
|
156495
|
+
const all = loadSessionMetaCacheByOffice();
|
|
156496
|
+
return all[officeId] || {};
|
|
156497
|
+
}
|
|
156498
|
+
function setSessionMetaCacheForOffice(officeId, meta) {
|
|
156499
|
+
const all = loadSessionMetaCacheByOffice();
|
|
156500
|
+
all[officeId] = meta;
|
|
156501
|
+
saveSessionMetaCacheByOffice(all);
|
|
156502
|
+
}
|
|
156503
|
+
function loadOverviewSpriteCache() {
|
|
156504
|
+
try {
|
|
156505
|
+
const raw = localStorage.getItem(OVERVIEW_SPRITE_CACHE_STORAGE_KEY);
|
|
156506
|
+
if (!raw) return {};
|
|
156507
|
+
const parsed = JSON.parse(raw);
|
|
156508
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
156509
|
+
} catch {
|
|
156510
|
+
return {};
|
|
156511
|
+
}
|
|
156512
|
+
}
|
|
156513
|
+
function saveOverviewSpriteCache(cache) {
|
|
156514
|
+
try {
|
|
156515
|
+
localStorage.setItem(OVERVIEW_SPRITE_CACHE_STORAGE_KEY, JSON.stringify(cache));
|
|
156516
|
+
} catch {
|
|
156517
|
+
}
|
|
156518
|
+
}
|
|
156519
|
+
var agentPreloadStatus = /* @__PURE__ */ new Map();
|
|
156520
|
+
var pendingStatusBarUpdate = false;
|
|
156521
|
+
var pendingTerminalContentUpdate = false;
|
|
156522
|
+
var OVERVIEW_SPRITE_MAX_RETRY_ATTEMPTS = 5;
|
|
156523
|
+
var OVERVIEW_SPRITE_RETRY_DELAY_MS = 120;
|
|
156524
|
+
var overviewSpriteRetryTimer = null;
|
|
156525
|
+
var overviewSpriteCache = loadOverviewSpriteCache();
|
|
156526
|
+
var overviewSpriteImageCache = /* @__PURE__ */ new Map();
|
|
156527
|
+
function scheduleUiUpdateWithFallback(callback) {
|
|
156528
|
+
let done = false;
|
|
156529
|
+
const runOnce = () => {
|
|
156530
|
+
if (done) return;
|
|
156531
|
+
done = true;
|
|
156532
|
+
callback();
|
|
156533
|
+
};
|
|
156534
|
+
requestAnimationFrame(runOnce);
|
|
156535
|
+
const fallbackDelayMs = document.hidden ? 80 : 200;
|
|
156536
|
+
setTimeout(runOnce, fallbackDelayMs);
|
|
156537
|
+
}
|
|
156538
|
+
function scheduleStatusBarUpdate() {
|
|
156539
|
+
if (pendingStatusBarUpdate) return;
|
|
156540
|
+
pendingStatusBarUpdate = true;
|
|
156541
|
+
scheduleUiUpdateWithFallback(() => {
|
|
156542
|
+
pendingStatusBarUpdate = false;
|
|
156543
|
+
updateStatusBarNow();
|
|
156544
|
+
});
|
|
156545
|
+
}
|
|
156546
|
+
function scheduleTerminalContentUpdate() {
|
|
156547
|
+
if (pendingTerminalContentUpdate) return;
|
|
156548
|
+
pendingTerminalContentUpdate = true;
|
|
156549
|
+
scheduleUiUpdateWithFallback(() => {
|
|
156550
|
+
pendingTerminalContentUpdate = false;
|
|
156551
|
+
updateTerminalContentNow();
|
|
156552
|
+
});
|
|
156553
|
+
}
|
|
156554
|
+
var container = document.getElementById("game-container");
|
|
156555
|
+
container.innerHTML = "";
|
|
156556
|
+
container.style.cssText = "display: flex; flex-direction: column; width: 100%; height: calc(100% - 58px);";
|
|
156557
|
+
var tabsBar = document.createElement("div");
|
|
156558
|
+
tabsBar.id = "office-tabs";
|
|
156559
|
+
tabsBar.style.cssText = `
|
|
156560
|
+
display: flex;
|
|
156561
|
+
align-items: center;
|
|
156562
|
+
background: #1a1a2a;
|
|
156563
|
+
border-bottom: 2px solid #333;
|
|
156564
|
+
padding: 0 16px;
|
|
156565
|
+
height: 72px;
|
|
156566
|
+
flex-shrink: 0;
|
|
156567
|
+
font-size: 22px;
|
|
156568
|
+
`;
|
|
156569
|
+
container.appendChild(tabsBar);
|
|
156570
|
+
var mainContent = document.createElement("div");
|
|
156571
|
+
mainContent.style.cssText = "display: flex; flex: 1; min-height: 0;";
|
|
156572
|
+
container.appendChild(mainContent);
|
|
156573
|
+
var officePanel = document.createElement("div");
|
|
156574
|
+
officePanel.id = "office-panel";
|
|
156575
|
+
officePanel.style.cssText = "width: 50%; height: 100%; position: relative;";
|
|
156576
|
+
mainContent.appendChild(officePanel);
|
|
156577
|
+
var terminalPanel = document.createElement("div");
|
|
156578
|
+
terminalPanel.id = "terminal-panel";
|
|
156579
|
+
terminalPanel.style.cssText = `
|
|
156580
|
+
width: 50%;
|
|
156581
|
+
height: 100%;
|
|
156582
|
+
background: #1e1e2e;
|
|
156583
|
+
border-left: 2px solid #333;
|
|
156584
|
+
display: flex;
|
|
156585
|
+
flex-direction: column;
|
|
156586
|
+
position: relative;
|
|
156587
|
+
`;
|
|
156588
|
+
mainContent.appendChild(terminalPanel);
|
|
156589
|
+
var overviewHost = document.createElement("div");
|
|
156590
|
+
overviewHost.id = "overview-host";
|
|
156591
|
+
overviewHost.style.cssText = `
|
|
156592
|
+
display: flex;
|
|
156593
|
+
flex-direction: column;
|
|
156594
|
+
flex: 1;
|
|
156595
|
+
min-height: 0;
|
|
156596
|
+
position: relative;
|
|
156597
|
+
`;
|
|
156598
|
+
terminalPanel.appendChild(overviewHost);
|
|
156599
|
+
var terminalHost = document.createElement("div");
|
|
156600
|
+
terminalHost.id = "terminal-host";
|
|
156601
|
+
terminalHost.style.cssText = "display: none; flex: 1; min-height: 0;";
|
|
156602
|
+
terminalPanel.appendChild(terminalHost);
|
|
156603
|
+
var seriousPlaceholder = document.createElement("div");
|
|
156604
|
+
seriousPlaceholder.id = "serious-terminal-placeholder";
|
|
156605
|
+
seriousPlaceholder.style.cssText = `
|
|
156606
|
+
display: none;
|
|
156607
|
+
flex: 1;
|
|
156608
|
+
min-height: 0;
|
|
156609
|
+
align-items: center;
|
|
156610
|
+
justify-content: center;
|
|
156611
|
+
padding: 24px;
|
|
156612
|
+
font-family: 'Cascadia Code', Consolas, monospace;
|
|
156613
|
+
text-align: center;
|
|
156614
|
+
color: #95a7d7;
|
|
156615
|
+
background: radial-gradient(circle at top, #222846 0%, #171c2f 50%, #13192a 100%);
|
|
156616
|
+
`;
|
|
156617
|
+
seriousPlaceholder.innerHTML = `
|
|
156618
|
+
<div style="max-width: 380px;">
|
|
156619
|
+
<div style="font-size: 34px; margin-bottom: 10px;">\u{1F4BB}</div>
|
|
156620
|
+
<div style="font-size: 18px; color: #c7d7ff; font-weight: 700; margin-bottom: 8px;">No terminal selected</div>
|
|
156621
|
+
<div style="font-size: 12px; line-height: 1.45; color: #8fa3d6;">
|
|
156622
|
+
Select an agent or office PC from the overview on the left to open a command line session.
|
|
156623
|
+
</div>
|
|
156624
|
+
</div>
|
|
156625
|
+
`;
|
|
156626
|
+
terminalHost.appendChild(seriousPlaceholder);
|
|
156627
|
+
var currentResponsiveLayout = "default";
|
|
156628
|
+
var resizeDebounceTimer = null;
|
|
156629
|
+
function isMobileModeActive() {
|
|
156630
|
+
return currentResponsiveLayout === "portrait-dashboard";
|
|
156631
|
+
}
|
|
156632
|
+
function applyMobileTopBarVisibility() {
|
|
156633
|
+
const hidden = isMobileModeActive();
|
|
156634
|
+
const ids = ["zoom-bar", "sprite-customizer-btn", "debug-toggle-btn"];
|
|
156635
|
+
for (const id of ids) {
|
|
156636
|
+
const el = document.getElementById(id);
|
|
156637
|
+
if (!el) continue;
|
|
156638
|
+
el.style.display = hidden ? "none" : "";
|
|
156639
|
+
}
|
|
156640
|
+
}
|
|
156641
|
+
function syncMainPanelLayout() {
|
|
156642
|
+
const hideOfficePanel = currentResponsiveLayout === "portrait-dashboard";
|
|
156643
|
+
if (hideOfficePanel) {
|
|
156644
|
+
officePanel.style.display = "none";
|
|
156645
|
+
officePanel.style.flexDirection = "";
|
|
156646
|
+
terminalPanel.style.width = "100%";
|
|
156647
|
+
terminalPanel.style.borderLeft = "none";
|
|
156648
|
+
return;
|
|
156649
|
+
}
|
|
156650
|
+
officePanel.style.display = appMode === "serious" ? "flex" : "";
|
|
156651
|
+
officePanel.style.flexDirection = appMode === "serious" ? "column" : "";
|
|
156652
|
+
terminalPanel.style.width = "50%";
|
|
156653
|
+
terminalPanel.style.borderLeft = "2px solid #333";
|
|
156654
|
+
}
|
|
156655
|
+
function applyResponsiveLayout(layoutKey) {
|
|
156656
|
+
if (layoutKey === currentResponsiveLayout) return;
|
|
156657
|
+
currentResponsiveLayout = layoutKey;
|
|
156658
|
+
syncMainPanelLayout();
|
|
156659
|
+
refreshRightPanelMode();
|
|
156660
|
+
if (phaserGameRef && appMode === "game") {
|
|
156661
|
+
phaserGameRef.events.emit("layout:change", { layoutKey });
|
|
156662
|
+
if (layoutKey === "default") {
|
|
156663
|
+
const width = officePanel.clientWidth || window.innerWidth / 2;
|
|
156664
|
+
const height = officePanel.clientHeight || window.innerHeight;
|
|
156665
|
+
phaserGameRef.scale.resize(width, height);
|
|
156666
|
+
}
|
|
156667
|
+
}
|
|
156668
|
+
applyMobileTopBarVisibility();
|
|
156669
|
+
}
|
|
156670
|
+
function onWindowResize() {
|
|
156671
|
+
if (resizeDebounceTimer !== null) {
|
|
156672
|
+
window.clearTimeout(resizeDebounceTimer);
|
|
156673
|
+
}
|
|
156674
|
+
resizeDebounceTimer = window.setTimeout(() => {
|
|
155596
156675
|
const next = computeResponsiveLayout(window.innerWidth, window.innerHeight);
|
|
155597
156676
|
applyResponsiveLayout(next);
|
|
155598
|
-
if (phaserGameRef && currentResponsiveLayout === "default") {
|
|
156677
|
+
if (phaserGameRef && appMode === "game" && currentResponsiveLayout === "default") {
|
|
155599
156678
|
const width = officePanel.clientWidth || window.innerWidth / 2;
|
|
155600
156679
|
const height = officePanel.clientHeight || window.innerHeight;
|
|
155601
156680
|
phaserGameRef.scale.resize(width, height);
|
|
155602
156681
|
}
|
|
155603
156682
|
}, RESIZE_DEBOUNCE_MS);
|
|
155604
156683
|
}
|
|
156684
|
+
function applyAppMode(nextMode, options = {}) {
|
|
156685
|
+
const { persist = false, refreshTabs = true, force = false } = options;
|
|
156686
|
+
if (!force && nextMode === appMode) return;
|
|
156687
|
+
const previousMode = appMode;
|
|
156688
|
+
appMode = nextMode;
|
|
156689
|
+
const selectedAgentBeforeModeSwitch = selectedAgentId;
|
|
156690
|
+
if (previousMode === "serious" && appMode === "game") {
|
|
156691
|
+
void seriousTerminalController?.closeView({ detach: true, silent: true });
|
|
156692
|
+
}
|
|
156693
|
+
if (appMode === "serious") {
|
|
156694
|
+
prewarmOverviewSpriteCacheFromTextures();
|
|
156695
|
+
teardownPhaserGame();
|
|
156696
|
+
} else {
|
|
156697
|
+
ensurePhaserGame();
|
|
156698
|
+
}
|
|
156699
|
+
container.dataset.appMode = appMode;
|
|
156700
|
+
tabsBar.dataset.appMode = appMode;
|
|
156701
|
+
mainContent.dataset.appMode = appMode;
|
|
156702
|
+
officePanel.dataset.appMode = appMode;
|
|
156703
|
+
terminalPanel.dataset.appMode = appMode;
|
|
156704
|
+
overviewHost.dataset.appMode = appMode;
|
|
156705
|
+
terminalHost.dataset.appMode = appMode;
|
|
156706
|
+
syncMainPanelLayout();
|
|
156707
|
+
if (phaserGameRef && appMode === "game" && currentResponsiveLayout === "default") {
|
|
156708
|
+
const width = officePanel.clientWidth || window.innerWidth / 2;
|
|
156709
|
+
const height = officePanel.clientHeight || window.innerHeight;
|
|
156710
|
+
phaserGameRef.scale.resize(width, height);
|
|
156711
|
+
}
|
|
156712
|
+
if (persist) persistAppMode(appMode);
|
|
156713
|
+
if (refreshTabs) renderOfficeTabs();
|
|
156714
|
+
refreshRightPanelMode();
|
|
156715
|
+
updateTerminalContent();
|
|
156716
|
+
updateStatusBar();
|
|
156717
|
+
phaserGameRef?.events.emit("app:mode:changed", { mode: appMode, previousMode });
|
|
156718
|
+
if (appMode === "serious" && selectedAgentBeforeModeSwitch && getSeriousLaunchConfig(selectedAgentBeforeModeSwitch)) {
|
|
156719
|
+
void openAgentTerminal(selectedAgentBeforeModeSwitch);
|
|
156720
|
+
}
|
|
156721
|
+
}
|
|
156722
|
+
function toggleAppMode() {
|
|
156723
|
+
const nextMode = appMode === "game" ? "serious" : "game";
|
|
156724
|
+
applyAppMode(nextMode, { persist: true, refreshTabs: true });
|
|
156725
|
+
}
|
|
155605
156726
|
applyResponsiveLayout(computeResponsiveLayout(window.innerWidth, window.innerHeight));
|
|
155606
156727
|
window.addEventListener("resize", onWindowResize);
|
|
155607
156728
|
if (typeof window !== "undefined") {
|
|
@@ -155651,6 +156772,21 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155651
156772
|
color: #4a4;
|
|
155652
156773
|
">+ New Office</div>
|
|
155653
156774
|
<div style="flex: 1;"></div>
|
|
156775
|
+
<div id="app-mode-toggle-btn" style="
|
|
156776
|
+
padding: 8px 14px;
|
|
156777
|
+
background: ${appMode === "serious" ? "#2f2638" : "#252538"};
|
|
156778
|
+
border: 2px solid ${appMode === "serious" ? "#a66be0" : "#444"};
|
|
156779
|
+
border-radius: 6px;
|
|
156780
|
+
cursor: pointer;
|
|
156781
|
+
font-family: monospace;
|
|
156782
|
+
color: ${appMode === "serious" ? "#d4b6ff" : "#8fb7ff"};
|
|
156783
|
+
font-size: 14px;
|
|
156784
|
+
user-select: none;
|
|
156785
|
+
transition: all 0.2s;
|
|
156786
|
+
margin-right: 8px;
|
|
156787
|
+
" title="Toggle app mode (game/serious)">
|
|
156788
|
+
${appMode === "serious" ? "\u{1F9E0} Serious Mode" : "\u{1F3AE} Game Mode"}
|
|
156789
|
+
</div>
|
|
155654
156790
|
<div id="sprite-customizer-btn" style="
|
|
155655
156791
|
padding: 8px 16px;
|
|
155656
156792
|
background: #252538;
|
|
@@ -155749,12 +156885,16 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155749
156885
|
});
|
|
155750
156886
|
});
|
|
155751
156887
|
document.getElementById("new-office-btn")?.addEventListener("click", showNewOfficeDialog);
|
|
156888
|
+
document.getElementById("app-mode-toggle-btn")?.addEventListener("click", (e) => {
|
|
156889
|
+
e.stopPropagation();
|
|
156890
|
+
toggleAppMode();
|
|
156891
|
+
});
|
|
155752
156892
|
document.getElementById("debug-toggle-btn")?.addEventListener("click", () => {
|
|
155753
156893
|
debugMode = !debugMode;
|
|
155754
|
-
|
|
156894
|
+
phaserGameRef?.events.emit("debug:toggle", debugMode);
|
|
155755
156895
|
renderOfficeTabs();
|
|
155756
156896
|
if (!isMobileModeActive()) {
|
|
155757
|
-
|
|
156897
|
+
phaserGameRef?.events.emit("game:panel:clicked");
|
|
155758
156898
|
}
|
|
155759
156899
|
console.log(`[Debug] Debug mode ${debugMode ? "ON" : "OFF"}`);
|
|
155760
156900
|
});
|
|
@@ -155794,19 +156934,20 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
155794
156934
|
applyMobileTopBarVisibility();
|
|
155795
156935
|
}
|
|
155796
156936
|
function switchToOffice(officeId) {
|
|
155797
|
-
if (
|
|
156937
|
+
if (phaserGameRef?.registry.get("animating")) {
|
|
155798
156938
|
console.log("[Office] Blocked: animation in progress");
|
|
155799
156939
|
return;
|
|
155800
156940
|
}
|
|
155801
156941
|
selectedAgentId = null;
|
|
156942
|
+
void seriousTerminalController?.closeView({ detach: true });
|
|
155802
156943
|
officeManager.switchOffice(officeId);
|
|
155803
|
-
|
|
155804
|
-
|
|
155805
|
-
|
|
156944
|
+
cachedSessionMeta = getSessionMetaCacheForOffice(officeId);
|
|
156945
|
+
syncActiveRosterForCurrentOffice();
|
|
156946
|
+
phaserGameRef?.events.emit("office:switch", officeId, officeManager.currentOffice?.config.workingDirectory);
|
|
155806
156947
|
renderOfficeTabs();
|
|
155807
156948
|
updateTerminalContent();
|
|
155808
156949
|
updateStatusBar();
|
|
155809
|
-
|
|
156950
|
+
void reconnectAgentStatuses();
|
|
155810
156951
|
fetchSessionMeta();
|
|
155811
156952
|
console.log(`[Office] Switched to office: ${officeManager.currentOffice?.config.name}`);
|
|
155812
156953
|
}
|
|
@@ -156001,8 +157142,8 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156001
157142
|
nameInput.select();
|
|
156002
157143
|
}
|
|
156003
157144
|
renderOfficeTabs();
|
|
156004
|
-
var
|
|
156005
|
-
|
|
157145
|
+
var overviewHeader = document.createElement("div");
|
|
157146
|
+
overviewHeader.style.cssText = `
|
|
156006
157147
|
padding: 14px 20px;
|
|
156007
157148
|
background: #141424;
|
|
156008
157149
|
border-bottom: 2px solid #2a2a4a;
|
|
@@ -156012,7 +157153,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156012
157153
|
justify-content: space-between;
|
|
156013
157154
|
align-items: center;
|
|
156014
157155
|
`;
|
|
156015
|
-
|
|
157156
|
+
overviewHeader.innerHTML = `
|
|
156016
157157
|
<div>
|
|
156017
157158
|
<div id="terminal-title" style="font-size: 18px; font-weight: bold; color: #8af; margin-bottom: 4px;">\u{1F3E2} Office Overview</div>
|
|
156018
157159
|
<div id="terminal-subtitle" style="font-size: 12px; color: #555;"></div>
|
|
@@ -156030,7 +157171,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156030
157171
|
white-space: nowrap;
|
|
156031
157172
|
">\u2715 Close Office</button>
|
|
156032
157173
|
`;
|
|
156033
|
-
|
|
157174
|
+
overviewHost.appendChild(overviewHeader);
|
|
156034
157175
|
document.getElementById("close-office-btn").addEventListener("click", () => {
|
|
156035
157176
|
const currentId = officeManager.currentOfficeId;
|
|
156036
157177
|
const office = officeManager.currentOffice;
|
|
@@ -156040,9 +157181,9 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156040
157181
|
switchToOffice("office-0");
|
|
156041
157182
|
}
|
|
156042
157183
|
});
|
|
156043
|
-
var
|
|
156044
|
-
|
|
156045
|
-
|
|
157184
|
+
var overviewContent = document.createElement("div");
|
|
157185
|
+
overviewContent.id = "terminal-content";
|
|
157186
|
+
overviewContent.style.cssText = `
|
|
156046
157187
|
flex: 1;
|
|
156047
157188
|
padding: 16px;
|
|
156048
157189
|
overflow-y: auto;
|
|
@@ -156051,7 +157192,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156051
157192
|
color: #ccc;
|
|
156052
157193
|
position: relative;
|
|
156053
157194
|
`;
|
|
156054
|
-
|
|
157195
|
+
overviewHost.appendChild(overviewContent);
|
|
156055
157196
|
var statusBar = document.createElement("div");
|
|
156056
157197
|
statusBar.id = "status-bar";
|
|
156057
157198
|
statusBar.style.cssText = `
|
|
@@ -156097,6 +157238,86 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156097
157238
|
function getAgentConfig(agentId) {
|
|
156098
157239
|
return getCurrentAgents().find((a) => a.id === agentId) || AGENTS.find((a) => a.id === agentId);
|
|
156099
157240
|
}
|
|
157241
|
+
var seriousTerminalController = null;
|
|
157242
|
+
function getSeriousLaunchConfig(agentId) {
|
|
157243
|
+
if (agentId === PC_TERMINAL_ID2) {
|
|
157244
|
+
return {
|
|
157245
|
+
name: "PC TERMINAL",
|
|
157246
|
+
description: "Local Shell",
|
|
157247
|
+
color: 7311064,
|
|
157248
|
+
workingDir: officeManager.getCurrentWorkingDirectory(),
|
|
157249
|
+
launchMode: "shell"
|
|
157250
|
+
};
|
|
157251
|
+
}
|
|
157252
|
+
const agent = getAgentConfig(agentId);
|
|
157253
|
+
if (!agent) return null;
|
|
157254
|
+
return {
|
|
157255
|
+
name: agent.name,
|
|
157256
|
+
description: agent.description,
|
|
157257
|
+
color: agent.color,
|
|
157258
|
+
workingDir: agent.workingDir || officeManager.getCurrentWorkingDirectory(),
|
|
157259
|
+
launchMode: "copilot"
|
|
157260
|
+
};
|
|
157261
|
+
}
|
|
157262
|
+
function refreshRightPanelMode() {
|
|
157263
|
+
const seriousDesktop = appMode === "serious" && currentResponsiveLayout === "default";
|
|
157264
|
+
const desiredOverviewParent = seriousDesktop ? officePanel : terminalPanel;
|
|
157265
|
+
if (overviewHost.parentElement !== desiredOverviewParent) {
|
|
157266
|
+
desiredOverviewParent.appendChild(overviewHost);
|
|
157267
|
+
}
|
|
157268
|
+
if (appMode === "serious") {
|
|
157269
|
+
const seriousVisible = !!seriousTerminalController?.isVisible();
|
|
157270
|
+
if (seriousDesktop) {
|
|
157271
|
+
overviewHost.style.display = "flex";
|
|
157272
|
+
terminalHost.style.display = "flex";
|
|
157273
|
+
seriousPlaceholder.style.display = seriousVisible ? "none" : "flex";
|
|
157274
|
+
return;
|
|
157275
|
+
}
|
|
157276
|
+
if (seriousVisible) {
|
|
157277
|
+
overviewHost.style.display = "none";
|
|
157278
|
+
terminalHost.style.display = "flex";
|
|
157279
|
+
seriousPlaceholder.style.display = "none";
|
|
157280
|
+
return;
|
|
157281
|
+
}
|
|
157282
|
+
overviewHost.style.display = "flex";
|
|
157283
|
+
terminalHost.style.display = "none";
|
|
157284
|
+
seriousPlaceholder.style.display = "none";
|
|
157285
|
+
return;
|
|
157286
|
+
}
|
|
157287
|
+
overviewHost.style.display = "flex";
|
|
157288
|
+
terminalHost.style.display = "none";
|
|
157289
|
+
seriousPlaceholder.style.display = "none";
|
|
157290
|
+
}
|
|
157291
|
+
async function openAgentTerminal(agentId) {
|
|
157292
|
+
if (appMode === "game") {
|
|
157293
|
+
phaserGameRef?.events.emit("open:agent:terminal", agentId);
|
|
157294
|
+
return;
|
|
157295
|
+
}
|
|
157296
|
+
const launchConfig = getSeriousLaunchConfig(agentId);
|
|
157297
|
+
if (!launchConfig || !window.copilotBridge) return;
|
|
157298
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
157299
|
+
const officeStatus = officeManager.getAgentStatus(officeId, agentId);
|
|
157300
|
+
if (officeStatus?.state === "slacking") {
|
|
157301
|
+
officeManager.setAgentStarting(officeId, agentId);
|
|
157302
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
157303
|
+
updateStatusBar();
|
|
157304
|
+
updateTerminalContent();
|
|
157305
|
+
}
|
|
157306
|
+
await seriousTerminalController?.openAgentTerminal({
|
|
157307
|
+
officeId,
|
|
157308
|
+
agentId,
|
|
157309
|
+
...launchConfig
|
|
157310
|
+
});
|
|
157311
|
+
refreshRightPanelMode();
|
|
157312
|
+
}
|
|
157313
|
+
seriousTerminalController = new SeriousTerminalController(terminalHost, {
|
|
157314
|
+
onClose: () => {
|
|
157315
|
+
selectedAgentId = null;
|
|
157316
|
+
refreshRightPanelMode();
|
|
157317
|
+
updateStatusBar();
|
|
157318
|
+
updateTerminalContent();
|
|
157319
|
+
}
|
|
157320
|
+
});
|
|
156100
157321
|
var notificationService = new NotificationService(
|
|
156101
157322
|
toastManager,
|
|
156102
157323
|
(agentId) => {
|
|
@@ -156109,7 +157330,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156109
157330
|
const oId = officeManager.currentOfficeId;
|
|
156110
157331
|
if (oId) officeManager.clearUnread(oId, agentId);
|
|
156111
157332
|
updateTerminalContent();
|
|
156112
|
-
|
|
157333
|
+
void openAgentTerminal(agentId);
|
|
156113
157334
|
}
|
|
156114
157335
|
);
|
|
156115
157336
|
function notifyAgent(agentId, eventType, context) {
|
|
@@ -156158,9 +157379,16 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156158
157379
|
var lastStatusBarHtml = "";
|
|
156159
157380
|
var cachedSessionMeta = {};
|
|
156160
157381
|
function fetchSessionMeta() {
|
|
157382
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
157383
|
+
const cached = getSessionMetaCacheForOffice(officeId);
|
|
157384
|
+
if (Object.keys(cached).length > 0) {
|
|
157385
|
+
cachedSessionMeta = cached;
|
|
157386
|
+
updateTerminalContent();
|
|
157387
|
+
}
|
|
156161
157388
|
if (!window.copilotBridge?.getAllSessionMeta) return;
|
|
156162
|
-
window.copilotBridge.getAllSessionMeta(
|
|
157389
|
+
window.copilotBridge.getAllSessionMeta(officeId).then((meta) => {
|
|
156163
157390
|
cachedSessionMeta = meta || {};
|
|
157391
|
+
setSessionMetaCacheForOffice(officeId, cachedSessionMeta);
|
|
156164
157392
|
updateTerminalContent();
|
|
156165
157393
|
}).catch(() => {
|
|
156166
157394
|
});
|
|
@@ -156169,6 +157397,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156169
157397
|
scheduleTerminalContentUpdate();
|
|
156170
157398
|
}
|
|
156171
157399
|
function updateTerminalContentNow() {
|
|
157400
|
+
syncActiveRosterForCurrentOffice();
|
|
156172
157401
|
const agentTools = getCurrentAgentTools();
|
|
156173
157402
|
const office = officeManager.currentOffice;
|
|
156174
157403
|
const closeBtn = document.getElementById("close-office-btn");
|
|
@@ -156193,47 +157422,135 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156193
157422
|
});
|
|
156194
157423
|
if (html !== lastTerminalContentHtml) {
|
|
156195
157424
|
lastTerminalContentHtml = html;
|
|
156196
|
-
|
|
156197
|
-
|
|
157425
|
+
overviewContent.innerHTML = html;
|
|
157426
|
+
}
|
|
157427
|
+
drawOverviewSprites();
|
|
157428
|
+
if (appMode === "serious") {
|
|
157429
|
+
seriousTerminalController?.refreshCardFromOverview();
|
|
156198
157430
|
}
|
|
156199
157431
|
}
|
|
156200
157432
|
function updateStatusBar() {
|
|
156201
157433
|
scheduleStatusBarUpdate();
|
|
156202
157434
|
}
|
|
156203
|
-
function
|
|
156204
|
-
|
|
156205
|
-
|
|
157435
|
+
function clearOverviewSpriteRetry() {
|
|
157436
|
+
if (overviewSpriteRetryTimer) {
|
|
157437
|
+
clearTimeout(overviewSpriteRetryTimer);
|
|
157438
|
+
overviewSpriteRetryTimer = null;
|
|
157439
|
+
}
|
|
157440
|
+
}
|
|
157441
|
+
function drawCachedOverviewSprite(canvas, textureKey) {
|
|
157442
|
+
const dataUrl = overviewSpriteCache[textureKey];
|
|
157443
|
+
if (!dataUrl) return false;
|
|
157444
|
+
let img = overviewSpriteImageCache.get(textureKey);
|
|
157445
|
+
if (!img || img.src !== dataUrl) {
|
|
157446
|
+
img = new Image();
|
|
157447
|
+
img.src = dataUrl;
|
|
157448
|
+
overviewSpriteImageCache.set(textureKey, img);
|
|
157449
|
+
}
|
|
157450
|
+
const ctx = canvas.getContext("2d");
|
|
157451
|
+
if (!ctx) return true;
|
|
157452
|
+
const drawNow = () => {
|
|
157453
|
+
if (!img) return;
|
|
157454
|
+
ctx.imageSmoothingEnabled = false;
|
|
157455
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
157456
|
+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
157457
|
+
};
|
|
157458
|
+
if (!img.complete || img.naturalWidth === 0) {
|
|
157459
|
+
img.onload = () => drawNow();
|
|
157460
|
+
return true;
|
|
157461
|
+
}
|
|
157462
|
+
drawNow();
|
|
157463
|
+
return true;
|
|
157464
|
+
}
|
|
157465
|
+
function updateOverviewSpriteCacheFromCanvas(canvas, textureKey) {
|
|
157466
|
+
try {
|
|
157467
|
+
const dataUrl = canvas.toDataURL("image/png");
|
|
157468
|
+
if (overviewSpriteCache[textureKey] !== dataUrl) {
|
|
157469
|
+
overviewSpriteCache = { ...overviewSpriteCache, [textureKey]: dataUrl };
|
|
157470
|
+
saveOverviewSpriteCache(overviewSpriteCache);
|
|
157471
|
+
const img = new Image();
|
|
157472
|
+
img.src = dataUrl;
|
|
157473
|
+
overviewSpriteImageCache.set(textureKey, img);
|
|
157474
|
+
}
|
|
157475
|
+
} catch {
|
|
157476
|
+
}
|
|
157477
|
+
}
|
|
157478
|
+
function drawTextureToOverviewCanvas(canvas, textureKey) {
|
|
157479
|
+
if (!phaserGameRef) {
|
|
157480
|
+
return drawCachedOverviewSprite(canvas, textureKey);
|
|
157481
|
+
}
|
|
157482
|
+
const texture = phaserGameRef.textures.get(textureKey);
|
|
157483
|
+
if (!texture || texture.key === "__MISSING") {
|
|
157484
|
+
return drawCachedOverviewSprite(canvas, textureKey);
|
|
157485
|
+
}
|
|
157486
|
+
const source = texture.getSourceImage();
|
|
157487
|
+
if (!source) {
|
|
157488
|
+
return drawCachedOverviewSprite(canvas, textureKey);
|
|
157489
|
+
}
|
|
157490
|
+
const ctx = canvas.getContext("2d");
|
|
157491
|
+
if (!ctx) return true;
|
|
157492
|
+
const sourceWidth = source instanceof HTMLImageElement ? source.naturalWidth || source.width : source.width;
|
|
157493
|
+
const sourceHeight = source instanceof HTMLImageElement ? source.naturalHeight || source.height : source.height;
|
|
157494
|
+
ctx.imageSmoothingEnabled = false;
|
|
157495
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
157496
|
+
if (sourceWidth > canvas.width || sourceHeight > canvas.height) {
|
|
157497
|
+
ctx.drawImage(source, 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
|
|
157498
|
+
} else {
|
|
157499
|
+
ctx.drawImage(source, 0, 0);
|
|
157500
|
+
}
|
|
157501
|
+
updateOverviewSpriteCacheFromCanvas(canvas, textureKey);
|
|
157502
|
+
return true;
|
|
157503
|
+
}
|
|
157504
|
+
function prewarmOverviewSpriteCacheFromTextures() {
|
|
157505
|
+
if (!phaserGameRef) return;
|
|
157506
|
+
const textureKeys = getCurrentAgents().map((agent) => agent.sprite);
|
|
157507
|
+
if (!textureKeys.includes("desktop_pc")) textureKeys.push("desktop_pc");
|
|
157508
|
+
for (const textureKey of textureKeys) {
|
|
157509
|
+
const texture = phaserGameRef.textures.get(textureKey);
|
|
157510
|
+
if (!texture || texture.key === "__MISSING") continue;
|
|
157511
|
+
const source = texture.getSourceImage();
|
|
157512
|
+
if (!source) continue;
|
|
157513
|
+
const scratch = document.createElement("canvas");
|
|
157514
|
+
scratch.width = textureKey === "desktop_pc" ? 32 : 32;
|
|
157515
|
+
scratch.height = textureKey === "desktop_pc" ? 32 : 34;
|
|
157516
|
+
const ctx = scratch.getContext("2d");
|
|
157517
|
+
if (!ctx) continue;
|
|
157518
|
+
const sourceWidth = source instanceof HTMLImageElement ? source.naturalWidth || source.width : source.width;
|
|
157519
|
+
const sourceHeight = source instanceof HTMLImageElement ? source.naturalHeight || source.height : source.height;
|
|
157520
|
+
ctx.imageSmoothingEnabled = false;
|
|
157521
|
+
ctx.clearRect(0, 0, scratch.width, scratch.height);
|
|
157522
|
+
if (sourceWidth > scratch.width || sourceHeight > scratch.height) {
|
|
157523
|
+
ctx.drawImage(source, 0, 0, scratch.width, scratch.height, 0, 0, scratch.width, scratch.height);
|
|
157524
|
+
} else {
|
|
157525
|
+
ctx.drawImage(source, 0, 0);
|
|
157526
|
+
}
|
|
157527
|
+
updateOverviewSpriteCacheFromCanvas(scratch, textureKey);
|
|
157528
|
+
}
|
|
157529
|
+
}
|
|
157530
|
+
function drawOverviewSprites(attempt = 0) {
|
|
157531
|
+
clearOverviewSpriteRetry();
|
|
157532
|
+
requestAnimationFrame(() => {
|
|
157533
|
+
let missingTexture = false;
|
|
156206
157534
|
for (const agent of getCurrentAgents()) {
|
|
156207
157535
|
const canvas = document.getElementById(`overview-sprite-${agent.id}`);
|
|
156208
157536
|
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
|
-
}
|
|
157537
|
+
const drawn = drawTextureToOverviewCanvas(canvas, agent.sprite);
|
|
157538
|
+
if (!drawn) missingTexture = true;
|
|
156219
157539
|
}
|
|
156220
157540
|
const pcCanvas = document.getElementById("overview-sprite-pc-terminal");
|
|
156221
157541
|
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
|
-
}
|
|
157542
|
+
const drawn = drawTextureToOverviewCanvas(pcCanvas, "desktop_pc");
|
|
157543
|
+
if (!drawn) missingTexture = true;
|
|
156232
157544
|
}
|
|
156233
|
-
|
|
157545
|
+
if (missingTexture && phaserGameRef && attempt < OVERVIEW_SPRITE_MAX_RETRY_ATTEMPTS) {
|
|
157546
|
+
overviewSpriteRetryTimer = setTimeout(() => {
|
|
157547
|
+
drawOverviewSprites(attempt + 1);
|
|
157548
|
+
}, OVERVIEW_SPRITE_RETRY_DELAY_MS);
|
|
157549
|
+
}
|
|
157550
|
+
});
|
|
156234
157551
|
}
|
|
156235
157552
|
function setupTerminalClickHandler() {
|
|
156236
|
-
|
|
157553
|
+
overviewHost.addEventListener("click", (e) => {
|
|
156237
157554
|
const target = e.target;
|
|
156238
157555
|
const layout = getLayout(getCurrentLayout());
|
|
156239
157556
|
const metaPanel = target.closest(".session-meta-panel");
|
|
@@ -156242,7 +157559,10 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156242
157559
|
const agentId = metaPanel.dataset.agent;
|
|
156243
157560
|
if (!agentId) return;
|
|
156244
157561
|
layout.clickHandler.handleMetaPanelClick(target, agentId, {
|
|
156245
|
-
startSessionMetaEdit
|
|
157562
|
+
startSessionMetaEdit,
|
|
157563
|
+
startNewSession: (id) => {
|
|
157564
|
+
void startSessionFromOverview(id);
|
|
157565
|
+
}
|
|
156246
157566
|
});
|
|
156247
157567
|
return;
|
|
156248
157568
|
}
|
|
@@ -156260,21 +157580,58 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156260
157580
|
},
|
|
156261
157581
|
updateContent: updateTerminalContent,
|
|
156262
157582
|
emitOpenTerminal: (id) => {
|
|
156263
|
-
|
|
157583
|
+
void openAgentTerminal(id);
|
|
156264
157584
|
}
|
|
156265
157585
|
});
|
|
156266
157586
|
}
|
|
156267
157587
|
});
|
|
156268
157588
|
}
|
|
157589
|
+
async function startSessionFromOverview(agentId) {
|
|
157590
|
+
if (!window.copilotBridge) return;
|
|
157591
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
157592
|
+
const launchConfig = getSeriousLaunchConfig(agentId);
|
|
157593
|
+
if (!launchConfig) return;
|
|
157594
|
+
cachedSessionMeta[agentId] = { title: "" };
|
|
157595
|
+
setSessionMetaCacheForOffice(officeId, cachedSessionMeta);
|
|
157596
|
+
updateTerminalContent();
|
|
157597
|
+
try {
|
|
157598
|
+
if (appMode === "serious" && seriousTerminalController) {
|
|
157599
|
+
await seriousTerminalController.startNewSession({
|
|
157600
|
+
officeId,
|
|
157601
|
+
agentId,
|
|
157602
|
+
...launchConfig
|
|
157603
|
+
});
|
|
157604
|
+
} else {
|
|
157605
|
+
await window.copilotBridge.resetSession(officeId, agentId);
|
|
157606
|
+
await window.copilotBridge.terminalStart(
|
|
157607
|
+
officeId,
|
|
157608
|
+
agentId,
|
|
157609
|
+
launchConfig.workingDir,
|
|
157610
|
+
void 0,
|
|
157611
|
+
void 0,
|
|
157612
|
+
void 0,
|
|
157613
|
+
launchConfig.launchMode
|
|
157614
|
+
);
|
|
157615
|
+
}
|
|
157616
|
+
} catch (error) {
|
|
157617
|
+
console.warn(`[Office] Failed to start new session from overview for ${agentId}:`, error);
|
|
157618
|
+
}
|
|
157619
|
+
officeManager.setAgentStarting(officeId, agentId);
|
|
157620
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
157621
|
+
updateStatusBar();
|
|
157622
|
+
updateTerminalContent();
|
|
157623
|
+
}
|
|
156269
157624
|
function startSessionMetaEdit(agentId) {
|
|
156270
|
-
const panel =
|
|
157625
|
+
const panel = overviewHost.querySelector(`.session-meta-panel[data-agent="${agentId}"]`);
|
|
156271
157626
|
if (!panel) return;
|
|
156272
157627
|
const meta = cachedSessionMeta[agentId] || { title: "" };
|
|
156273
157628
|
const titleEl = panel.querySelector(".session-title-display");
|
|
156274
157629
|
if (titleEl) {
|
|
156275
157630
|
replaceWithInput(titleEl, meta.title, "Session title...", 80, async (value) => {
|
|
156276
|
-
|
|
157631
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
157632
|
+
await window.copilotBridge.setSessionMeta(officeId, agentId, { title: value });
|
|
156277
157633
|
cachedSessionMeta[agentId] = { title: value };
|
|
157634
|
+
setSessionMetaCacheForOffice(officeId, cachedSessionMeta);
|
|
156278
157635
|
updateTerminalContent();
|
|
156279
157636
|
});
|
|
156280
157637
|
}
|
|
@@ -156347,7 +157704,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156347
157704
|
console.log(`[Office] Status: ${agentId} \u2192 thinking (${toolName})`);
|
|
156348
157705
|
notifyAgent(agentId, "toolStart", { toolName });
|
|
156349
157706
|
}
|
|
156350
|
-
|
|
157707
|
+
phaserGameRef?.events.emit("agent:tool:start", agentId, toolName, status);
|
|
156351
157708
|
updateTerminalContent();
|
|
156352
157709
|
updateStatusBar();
|
|
156353
157710
|
});
|
|
@@ -156366,7 +157723,12 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156366
157723
|
officeManager.pushRecentAction(officeId, agentId, completedToolName, "completed");
|
|
156367
157724
|
notifyAgent(agentId, "toolComplete", { toolName: completedToolName });
|
|
156368
157725
|
if (remaining.length === 0) {
|
|
156369
|
-
officeManager.
|
|
157726
|
+
const currentStatus = officeManager.getAgentStatus(officeId, agentId);
|
|
157727
|
+
if (currentStatus?.subState === "thinking") {
|
|
157728
|
+
officeManager.setAgentThinking(officeId, agentId, currentStatus.thinkingDetail ?? "Processing...");
|
|
157729
|
+
} else {
|
|
157730
|
+
officeManager.setAgentReady(officeId, agentId);
|
|
157731
|
+
}
|
|
156370
157732
|
} else if (remaining.some((t) => isAskUserTool(t.name, t.status))) {
|
|
156371
157733
|
officeManager.setAgentWaiting(officeId, agentId);
|
|
156372
157734
|
} else {
|
|
@@ -156374,7 +157736,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156374
157736
|
officeManager.setAgentThinking(officeId, agentId, `${last.name}`);
|
|
156375
157737
|
}
|
|
156376
157738
|
}
|
|
156377
|
-
|
|
157739
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156378
157740
|
updateTerminalContent();
|
|
156379
157741
|
updateStatusBar();
|
|
156380
157742
|
});
|
|
@@ -156396,7 +157758,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156396
157758
|
}
|
|
156397
157759
|
notifyAgent(agentId, "turnEnd");
|
|
156398
157760
|
}
|
|
156399
|
-
|
|
157761
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156400
157762
|
updateTerminalContent();
|
|
156401
157763
|
updateStatusBar();
|
|
156402
157764
|
});
|
|
@@ -156413,7 +157775,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156413
157775
|
officeManager.setAgentThinking(officeId, agentId, "Processing...");
|
|
156414
157776
|
console.log(`[Office] Status: ${agentId} \u2192 thinking (turn start)`);
|
|
156415
157777
|
notifyAgent(agentId, "turnStart");
|
|
156416
|
-
|
|
157778
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156417
157779
|
updateTerminalContent();
|
|
156418
157780
|
updateStatusBar();
|
|
156419
157781
|
});
|
|
@@ -156428,12 +157790,14 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156428
157790
|
}
|
|
156429
157791
|
officeManager.setAgentThinking(officeId, agentId, "Processing...");
|
|
156430
157792
|
console.log(`[Office] Status: ${agentId} \u2192 thinking (user message)`);
|
|
156431
|
-
|
|
157793
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156432
157794
|
updateTerminalContent();
|
|
156433
157795
|
});
|
|
156434
157796
|
window.copilotBridge.onSessionMetaUpdated((agentId, meta) => {
|
|
156435
157797
|
console.log(`[Office] Session meta updated for ${agentId}: "${meta.title}"`);
|
|
157798
|
+
const officeId = officeManager.currentOfficeId || "office-0";
|
|
156436
157799
|
cachedSessionMeta[agentId] = meta;
|
|
157800
|
+
setSessionMetaCacheForOffice(officeId, cachedSessionMeta);
|
|
156437
157801
|
updateTerminalContent();
|
|
156438
157802
|
});
|
|
156439
157803
|
window.copilotBridge.onTerminalPreloadStatus((agentId, status) => {
|
|
@@ -156459,17 +157823,45 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156459
157823
|
notifyAgent(agentId, "sessionError");
|
|
156460
157824
|
}
|
|
156461
157825
|
}
|
|
156462
|
-
|
|
157826
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156463
157827
|
updateStatusBar();
|
|
156464
157828
|
updateTerminalContent();
|
|
156465
157829
|
});
|
|
156466
157830
|
}
|
|
156467
157831
|
var syncInProgress = false;
|
|
156468
|
-
|
|
156469
|
-
|
|
157832
|
+
var syncStartedAt = 0;
|
|
157833
|
+
var SYNC_LOCK_TIMEOUT_MS = 15e3;
|
|
157834
|
+
var STALE_IN_TURN_THINKING_TIMEOUT_MS = 9e4;
|
|
157835
|
+
var THINKING_TO_READY_GRACE_MS = 7e3;
|
|
157836
|
+
var SYNC_WAIT_POLL_MS = 50;
|
|
157837
|
+
async function waitForSyncIdle(timeoutMs = SYNC_LOCK_TIMEOUT_MS) {
|
|
157838
|
+
const startedAt = Date.now();
|
|
157839
|
+
while (syncInProgress && Date.now() - startedAt < timeoutMs) {
|
|
157840
|
+
await new Promise((resolve) => setTimeout(resolve, SYNC_WAIT_POLL_MS));
|
|
157841
|
+
}
|
|
157842
|
+
}
|
|
157843
|
+
async function syncAgentStatuses(force = false) {
|
|
157844
|
+
if (!window.copilotBridge) return;
|
|
157845
|
+
if (syncInProgress) {
|
|
157846
|
+
if (force) {
|
|
157847
|
+
await waitForSyncIdle();
|
|
157848
|
+
if (syncInProgress) {
|
|
157849
|
+
console.warn(`[Office] syncAgentStatuses lock held for >${SYNC_LOCK_TIMEOUT_MS / 1e3}s during forced sync \u2014 force-releasing`);
|
|
157850
|
+
syncInProgress = false;
|
|
157851
|
+
}
|
|
157852
|
+
} else {
|
|
157853
|
+
if (syncStartedAt && Date.now() - syncStartedAt > SYNC_LOCK_TIMEOUT_MS) {
|
|
157854
|
+
console.warn(`[Office] syncAgentStatuses lock held for >${SYNC_LOCK_TIMEOUT_MS / 1e3}s \u2014 force-releasing`);
|
|
157855
|
+
syncInProgress = false;
|
|
157856
|
+
} else {
|
|
157857
|
+
return;
|
|
157858
|
+
}
|
|
157859
|
+
}
|
|
157860
|
+
}
|
|
156470
157861
|
const officeId = officeManager.currentOfficeId;
|
|
156471
157862
|
if (!officeId) return;
|
|
156472
157863
|
syncInProgress = true;
|
|
157864
|
+
syncStartedAt = Date.now();
|
|
156473
157865
|
try {
|
|
156474
157866
|
const statuses = await window.copilotBridge.queryAgentStatuses(officeId);
|
|
156475
157867
|
let changed = false;
|
|
@@ -156480,6 +157872,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156480
157872
|
const current = officeManager.getAgentStatus(officeId, agent.id);
|
|
156481
157873
|
const activeTools = getCurrentAgentTools().get(agent.id) || [];
|
|
156482
157874
|
const waitingToolActive = activeTools.some((t) => isAskUserTool(t.name, t.status));
|
|
157875
|
+
const thinkingSince = current?.subState === "thinking" ? current.activityStartTime : null;
|
|
157876
|
+
const thinkingAgeMs = thinkingSince ? now - thinkingSince : null;
|
|
157877
|
+
const staleInTurnThinking = Boolean(
|
|
157878
|
+
current?.subState === "thinking" && thinkingSince && now - thinkingSince > STALE_IN_TURN_THINKING_TIMEOUT_MS && activeTools.length === 0
|
|
157879
|
+
);
|
|
156483
157880
|
if (current?.subState === "starting" && current.activityStartTime && now - current.activityStartTime > STARTING_TIMEOUT_MS) {
|
|
156484
157881
|
console.warn(`[Office] Agent ${agent.id} stuck in starting for >${STARTING_TIMEOUT_MS / 1e3}s \u2014 transitioning to error`);
|
|
156485
157882
|
officeManager.setAgentError(officeId, agent.id, "Startup timed out");
|
|
@@ -156494,7 +157891,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156494
157891
|
changed = true;
|
|
156495
157892
|
}
|
|
156496
157893
|
} else if (serverStatus.inTurn) {
|
|
156497
|
-
if (
|
|
157894
|
+
if (staleInTurnThinking) {
|
|
157895
|
+
console.warn(`[Office] Agent ${agent.id} stale inTurn for >${STALE_IN_TURN_THINKING_TIMEOUT_MS / 1e3}s \u2014 resetting to ready`);
|
|
157896
|
+
officeManager.setAgentReady(officeId, agent.id);
|
|
157897
|
+
changed = true;
|
|
157898
|
+
} else if (!current || current.subState !== "thinking" && current.subState !== "waiting") {
|
|
156498
157899
|
officeManager.setTaskSummary(officeId, agent.id, "Processing...");
|
|
156499
157900
|
officeManager.setAgentThinking(officeId, agent.id, "Processing...");
|
|
156500
157901
|
changed = true;
|
|
@@ -156506,6 +157907,9 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156506
157907
|
officeManager.setAgentReady(officeId, agent.id);
|
|
156507
157908
|
changed = true;
|
|
156508
157909
|
} else if (current.subState === "thinking" && !serverStatus.inTurn) {
|
|
157910
|
+
if (thinkingAgeMs !== null && thinkingAgeMs < THINKING_TO_READY_GRACE_MS) {
|
|
157911
|
+
continue;
|
|
157912
|
+
}
|
|
156509
157913
|
console.warn(`[Office] Agent ${agent.id} stuck in thinking but server reports idle \u2014 resetting to ready`);
|
|
156510
157914
|
const agentTools = getCurrentAgentTools();
|
|
156511
157915
|
if (agentTools.has(agent.id)) {
|
|
@@ -156529,7 +157933,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156529
157933
|
}
|
|
156530
157934
|
if (changed) {
|
|
156531
157935
|
for (const agent of getCurrentAgents()) {
|
|
156532
|
-
|
|
157936
|
+
phaserGameRef?.events.emit("agent:status:changed", agent.id);
|
|
156533
157937
|
}
|
|
156534
157938
|
updateTerminalContent();
|
|
156535
157939
|
updateStatusBar();
|
|
@@ -156549,8 +157953,27 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156549
157953
|
pendingTerminalContentUpdate = false;
|
|
156550
157954
|
updateStatusBarNow();
|
|
156551
157955
|
updateTerminalContentNow();
|
|
157956
|
+
drawOverviewSprites();
|
|
156552
157957
|
phaserGameRef?.events.emit("agent:status:changed");
|
|
156553
|
-
void
|
|
157958
|
+
void reconnectAgentStatuses();
|
|
157959
|
+
}
|
|
157960
|
+
async function reconnectAgentStatuses() {
|
|
157961
|
+
if (!window.copilotBridge) return;
|
|
157962
|
+
const officeId = officeManager.currentOfficeId;
|
|
157963
|
+
if (!officeId) return;
|
|
157964
|
+
await waitForSyncIdle();
|
|
157965
|
+
try {
|
|
157966
|
+
const statuses = await window.copilotBridge.queryAgentStatuses(officeId);
|
|
157967
|
+
for (const [agentId, info] of Object.entries(statuses)) {
|
|
157968
|
+
if (info.alive) {
|
|
157969
|
+
await window.copilotBridge.terminalAttach(officeId, agentId).catch(() => {
|
|
157970
|
+
});
|
|
157971
|
+
}
|
|
157972
|
+
}
|
|
157973
|
+
} catch (e) {
|
|
157974
|
+
console.warn("[Office] Failed to reconnect agent viewers:", e);
|
|
157975
|
+
}
|
|
157976
|
+
await syncAgentStatuses(true);
|
|
156554
157977
|
}
|
|
156555
157978
|
var ELAPSED_TICK_MS = 1e3;
|
|
156556
157979
|
setInterval(() => {
|
|
@@ -156579,6 +158002,7 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156579
158002
|
}
|
|
156580
158003
|
}, ELAPSED_TICK_MS);
|
|
156581
158004
|
function updateStatusBarNow() {
|
|
158005
|
+
syncActiveRosterForCurrentOffice();
|
|
156582
158006
|
const office = officeManager.currentOffice;
|
|
156583
158007
|
const agents = office ? Array.from(office.agents.values()) : [];
|
|
156584
158008
|
const officeName = officeManager.currentOffice?.config.name || "No Office";
|
|
@@ -156610,6 +158034,17 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156610
158034
|
cursor: pointer;
|
|
156611
158035
|
margin-right: 24px;
|
|
156612
158036
|
">\u27F3 Reset All Sessions</button>
|
|
158037
|
+
<button id="reconnect-statuses-btn" style="
|
|
158038
|
+
background: #1a2a2a;
|
|
158039
|
+
border: 1px solid #4a8;
|
|
158040
|
+
color: #8f8;
|
|
158041
|
+
font-family: monospace;
|
|
158042
|
+
font-size: 14px;
|
|
158043
|
+
padding: 4px 16px;
|
|
158044
|
+
border-radius: 4px;
|
|
158045
|
+
cursor: pointer;
|
|
158046
|
+
margin-right: 24px;
|
|
158047
|
+
">\u{1F50C} Re-connect Statuses</button>
|
|
156613
158048
|
<span style="color: #666; font-size: 10px;">WASD: Walk | Shift: Run | Space: Talk | F10: Close terminal</span>
|
|
156614
158049
|
`;
|
|
156615
158050
|
if (html !== lastStatusBarHtml) {
|
|
@@ -156629,60 +158064,37 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156629
158064
|
btn.textContent = "\u27F3 Reset All Sessions";
|
|
156630
158065
|
}
|
|
156631
158066
|
});
|
|
158067
|
+
document.getElementById("reconnect-statuses-btn")?.addEventListener("click", async () => {
|
|
158068
|
+
const btn = document.getElementById("reconnect-statuses-btn");
|
|
158069
|
+
if (btn) {
|
|
158070
|
+
btn.disabled = true;
|
|
158071
|
+
btn.textContent = "\u{1F50C} Reconnecting...";
|
|
158072
|
+
}
|
|
158073
|
+
await reconnectAgentStatuses();
|
|
158074
|
+
if (btn) {
|
|
158075
|
+
btn.disabled = false;
|
|
158076
|
+
btn.textContent = "\u{1F50C} Re-connect Statuses";
|
|
158077
|
+
}
|
|
158078
|
+
});
|
|
156632
158079
|
}
|
|
156633
158080
|
}
|
|
156634
|
-
updateStatusBar();
|
|
156635
158081
|
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) => {
|
|
158082
|
+
function onAgentSessionClosed(agentId) {
|
|
156670
158083
|
const officeId = officeManager.currentOfficeId;
|
|
156671
158084
|
if (officeId) officeManager.setAgentSlacking(officeId, agentId);
|
|
156672
|
-
|
|
158085
|
+
phaserGameRef?.events.emit("agent:status:changed", agentId);
|
|
156673
158086
|
updateTerminalContent();
|
|
156674
158087
|
updateStatusBar();
|
|
156675
|
-
}
|
|
156676
|
-
|
|
158088
|
+
}
|
|
158089
|
+
function onAgentStatusChanged() {
|
|
156677
158090
|
updateTerminalContent();
|
|
156678
158091
|
updateStatusBar();
|
|
156679
|
-
}
|
|
156680
|
-
|
|
158092
|
+
}
|
|
158093
|
+
function onAgentReattached(agentId) {
|
|
156681
158094
|
console.log(`[Office] Agent reattached: ${agentId}`);
|
|
156682
|
-
syncAgentStatuses();
|
|
156683
|
-
}
|
|
156684
|
-
|
|
156685
|
-
phaserGame.events.on("fleet:office:created", async (officeId, sourceOfficeId) => {
|
|
158095
|
+
void syncAgentStatuses();
|
|
158096
|
+
}
|
|
158097
|
+
async function onFleetOfficeCreated(officeId, sourceOfficeId) {
|
|
156686
158098
|
console.log(`[Office] Fleet V-Team office created: ${officeId} (source: ${sourceOfficeId ?? "none"})`);
|
|
156687
158099
|
if (sourceOfficeId && window.copilotBridge?.transferSession) {
|
|
156688
158100
|
try {
|
|
@@ -156693,11 +158105,11 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156693
158105
|
}
|
|
156694
158106
|
}
|
|
156695
158107
|
if (sourceOfficeId) {
|
|
156696
|
-
|
|
158108
|
+
phaserGameRef?.events.emit("fleet:source-office", { sourceOfficeId });
|
|
156697
158109
|
}
|
|
156698
158110
|
switchToOffice(officeId);
|
|
156699
|
-
}
|
|
156700
|
-
|
|
158111
|
+
}
|
|
158112
|
+
async function onFleetDeployRequested(data) {
|
|
156701
158113
|
console.log(`[Fleet] Deploy requested: "${data.officeName}" from office ${data.sourceOfficeId}`);
|
|
156702
158114
|
const fleetOffice = officeManager.createOffice(data.officeName, ".", "fleet-vteam");
|
|
156703
158115
|
const officeId = fleetOffice.config.id;
|
|
@@ -156713,24 +158125,96 @@ WARNING: This link could potentially be dangerous`)) {
|
|
|
156713
158125
|
console.warn("[Fleet] copilotBridge.transferSession not available");
|
|
156714
158126
|
}
|
|
156715
158127
|
data.resolve?.();
|
|
156716
|
-
|
|
158128
|
+
phaserGameRef?.events.emit("fleet:source-office", { sourceOfficeId: data.sourceOfficeId, prompt: data.prompt });
|
|
156717
158129
|
switchToOffice(officeId);
|
|
156718
|
-
}
|
|
156719
|
-
|
|
158130
|
+
}
|
|
158131
|
+
function onFleetStatus(status) {
|
|
156720
158132
|
const subtitle = document.getElementById("terminal-subtitle");
|
|
156721
158133
|
if (subtitle && officeManager.currentOffice?.config.layout === "fleet-vteam") {
|
|
156722
158134
|
subtitle.textContent = `Fleet: ${status.active} active \xB7 ${status.completed} done \xB7 ${status.failed} failed / ${status.total} total`;
|
|
156723
158135
|
}
|
|
156724
158136
|
updateTerminalContent();
|
|
156725
|
-
}
|
|
156726
|
-
|
|
158137
|
+
}
|
|
158138
|
+
function onFleetComplete() {
|
|
156727
158139
|
console.log("[Fleet] All sub-agents complete");
|
|
156728
158140
|
const subtitle = document.getElementById("terminal-subtitle");
|
|
156729
158141
|
if (subtitle) {
|
|
156730
158142
|
subtitle.textContent = "\u2705 Fleet complete!";
|
|
156731
158143
|
}
|
|
156732
158144
|
updateTerminalContent();
|
|
158145
|
+
}
|
|
158146
|
+
var officePanelListenersBound = false;
|
|
158147
|
+
function bindOfficePanelListeners() {
|
|
158148
|
+
if (officePanelListenersBound) return;
|
|
158149
|
+
officePanelListenersBound = true;
|
|
158150
|
+
officePanel.addEventListener("click", () => {
|
|
158151
|
+
const canvas = officePanel.querySelector("canvas");
|
|
158152
|
+
canvas?.focus();
|
|
158153
|
+
});
|
|
158154
|
+
officePanel.addEventListener("mousedown", () => {
|
|
158155
|
+
if (isMobileModeActive()) return;
|
|
158156
|
+
console.log("[main] game panel mousedown \u2014 emitting game:panel:clicked");
|
|
158157
|
+
phaserGameRef?.events.emit("game:panel:clicked");
|
|
158158
|
+
});
|
|
158159
|
+
}
|
|
158160
|
+
function getPhaserDimensions() {
|
|
158161
|
+
return {
|
|
158162
|
+
width: officePanel.clientWidth || window.innerWidth / 2,
|
|
158163
|
+
height: officePanel.clientHeight || window.innerHeight
|
|
158164
|
+
};
|
|
158165
|
+
}
|
|
158166
|
+
function bindPhaserEventListeners(game) {
|
|
158167
|
+
game.events.once("ready", () => {
|
|
158168
|
+
drawOverviewSprites();
|
|
158169
|
+
game.events.emit("layout:change", { layoutKey: currentResponsiveLayout });
|
|
158170
|
+
});
|
|
158171
|
+
game.events.on("agent:session:closed", onAgentSessionClosed);
|
|
158172
|
+
game.events.on("agent:status:changed", onAgentStatusChanged);
|
|
158173
|
+
game.events.on("agent:reattached", onAgentReattached);
|
|
158174
|
+
game.events.on("bgm:started", onBgmStarted);
|
|
158175
|
+
game.events.on("fleet:office:created", onFleetOfficeCreated);
|
|
158176
|
+
game.events.on("fleet:deploy-requested", onFleetDeployRequested);
|
|
158177
|
+
game.events.on("fleet:status", onFleetStatus);
|
|
158178
|
+
game.events.on("fleet:complete", onFleetComplete);
|
|
158179
|
+
}
|
|
158180
|
+
function ensurePhaserGame() {
|
|
158181
|
+
if (phaserGameRef) return;
|
|
158182
|
+
const { width, height } = getPhaserDimensions();
|
|
158183
|
+
const game = new import_phaser10.default.Game({
|
|
158184
|
+
type: import_phaser10.default.AUTO,
|
|
158185
|
+
parent: officePanel,
|
|
158186
|
+
width,
|
|
158187
|
+
height,
|
|
158188
|
+
backgroundColor: "#1a1a2e",
|
|
158189
|
+
physics: { default: "arcade", arcade: { debug: false } },
|
|
158190
|
+
scene: [BootScene, OfficeScene, MeetingScene]
|
|
158191
|
+
});
|
|
158192
|
+
phaserGameRef = game;
|
|
158193
|
+
bindPhaserEventListeners(game);
|
|
158194
|
+
}
|
|
158195
|
+
function teardownPhaserGame() {
|
|
158196
|
+
if (!phaserGameRef) return;
|
|
158197
|
+
const game = phaserGameRef;
|
|
158198
|
+
phaserGameRef = void 0;
|
|
158199
|
+
try {
|
|
158200
|
+
game.destroy(true);
|
|
158201
|
+
} catch (error) {
|
|
158202
|
+
console.warn("[main] Failed to destroy Phaser game cleanly:", error);
|
|
158203
|
+
}
|
|
158204
|
+
officePanel.innerHTML = "";
|
|
158205
|
+
}
|
|
158206
|
+
bindOfficePanelListeners();
|
|
158207
|
+
window.addEventListener("focus", () => {
|
|
158208
|
+
catchUpStatusViews("window focus");
|
|
158209
|
+
});
|
|
158210
|
+
document.addEventListener("visibilitychange", () => {
|
|
158211
|
+
if (!document.hidden) {
|
|
158212
|
+
catchUpStatusViews("document visible");
|
|
158213
|
+
}
|
|
156733
158214
|
});
|
|
158215
|
+
syncActiveRosterForCurrentOffice();
|
|
158216
|
+
applyAppMode(appMode, { force: true, refreshTabs: false });
|
|
158217
|
+
fetchSessionMeta();
|
|
156734
158218
|
}
|
|
156735
158219
|
});
|
|
156736
158220
|
return require_main();
|