Feature/delta team/epic r04 #7
@@ -29,14 +29,35 @@ infrastructure/ (Adapters, LLM Providers, Atomic Persistence, Keyring SecretStor
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### 1. Run the Desktop Application
|
||||
From the repository root:
|
||||
### 1. Windows — two double-clicks
|
||||
|
||||
```
|
||||
install.bat once, to install the Python dependencies
|
||||
run.bat every time, to start the app
|
||||
```
|
||||
|
||||
`install.bat` builds an isolated virtualenv under `%LOCALAPPDATA%\CoworkLocal`
|
||||
(deliberately **outside** the repo — the quality gates walk the whole directory
|
||||
tree, so a `.venv` in here would turn every vendored module into a Gate O
|
||||
violation). Add `--dev` to also install the test dependencies, or `--system` to
|
||||
skip the virtualenv and install into the Python already on `PATH`.
|
||||
|
||||
Both scripts also make the source importable under its package name. That step
|
||||
is not optional: `python -m cowork_local` only resolves when the checkout
|
||||
directory is literally named `cowork_local`, and the MS365 MCP server is
|
||||
launched as a subprocess with `python -m cowork_local.mcp_servers.ms365_server`,
|
||||
so a differently-named checkout breaks the app *and* its subprocesses. The
|
||||
scripts create a junction instead of forcing anyone to rename their folder.
|
||||
|
||||
### 2. Any platform — run from source
|
||||
|
||||
From the **parent** of a checkout directory named `cowork_local`:
|
||||
|
||||
```bash
|
||||
python -m cowork_local
|
||||
```
|
||||
|
||||
### 2. Run Automated Tests
|
||||
### 3. Run Automated Tests
|
||||
```bash
|
||||
python -m pip install -r requirements-test.txt
|
||||
pytest -q
|
||||
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
@echo off
|
||||
rem ===========================================================================
|
||||
rem Cowork-Local BamBOO - cai dat thu vien Python (chay MOT lan)
|
||||
rem
|
||||
rem Cach dung:
|
||||
rem install.bat cai vao moi truong ao rieng (khuyen dung)
|
||||
rem install.bat --dev cai them thu vien de chay test
|
||||
rem install.bat --system cai thang vao Python dang co, khong dung venv
|
||||
rem install.bat --force dung lai moi truong ao tu dau
|
||||
rem
|
||||
rem Cai gi va cai o dau:
|
||||
rem %LOCALAPPDATA%\CoworkLocal\venv moi truong ao
|
||||
rem %LOCALAPPDATA%\CoworkLocal\launcher lien ket de import duoc goi
|
||||
rem
|
||||
rem Vi sao KHONG dat venv trong repo: cac cong chat luong
|
||||
rem (scripts/check_orphan_modules.py, check_imports.py) quet TOAN BO cay thu
|
||||
rem muc chu khong doc .gitignore, nen mot thu muc .venv o day se bien vai nghin
|
||||
rem module cua thu vien thanh "ma production khong ai import" va lam cong do.
|
||||
rem ===========================================================================
|
||||
setlocal EnableExtensions EnableDelayedExpansion
|
||||
chcp 65001 >nul 2>&1
|
||||
|
||||
set "REPO=%~dp0"
|
||||
set "REPO=%REPO:~0,-1%"
|
||||
set "APPHOME=%LOCALAPPDATA%\CoworkLocal"
|
||||
set "VENV=%APPHOME%\venv"
|
||||
set "LAUNCHER=%APPHOME%\launcher"
|
||||
|
||||
set "DEV=0"
|
||||
set "USE_SYSTEM=0"
|
||||
set "FORCE=0"
|
||||
|
||||
:parse_args
|
||||
if "%~1"=="" goto args_done
|
||||
if /I "%~1"=="--dev" set "DEV=1" & shift & goto parse_args
|
||||
if /I "%~1"=="--system" set "USE_SYSTEM=1" & shift & goto parse_args
|
||||
if /I "%~1"=="--force" set "FORCE=1" & shift & goto parse_args
|
||||
if /I "%~1"=="-h" goto usage
|
||||
if /I "%~1"=="--help" goto usage
|
||||
echo [LOI] Khong hieu tham so: %~1
|
||||
goto usage
|
||||
:args_done
|
||||
|
||||
echo.
|
||||
echo ===========================================================================
|
||||
echo Cowork-Local BamBOO — cài đặt
|
||||
echo ===========================================================================
|
||||
echo Mã nguồn : %REPO%
|
||||
echo Cài vào : %APPHOME%
|
||||
echo.
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
rem 1. Tim Python
|
||||
rem
|
||||
rem Uu tien "py -3" chu khong phai "python": tren Windows 11, python.exe trong
|
||||
rem WindowsApps thuong chi la lien ket mo Microsoft Store chu khong phai
|
||||
rem Python that.
|
||||
rem --------------------------------------------------------------------------
|
||||
set "PY="
|
||||
py -3 -c "import sys" >nul 2>&1 && set "PY=py -3"
|
||||
if not defined PY (
|
||||
python -c "import sys" >nul 2>&1 && set "PY=python"
|
||||
)
|
||||
if not defined PY (
|
||||
echo [LỖI] Không tìm thấy Python trên máy này.
|
||||
echo Cài Python 3.11 trở lên từ https://www.python.org/downloads/
|
||||
echo và nhớ tích "Add python.exe to PATH" khi cài.
|
||||
goto fail
|
||||
)
|
||||
|
||||
for /f "delims=" %%V in ('%PY% -c "import sys;print('%%d.%%d'%%sys.version_info[:2])" 2^>nul') do set "PYVER=%%V"
|
||||
echo [1/5] Python %PYVER% (%PY%)
|
||||
|
||||
%PY% -c "import sys;raise SystemExit(0 if sys.version_info>=(3,11) else 1)" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo [LỖI] Cần Python 3.11 trở lên, máy đang có %PYVER%.
|
||||
goto fail
|
||||
)
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
rem 2. Moi truong ao
|
||||
rem --------------------------------------------------------------------------
|
||||
if "%USE_SYSTEM%"=="1" (
|
||||
echo [2/5] Bỏ qua môi trường ảo — cài thẳng vào Python đang có ^(--system^)
|
||||
set "PIP=%PY% -m pip"
|
||||
goto deps
|
||||
)
|
||||
|
||||
if "%FORCE%"=="1" if exist "%VENV%" (
|
||||
echo [2/5] Xoá môi trường ảo cũ...
|
||||
rmdir /s /q "%VENV%" 2>nul
|
||||
)
|
||||
|
||||
if exist "%VENV%\Scripts\python.exe" (
|
||||
echo [2/5] Môi trường ảo đã có — dùng lại
|
||||
) else (
|
||||
echo [2/5] Tạo môi trường ảo...
|
||||
%PY% -m venv "%VENV%"
|
||||
if errorlevel 1 (
|
||||
echo [LỖI] Không tạo được môi trường ảo.
|
||||
echo Thử lại với: install.bat --system
|
||||
goto fail
|
||||
)
|
||||
)
|
||||
set "PIP="%VENV%\Scripts\python.exe" -m pip"
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
rem 3. Cai thu vien
|
||||
rem --------------------------------------------------------------------------
|
||||
:deps
|
||||
echo [3/5] Cập nhật pip...
|
||||
%PIP% install --disable-pip-version-check --quiet --upgrade pip
|
||||
if errorlevel 1 echo ^(bỏ qua — pip cũ vẫn dùng được^)
|
||||
|
||||
echo [3/5] Cài thư viện từ requirements.txt ^(PySide6 khá nặng, chờ vài phút^)...
|
||||
%PIP% install --disable-pip-version-check -r "%REPO%\requirements.txt"
|
||||
if errorlevel 1 (
|
||||
echo [LỖI] Cài thư viện thất bại.
|
||||
echo Nếu máy qua proxy công ty, đặt biến môi trường HTTPS_PROXY rồi chạy lại.
|
||||
goto fail
|
||||
)
|
||||
|
||||
if "%DEV%"=="1" (
|
||||
echo [3/5] Cài thêm thư viện chạy test ^(--dev^)...
|
||||
%PIP% install --disable-pip-version-check -r "%REPO%\requirements-test.txt"
|
||||
if errorlevel 1 (
|
||||
echo [LỖI] Cài thư viện test thất bại.
|
||||
goto fail
|
||||
)
|
||||
)
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
rem 4. Lien ket de goi import duoc dung ten
|
||||
rem
|
||||
rem Ma nguon phai import duoc duoi dung ten "cowork_local". Thu muc nay ten la
|
||||
rem "%~nx0"'s parent — neu no khong phai "cowork_local" thi ca
|
||||
rem "python -m cowork_local" lan "python __main__.py" deu bao
|
||||
rem ModuleNotFoundError, va tien trinh con chay may chu MCP MS365
|
||||
rem (state.py: python -m cowork_local.mcp_servers.ms365_server) cung hong theo.
|
||||
rem
|
||||
rem Junction giai quyet ca hai ma khong phai doi ten thu muc lam viec, khong
|
||||
rem phai sua mot dong code nao, va khong can quyen quan tri.
|
||||
rem --------------------------------------------------------------------------
|
||||
for %%I in ("%REPO%") do set "REPO_NAME=%%~nxI"
|
||||
if /I "%REPO_NAME%"=="cowork_local" (
|
||||
echo [4/5] Thư mục đã đúng tên "cowork_local" — không cần liên kết
|
||||
goto smoke
|
||||
)
|
||||
|
||||
if not exist "%LAUNCHER%" mkdir "%LAUNCHER%" >nul 2>&1
|
||||
if exist "%LAUNCHER%\cowork_local" rmdir "%LAUNCHER%\cowork_local" >nul 2>&1
|
||||
mklink /J "%LAUNCHER%\cowork_local" "%REPO%" >nul
|
||||
if errorlevel 1 (
|
||||
echo [LỖI] Không tạo được liên kết thư mục.
|
||||
echo Thư mục "%REPO_NAME%" không phải tên gói Python hợp lệ nên
|
||||
echo ứng dụng không import được chính nó. Cách khác: đổi tên thư mục
|
||||
echo mã nguồn thành "cowork_local".
|
||||
goto fail
|
||||
)
|
||||
echo [4/5] Đã tạo liên kết: %LAUNCHER%\cowork_local
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
rem 5. Chay thu mot lan
|
||||
rem --------------------------------------------------------------------------
|
||||
:smoke
|
||||
if "%USE_SYSTEM%"=="1" (set "RUNPY=%PY%") else (set "RUNPY="%VENV%\Scripts\python.exe"")
|
||||
if /I "%REPO_NAME%"=="cowork_local" (
|
||||
for %%I in ("%REPO%\..") do set "PKGPATH=%%~fI"
|
||||
) else (
|
||||
set "PKGPATH=%LAUNCHER%"
|
||||
)
|
||||
|
||||
echo [5/5] Kiểm tra lại...
|
||||
set "PYTHONPATH=!PKGPATH!"
|
||||
%RUNPY% -c "import cowork_local, PySide6; print(' cowork_local + PySide6 nạp được')"
|
||||
if errorlevel 1 (
|
||||
echo [LỖI] Cài xong nhưng vẫn chưa import được gói.
|
||||
goto fail
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ===========================================================================
|
||||
echo XONG. Từ giờ chỉ cần bấm đúp vào run.bat
|
||||
echo ===========================================================================
|
||||
echo.
|
||||
pause
|
||||
exit /b 0
|
||||
|
||||
:usage
|
||||
echo.
|
||||
echo install.bat [--dev] [--system] [--force]
|
||||
echo.
|
||||
echo --dev cài thêm thư viện để chạy test ^(pytest, pydantic^)
|
||||
echo --system cài thẳng vào Python đang có, không tạo môi trường ảo
|
||||
echo --force xoá môi trường ảo cũ rồi tạo lại từ đầu
|
||||
echo.
|
||||
pause
|
||||
exit /b 2
|
||||
|
||||
:fail
|
||||
echo.
|
||||
echo Cài đặt KHÔNG thành công. Xem thông báo lỗi ở trên.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
+18
-1
@@ -21,4 +21,21 @@ msal>=1.24.0 # OAuth device-code flow for MS365
|
||||
keyring>=24.0.0 # OS credential store (token cache)
|
||||
|
||||
# --- MCP (Model Context Protocol) ---
|
||||
mcp>=1.0.0 # MCP client SDK (stdio transport)
|
||||
mcp>=1.0.0 # MCP client SDK (stdio transport)
|
||||
|
||||
# --- Bắt buộc: import KHÔNG có try/except, thiếu là app chết lúc khởi động ---
|
||||
# Hai dòng dưới đây bị bỏ sót cho tới 30/08. Triệu chứng của việc thiếu chúng
|
||||
# không phải "tính năng đó không chạy" mà là ModuleNotFoundError ngay khi dựng
|
||||
# cửa sổ chính — cài đúng theo requirements.txt xong app vẫn không mở được.
|
||||
pygments>=2.15.0 # tô màu cú pháp — presentation/folder/code_editor.py
|
||||
pydantic>=2,<3 # kiểu dữ liệu định tuyến — core/routing/models.py
|
||||
|
||||
# --- Tuỳ chọn: mỗi chỗ dùng đều bọc try/except, thiếu thì mất tính năng ---
|
||||
# Vẫn cài mặc định vì đều nhẹ và đều là tính năng người dùng nhìn thấy được.
|
||||
networkx>=3.0 # bố cục đồ thị đẹp hơn cho GraphRAG nhiều node
|
||||
holidays>=0.40 # lịch nghỉ theo quốc gia cho màn Lịch task
|
||||
pywin32>=306; sys_platform == "win32" # Office -> PDF, thông báo Outlook
|
||||
|
||||
# opendataloader-pdf # bộ đọc PDF thay thế — KHÔNG cài sẵn có chủ ý:
|
||||
# # application/workspaces/graph_index_service.py tự cài
|
||||
# # khi cần, qua core/deps.py::ensure_module.
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
@echo off
|
||||
rem ===========================================================================
|
||||
rem Cowork-Local BamBOO - chay ung dung
|
||||
rem
|
||||
rem Bam dup vao file nay la xong.
|
||||
rem
|
||||
rem Lan dau tien phai chay install.bat truoc.
|
||||
rem
|
||||
rem Tham so truyen vao duoc chuyen thang cho QApplication (xem app.py::run),
|
||||
rem nen dung duoc cac co cua Qt, vi du: run.bat -style Fusion
|
||||
rem ===========================================================================
|
||||
setlocal EnableExtensions EnableDelayedExpansion
|
||||
chcp 65001 >nul 2>&1
|
||||
title Cowork-Local BamBOO
|
||||
|
||||
set "REPO=%~dp0"
|
||||
set "REPO=%REPO:~0,-1%"
|
||||
set "APPHOME=%LOCALAPPDATA%\CoworkLocal"
|
||||
set "VENV=%APPHOME%\venv"
|
||||
set "LAUNCHER=%APPHOME%\launcher"
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
rem 1. Chon trinh thong dich
|
||||
rem
|
||||
rem Uu tien moi truong ao do install.bat dung. Khong co thi quay ve Python cua
|
||||
rem he thong — nguoi dung co the da chay "install.bat --system".
|
||||
rem --------------------------------------------------------------------------
|
||||
rem Duong dan luon duoc boc trong dau nhay: %LOCALAPPDATA% co the chua khoang
|
||||
rem trang neu ten dang nhap co khoang trang.
|
||||
if exist "%VENV%\Scripts\python.exe" (
|
||||
set "RUNPY="%VENV%\Scripts\python.exe""
|
||||
) else (
|
||||
set "RUNPY="
|
||||
for /f "delims=" %%P in ('where py 2^>nul') do if not defined RUNPY set "RUNPY="%%P" -3"
|
||||
if not defined RUNPY (
|
||||
for /f "delims=" %%P in ('where python 2^>nul') do if not defined RUNPY set "RUNPY="%%P""
|
||||
)
|
||||
)
|
||||
|
||||
if not defined RUNPY (
|
||||
echo.
|
||||
echo [LỖI] Không tìm thấy Python. Chạy install.bat trước đã.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
rem Chua co moi truong ao thi kiem xem Python he thong co du thu vien khong.
|
||||
rem Khong kiem thi nguoi dung chi nhan duoc mot ModuleNotFoundError tho, chang
|
||||
rem biet la phai chay install.bat.
|
||||
if not exist "%VENV%\Scripts\python.exe" (
|
||||
!RUNPY! -c "import PySide6" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo [LỖI] Thư viện chưa được cài. Chạy install.bat trước đã.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
rem 2. Duong dan de import duoc goi "cowork_local"
|
||||
rem
|
||||
rem Thu muc ma nguon phai mang dung ten "cowork_local" thi Python moi import
|
||||
rem duoc no. Neu khong, install.bat da tao mot junction; o day chi kiem tra va
|
||||
rem tu dung lai neu no bi xoa — de nguoi dung khong phai chay lai install.bat
|
||||
rem chi vi mot thu muc tam bi don.
|
||||
rem --------------------------------------------------------------------------
|
||||
for %%I in ("%REPO%") do set "REPO_NAME=%%~nxI"
|
||||
if /I "%REPO_NAME%"=="cowork_local" (
|
||||
for %%I in ("%REPO%\..") do set "PKGPATH=%%~fI"
|
||||
) else (
|
||||
if not exist "%LAUNCHER%\cowork_local" (
|
||||
if not exist "%LAUNCHER%" mkdir "%LAUNCHER%" >nul 2>&1
|
||||
mklink /J "%LAUNCHER%\cowork_local" "%REPO%" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo [LỖI] Không tạo được liên kết thư mục. Chạy install.bat lại.
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
set "PKGPATH=%LAUNCHER%"
|
||||
)
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
rem 3. Chay
|
||||
rem
|
||||
rem Dat thu muc lam viec o goc ma nguon va PYTHONPATH tro toi thu muc CHA cua
|
||||
rem goi — dung cach CI dang chay (.gitea/workflows/ci.yaml). Tien trinh con
|
||||
rem (may chu MCP MS365) thua ke PYTHONPATH nay nen cung import duoc.
|
||||
rem --------------------------------------------------------------------------
|
||||
if defined PYTHONPATH (
|
||||
set "PYTHONPATH=!PKGPATH!;%PYTHONPATH%"
|
||||
) else (
|
||||
set "PYTHONPATH=!PKGPATH!"
|
||||
)
|
||||
set "PYTHONIOENCODING=utf-8"
|
||||
cd /d "%REPO%"
|
||||
|
||||
!RUNPY! -m cowork_local %*
|
||||
set "RC=%ERRORLEVEL%"
|
||||
|
||||
if not "%RC%"=="0" (
|
||||
echo.
|
||||
echo Ứng dụng thoát với mã lỗi %RC%. Xem thông báo ở trên.
|
||||
echo.
|
||||
pause
|
||||
)
|
||||
exit /b %RC%
|
||||
Reference in New Issue
Block a user