Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ Minimal workspace orchestrator for tmuxp + Claude Code + Neovim.
./cli/devman
```

## Documentation

- [Getting started](docs/getting-started.md)
- [Workspace schema](docs/workspace-schema.md)
- [Claude integration](docs/claude-integration.md)
- [Troubleshooting](docs/troubleshooting.md)

## NixOS + Home Manager (flakes)

Use a flake input pinned with `git+` to avoid GitHub API rate limits.
Expand Down Expand Up @@ -66,9 +73,3 @@ Use `cli/setup_config.py` to validate `.env.example`, `.toml.example`, or
```bash
uv run ./cli/setup_config.py validate .env.example
```

## Templates

- `templates/workspace-min`: starter `.devman/` layout for a single repo.
- `templates/workspace-nixos-collection`: example multi-repo NixOS workspace
with tmuxp + mini.sessions defaults.
43 changes: 43 additions & 0 deletions docs/claude-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Claude Code integration

## Requirements

Claude Code integration requires the `claude` CLI to be installed and available
on your `PATH`. You can verify this with:

```bash
claude --version
```

## Workspace configuration

Configure Claude Code in `.devman/devman.toml`:

```toml
[claude_code]
interaction = "interaction.md" # optional
emit_project_config = false # optional
```

- `interaction` points to the interaction guide used by Claude Code.
- `emit_project_config` controls whether devman writes `.claude/project.json`
and an optional `CLAUDE.md` to the workspace root.

## What devman writes

When enabled, devman will:

- Create `.claude/settings.json` with workspace metadata.
- Optionally emit `.claude/project.json` plus `CLAUDE.md` instructions so Claude
Code can load workspace-specific context.

## Helpful commands

```bash
./cli/devman doctor
./cli/devman up
./cli/devman bootstrap
```

If the CLI is missing, these commands will surface a message pointing you to
https://claude.ai/code.
67 changes: 67 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Getting Started

## Overview

devman is a minimal workspace orchestrator for tmuxp, Claude Code, and Neovim.
It discovers `.devman/` workspaces, builds an index, and launches tmux sessions
with the right editor context.

## Prerequisites

- **Python 3.11+** (use `uv` for environments).
- **tmux** + **tmuxp** for session management.
- **Neovim** (`nvim`) if you want editor/session bootstrapping.
- **Claude Code** (`claude`) is required for Claude integration.

## Create a workspace

A workspace is any project root that contains a `.devman/` directory. The
minimum requirement is the directory itself, but a `devman.toml` file provides
metadata and paths.

Example `.devman/devman.toml`:

```toml
[workspace]
name = "my-app"

[tmuxp]
workspace = "workspace.tmuxp.yaml"
session_name = "my-app"

[claude_code]
interaction = "interaction.md"
emit_project_config = false

[nvim]
init = "nvim/init.lua"
listen = ".devman/.state/nvim.sock"
sessions_dir = "sessions"
default_session = "home.vim"
```

For the full schema, see [`docs/workspace-schema.md`](workspace-schema.md).

## Build the index

```bash
./cli/devman index rebuild
```

## Launch devman

```bash
./cli/devman
```

## Switch workspaces

```bash
./cli/devman switch <name|tag|path>
```

## Next steps

- Review the workspace schema in [`docs/workspace-schema.md`](workspace-schema.md).
- Configure Claude Code in [`docs/claude-integration.md`](claude-integration.md).
- If something fails, check [`docs/troubleshooting.md`](troubleshooting.md).
35 changes: 35 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Troubleshooting

## Verify external tools

Run the doctor command to check for required dependencies:

```bash
./cli/devman doctor
```

Ensure these tools are installed:

- `tmux`
- `tmuxp`
- `nvim` (if you use Neovim integration)
- `claude`

## Workspace not found

- Confirm the workspace root contains a `.devman/` directory.
- Rebuild the index:

```bash
./cli/devman index rebuild
```

## tmuxp session issues

- Verify the `workspace.tmuxp.yaml` path in `.devman/devman.toml`.
- Confirm the file exists relative to `.devman/`.

## Claude Code not detected

- Ensure the `claude` CLI is on your `PATH`.
- Re-run `./cli/devman doctor` to confirm availability.
51 changes: 51 additions & 0 deletions docs/workspace-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Workspace schema

This document defines the `.devman/devman.toml` schema used by devman.

## Overview

- **Required** fields are listed explicitly.
- All paths are relative to the `.devman/` directory unless noted.
- TOML overrides `.env` values if both are present.

## Schema

```toml
[workspace]
name = "my-app" # required
tags = ["api", "web"] # optional
group = "client-x" # optional

[tmuxp]
workspace = "workspace.tmuxp.yaml" # optional
session_name = "my-app" # optional

[claude_code]
interaction = "interaction.md" # optional
emit_project_config = false # optional

[nvim]
init = "nvim/init.lua" # optional
listen = ".devman/.state/nvim.sock" # optional (relative to workspace root)
sessions_dir = "sessions" # optional
default_session = "home.vim" # optional
```

## Precedence rules

1. `.devman/devman.toml` is the primary configuration source.
2. `.devman/.env` may supply environment toggles for:
- `DEVMAN_TMUXP_WORKSPACE`
- `DEVMAN_SESSION_NAME`
3. If TOML fields are present they always override `.env` values.

## Required files

A workspace is valid if `.devman/` exists. The following files are optional but
recommended for full functionality:

- `.devman/devman.toml`
- `.devman/interaction.md`
- `.devman/workspace.tmuxp.yaml`
- `.devman/nvim/init.lua`
- `.devman/sessions/home.vim`
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,13 @@ warn_unused_configs = true
disallow_untyped_defs = true

[tool.pytest.ini_options]
testpaths = ["src/tests"]
testpaths = ["tests/unit", "tests/integration"]
addopts = "-v --cov=src/devman --cov-report=html"
python_files = ["test_*.py", "*_test.py"]
markers = [
"unit: fast, isolated tests",
"integration: integration or external dependency coverage",
]

[tool.coverage.report]
exclude_lines = [
Expand Down
7 changes: 4 additions & 3 deletions src/tests/run_tests.py → scripts/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# ]
# ///

# tests/run_tests.py
# scripts/run_tests.py
"""Test runner script for devman library."""

from __future__ import annotations
Expand All @@ -22,8 +22,9 @@

def main() -> None:
"""Run pytest with coverage and formatting."""
test_dir = Path(__file__).parent
src_dir = test_dir.parent / "src"
repo_root = Path(__file__).resolve().parent.parent
test_dir = repo_root / "tests"
src_dir = repo_root / "src"

cmd = [
sys.executable,
Expand Down
5 changes: 5 additions & 0 deletions scripts/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail

uv sync --extra dev
uv run pytest
File renamed without changes.
Empty file added tests/fixtures/.gitkeep
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from devman.claude_code import check_claude_code, generate_claude_code_settings
from devman.models.workspace import WorkspaceConfig

pytestmark = pytest.mark.integration


def test_generate_claude_code_settings(tmp_path: Path) -> None:
"""Generate settings payload for Claude Code."""
Expand Down
4 changes: 3 additions & 1 deletion src/tests/test_config.py → tests/unit/test_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# tests/test_config.py
# tests/unit/test_config.py
"""Test configuration models."""

from __future__ import annotations
Expand All @@ -8,6 +8,8 @@

from devman.config import ProjectConfig

pytestmark = pytest.mark.unit


class TestProjectConfig:
"""Test ProjectConfig model."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

from pathlib import Path

import pytest

from devman.models.workspace import WorkspaceConfig

pytestmark = pytest.mark.unit


def test_minimal_workspace_config(tmp_path: Path) -> None:
"""Ensure minimal .devman directory loads defaults."""
Expand Down