{"id":50686800,"url":"https://github.com/t1/tdder","last_synced_at":"2026-06-08T23:32:35.278Z","repository":{"id":339323204,"uuid":"1160659036","full_name":"t1/tdder","owner":"t1","description":"A Claude Code plugin that guides AI agents through disciplined Test-Driven Development and Clean Code practices.","archived":false,"fork":false,"pushed_at":"2026-06-07T17:38:44.000Z","size":615,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"trunk","last_synced_at":"2026-06-07T18:06:18.533Z","etag":null,"topics":["claude-code-plugin","clean-code","tdd"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/t1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-18T08:04:35.000Z","updated_at":"2026-06-07T17:38:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/t1/tdder","commit_stats":null,"previous_names":["t1/tdder"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/t1/tdder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t1%2Ftdder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t1%2Ftdder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t1%2Ftdder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t1%2Ftdder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/t1","download_url":"https://codeload.github.com/t1/tdder/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t1%2Ftdder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34085321,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-code-plugin","clean-code","tdd"],"created_at":"2026-06-08T23:32:35.210Z","updated_at":"2026-06-08T23:32:35.269Z","avatar_url":"https://github.com/t1.png","language":"TypeScript","funding_links":[],"categories":["Source Catalog"],"sub_categories":[],"readme":"# tdd'er\n\nA plugin for pi, Claude Code, and OpenCode that guides AI agents through disciplined Test-Driven Development\nand Clean Code practices.\n\nNote that currently this is **WORK IN PROGRESS**! I'm not even trying to keep it stable or tested.\nAt the moment, I'm writing it only for my personal use; it may also work for you, but be ready to have issues;\nI'd be happy to hear about them!\n\n## Features\n\n- **TDD discipline**: Strict Red-Green-Refactor cycles with baby steps and guessing game\n- **Clean Code review**: Automated code review during refactor phases via subagent\n- **APP mass calculations**: Objective code complexity measurement\n- **Language-agnostic core**: TDD and Clean Code principles work with any language\n- **Extensible**: Add language skills (Java, TypeScript, ...) and build-system skills (Maven, npm, ...)\n- **Unfolding Architecture**: Progressive architectural decisions — start simple, add complexity only when it reduces\n  complexity\n- **Configurable human-in-the-loop**: Control how often the AI pauses for your input\n\n## Skills\n\nLanguage-agnostic core skills work with any language. Language and build-system skills complement them automatically\nwhen matching files are detected.\n\n| Skill                      | Purpose                                                                        |\n|----------------------------|--------------------------------------------------------------------------------|\n| `tdd`                      | Core TDD process (Red-Green-Refactor, baby steps, guessing game)               |\n| `clean-code`               | Clean Code principles (naming, SOLID, smells, method design)                   |\n| `app`                      | Absolute Priority Premise mass calculations                                    |\n| `java`                     | Java-specific conventions (var, BDD testing, static imports)                   |\n| `unfolding-architecture`   | Progressive architectural decisions (start simple, unfold on demand)           |\n| `integration-architecture` | Integration messaging patterns (commands vs events, push vs pull, reliability) |\n| `maven`                    | Maven-specific conventions (test execution, project structure)                 |\n| `nested-fixture-pattern`   | JUnit nested fixture pattern for layered test preconditions                    |\n| `grill-po`                 | Requirements grilling session with a PO: sharpens terminology, documents features as Gherkin, updates bounded-context files and ADRs inline |\n| `project-hygiene`          | Interaction style, commit conventions, documentation discipline                |\n| `github-safety`            | Prompt-injection defense for GitHub issues and pull requests                   |\n| `prove-me-wrong`           | Devil's advocate mode: finds the strongest objections to the user's position   |\n\n## Extensions\n\nExtensions add active behaviour beyond passive skills — they register commands, tools, and UI components\ndirectly into the coding agent.\n\n### quarkus (pi only)\n\nIntegrates [quarkus-agent-mcp](https://github.com/quarkusio/quarkus-agent-mcp) into\n[pi](https://github.com/earendil-works/pi-coding-agent) so the LLM can manage Quarkus dev-mode\napplications without leaving the chat.\n\n**Auto-activation:** the extension detects whether the current directory is a Quarkus project\n(contains a `pom.xml` or `build.gradle` referencing `quarkus`) and starts the MCP server lazily\nin the background. All quarkus-agent-mcp tools (`quarkus_start`, `quarkus_stop`, `quarkus_status`,\n`quarkus_skills`, `quarkus_searchDocs`, `quarkus_callTool`, …) are registered as native pi tools\nand become available to the LLM automatically.\n\n**Footer status:** a live status indicator in the pi footer shows the running app state:\n\n- `quarkus ● :8080` — running on the detected port\n- `quarkus ◌ starting…` — dev mode booting\n- `quarkus ⚠ crashed` — process exited unexpectedly\n- (blank) — stopped / not started\n\n**`/quarkus` command:** a unified slash command for common Quarkus actions.\nWith no argument it opens an interactive selector; with an argument it dispatches directly.\nTab-completion lists all subcommands.\n\n| Subcommand      | Behaviour                                                                      |\n|-----------------|--------------------------------------------------------------------------------|\n| `status`        | Show current app state (direct, LLM on failure)                                |\n| `start`         | Start app in dev mode — blocks until running, shows startup log (LLM on failure) |\n| `stop`          | Stop the running app (direct, LLM on failure)                                  |\n| `logs`          | Show recent log output (direct, LLM on failure)                                |\n| `list`          | List all managed Quarkus instances (direct, LLM on failure)                    |\n| `agent-log`     | Read the MCP server's own log file (direct, LLM on failure)                   |\n| `restart`       | Hot-reload the app (direct, LLM on failure)                                    |\n| `open`          | Open the app in the browser                                                    |\n| `devui`         | Open the Quarkus Dev UI in the browser                                         |\n| `info`          | Show app status, endpoints, and dev services (requires dev mode)               |\n| `skills`        | Manage community skills: list installed, delete, browse and install new ones   |\n| `update`        | Check for Quarkus updates — output always sent to LLM for analysis             |\n| `search-tools`  | Discover Dev MCP tools on the running app — output sent to LLM for analysis    |\n| `test-affected` | Run tests affected by recent changes — results always sent to LLM for analysis |\n| `test-all`      | Run the full test suite — results always sent to LLM for analysis              |\n| `mcp-restart`   | Restart the quarkus-agent-mcp server process itself                            |\n| `mcp-tools`     | List all tools advertised by the MCP server (output sent to LLM)               |\n\n**Dispatch strategy:** direct subcommands call the MCP tool immediately and show the result as a\nnotification. On failure, the error output is automatically forwarded to the LLM with\n*\"what went wrong and how should I fix it?\"*. `update`, `test-affected`, and `test-all` always route through the LLM\nbecause their output is analytical rather than a simple pass/fail signal.\n\n### maven\n\nStructured Maven execution with test report parsing, compilation error extraction, and\nMaven Central version lookup.\n\n**pi extension:** registers `maven_run`, `maven_project_info`, and `maven_lookup_version` tools\nplus a `/maven` slash command with live progress widget.\n\n**CLI (`tdder-maven`):** the same functionality as a standalone command, usable from any agent\nthat has shell access (Claude Code, OpenCode, Cursor, terminal, …). Requires\n[`tsx`](https://github.com/privatenumber/tsx) on your `PATH`. Run `tdder-maven help` for usage.\n\nAll commands output structured JSON to stdout. Non-zero exit code on failure.\n\n### idea (pi only)\n\nIntegrates the official JetBrains [MCP Server](https://plugins.jetbrains.com/plugin/26071-mcp-server)\nplugin into pi so the LLM can use IntelliJ IDEA's PSI, inspections, refactorings, and debugger\nwithout leaving the chat.\n\n**Auto-activation:** the extension is always loaded but lazy-connects to the IDE's MCP endpoint\n(default `http://127.0.0.1:64342/sse`). On every probe it sends a cheap project-scoped call\n(e.g. `get_project_modules`) with `projectPath` = pi's CWD. Three outcomes drive the footer:\n\n- `idea ●` — IDE reachable and pi's CWD is open as a project\n- `idea ⚠ not open` — IDE reachable, but pi's CWD isn't one of the open projects (tools are hidden;\n  the list of currently open projects is surfaced for diagnosis)\n- (blank) — IDE not reachable\n\n**projectPath injection:** every JetBrains MCP tool takes an optional `projectPath`. The extension\n**always injects pi's CWD** on every forwarded call, overriding whatever the LLM tries to pass.\nThe LLM should never think about `projectPath` — same way it doesn't think about filesystem roots.\n\n**Modes of operation (vocabulary):** tools are tagged with a 2×3 lens so the LLM can pick the\nright family for the task. This vocabulary is documented per-tool in the extension's tool\ndescriptions; it may later be promoted to a dedicated `idea` skill if cross-tool patterns emerge.\n\n|             | code (static)                                  | runtime (dynamic)                             | session (IDE / env)                 |\n|-------------|------------------------------------------------|-----------------------------------------------|-------------------------------------|\n| **explore** | search symbols, get inspections, project model | debugger inspect, app logs / metrics / traces | which files are open, IDE version   |\n| **modify**  | edit, rename, reformat                         | set breakpoint, set variable, run, hot-reload | open file in editor, switch project |\n\n- **code (static)** = facts about source / config / dependencies (true regardless of any process running)\n- **runtime (dynamic)** = facts about the program being developed when it's executing\n- **session (env)** = facts about the development environment itself; mostly serves LLM↔human collaboration\n\n**Available tools** — tagged with the 2×3 modes vocabulary above (31 total):\n\n| Modes                            | Tools                                                                                                                                                                                                                                                                                                                                               |\n|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| explore/code                     | `search_symbol`, `get_symbol_info`, `search_in_files_by_regex`, `find_files_by_glob`, `list_directory_tree`, `get_project_modules`, `read_file`, `get_file_problems`, `get_project_dependencies`, `get_file_text_by_path`, `get_repositories`                                                                                                       |\n| explore/session                  | `get_all_open_file_paths`                                                                                                                                                                                                                                                                                                                           |\n| modify/session                   | `open_file_in_editor`                                                                                                                                                                                                                                                                                                                               |\n| modify/code                      | `rename_refactoring`, `reformat_file`                                                                                                                                                                                                                                                                                                               |\n| modify/runtime                   | `build_project`, `get_run_configurations`, `execute_run_configuration`                                                                                                                                                                                                                                                                              |\n| explore/runtime + modify/runtime | `xdebug_get_stack`, `xdebug_get_frame_values`, `xdebug_get_threads`, `xdebug_evaluate_expression`, `xdebug_get_value_by_path`, `xdebug_get_debugger_status`, `xdebug_list_breakpoints`, `xdebug_set_breakpoint`, `xdebug_remove_breakpoint`, `xdebug_set_variable`, `xdebug_run_to_line`, `xdebug_control_session`, `xdebug_start_debugger_session` |\n\n**Explicitly out of scope** (duplicates of pi built-ins):\n\n- `replace_text_in_file`, `create_new_file` — use pi's `edit` / `write`\n- `find_files_by_name_keyword` — use `find_files_by_glob`\n- `search_file`, `search_text`, `search_regex`, `search_in_files_by_text` — use `search_in_files_by_regex`\n- `execute_terminal_command` — redundant with pi's `bash`\n\n## Agents\n\n| Agent                 | Purpose                                       |\n|-----------------------|-----------------------------------------------|\n| `clean-code-reviewer` | Autonomous code review during refactor phases |\n\n## Hooks (Claude Code only)\n\nThe Claude Code plugin includes a `PreToolUse` hook that reminds the agent to load language/build-system skills\nbefore editing matching files:\n\n| File pattern | Skill reminded |\n|--------------|----------------|\n| `*.java`     | `java`         |\n| `pom.xml`    | `maven`        |\n\n## Configuration\n\n### Human-in-the-Loop\n\nIf no settings file exists, the TDD skill will ask on first use and persist your choice.\nYou can also create `.claude/tdder.local.md` manually in your project root:\n\n```markdown\n---\nhitl: every-phase\n---\n```\n\n| Level          | Behavior                                          |\n|----------------|---------------------------------------------------|\n| `every-phase`  | Stop after every Red, Green, Refactor phase       |\n| `end-of-cycle` | Stop after each complete Red-Green-Refactor cycle |\n| `off`          | Run autonomously, report at end                   |\n\n## Installation\n\n### pi\n\nInstall the tdder package, which registers all skills and extensions automatically:\n\n```bash\npi install git:github.com/t1/tdder\n```\n\nThe `quarkus` extension activates automatically in Quarkus projects (requires\n[jbang](https://www.jbang.dev/) on your PATH).\n\nThe `idea` extension activates when the IntelliJ IDEA MCP Server plugin is reachable\non `127.0.0.1:64342` and the current pi working directory matches an open IDE project.\n\n### Claude Code\n\nAdd this repo as a marketplace, then install the plugin:\n\n```bash\n/plugin marketplace add t1/tdder\n/plugin install tdder@t1\n```\n\nNote that the official docs are not very clear about this, but you actually need a `marketplace.json`,\neven if you have only a single plugin.\n\n### OpenCode\n\nAdd tdder to the `plugin` array in your `opencode.json` (global or project-level):\n\n```json\n{\n  \"plugin\": [\"tdder@git+https://github.com/t1/tdder.git\"]\n}\n```\n\nRestart OpenCode. The plugin auto-installs and registers all skills.\n\n## Development\n\nDevelopment currently requires [`tsx`](https://github.com/privatenumber/tsx) to be installed and available on your `PATH`, because repo utility scripts use a `#!/usr/bin/env tsx` shebang.\n\nFor example:\n\n```bash\nnpm install -g tsx\n```\n\nSeparately released pi extension packages in this repo vendor shared TypeScript from\nelsewhere in this repo during a sync step instead of publishing a separate shared\npackage. In this setup, `pretest` and `prepack` are only safety nets: after every edit\nto shared code or to a consumer of that shared code, run `npm run sync-extensions`\nimmediately so development, tests, and packaging all see the same files.\n\n## Updating\n\n### Claude Code\n\nAs of Claude Code v2.1.44, it's not an easy task to update the plugin; even uninstalling and reinstalling doesn't help.\nThe problem is that the marketplace is checked out to `~/.claude/plugins/marketplaces/t1/`,\nwhile the plugins are cached in `~/.claude/plugins/cache/t1/tdder/`.\nSo to update to a new version of the plugin, you'll have to do this:\n\n```bash\ncd ~/.claude/plugins/marketplaces/t1/ \u0026\u0026 git pull \u0026\u0026 rm -r ~/.claude/plugins/cache/t1/tdder/ \u0026\u0026 cd -\n```\n\n### OpenCode\n\ntdder updates automatically when you restart OpenCode.\n\n## Extending\n\nTo add a new language or build system, create `skills/\u003cname\u003e/SKILL.md` with the relevant conventions\n(testing framework, naming, commands, etc.).\nThe skill triggers automatically when working in projects with matching files.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft1%2Ftdder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ft1%2Ftdder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft1%2Ftdder/lists"}