13 Commits

Author SHA1 Message Date
CatJuly 2584c45644 fix(ui): bind delete-project dialog to theme tokens so paper theme is readable
The confirm dialog painted its panel with `var(--bg-surface, #1e1e2e)`, but
`--bg-surface` is not defined by any stylesheet in the project. Every theme
therefore fell through to the hardcoded dark `#1e1e2e`.

That went unnoticed under the six dark themes, whose `--text` is light and so
still contrasted against the dark panel. The paper theme is the only light
palette: its `--text` is `#1e293b`, which put dark text on the dark panel at
roughly 1.05:1 contrast and made the title and body invisible.

Point the panel at `--bg-elevated` so it tracks the active palette, and give
the title and body explicit `--text` / `--text-secondary` colors instead of
relying on inherited color plus `opacity: 0.7`, which is equally unreliable
over a light surface. Add a `--border` outline so the now-white panel still
reads as a distinct layer above the scrim.

Verified by hand across all seven themes.
2026-08-05 17:21:40 +08:00
LZH-YS1998 2df564d9e9 Merge PR #9: harden company resume, external sessions, and Office UI i18n
Merges xiaodong-l's hardening work: company suspend-checkpoint resume
reconciliation, external session token lifecycle fixes, Windows launch
shims, codex shell_environment_policy forwarding, Office UI i18n
(en/zh-CN), and two org presets. frontend_dist is rebuilt from the
merged sources in this commit so the #11 runtime-status fixes and the
i18n bundle coexist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

# Conflicts:
#	opc/plugins/office_ui/frontend_dist/assets/index-BgyI65M_.js
#	opc/plugins/office_ui/frontend_dist/index.html
2026-07-21 15:34:28 +08:00
LZH-YS1998 0c6925402c fix(ui): reconcile runtime status so stale chips converge without a refresh (#11)
Live status deltas are one-shot best-effort broadcasts: a delta lost to a
disconnect window, a project-scope drop, or a not-ready store left the UI
stuck on a stale status ("thinking" vs stopped) until a hard refresh, which
rebuilds from the always-correct snapshot. Close the class, not the sites:

- Add a low-frequency runtime_status_sync reconciliation broadcast: every
  12s (lazily started, cancelled on shutdown) re-broadcast the persisted
  status + in-memory tracker state of every task with a live runtime, plus
  one final tick for tasks that just ended. Candidates come purely from
  in-memory registries (no table scans); idle system pays nothing.
- Frontend consumes it diff-before-dispatch: a tick where nothing drifted
  triggers zero store updates and zero re-renders; clearing mirrors the
  mergeLiveRuntimeField semantics already used by collab_sync.
- Fix the EventAdapter tracker state machine: tool_completed returns to
  REFLECTING (the turn is still running), and turn_completed/turn_failed
  now transition to IDLE and emit an authoritative idle runtime update.
- Guarantee the terminal board_task_status_changed in _run_session_task's
  finally: a cancelled run previously skipped it, leaving the board on
  "running". The fallback mirrors persisted state read-only.

Verified: 7 new tests in test_runtime_status_sync.py; 236 backend tests
pass with zero new failures; tsc clean; frontend structural tests pass;
dist rebuilt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 12:54:46 +08:00
小东 cb6b8ed6e1 feat: harden company resume, external sessions, and Office UI i18n
Improve suspend/resume identity continuity and external broker session handling, add Office UI internationalization with rebuilt assets, and expand company org configs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 09:20:40 +08:00
LZH-YS1998 5938b4c215 fix(ui): stabilize company chat result topology 2026-07-14 20:31:10 +08:00
LZH-YS1998 b8202bbe9e fix: unify company runtime recovery lifecycle 2026-07-14 14:35:43 +08:00
LZH-YS1998 4bc18dcd27 fix(ui): stabilize workplace chat scrolling 2026-07-13 23:02:39 +08:00
LZH-YS1998 a0402522da fix(office-ui): stop progress-row flicker and surface native role replies end to end
Two user-visible defects in company mode, root-caused via project 6666/8888
DB forensics:

Progress-row flicker (thinking preview appearing/disappearing): progress
entries were broadcast to clients before reaching the persistence buffer,
so a tool_call-triggered session_detail snapshot rebuilt from the DB erased
freshly streamed entries from the live log. Buffer now fills before the
broadcast and session_detail flushes it before reading.

Native role transcripts incomplete (thinking only at start, no narration,
no final summary — external agents unaffected):
- thinking deltas shared one stream id per conversation turn while seq
  reset per iteration, collapsing all iterations into one entry and
  silently dropping live thinking from iteration 2 on; now keyed per
  iteration like assistant deltas
- assistant_delta events were mapped to None; company mode now surfaces
  them as streaming 'assistant' progress entries (rendered as Reply cards,
  merged like thinking, excluded from inline chat rows)
- thinking was persisted one row per token, flooding the 1000-entry cap
  and evicting interleaved tool history; append_progress now folds
  streaming deltas per (type, turn, stream) with seq dedup
- the terminal company turn was hidden at summary detail and, worse, its
  id-keyed backfill merge kept the first-inserted intermediate content, so
  the final reply never reached any channel; terminal turns are now
  flagged company_final_turn, visible at summary detail, and carry their
  own ui_message_id so they insert as fresh rows
- appendProgressEntry applied its seq guard against unrelated entries when
  the stream key was absent from the log, killing the first delta of any
  fresh stream; the guard now only applies within the same stream

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 20:46:14 +08:00
LZH-YS1998 e3bed49811 perf(office-ui): stop per-token full-tree renders, sleep hidden Phaser loop, cut broadcast churn
Company-mode UIs became unusably slow once work items and transcripts
grew. Three presentation-layer fixes, none touching work progression:

- App.tsx: buffer assistant_delta/thinking_delta store writes per task
  and flush every 80ms instead of once per token; any non-delta event
  for the same task flushes first so draft/clearDraft ordering is
  byte-identical. The unconditional per-event setUiTick (whole-app
  re-render per websocket event) is now a 300ms trailing throttle.
- PhaserGame: display:none does not stop requestAnimationFrame, so the
  office scene kept burning CPU on every other page. The loop now
  sleeps when the office page is hidden and wakes (with a parent-bounds
  refresh) on return; bridge writes stay synchronous so no state is lost.
- Kanban collab_sync debounce 0.2s -> 1.5s: the broadcaster is a
  trailing coalescer, so the final board state still always ships; each
  fire is a full-project snapshot build, which at 5/s dominated backend
  CPU on large projects. CommsPanel poll 8s -> 30s (comms_state_dirty
  push already drives freshness) and its interval no longer pins a
  stale onRefresh closure.

Verified: tsc + vite build, App.test.tsx / workItemSessions structural
tests, backend suites (company_review_flow incl. debounce push test,
kanban_push_runtime, actor_runtime_company_mode, task_mode_contract,
work_item_transition — 119 green), and canvas_smoke e2e against a real
server with zero console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 16:36:39 +08:00
LZH-YS1998 3a2c935025 fix: deduplicate re-delivered session sends on the client message id
Typed-3-shown-5 forensics (project 000): the WS client queues session_send
payloads while disconnected and flushes the queue after a reconnect, and the
server minted a fresh row id per delivery — so one typed message could land
as several user turns, each dispatched to the engine.

Every send now carries a client-generated ui_message_id (dispatchSessionSend
injects one when the caller didn't). The handler persists the user row under
that id and answers any later delivery in the same channel with an idempotent
ack instead of inserting and dispatching again. Because the row id now equals
the optimistic bubble's ui_message_id, the echo also merges with the local
message even after the transcript sync rewrites row metadata.

Same text intentionally sent again gets a fresh id and still starts a new turn.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 22:47:00 +08:00
LZH-YS1998 12817a4e60 fix(office-ui): native progress parity, ui_state lock hardening, approval-card idempotency
Native agent progress panel (company mode):
- ws_handler: filter runtime bookkeeping noise (turn/status/member_inbox_updated),
  keep tool_completed as tool_call, thinking summary previews content,
  preserve raw thinking_delta fragments (no strip; skip whitespace-only)
- frontend progressLog: summarize thinking by content preview; merge thinking
  by detail only so the 'Thinking' label never splices into text
- AgentProgressBlock: add bottom "Show more (N earlier steps)" toggle

ui_state.db "database is locked" hardening:
- ws_handler: isolate engine progress/kanban/runtime-event callbacks so UI
  persistence failures never crash work items
- chat_store: busy_timeout, _retry_locked backoff, idempotent insert_message
  (INSERT OR REPLACE), create_channel read-before-write to stop poll writes
- server: flock single-instance guard for `opc ui` per OPC home

Approval card duplicate-click bug:
- EscalationPanel: disable buttons on click with Submitting state and 30s
  reconnect fallback
- ws_handler: stale-escalation branch checks real card status (new
  chat_store.get_checkpoint_message); already-resolved cards get an accurate
  "already handled (decision: X)" reply without being re-marked stale;
  dedup identical helper messages within 120s to stop reply spam

Company mode prompt:
- add soft guidance that the runtime monitors state and re-activates roles,
  so leaders need not poll work items after delegation/review

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 16:18:01 +08:00
LZH-YS1998 ee79331d48 fix(office-ui): resolve blank/frozen office canvas and add sidebar collapse
Office canvas fixes:
- Lazy-create the Phaser game via ResizeObserver on the first non-zero
  layout instead of creating it inside the display:none office page with
  inline px fallback sizes. Phaser's RESIZE-mode 500ms parent poll has no
  zero guard, so the old path shrank the canvas to 0x0 (blue-black screen)
  and later restored it to a stale wrong size (clipped office).
- On unhide, re-measure with scale.getParentBounds() before scale.refresh();
  plain scale.resize() is clobbered by the stale cached parentSize in
  RESIZE mode.
- Fix whole-game freeze when clicking an office card: camera effects
  resolve ease names via EaseMap, which has no 'Cubic.Out' key, leaving
  effect.ease undefined and killing the RAF loop with a per-frame
  TypeError. Use 'Cubic.easeOut' for cam.pan in panToOffice/resetCameraView.
- Bound GameBridge queues (latest snapshot supersedes, event queue capped)
  since game creation is now deferred until the Office page is first opened.

Sidebar:
- Add a collapse/expand handle on the canvas/sidebar boundary with a 220ms
  grid transition; state persists in localStorage. The canvas follows the
  column change automatically through the ResizeObserver path. Stacked
  (<=1024px) layout collapses the bottom panel and moves the handle to the
  bottom edge.

README:
- Add Simplified Chinese translation (README.zh-CN.md) with a language
  switcher in both files; fix stale TOC entries in the English README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:47:04 +08:00
LZH-YS1998 d78931979d Initial commit 2026-07-01 17:56:31 +08:00