Commit Graph
4 Commits
Author SHA1 Message Date
Nam Pham Dinh ThanhandClaude Opus 5 c77ce36191 refactor(shell): R08-T10 — bootstrap + tách TrayManager và LifecycleCoordinator
app.py 1356 -> 1293 dòng. presentation/shell/ có 3 file:

  bootstrap.py               Composition Root (đã vào ở commit trước)
  tray_manager.py            khay hệ thống + thông báo bong bóng
  lifecycle_coordinator.py   canh cửa sổ theo màn hình + tắt cho sạch

Vì sao tách khay: khay là thứ CÓ THỂ KHÔNG TỒN TẠI (một số môi trường Linux,
phiên RDP). Trước đây mỗi chỗ dùng phải tự nhớ kiểm `if self.tray is not None`
— có 6 chỗ như thế, và 3 chỗ còn phải tự bọc try/except quanh showMessage.
Gói lại thì chỗ gọi cứ gọi, không có khay thì không có gì xảy ra.

Vì sao tách vòng đời: hai việc trong đó không phải việc của giao diện. Canh
cửa sổ theo màn hình là số học thuần (anh Nam có hai màn khác độ phân giải và
khác tỉ lệ phóng — kéo qua lại là vùng làm việc đổi). Còn shutdown là thứ tự
dừng có ý nghĩa: bộ lập lịch trước để nó không kịp khởi động việc mới trong
lúc ta đang dừng việc cũ, rồi mới tới worker, rồi ngắt tiến trình MCP.

closeEvent/moveEvent/resizeEvent vẫn ở lớp cửa sổ vì Qt gọi thẳng vào đó,
nhưng phần quyết định đã chuyển đi. closeEvent từ 30 dòng còn 11.

Giữ self.tray thành property trỏ vào self._tray.icon — vài chỗ còn đọc tên cũ.

Đã lấy mốc trước khi bóc rồi so lại sau: 24/24 checker trong tools/ qua cả hai
lần. Đây là bộ đặc tả thật cho MainWindow (check_nav, check_rail_align,
check_layout_geometry, check_controls_alive... dựng cửa sổ thật offscreen trên
BẢN SAO của ~/.cowork_local, scheduler bị vô hiệu hoá). 632 test xanh.

CHƯA làm hết R08-T10: plan ghi tách thành main_window.py + tray_manager.py +
lifecycle_coordinator.py. Hai file sau đã xong, main_window.py thì chưa —
MainWindow vẫn nằm trong app.py và vẫn 1095 dòng. Đo lại thì khối lượng không
nằm ở ba cụm plan nêu mà ở hai cụm khác:

    nav rail    18 method, ~340 dòng
    topbar      8 method,  ~157 dòng
    __init__    279 dòng

Hai cụm đó dính chặt vào state của cửa sổ, chuyển đi cần đổi giao diện giữa
chúng chứ không phải dời chỗ, nên tôi dừng ở đây thay vì làm nửa vời.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 19:56:37 +09:00
Nam Pham Dinh ThanhandClaude Opus 5 2246d55286 feat(infra): R02 vào thật — app chạy bằng JsonConfigRepository, khoá rời khỏi config.json
Từ 21/08 tôi đã viết xong 7 file R02 với 46 test xanh, và báo là "xong R02".
Báo sai: code mới nằm song song, KHÔNG một dòng nào ngoài infrastructure/ và
tests/ gọi tới nó. App vẫn chạy nguyên trên config.py, 29 file dùng nó, và
khoá API của người dùng vẫn nằm plaintext trong config.json suốt 4 ngày.

Commit này mới là phần refactor thật.

Bù 21 thành viên còn thiếu (85 dòng)
------------------------------------
JsonConfigRepository có 18/34 thành viên công khai của AppConfig nên không
tráo được. Chép nguyên ngữ nghĩa 21 cái còn lại: load, ms365_*, ext_connectors,
connect_external, routing_mode_for, seeded_*, mcp_servers, teams, history,
structure, monitoring_visibility, model_label, ca_bundle... Giờ 40/34, không
thiếu gì. Không phải thiết kế mới — chừng nào 29 file còn gọi qua ctx.config
thì repository phải trả lời được đúng các câu hỏi cũ.

ROUTING_MODES lấy theo bản Delta (4 chế độ, có "fallback" từ R03-T03) chứ
không theo bản main cũ 3 chế độ. Chép bản cũ là routing "fallback" âm thầm rơi
về "off" sau khi Delta merge, không lỗi nào báo.

Composition Root (R08-T10, phần đầu)
-------------------------------------
presentation/shell/bootstrap.py: một chỗ duy nhất quyết định app dựng bằng
mảnh nào. app.py::run giờ gọi build_context() thay cho AppConfig.load().
Đây cũng là chỗ ráp kho bí mật vào; máy không có keyring thì secrets=None và
mọi thứ chạy như cũ.

Kiểm trên dữ liệu thật
----------------------
Chạy lên máy tôi, migration tự chạy đúng như thiết kế:

  openai_compat  39 ký tự  config.json -> Windows Credential Manager
  ollama         giá trị bù nhìn, để nguyên trong file, không đẩy vào kho
  schema_version 1 -> 2
  sao lưu        config.json.v20260825-193206.bak

Sau khi bật lại app và để nó ghi cấu hình, config.json vẫn sạch: api_key rỗng,
không còn chuỗi nào có hình dạng khoá. scripts/audit_security.py sạch.

Tiêu chí nghiệm thu A của plan (dòng 244) — "0 lưu trữ plaintext API Key trong
JSON" — tới commit này mới thật sự đạt.

632 test xanh. check_dialogs, check_nav, check_design_parity đều qua.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 19:35:44 +09:00
1419587401 Feature/fsg gamma team ui fix (#3)
CI / test (push) Canceled after 0s
## Summary

What changed and why?

## Change Type

- [ ] Cowork feature
- [ ] Bug fix
- [x] Core AI contribution
- [ ] Test / hardening
- [ ] Performance
- [ ] Documentation

## Related Work

Cowork Task:

Core Repo: http://34.143.229.138/gitea-admin/fsg-ai-core-assets

Core AI Issue:

Core Task:

Related PR:

## Scope

What is intentionally included?

What is intentionally NOT included?

## Validation

- [ ] Unit tests
- [ ] Integration tests
- [ ] Manual verification
- [ ] Regression check

Commands / evidence:

## Security Impact

Permission / credential / network / customer data impact:

## Compatibility

- [ ] No breaking change
- [ ] Breaking change documented

## Reviewer Notes

Anything Cowork reviewers should pay attention to.

---------

Co-authored-by: Hiep Ha Van <hiephv3@fpt.com>
Co-authored-by: Nam Pham Dinh Thanh <nampdt@fpt.com>
Co-authored-by: Lam Hoang Van <lamhv7@fpt.com>
Co-authored-by: NamPDT <minhanhpkpro@gmail.com>
Reviewed-on: #3
2026-08-20 12:12:56 +00:00
thanhnv 414eaddca3 chore(repo): initialize Cowork Local Gitea repository
CI / test (push) Canceled after 0s
2026-08-09 20:12:05 +07:00