Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7d223673e |
@@ -6,20 +6,23 @@ The Cowork Team owns this product and its stable branch. The FSG AI Core Team co
|
|||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
The imported application is a Python/PySide6 package. Run it from the directory that contains `cowork_local`:
|
Install the Python/PySide6 desktop application into an isolated environment:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m cowork_local
|
./scripts/install_local.sh
|
||||||
|
./scripts/run_local.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
The source snapshot does not include a complete runtime dependency manifest. Use the Cowork Team's supported runtime environment until that packaging contract is documented. The reliable automated test surface currently checked by CI is:
|
The installer also creates `~/.local/bin/cowork-local` when that path is available. See [docs/installation.md](docs/installation.md) for prerequisites, configuration, verification, optional document tooling, and platform limitations.
|
||||||
|
|
||||||
|
The reliable automated test surface checked by CI is:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m pip install -r cowork_local/requirements-test.txt
|
python -m pip install -r cowork_local/requirements-test.txt
|
||||||
python -m pytest cowork_local/tests -q
|
python -m pytest cowork_local/tests -q
|
||||||
```
|
```
|
||||||
|
|
||||||
When already inside this repository, run `python -m pytest tests -q`.
|
When already inside this repository, run `.venv/bin/python -m pytest tests -q`.
|
||||||
|
|
||||||
Configuration and runtime data live under `~/.cowork_local/`. Provider keys and local unlock codes must be supplied through environment variables or an approved secret manager; see `.env.example`.
|
Configuration and runtime data live under `~/.cowork_local/`. Provider keys and local unlock codes must be supplied through environment variables or an approved secret manager; see `.env.example`.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
# Installation Record — 2026-08-11
|
||||||
|
|
||||||
|
This record captures the successful local source installation performed on an Apple Silicon macOS host. It contains no credentials or machine-specific home-directory path.
|
||||||
|
|
||||||
|
## Environment
|
||||||
|
|
||||||
|
```text
|
||||||
|
Architecture: arm64
|
||||||
|
Python: 3.11.15
|
||||||
|
Installer: uv 0.11.8
|
||||||
|
Virtual environment: <repository>/.venv
|
||||||
|
Launcher: ~/.local/bin/cowork-local
|
||||||
|
Installed size: approximately 1.3 GB
|
||||||
|
```
|
||||||
|
|
||||||
|
## Steps executed
|
||||||
|
|
||||||
|
From the repository root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git switch -c chore/local-installation
|
||||||
|
./scripts/install_local.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The installer selected Homebrew Python 3.11, created `.venv`, installed the runtime and test requirement sets, and created the user launcher without replacing any existing path.
|
||||||
|
|
||||||
|
Key resolved packages:
|
||||||
|
|
||||||
|
```text
|
||||||
|
PySide6==6.11.1
|
||||||
|
anyio==4.14.2
|
||||||
|
holidays==0.102
|
||||||
|
keyring==25.7.0
|
||||||
|
mcp==1.29.0
|
||||||
|
msal==1.37.0
|
||||||
|
networkx==3.6.1
|
||||||
|
openpyxl==3.1.5
|
||||||
|
psutil==7.2.2
|
||||||
|
pydantic==2.13.4
|
||||||
|
Pygments==2.20.0
|
||||||
|
python-pptx==1.0.2
|
||||||
|
requests==2.34.2
|
||||||
|
pytest==9.1.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verification executed
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python -m pytest tests -q
|
||||||
|
.venv/bin/python -c "import PySide6, pydantic, requests"
|
||||||
|
```
|
||||||
|
|
||||||
|
Additional verification imported every module under `cowork_local` with `QT_QPA_PLATFORM=offscreen`, then started the real application entry point with a 1.5-second automatic Qt shutdown.
|
||||||
|
|
||||||
|
Results:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Tests: 81 passed
|
||||||
|
Runtime dependency imports: PASS
|
||||||
|
Application module imports: 0 failures
|
||||||
|
Headless startup: exit 0
|
||||||
|
Launcher in PATH: PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Qt emitted one non-fatal warning while populating the fallback alias for the missing `Sans Serif` family. It did not affect application startup.
|
||||||
|
|
||||||
|
## Optional capabilities
|
||||||
|
|
||||||
|
`pypdf` and `opendataloader-pdf` were intentionally not installed in the baseline environment. Install `requirements-optional.txt` when advanced PDF extraction is required. A `soffice` command was detected on the installation host, but LibreOffice availability remains an external host prerequisite rather than a Python dependency.
|
||||||
|
|
||||||
|
No provider credential, unlock code, token, or application state was written to the repository during installation or verification.
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
# Local Installation
|
||||||
|
|
||||||
|
This guide installs the source checkout into an isolated virtual environment. It does not modify the system Python and does not store provider credentials in the repository.
|
||||||
|
|
||||||
|
## Supported baseline
|
||||||
|
|
||||||
|
- Python 3.11 or newer; CI and this installation use Python 3.11.
|
||||||
|
- macOS, Linux, or Windows for the cross-platform desktop UI.
|
||||||
|
- Windows-only integrations such as AppContainer, Windows Sandbox, Outlook COM, and Office COM conversion remain unavailable on macOS/Linux and degrade gracefully.
|
||||||
|
|
||||||
|
## Automated installation
|
||||||
|
|
||||||
|
From the repository root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/install_local.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The installer:
|
||||||
|
|
||||||
|
1. selects `python3.11` when available;
|
||||||
|
2. creates `.venv/` inside the repository;
|
||||||
|
3. installs `requirements.txt` and `requirements-test.txt` with `uv` when available, otherwise `pip`;
|
||||||
|
4. creates `~/.local/bin/cowork-local` when that path is free;
|
||||||
|
5. never replaces an existing launcher or global Python package.
|
||||||
|
|
||||||
|
Override the interpreter when necessary:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
COWORK_PYTHON=/path/to/python3.11 ./scripts/install_local.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
Use the repository launcher:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/run_local.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
If `~/.local/bin` is in `PATH`, use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cowork-local
|
||||||
|
```
|
||||||
|
|
||||||
|
The launcher changes to the package's parent directory and runs `python -m cowork_local`, which is required by the current source layout.
|
||||||
|
|
||||||
|
## Configure credentials
|
||||||
|
|
||||||
|
Application state is stored outside Git under `~/.cowork_local/`. Export only the variables you need; `.env.example` documents the supported names. For example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export OPENAI_API_KEY="..."
|
||||||
|
export OPENAI_BASE_URL="https://your-approved-gateway/v1"
|
||||||
|
export COWORK_SANDBOX_PASSWORD="..."
|
||||||
|
export COWORK_MS365_UNLOCK_CODE="..."
|
||||||
|
cowork-local
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not put real values in `.env.example` or any tracked file.
|
||||||
|
|
||||||
|
## Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.venv/bin/python -m pytest tests -q
|
||||||
|
.venv/bin/python -c "import PySide6, pydantic, requests; print('runtime imports OK')"
|
||||||
|
```
|
||||||
|
|
||||||
|
A headless startup smoke test suitable for CI or remote shells is documented in the verification section below:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ..
|
||||||
|
QT_QPA_PLATFORM=offscreen cowork_local/.venv/bin/python -c \
|
||||||
|
"from PySide6.QtCore import QTimer; from PySide6.QtWidgets import QApplication; app=QApplication([]); QTimer.singleShot(1000, app.quit); from cowork_local.app import run; raise SystemExit(run([]))"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Optional document tooling
|
||||||
|
|
||||||
|
Install PDF extraction helpers when needed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv pip install --python .venv/bin/python -r requirements-optional.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
LibreOffice is an external application, not a Python package. Install it separately if headless Office-to-PDF conversion is required. Microsoft Office/Outlook COM integration and `pywin32` are Windows-only.
|
||||||
|
|
||||||
|
## Update or repair
|
||||||
|
|
||||||
|
Pull the desired reviewed revision and rerun `./scripts/install_local.sh`. The operation is idempotent: it reuses `.venv`, reconciles declared packages, and keeps the existing launcher when it already points to this checkout.
|
||||||
|
|
||||||
|
The first verified macOS installation is recorded in [installation-log-2026-08-11.md](installation-log-2026-08-11.md).
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Optional document/PDF extraction helpers. The application degrades
|
||||||
|
# gracefully or can install these on demand when they are not present.
|
||||||
|
pypdf>=4,<7
|
||||||
|
opendataloader-pdf
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Cowork Local desktop runtime (Python 3.11).
|
||||||
|
# Keep optional/heavy document tooling out of this baseline; see
|
||||||
|
# requirements-optional.txt and docs/installation.md.
|
||||||
|
PySide6>=6.7,<7
|
||||||
|
anyio>=4,<5
|
||||||
|
holidays>=0.40,<1
|
||||||
|
keyring>=24,<26
|
||||||
|
mcp>=1,<2
|
||||||
|
msal>=1.28,<2
|
||||||
|
networkx>=3.2,<4
|
||||||
|
openpyxl>=3.1,<4
|
||||||
|
psutil>=5.9,<8
|
||||||
|
pydantic>=2,<3
|
||||||
|
Pygments>=2.17,<3
|
||||||
|
python-pptx>=1,<2
|
||||||
|
requests>=2.31,<3
|
||||||
Executable
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
repo_dir=$(cd "$script_dir/.." && pwd)
|
||||||
|
venv_dir="$repo_dir/.venv"
|
||||||
|
launcher_dir="$HOME/.local/bin"
|
||||||
|
launcher_link="$launcher_dir/cowork-local"
|
||||||
|
launcher_target="$repo_dir/scripts/run_local.sh"
|
||||||
|
|
||||||
|
if [[ -n "${COWORK_PYTHON:-}" ]]; then
|
||||||
|
python_bin="$COWORK_PYTHON"
|
||||||
|
elif command -v python3.11 >/dev/null 2>&1; then
|
||||||
|
python_bin=$(command -v python3.11)
|
||||||
|
else
|
||||||
|
python_bin=$(command -v python3)
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$python_bin" -c 'import sys; assert sys.version_info >= (3, 11), "Cowork Local requires Python 3.11+"'
|
||||||
|
|
||||||
|
if [[ ! -x "$venv_dir/bin/python" ]]; then
|
||||||
|
if command -v uv >/dev/null 2>&1; then
|
||||||
|
uv venv --python "$python_bin" "$venv_dir"
|
||||||
|
else
|
||||||
|
"$python_bin" -m venv "$venv_dir"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v uv >/dev/null 2>&1; then
|
||||||
|
uv pip install --python "$venv_dir/bin/python" \
|
||||||
|
-r "$repo_dir/requirements.txt" \
|
||||||
|
-r "$repo_dir/requirements-test.txt"
|
||||||
|
else
|
||||||
|
"$venv_dir/bin/python" -m pip install --disable-pip-version-check \
|
||||||
|
-r "$repo_dir/requirements.txt" \
|
||||||
|
-r "$repo_dir/requirements-test.txt"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$launcher_dir"
|
||||||
|
if [[ ! -e "$launcher_link" && ! -L "$launcher_link" ]]; then
|
||||||
|
ln -s "$launcher_target" "$launcher_link"
|
||||||
|
echo "Installed launcher: $launcher_link"
|
||||||
|
elif [[ -L "$launcher_link" && "$(readlink "$launcher_link")" == "$launcher_target" ]]; then
|
||||||
|
echo "Launcher already installed: $launcher_link"
|
||||||
|
else
|
||||||
|
echo "Not replacing existing path: $launcher_link" >&2
|
||||||
|
echo "Run Cowork Local with: $launcher_target" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cowork Local environment: $venv_dir"
|
||||||
|
echo "Run: $launcher_target"
|
||||||
|
echo "Or add $launcher_dir to PATH and run: cowork-local"
|
||||||
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
launcher_source=${BASH_SOURCE[0]}
|
||||||
|
while [[ -L "$launcher_source" ]]; do
|
||||||
|
launcher_dir=$(cd "$(dirname "$launcher_source")" && pwd)
|
||||||
|
launcher_target=$(readlink "$launcher_source")
|
||||||
|
if [[ "$launcher_target" = /* ]]; then
|
||||||
|
launcher_source="$launcher_target"
|
||||||
|
else
|
||||||
|
launcher_source="$launcher_dir/$launcher_target"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
script_dir=$(cd "$(dirname "$launcher_source")" && pwd)
|
||||||
|
repo_dir=$(cd "$script_dir/.." && pwd)
|
||||||
|
python_bin="$repo_dir/.venv/bin/python"
|
||||||
|
|
||||||
|
if [[ ! -x "$python_bin" ]]; then
|
||||||
|
echo "Cowork Local is not installed. Run $repo_dir/scripts/install_local.sh first." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$(dirname "$repo_dir")"
|
||||||
|
exec "$python_bin" -m cowork_local "$@"
|
||||||
Reference in New Issue
Block a user