Metadata-Version: 2.5
Name: dreamteam-cli
Version: 2.0.0
Summary: Project scaffolding CLI with built-in methodology (Copier-backed).
Project-URL: Homepage, https://github.com/vlakir/dreamteam
Project-URL: Issues, https://github.com/vlakir/dreamteam/issues
Project-URL: Source, https://github.com/vlakir/dreamteam
Project-URL: Changelog, https://github.com/vlakir/dreamteam/blob/main/CHANGELOG.md
Author-email: vlakir <vlakir1234@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: adr,cli,copier,kanban,methodology,scaffolding,template
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Code Generators
Classifier: Typing :: Typed
Requires-Python: >=3.14
Requires-Dist: copier>=9.15.1
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: typer>=0.25.1
Description-Content-Type: text/markdown

# dreamteam

**Project scaffolding CLI with built-in methodology.** One command —
working project with linters, tests, kanban, ADR log, and a complete
set of rules for AI-assisted development baked in.

**dreamteam 2.0.0** uses OpenCode 1.19.0 and Ensemble 0.18.0. It provides
explicit, recoverable migration of an existing project's agent configuration,
not a disk-wide conversion during package installation. See [Status](#status)
and the [migration guide](docs/opencode-migration.md) for the supported inputs
and platform boundary. Registry packages and source checkouts can differ;
check the installed version with `dt --version`.

**Installing or upgrading `dreamteam-cli` does not migrate projects.** Choose
one project explicitly with `dt update <project>` (already managed) or
`dt apply <project>` (unmanaged). Preview first; read the
[OpenCode migration guide](docs/opencode-migration.md) before migrating legacy
rules. New projects use `dt init` and contain only active OpenCode artifacts.

```bash
pip install dreamteam-cli                              # then `dreamteam` (or `dt`) is available
# or zero-install via uvx:
uvx --from dreamteam-cli dreamteam init my-project
# short form:
dt init my-project

cd my-project
uv sync
```

> **Note:** the PyPI package name is `dreamteam-cli` (the bare `dreamteam` slot on PyPI is held by an unrelated 2019 package). The **command** stays `dreamteam` regardless — `pip install dreamteam-cli` exposes the `dreamteam` console script, and that's what you use in everyday work. The package also installs **`dt`** as a short alias pointing at the same callable, so `dt init my-project`, `dt update --dry-run`, `dt --version` all work equivalently.

That's it. The generated project passes its own pre-push check suite
(ruff / ruff format / mypy / pytest with an explicit ≥80% coverage
gate) immediately — verified by the integration test in this repo.

## What you get

Every project scaffolded by `dreamteam init` includes:

- **Python stack with your chosen package manager** — `dreamteam
  init` asks for `package_manager` (`uv` default, or `poetry` /
  `pdm` / `hatch` / `pip`); the rendered `pyproject.toml`,
  `AGENTS.md`, and `README.md` use the right build-backend and
  command prefix for the chosen manager. `ruff` (`select = ["ALL"]`
  with a curated `ignore`), `mypy` (`mypy_path = "src"`), `pytest +
  pytest-cov + pytest-asyncio` with a `--cov-fail-under=80` gate
  are universal regardless of manager. Coverage is kept **out** of the
  default `addopts` (a light default `pytest` for repeated local
  iteration); the ≥80% threshold runs as an explicit command in the
  pre-push gate and CI.
- **`src/`-layout** with a working `main.py` (CLI-style logging:
  DEBUG/INFO → stdout, WARNING+ → stderr) and a coverage-100%
  `tests/test_main.py`.
- **`scripts/pytest-guard.sh`** — a heavy-run mutex wrapper that
  serialises full / coverage test runs across all git worktrees sharing
  one machine (a per-user `flock`, blocking wait), so parallel runs
  don't stack into OOM. Degrades to a direct run where `flock` is absent
  (e.g. Windows); optional per-run memory cap via `PYTEST_GUARD_MEM_MAX`.
- **Methodology files** that are not just placeholders but
  ready-to-fill documents:
  - `CONCEPT.md` — immutable initial draft of the project vision.
  - `DECISIONS.md` — ADR-Lite for architectural decisions.
  - `BACKLOG.md` / `BOARD.md` — markdown kanban with task numbering
    (`T<NNN>` IDs, branch naming, PR naming, spec folder naming).
  - `CHANGELOG.md` — Keep-a-Changelog style with retrospective
    sections at milestone boundaries.
  - `AGENTS.md` — project rules for [OpenCode](https://opencode.ai),
    including scope discipline, Git workflow, pre-push contract, and
    a structured code-review checklist.
- **`hooks/pre-push`** — optional local hook rejecting direct pushes
  to `main` / `master`.
- **`specs/spec-template.md`** — template for major-feature specs
  with `clarify` / `analyze` sections.
- **Nine native OpenCode roles** with Ensemble peer messaging and isolated worktrees.

## Team roles in OpenCode

The standard team has nine roles: technical lead, analyst/architect, UX/UI
designer, frontend, mobile, backend, test engineer, reviewer and DevOps. Each
ships as an OpenCode agent; the lead selects the roles needed for a task.

OpenCode 1.19.0 is the required agent runtime. Generated projects pin Ensemble
0.18.0 for task coordination, peer messages and its local dashboard. Configure
providers, models and optional MCP servers in your personal OpenCode settings;
no particular provider or API subscription is required by dreamteam.

Use `dt doctor` to check the runtime. Start one persistent server with
`dt serve <project>`, then connect from another terminal with `dt run <project>`.
Additional clients must attach to the same server.
Use `dt run <project> --session <id>` to resume an OpenCode session. The Architect
is a read-only agent at `.opencode/agents/architect.md`; its model inherits the
caller unless `architect_model=provider/model-id` is supplied at generation.
A designer can use a vision model or optional MCP service of your choice.

Ensemble 0.18.0 shares its database across processes. Independent OpenCode
processes with different session stores can archive active teams; plugin
initialization can mark busy workers stale. Use one server for team work.
Concurrent standalone and IDE ACP processes have not yet been accepted.

Project `opencode.json` loads `.opencode/team-roles.md` as instructions. Keep
BOARD.md and BACKLOG.md as the project record and Ensemble tasks as execution
state. Automatic merging on team cleanup is disabled. Review and validate
changes before explicitly integrating branches. ChatGPT Plus/Pro authentication
is available through OpenCode; Anthropic subscription plugins are not supported.

Install the pinned runtime from the official OpenCode release assets and put
`opencode` on PATH. Use `opencode auth login` when you want to connect an account;
login is not required for the offline migration version prerequisite. A successful
`dt doctor` checks the binary version, not provider or model functionality.
With a running server, use `dt doctor --server http://127.0.0.1:4096 --path <project>`
to verify that Ensemble tools actually registered.


See [provider and role configuration](docs/opencode-providers.md) for native
protocols, model assignments and feature checks.

## Recovering interrupted workers

After restarting the server, run `dt recover <project>` on the server host to
list interrupted members. Resume a verified task with:

```bash
dt recover <project> --member <name> --lead-session <session-id> --task <task-id>
```

This compatibility adapter targets Ensemble 0.18.0 and OpenCode 1.19.0. It checks
session ownership and the preserved Git worktree, backs up coordination state,
reclaims the specified pending task, and sends one continuation request to the
original session. Obtain the task ID from the team task list/dashboard.
It never creates a replacement worker. Repeat requests are
blocked; uncertain HTTP delivery requires inspection before another attempt.
An interrupted external action may already have succeeded: the worker must
reconcile files and tool results before retrying. This is explicit recovery,
not a promise of exactly-once execution or unattended recovery from every failure.

## Multilingual methodology

`dreamteam init` first asks for a methodology language (default `en`):

```
language  [en (English) / ru (Русский) / fr (Français) /
           de (Deutsch) / zh (中文)]
```

The chosen language renders into the derived project's narrative files
(`AGENTS.md` / `README.md` / `CONCEPT.md` / `BACKLOG.md` / `BOARD.md` /
`CHANGELOG.md` / `DECISIONS.md` / `specs/spec-template.md`). Technical
files (`pyproject.toml`, `src/`, `tests/`, `hooks/`) and kanban
keywords (`To Do` / `Doing` / `Done`) are language-agnostic.

**Source of truth — Russian.** Files in
`src/dreamteam/template/i18n/ru/` are hand-edited by the maintainer;
`en` / `fr` / `de` / `zh` are AI-translations from the Russian
source. Translation tooling and models may change over time; historical
`translation_engine` values record provenance, not a runtime dependency.
OpenCode does not provide a dreamteam-specific Max subscription, and translation
cost depends on the user's provider/account. Each
translated file carries a YAML frontmatter with `translated_from`,
`source_hash` (sha256 of the ru source at translation time),
`translation_engine`, and `translation_date`. The frontmatter is
stripped from the rendered derived project — users see clean
markdown.

**Contributing to the methodology:**

1. Edit only `src/dreamteam/template/i18n/ru/<file>.md` (the source).
2. In an OpenCode session ask: *"re-translate this change into
   en/fr/de/zh and refresh `source_hash` in the frontmatter."*
3. Commit the ru edit together with the four regenerated translations.
4. CI guard (`scripts/translate_check.py`, runs after pytest in
   `.github/workflows/ci.yml`) verifies that the recorded
   `source_hash` matches the actual sha256 of `i18n/ru/<file>.md`.
   A mismatch fails the PR with a clear hint about regeneration.

For cosmetic ru edits (typo, whitespace, paragraph re-flow) the
short-cut is to ask OpenCode to refresh only the `source_hash` in all
four translations without retranslating the content. Preserve original
`translation_engine` / `translation_date` provenance; record later partial
translation edits separately rather than attributing the whole file to a new
model. There is no
machine-readable way to distinguish cosmetic from semantic diffs —
maintainer judgment per change.

> **AI translation disclaimer.** All four non-Russian variants are
> AI-generated. They are reviewed by the maintainer at translation
> time but have not gone through a bilingual human review. PRs
> correcting wording, nuance, or terminology in any of the four
> languages are welcome. If you find a passage where the meaning
> diverges from the ru source — please open an issue.

## Applying to an existing project

If you started a project with another tool — PyCharm's new-project
wizard, `poetry new`, `hatch new`, or just `mkdir + cd` — and now
want to layer dreamteam's methodology on top, use:

```bash
cd my-existing-project
dt apply           # or `dt apply .` — defaults to the current directory
# from one level up: `dt apply my-existing-project` also works
```

For a project without legacy agent artifacts, `dt apply` renders the template
into a temporary preview and decides per template-managed file. Legacy inputs
instead require the [migration safety contract](docs/opencode-migration.md);
the conflict switches below do not bypass it:

- **File absent in target** → create silently.
- **File matches template render exactly** → no-op.
- **File differs** → 4-way interactive prompt:
  - `[k]eep` your version (default if you just hit Enter);
  - `[o]verwrite` with the template version;
  - `[d]iff` to see a unified diff (loops back to the prompt);
  - `[s]ave-as-new` writes the template content next to your
    file as `<file>.dt-new` for manual merge later.

`.venv/`, `.git/`, your `src/` packages and unrelated non-template-managed
files are left alone. During legacy migration, supported custom agent artifacts
are also inputs; `.claude/worktrees` remains protected, not a migration source.

For non-interactive runs (CI, scripts) pass `--on-conflict
<keep|overwrite|save-as-new>`. `--dry-run` prints the per-bucket
plan without writing anything. `--data key=value` (repeatable)
seeds copier answers the same way as `dt init`.

> **Pre-flight checks.** If the target already contains
> `.copier-answers.yml` (i.e. it was created via `dt init`),
> `dt apply` exits with a hint to use `dt update` instead.
> If stdin is not a TTY and `--on-conflict` was not supplied,
> the command exits before any render work with an explicit
> error.

After a successful apply the target carries a valid
`.copier-answers.yml`, so subsequent `dt update` (three-way merge
against future template evolutions) works the same as for an
`dt init`-ed project.

## Updating an existing project

When the methodology evolves, propagate the changes into your derived
project with a three-way merge:

```bash
cd my-project
dreamteam update                   # default: three-way merge
dreamteam update --dry-run         # preview: per-file diff + summary, no writes
dreamteam update --force           # overwrite native template files; not migration safety
```

`dreamteam update` merges three states:

- **base** — the template snapshot at the moment of `dreamteam init`
  (or the previous successful update), pulled from a bare git repo
  shipped inside the wheel (`src/dreamteam/template/.bundle/`).
- **theirs** — the current template state from the installed
  `dreamteam-cli` package.
- **ours** — the current state of your derived project on disk.

Files you have not edited are updated to **theirs**. Files where
only you changed something are kept as-is. Files where both you and
the template changed the same region produce git-style markers
(`<<<<<<<` / `=======` / `>>>>>>>`) and the command exits with code
`2`, listing the conflicted files in stderr. Clean merges exit `0`;
hard errors exit `1`.

> **Requirements.** Your derived project must be a git repository
> (`git init && git add -A && git commit -m 'initial'` once after
> `dreamteam init`). The git binary must be on `PATH`. If either is
> missing, native OpenCode projects may fall back to template overwrite with
> a warning. Legacy migration instead requires a verified bundled base and
> refuses unsafe overwrite. `--force` can discard native template edits, but
> cannot bypass migration prerequisites, unsupported inputs, BOTH preservation
> or verified-transfer-before-delete. Migration conflicts return `2` without
> writing conflict markers or advancing answers; this differs from ordinary
> native update conflicts described above.

> **Preview before applying.** `dreamteam update --dry-run` shows
> exactly what would change without touching the target: per-file
> unified diff to stdout plus a one-line summary
> (`N would change, M unchanged, K added, L removed, X conflicts`).
> Exit code matches what an actual update would emit.

## How it works

`dreamteam` is a thin Typer-based CLI on top of
[Copier](https://copier.readthedocs.io/). The template lives at
`src/dreamteam/template/` inside the installed package; `dreamteam
init` calls `copier.run_copy` programmatically, then persists answers
to `.copier-answers.yml` so updates can replay them.

Methodology evolves in this repository:
- **`BACKLOG.md` / `BOARD.md`** — what's planned / in progress for
  the `dreamteam` package itself.
- **`DECISIONS.md`** — ADRs for the package (e.g., why `uv` over
  `poetry`, why `src/`-layout, why Copier, why TEMPLATE-prefix was
  introduced and then dropped).
- **`CHANGELOG.md`** — Keep-a-Changelog for the package, with
  retrospective sections at milestone boundaries.

In derived projects (created via `dreamteam init`) there is a
separate set of these files with the same names but different
content — they live in `src/dreamteam/template/` here and get
rendered into the user's project. The two sets never collide
because they're physically separated by the package boundary.

## Development

```bash
git clone https://github.com/vlakir/dreamteam.git
cd dreamteam
uv sync
uv run pytest                                    # fast tests
uv run pytest -m integration                     # e2e (slow, runs uv sync inside generated project)
```

Pre-push checks (run all four with 0 errors before any push):

```bash
uv run ruff check .
uv run ruff format --check .
uv run mypy src
uv run pytest
```

Methodology rules — including scope discipline, never push to `main`,
one PR one commit, mandatory code review, task numbering `T<NNN>` —
are documented in `AGENTS.md` (project-level) and `~/.config/opencode/AGENTS.md`
(developer-level, optional).

### Sandbox (try the tool without touching the repo)

`scripts/sandbox.sh` creates throwaway `dreamteam`-projects inside
`/tmp/dreamteam-sandbox/` (ephemeral, wiped on reboot). The path is
hardcoded — script refuses to write anywhere else.

```bash
scripts/sandbox.sh init                         # install from PyPI
scripts/sandbox.sh init --local                 # install from local dist/*.whl (builds if missing)
scripts/sandbox.sh init --name my-experiment    # custom name (default: test-<HHMMSS>)

scripts/sandbox.sh list                         # list existing sandbox projects
scripts/sandbox.sh shell my-experiment          # open sub-shell inside that sandbox
scripts/sandbox.sh clean                        # remove /tmp/dreamteam-sandbox/ (asks confirm)
```

Use `--local` when testing changes before publishing to PyPI. The
script builds `dist/dreamteam_cli-*.whl` if missing and installs
into a uv-managed cache (does not touch the repo's `.venv/`).

### Releases — publishing to PyPI

`scripts/publish.sh` builds and uploads to PyPI. Token lives in
`.secrets` (git-ignored — copy `.secrets.example` and fill in):

```bash
cp .secrets.example .secrets
# edit .secrets, paste PYPI_TOKEN

scripts/publish.sh                              # publish to real PyPI
scripts/publish.sh --test                       # publish to TestPyPI
```

The script runs `twine check` on built artefacts before upload to
catch metadata / README rendering issues.

## Status

The package is named **`dreamteam-cli`**. Version **2.0.0** moves the methodology
to OpenCode and adds verified legacy transfer, protected recovery and an offline
runtime prerequisite. Migration is validated on **Linux** and requires POSIX
security capabilities; secure Windows legacy migration/recovery is not
implemented. Native operations without a pending migration remain separate.
Historical template snapshots are retained for safe updates from older versions.
See [GitHub releases](https://github.com/vlakir/dreamteam/releases) and
[PyPI](https://pypi.org/project/dreamteam-cli/) for published artifacts; the
validation matrix is in `specs/T171-complete-opencode-migration/acceptance.md`.
Full history is in `CHANGELOG.md`; current work and roadmap are in `BOARD.md`
and `BACKLOG.md`.

## License

[MIT](LICENSE) — Copyright (c) 2026 vlakir.

This applies to `dreamteam` itself. Projects generated via
`dreamteam init` do not automatically inherit MIT — license choice
is left to the user (add your own `LICENSE` after `init`).
