Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
ASSET_ALLOWED_EXTS = {".png", ".webp", ".jpg", ".jpeg", ".gif", ".svg", ".avif"}
ASSET_TEMPLATE_ZIP = os.path.join(ROOT_DIR, "assets-replace-template.zip")
WORKSPACE_DIR = os.path.dirname(ROOT_DIR)
OPENCLAW_WORKSPACE = os.environ.get("OPENCLAW_WORKSPACE") or os.path.join(os.path.expanduser("~"), ".openclaw", "workspace")
IDENTITY_FILE = os.path.join(OPENCLAW_WORKSPACE, "IDENTITY.md")
GEMINI_SCRIPT = os.path.join(WORKSPACE_DIR, "skills", "gemini-image-generate", "scripts", "gemini_image_generate.py")
GEMINI_PYTHON = os.path.join(WORKSPACE_DIR, "skills", "gemini-image-generate", ".venv", "bin", "python")
ROOM_REFERENCE_IMAGE = (
Expand Down Expand Up @@ -199,6 +201,22 @@ def load_state():
return state


def get_office_name_from_identity():
"""Read office display name from OpenClaw workspace IDENTITY.md (Name field) -> 'XXX的办公室'."""
if not os.path.isfile(IDENTITY_FILE):
return None
try:
with open(IDENTITY_FILE, "r", encoding="utf-8") as f:
content = f.read()
m = re.search(r"-\s*\*\*Name:\*\*\s*(.+)", content)
if m:
name = m.group(1).strip().replace("\r", "").split("\n")[0].strip()
return f"{name}的办公室" if name else None
except Exception:
pass
return None


def save_state(state: dict):
"""Save state to file"""
with open(STATE_FILE, "w", encoding="utf-8") as f:
Expand Down Expand Up @@ -1127,8 +1145,11 @@ def leave_agent():

@app.route("/status", methods=["GET"])
def get_status():
"""Get current main state (backward compatibility)"""
"""Get current main state (backward compatibility). Optionally include officeName from IDENTITY.md."""
state = load_state()
office_name = get_office_name_from_identity()
if office_name:
state["officeName"] = office_name
return jsonify(state)


Expand Down
6 changes: 5 additions & 1 deletion frontend/electron-standalone.html
Original file line number Diff line number Diff line change
Expand Up @@ -1874,7 +1874,7 @@

function t(key) { return (I18N[uiLang] && I18N[uiLang][key]) || key; }
function getOfficePlaqueTitle() {
return officePlaqueCustomTitle || t('officeTitle');
return (window.officeNameFromServer || officePlaqueCustomTitle || t('officeTitle'));
}
function refreshOfficePlaqueTitle() {
const el = document.getElementById('office-plaque-text');
Expand Down Expand Up @@ -5474,6 +5474,10 @@
.then(response => response.json())
.then(data => {
try {
if (data.officeName) {
window.officeNameFromServer = data.officeName;
refreshOfficePlaqueTitle();
}
const nextState = normalizeState(data.state);
const stateInfo = STATES[nextState] || STATES.idle;
// If we're mid-transition, don't restart the path every poll
Expand Down
14 changes: 11 additions & 3 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1459,8 +1459,9 @@
if (memoTitle) memoTitle.textContent = t('memoTitle');
const guestTitle = document.getElementById('guest-agent-panel-title');
if (guestTitle) guestTitle.textContent = t('guestTitle');
const plaqueTitle = (typeof window.officeNameFromServer !== 'undefined' && window.officeNameFromServer) || t('officeTitle');
if (window.officePlaqueText && window.officePlaqueText.setText) {
window.officePlaqueText.setText(t('officeTitle'));
window.officePlaqueText.setText(plaqueTitle);
}

const coordsBtn = document.getElementById('coords-toggle');
Expand Down Expand Up @@ -4091,7 +4092,9 @@
fontWeight: '900',
fontStyle: 'bold',
stroke: '#000',
strokeThickness: 3
strokeThickness: 3,
wordWrap: { width: 400 },
align: 'center'
}).setOrigin(0.5);
// 牌匾两边加个小装饰(跟随牌匾居中)
game.add.text(plaqueX - 190, plaqueY, '⭐', { fontFamily: 'ArkPixel, monospace', fontSize: '20px' }).setOrigin(0.5);
Expand Down Expand Up @@ -4664,7 +4667,12 @@
.then(response => response.json())
.then(data => {
try {

if (data.officeName) {
window.officeNameFromServer = data.officeName;
if (window.officePlaqueText && window.officePlaqueText.setText) {
window.officePlaqueText.setText(data.officeName);
}
}
const nextState = normalizeState(data.state);
const stateInfo = STATES[nextState] || STATES.idle;
// If we're mid-transition, don't restart the path every poll
Expand Down