Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions A.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a
1 change: 1 addition & 0 deletions B.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b
47 changes: 47 additions & 0 deletions README-Windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# ClawTeam for Windows

This repository has been locally hardened to support native Windows use without relying on WSL for the core coordination path.

## What works

- Native Windows Python install
- Team creation, board display, inbox flow, task flow
- Cost/session persistence
- Team snapshots and dry-run restores
- Git worktree workspace flows
- Background agent spawning through the `windows` backend
- Web dashboard via `clawteam board serve`

## What is different from Linux

The original project is tmux-first. On Windows:

- `tmux` pane tiling/attach is not available natively
- the recommended runtime is the `windows` backend, which maps to subprocess spawning
- the Web board is the preferred live monitoring view

## Recommended commands

```powershell
python -m pip install -e .
python -m clawteam config set default_backend windows
python -m clawteam team spawn-team demo-win -d "Windows demo" -n leader
python -m clawteam board serve demo-win --port 8080
python -m clawteam spawn --team demo-win --agent-name worker1 --task "Do work" windows python
```

## Helper scripts

See `scripts/`:

- `clawteam-win.ps1`
- `smoke-test-win.ps1`
- `spawn-worker-win.ps1`

## Validation status

Validated locally on Windows across config, mailbox, snapshots, spawn CLI, registry, workspace, session, cost, and web board flows.

## Notes

This is a Windows-compatibility path, not yet official upstream Windows support. For your system, this is the intended production path.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

Human provides the goal. The Agent Team orchestrates everything else.

Full compatibility with [Claude Code](https://claude.ai/claude-code), [Codex](https://openai.com/codex), [OpenClaw](https://github.com/openclaw/openclaw), [nanobot](https://github.com/HKUDS/nanobot), [Cursor](https://cursor.com), and any CLI agent.  [**中文文档**](README_CN.md) | [**한국어**](README_KR.md)
Full compatibility with [Claude Code](https://claude.ai/claude-code), [Codex](https://openai.com/codex), [OpenClaw](https://github.com/openclaw/openclaw), [nanobot](https://github.com/HKUDS/nanobot), [Cursor](https://cursor.com), and any CLI agent.  [**中文文档**](README_CN.md) | [**한국어**](README_KR.md) | [**Windows Guide**](README-Windows.md)

---

Expand Down
37 changes: 37 additions & 0 deletions SECURITY-NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# SECURITY NOTES

This Windows compatibility branch is intended to be safe to share and use on another machine.

## What was checked

A repo scan was performed for:
- embedded API keys
- access tokens
- passwords / bearer tokens
- user-specific local paths
- user-specific fork / PR references in local docs

## Result

No actual live credentials were found in the Windows compatibility changes.

## Important distinctions

The upstream project contains documentation and test fixtures that reference environment variable names such as:
- `OPENROUTER_API_KEY`
- `MOONSHOT_API_KEY`
- `ANTHROPIC_API_KEY`
- `OPENAI_API_KEY`

These are placeholders, examples, or environment variable names — not embedded secrets.

## Windows-specific operational guidance

- Prefer binding local board servers to `127.0.0.1` unless you intentionally want LAN exposure.
- Treat saved session/task/cost data as local operational metadata.
- Review spawned command profiles before distributing to other users.
- Use environment variables for provider credentials; do not hardcode them into scripts or config files you plan to share.

## Caveat

Git commit history on a public branch may still contain author metadata (name/email) from commits already created. That metadata is separate from source-file secret scanning.
172 changes: 172 additions & 0 deletions WINDOWS_RUNBOOK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# ClawTeam on Windows — Local Runbook

This repo has been patched locally to run natively on Windows without requiring WSL for the core coordination path.

## Current Status

Working on this machine:
- native Windows Python install
- team creation and status
- task create/list/update and dependency unblocking
- inbox send/peek/receive
- cost budget/report/show
- session save/show
- team snapshot + snapshot listing + dry-run restore
- git worktree workspace create/list/status/checkpoint/merge/cleanup
- agent spawning through the `windows` backend (Windows-friendly subprocess mode)

Notes:
- `windows` backend is an alias of the subprocess backend
- default backend is set locally to `windows`
- tmux is not required for the Windows path
- visual tmux pane orchestration is still a Unix/Linux-oriented feature

## Install / Reinstall

From this repo root:

```powershell
python -m pip install -e .
```

If the `clawteam` executable is not on PATH, use:

```powershell
python -m clawteam --help
```

## Config

Show current config:

```powershell
python -m clawteam config show
```

Set backend explicitly:

```powershell
python -m clawteam config set default_backend windows
```

## Quick Smoke Test

```powershell
python -m clawteam team spawn-team demo-win -d "Windows demo" -n leader
python -m clawteam task create demo-win "first task" -o leader
python -m clawteam inbox send demo-win leader "hello from windows"
python -m clawteam inbox receive demo-win --agent leader
python -m clawteam board show demo-win
```

## Spawn Agents on Windows

Recommended style:

```powershell
python -m clawteam spawn --team demo-win --agent-name worker1 --task "Do the task" windows python
```

Or rely on configured default backend:

```powershell
python -m clawteam spawn --team demo-win --agent-name worker1 --task "Do the task" python
```

## Workspace Flow

Create a spawned worker with git worktree isolation:

```powershell
python -m clawteam spawn --team demo-win --agent-name gitworker --task "Inspect repo" windows python
python -m clawteam workspace list demo-win
python -m clawteam workspace status demo-win gitworker
python -m clawteam workspace checkpoint demo-win gitworker -m "checkpoint"
python -m clawteam workspace merge demo-win gitworker --no-cleanup
python -m clawteam workspace cleanup demo-win --agent gitworker
```

## Validated Commands

These were manually validated on this machine:
- `team spawn-team`
- `team status`
- `team snapshot`
- `team snapshots`
- `team restore --dry-run`
- `task create`
- `task update`
- `task list`
- `inbox send`
- `inbox peek`
- `inbox receive`
- `cost budget`
- `cost report`
- `cost show`
- `session save`
- `session show`
- `workspace list`
- `workspace status`
- `workspace checkpoint`
- `workspace merge`
- `workspace cleanup`
- `spawn` using `windows` backend

## Known Caveats

1. This is a **local compatibility patch**, not upstreamed yet.
2. The Unix/tmux experience is still a separate path; Windows mode uses subprocess execution.
3. CLI argument parsing can be fussy when passing commands that start with dashes. If needed, place options before the backend/command, or use `--` carefully.
4. If you want a stable command experience, prefer invoking via `python -m clawteam`.

## Recommended Usage on This Machine

- Use OpenClaw/webchat as the control surface
- Run ClawTeam via the patched local repo
- Prefer subprocess/windows backend
- Use git worktree flows for isolated worker changes

## Convenience Scripts

Included in `scripts/`:

- `clawteam-win.ps1` — wrapper for `python -m clawteam`
- `smoke-test-win.ps1` — quick Windows smoke test
- `spawn-worker-win.ps1` — helper to spawn a Windows worker
- `board-serve-win.ps1` — start the web board on a chosen host/port
- `session-save-win.ps1` — save session metadata quickly
- `session-show-win.ps1` — show session metadata for a team
- `soak-test-win.ps1` — repeated task/inbox/session/cost loop for Windows soak testing
- `launch-demo-win.ps1` — one-click demo team + board startup
- `full-cycle-win.ps1` — one-click team/task/session/board startup flow
- `prod-soak-win.ps1` — longer production-style worker/workspace/session soak loop

Examples:

```powershell
./scripts/clawteam-win.ps1 config show
./scripts/smoke-test-win.ps1
./scripts/spawn-worker-win.ps1 -Team demo-win -AgentName worker1 -Task "Do the task"
./scripts/board-serve-win.ps1 -Team demo-win -Port 8080
./scripts/session-save-win.ps1 -Team demo-win -Agent leader -SessionId sess-001
./scripts/session-show-win.ps1 -Team demo-win
./scripts/soak-test-win.ps1 -Team soak-win -Iterations 10
./scripts/launch-demo-win.ps1 -Team demo-win
./scripts/full-cycle-win.ps1 -Team prod-win -Port 8080
./scripts/prod-soak-win.ps1 -Team prod-soak-win -Cycles 5
```

## Publishing Note

This runbook is intentionally generic and contains no user-specific remotes, usernames, or local secrets.

## Windows Caveats

- Native Windows uses the `windows`/`subprocess` backend, not tmux panes.
- For a live monitor on Windows, use `board serve` and open the web UI.
- tmux-style tiled attach remains a Unix/Linux-first feature upstream.
- If you need exact Linux/tmux behavior, use WSL as an optional advanced mode.

## Suggested Next Step

Run the smoke test, then start using the wrapper scripts for normal operation.
1 change: 1 addition & 0 deletions WINDOWS_TEST.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ok from gitworker
19 changes: 14 additions & 5 deletions clawteam/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2610,7 +2610,7 @@ def lifecycle_on_exit(

@app.command("spawn")
def spawn_agent(
backend: Optional[str] = typer.Argument(None, help="Backend: tmux (default) or subprocess"),
backend: Optional[str] = typer.Argument(None, help="Backend: tmux, subprocess, or windows"),
command: list[str] = typer.Argument(None, help="Command and arguments to run (default: claude)"),
team: Optional[str] = typer.Option(None, "--team", "-t", help="Team name"),
agent_name: Optional[str] = typer.Option(None, "--agent-name", "-n", help="Agent name"),
Expand All @@ -2625,11 +2625,13 @@ def spawn_agent(
):
"""Spawn a new agent process with identity + task as its initial prompt.

Defaults: tmux backend, claude command, git worktree isolation, skip-permissions on.
Defaults: tmux backend on Unix, subprocess backend on Windows, claude command,
git worktree isolation, skip-permissions on.

Backends:
tmux - Launch in tmux windows (visual monitoring)
subprocess - Launch as background processes
windows - Alias for subprocess, intended for native Windows setups
"""
from clawteam.config import get_effective
from clawteam.spawn import get_backend
Expand Down Expand Up @@ -2972,11 +2974,18 @@ def board_serve(
def board_attach(
team: str = typer.Argument(..., help="Team name"),
):
"""Attach to tmux session with all agent windows tiled side by side.
"""Attach to a live team monitor.

Merges all agent tmux windows into a single tiled view so you can
watch every agent working simultaneously.
On Unix/tmux setups this opens the tiled tmux view. On Windows, tmux is not
available, so fall back to the Web board and explain how to open it.
"""
import os

if os.name == "nt":
console.print("[yellow]tmux board attach is not available on Windows.[/yellow]")
console.print("Use [bold]clawteam board serve[/bold] and open the Web UI instead.")
raise typer.Exit(1)

from clawteam.spawn.tmux_backend import TmuxBackend

result = TmuxBackend.attach_all(team)
Expand Down
72 changes: 72 additions & 0 deletions clawteam/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""Cross-platform compatibility helpers for ClawTeam."""

from __future__ import annotations

import os
from contextlib import contextmanager
from pathlib import Path

if os.name == "nt":
import msvcrt
else: # pragma: no cover
import fcntl # type: ignore


@contextmanager
def exclusive_lock(file_obj):
"""Cross-platform exclusive file lock.

Uses advisory flock on Unix and msvcrt.locking on Windows.
Locks the first byte of the file, which is sufficient because all callers
coordinate through the same lock file handle.
"""
if os.name == "nt":
file_obj.seek(0)
file_obj.write("0")
file_obj.flush()
file_obj.seek(0)
msvcrt.locking(file_obj.fileno(), msvcrt.LK_LOCK, 1)
try:
yield
finally:
file_obj.seek(0)
msvcrt.locking(file_obj.fileno(), msvcrt.LK_UNLCK, 1)
else: # pragma: no cover
fcntl.flock(file_obj.fileno(), fcntl.LOCK_EX)
try:
yield
finally:
fcntl.flock(file_obj.fileno(), fcntl.LOCK_UN)


def is_path_locked(path: Path) -> bool:
"""Best-effort lock probe.

On Windows this attempts a 1-byte non-blocking lock via msvcrt.
"""
try:
handle = path.open("a+b")
except Exception:
return True
try:
if os.name == "nt":
try:
if handle.tell() == 0:
handle.write(b"0")
handle.flush()
handle.seek(0)
msvcrt.locking(handle.fileno(), msvcrt.LK_NBLCK, 1)
handle.seek(0)
msvcrt.locking(handle.fileno(), msvcrt.LK_UNLCK, 1)
return False
except OSError:
return True
else: # pragma: no cover
try:
fcntl.flock(handle.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except OSError:
return True
fcntl.flock(handle.fileno(), fcntl.LOCK_UN)
return False
finally:
handle.close()
Loading