Metadata-Version: 2.4
Name: d-method
Version: 1.2.4
Summary: Code-aware memory-bank framework for AI-assisted development
Author-email: Bruno <allanbruno@gmail.com>
Project-URL: Homepage, https://github.com/allanbrunoafya/d-method
Project-URL: Repository, https://github.com/allanbrunoafya/d-method
Project-URL: Changelog, https://github.com/allanbrunoafya/d-method/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/allanbrunoafya/d-method/issues
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: multilspy>=0.0.13
Requires-Dist: tree-sitter>=0.21
Requires-Dist: tree-sitter-python>=0.21
Requires-Dist: jsonschema>=4.21
Requires-Dist: jinja2>=3.1
Requires-Dist: anthropic>=0.90
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-snapshot>=0.9; extra == "dev"
Dynamic: license-file

# d-method

[![tests](https://github.com/allanbrunoafya/d-method/actions/workflows/test.yml/badge.svg)](https://github.com/allanbrunoafya/d-method/actions/workflows/test.yml)
[![PyPI](https://img.shields.io/pypi/v/d-method.svg)](https://pypi.org/project/d-method/)
[![Python](https://img.shields.io/pypi/pyversions/d-method.svg)](https://pypi.org/project/d-method/)

Code-aware memory-bank framework for AI-assisted development.

- 📜 **License:** [LICENSE](LICENSE) (MIT)
- 🛠️ **Setup:** [INSTALL.md](INSTALL.md) — prerequisites, install
  flavors, uninstall, troubleshooting.
- 🧭 **Reference:** [COMMANDS.md](COMMANDS.md) — every SKILL and
  every launcher CLI subcommand.
- 📝 **Changes:** [CHANGELOG.md](CHANGELOG.md) — release-by-release
  notes.
- 📐 **Design:** `docs/superpowers/specs/2026-05-01-d-method-design.md`
  for the full architecture.

## Status

**v1 shipped** (2026-05-04) — every milestone (M1 → M7) has
landed; every command in the cheat sheet is in production. `init`
builds the memory bank; `propose / apply / archive` drive the
per-feature spec lifecycle on top of it, with incremental refresh
between tasks; `/d-method:rigorous-run` adds the locked six-phase
audited workflow; the M6 auxiliaries (`status`, `refresh`,
`party`) plus `scripts/install.sh` make d-method usable on a real
project without hand-copying files; M7 added the v1 doc cluster
(`LICENSE`, `INSTALL.md`, `COMMANDS.md`, `docs/demo.md`).

### What works today

- ✅ `/d-method:init` — build the memory bank from scratch
  (extract → enrich → graphs → views → manifest).
- ✅ `/d-method:propose <idea>` — slugs the idea, drafts the
  four-file spec under `.d-method/specs/<change-id>/`.
- ✅ `/d-method:apply <change-id>` — implements one task per
  invocation, TDD-strict, then incremental memory-bank refresh.
- ✅ `/d-method:archive <change-id>` — atomically moves a fully
  checked spec to `.d-method/archive/`.
- ✅ `/d-method:rigorous-run <idea>` — locked six-phase
  (Analyze → Spec → Plan → Implement → Review → Close) audited
  workflow with audit→repair budget.
- ✅ `/d-method:status` — read-only health report
  (`memory: missing | fresh | stale`, active specs, active runs,
  next-step suggestion).
- ✅ `/d-method:refresh` — thin SKILL wrapper around the
  incremental refresh pipeline; closes the v1 decision that
  refresh is **never** auto-triggered before propose.
- ✅ `/d-method:party "<question>"` — non-binding 3-persona
  exploration (skeptic / architect / pragmatist) under
  `.d-method/explorations/<date>-<slug>.md`.
- ✅ `scripts/install.sh` — multi-target installer
  (`--target claude | codex | both`), idempotent, never touches
  existing `.d-method/state/` or `.d-method/specs/`.

### Milestones complete

- **M1 — Foundation:** pyproject, schemas, fixtures, CI.
- **M2 — Memory bank:** symbol extraction (tree-sitter for Python
  as of v1.2; multilspy/LSP for TypeScript); LLM enrichment
  (Anthropic + mock) with per-class hash cache; markdown views
  (`architecture.md` + `memory/<class>.md` + Mermaid mini-graphs);
  `skills/init/SKILL.md` wires the full 5-step pipeline. (The TS
  LSP path is gated behind `pytest.skip` due to multilspy 0.0.15's
  `initialize` deadlock on macOS — see `KNOWN_ISSUES.md`. The
  Python path runs live end-to-end after v1.2.)
- **M3 — Graphs & suggested agents:** `compute_graphs.py` derives
  five graphs (`classDeps`, `modules`, `testCoverage`,
  `components`, `domain`) and a `suggestedAgents` list. Four
  graphs are deterministic; only the `domain` graph and per-agent
  rationales call the LLM.
- **M4 — Per-feature flow:** `propose / apply / archive` with
  incremental refresh between tasks (Contract B:
  `git diff <manifest.repoHash>..HEAD ∪ git status --porcelain`),
  plus Q4 config (`.d-method/config.toml`) for `domainRoleMap`
  overrides.
- **M5 — Rigorous run:** locked six-phase cycle with
  `*.md.lock` sentinels (Contract C1), audit→repair (max 3, per
  Contract C4), code-review subagent fallback chain
  (`pr-review-toolkit:code-reviewer` → `superpowers:code-reviewer`
  → `general-purpose`, per Contract C6), composed close-and-archive
  with idempotency.
- **M6 — Auxiliaries + installer:** `/d-method:status` (read-only
  diagnostic, Contract M6-B), `/d-method:refresh` (thin SKILL,
  no auto-trigger per Contract M6-C), `/d-method:party`
  (non-binding 3-persona exploration, Contract M6-G), and
  `scripts/install.sh` (multi-target, idempotent, never modifies
  existing state per Contract M6-F).

- **M7 — v1 polish:** MIT [`LICENSE`](LICENSE),
  [`INSTALL.md`](INSTALL.md), [`COMMANDS.md`](COMMANDS.md), and a
  recordable [`docs/demo.md`](docs/demo.md) walk-through.
  Migrated `apply.SKILL`'s `post_task_refresh` block to the
  launcher (`.d-method/bin/d-method refresh`) so the SKILL no
  longer requires `pip install -e .` on the user side.

> **v1 is the line.** Past v1, milestone status sits inside
> [`COMMANDS.md`](COMMANDS.md) and per-SKILL changelogs rather
> than in this README, so this section becomes a stable history
> snapshot rather than a moving roadmap.

## Quickstart

```bash
# 1. Install the SKILLs + bundled python package into your project
bash scripts/install.sh --repo-root /path/to/your/repo --target both

# 2. From inside that repo, run /d-method:init once
export ANTHROPIC_API_KEY=sk-…
cd /path/to/your/repo
# In Claude Code or Codex, invoke:
/d-method:init
```

`scripts/install.sh` lays down `.claude/skills/d-method/` (Claude
Code) and/or `.agents/skills/d-method/` (Codex), bundles the
`d_method` python package alongside, and seeds
`.d-method/.gitignore` with the two non-tracked subdirs (`runs/`
and `explorations/`). Re-running it is safe — existing
`.d-method/state/` and `.d-method/specs/` are never touched.

## Quick start (developer)

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

## Sample output (M3)

After `/d-method:init`, `views/graphs/classDeps.mmd` looks like:

```mermaid
graph LR
  UserController
  UserRepository
  UserService
  UserController --> UserService
  UserService --> UserRepository
```

`views/suggested-agents.md` flags hot-spot classes (≥2 methods, no tests):

```markdown
## UserService Agent

**Domain:** service
UserService coordinates user lifecycle but has zero tests; an agent
here can grow coverage and prevent regressions.
```

## Sample output (M4)

After `/d-method:propose "Add user OAuth"`, the spec folder
`.d-method/specs/add-user-oauth/` holds four files. `tasks.md` looks
roughly like this (one TDD-ordered task per line):

```markdown
# Tasks — add-user-oauth

> Generated 2026-05-04 from idea: *Add user OAuth*

## Tasks

- [ ] Add UserService.login() returning a session
```

The companion `proposal.md`, `spec.md`, and `design.md` each follow
the same idea / change-id / date / body header layout, so the memory
bank's pages and any downstream tools can parse them with one
template.

`/d-method:apply add-user-oauth` then walks one unchecked task at a
time through RED → verify-RED → GREEN → verify-GREEN → REFACTOR,
flips the line to `- [x]`, and refreshes the memory bank with only
the files touched since the last manifest hash. When every task is
checked, `/d-method:archive add-user-oauth` moves the folder into
`.d-method/archive/`.

## Sample output (M5)

After `/d-method:rigorous-run "Add user OAuth"`, the run directory
`.d-method/runs/2026-05-04-add-user-oauth/` holds six phase docs.
Each one carries an audit history in its sibling `.meta.json` —
the `phase-3-implement.md` body looks like:

```markdown
# Phase 3 — Implement

- **Run id:** `2026-05-04-add-user-oauth`
- **Task:** Add user OAuth
- **Change id:** `add-user-oauth`

## Implementation log

### Task 1 — Add UserService.login()

- **RED:** test_login_returns_session FAILED (AssertionError: …)
- **GREEN:** test_login_returns_session PASSED
- **Refactor:** n/a — already minimal
```

`.d-method/bin/d-method rigorous_run status 2026-05-04-add-user-oauth`
prints one line per phase with its current state and (for active
phases) `audit_count`, so the user can see at a glance how much of
the Contract C4 budget remains:

```
Run: 2026-05-04-add-user-oauth
Task: Add user OAuth

Phase 0 (analyze):   locked
Phase 1 (spec):      locked
Phase 2 (plan):      locked
Phase 3 (implement): active   (audit_count=2)
Phase 4 (review):    unstarted
Phase 5 (close):     unstarted
```

A run is "sealed" once all six `*.md.lock` sentinels exist; at that
point the underlying spec has also been moved from
`.d-method/specs/<change-id>/` to `.d-method/archive/<change-id>/`.

## /d-method:status

A read-only diagnostic — never writes anything. Reports one of three
states for the memory bank:

- `missing` — `.d-method/state/manifest.json` not found.
  Next step: `/d-method:init`.
- `fresh` — manifest's recorded `repoHash` equals
  `git rev-parse HEAD`. Memory bank is up-to-date.
- `stale` — manifest exists but its hash differs from HEAD (or HEAD
  isn't reachable from the recorded hash). Next step:
  `/d-method:refresh`.

The CLI also enumerates active specs (`.d-method/specs/<change-id>/`
without an `archive/` counterpart) and active runs
(`.d-method/runs/<run-id>/` without all six `*.md.lock` sentinels)
and prints a single `Next:` line so the user knows what to do.

```bash
.d-method/bin/d-method status            # human output
.d-method/bin/d-method status --json     # machine output
```

The `.d-method/bin/d-method` launcher is dropped by
`scripts/install.sh`; it wraps `python -m d_method.scripts.<verb>`
with the right `PYTHONPATH` so the bundled package imports cleanly
without a separate `pip install` on the user side.

Per Contract M6-B the SKILL's `allowed-tools` is **exactly**
`[Read, Bash]` — status is the canonical "safe to run anywhere,
anytime" diagnostic.

## /d-method:refresh

Thin user-facing SKILL around the incremental refresh pipeline
already shipped in M2. Decides between four paths automatically:

- **skip** — manifest's `repoHash` already equals HEAD.
- **bump-only** — hash drift, but no source-extension files
  changed; just advance the manifest's `repoHash`.
- **partial** — hash drift with source files changed; re-extract
  only those files, merge with `repo.json`'s known classes.
- **full** — `--force`, missing manifest, unreachable hash, or
  unsupported language; full extract → enrich → graphs → views.

Per Contract M6-C, `/d-method:refresh` is **never auto-triggered**
before `/d-method:propose` — the user must invoke it explicitly
when status reports `stale`. (Rationale: silent refresh on every
propose call would surprise users with multi-minute LLM bills.)

## /d-method:party

A non-binding 3-persona design exploration. Mirrors `/d-method:propose`
in shape (slugify, atomic rename via tempdir staging, same-day
collision raises `FileExistsError`) but never modifies specs/, runs/,
or production code. The output lives at
`.d-method/explorations/<YYYY-MM-DD>-<slug>.md` and contains exactly
three sections in this fixed order:

1. **Skeptic** — pushes back on premature complexity.
2. **Architect** — argues structure, layers, contracts.
3. **Pragmatist** — argues for the smallest concrete experiment.

Per Contract M6-G the personas are hardcoded in v1, the LLM is
called exactly once with all three voices in a single response, and
the file is purely advisory. To convert a party take into a recorded
decision, draft a `/d-method:propose` from it (party never runs
inside `/d-method:rigorous-run`).

```bash
.d-method/bin/d-method party "should we cache the order list?" \
  --repo-root . --llm anthropic
```

## Cheat sheet

| Command | What it does |
|---|---|
| `bash scripts/install.sh --target both --repo-root <path>` | One-shot installer (`.claude/skills/` + `.agents/skills/` + `.d-method/.gitignore`). Idempotent. |
| `/d-method:init` | Build the memory bank from scratch (extract → enrich → graphs → views → manifest). |
| `/d-method:status` | Read-only health report (`memory: missing/fresh/stale`, active specs, active runs, next-step suggestion). |
| `/d-method:refresh` | Incremental refresh of the memory bank (skip / bump-only / partial / full). |
| `/d-method:propose <idea>` | Generate a four-file spec under `.d-method/specs/<change-id>/`. |
| `/d-method:apply <change-id>` | Implement the next unchecked task (TDD-strict), then incremental refresh. |
| `/d-method:archive <change-id>` | Move a fully-checked spec to `.d-method/archive/`. |
| `/d-method:rigorous-run <idea>` | Drive a locked six-phase audited run end-to-end. |
| `/d-method:party "<question>"` | Non-binding 3-persona exploration under `.d-method/explorations/`. |
| `.d-method/bin/d-method apply list-tasks <change-id>` | Print one line per task (read-only). |
| `.d-method/bin/d-method apply read <change-id>` | Print all four spec files. |
| `.d-method/bin/d-method rigorous_run list` | List every run under `.d-method/runs/` with status. |
| `.d-method/bin/d-method rigorous_run status <run-id>` | Per-phase state + audit_count for one run. |
