xtrm-tools 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -111
- package/cli/dist/index.cjs +107 -53
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/config/pi/extensions/beads.ts +24 -0
- package/hooks/beads-gate-core.mjs +6 -4
- package/hooks/beads-memory-gate.mjs +12 -5
- package/hooks/hooks.json +126 -0
- package/package.json +3 -1
- package/skills/test-planning/SKILL.md +208 -0
- package/skills/test-planning/evals/evals.json +23 -0
- package/skills/using-xtrm/SKILL.md +5 -27
- package/project-skills/tdd-guard/.claude/hooks/tdd-guard-pretool-bridge.cjs +0 -103
- package/project-skills/tdd-guard/.claude/settings.json +0 -38
- package/project-skills/tdd-guard/.claude/skills/using-tdd-guard/SKILL.md +0 -79
- package/project-skills/tdd-guard/CLAUDE.md +0 -98
- package/project-skills/tdd-guard/CONTRIBUTING.md +0 -38
- package/project-skills/tdd-guard/DEVELOPMENT.md +0 -127
- package/project-skills/tdd-guard/LICENSE +0 -21
- package/project-skills/tdd-guard/README.md +0 -398
- package/project-skills/tdd-guard/docs/adr/001-claude-session-subdirectory.md +0 -52
- package/project-skills/tdd-guard/docs/adr/002-secure-claude-binary-path.md +0 -56
- package/project-skills/tdd-guard/docs/adr/003-remove-configurable-data-directory.md +0 -56
- package/project-skills/tdd-guard/docs/adr/004-monorepo-architecture.md +0 -64
- package/project-skills/tdd-guard/docs/adr/005-claude-project-dir-support.md +0 -55
- package/project-skills/tdd-guard/docs/adr/006-phpunit-separate-repository.md +0 -93
- package/project-skills/tdd-guard/docs/adr/007-golangci-lint-path-support.md +0 -83
- package/project-skills/tdd-guard/docs/adr/008-storybook-reporter-design.md +0 -182
- package/project-skills/tdd-guard/docs/assets/tdd-guard-demo-screenshot.gif +0 -0
- package/project-skills/tdd-guard/docs/config-migration.md +0 -143
- package/project-skills/tdd-guard/docs/configuration.md +0 -137
- package/project-skills/tdd-guard/docs/custom-instructions.md +0 -43
- package/project-skills/tdd-guard/docs/enforcement.md +0 -46
- package/project-skills/tdd-guard/docs/ignore-patterns.md +0 -81
- package/project-skills/tdd-guard/docs/linting.md +0 -109
- package/project-skills/tdd-guard/docs/quick-commands.md +0 -52
- package/project-skills/tdd-guard/docs/session-management.md +0 -75
- package/project-skills/tdd-guard/docs/storybook-vitest-addon.md +0 -120
- package/project-skills/tdd-guard/docs/validation-model.md +0 -63
- package/project-skills/tdd-guard/eslint.config.mjs +0 -140
- package/project-skills/tdd-guard/package-lock.json +0 -16937
- package/project-skills/tdd-guard/package.json +0 -102
- package/project-skills/tdd-guard/reporters/go/README.md +0 -67
- package/project-skills/tdd-guard/reporters/go/cmd/tdd-guard-go/main.go +0 -127
- package/project-skills/tdd-guard/reporters/go/cmd/tdd-guard-go/main_test.go +0 -280
- package/project-skills/tdd-guard/reporters/go/go.mod +0 -3
- package/project-skills/tdd-guard/reporters/go/go.sum +0 -0
- package/project-skills/tdd-guard/reporters/go/internal/formatter/formatter.go +0 -126
- package/project-skills/tdd-guard/reporters/go/internal/formatter/formatter_test.go +0 -264
- package/project-skills/tdd-guard/reporters/go/internal/io/tee_reader.go +0 -26
- package/project-skills/tdd-guard/reporters/go/internal/io/tee_reader_test.go +0 -37
- package/project-skills/tdd-guard/reporters/go/internal/parser/mixed_reader.go +0 -94
- package/project-skills/tdd-guard/reporters/go/internal/parser/mixed_reader_test.go +0 -198
- package/project-skills/tdd-guard/reporters/go/internal/parser/parser.go +0 -245
- package/project-skills/tdd-guard/reporters/go/internal/parser/parser_test.go +0 -547
- package/project-skills/tdd-guard/reporters/go/internal/storage/storage.go +0 -35
- package/project-skills/tdd-guard/reporters/go/internal/storage/storage_test.go +0 -113
- package/project-skills/tdd-guard/reporters/go/internal/transformer/transformer.go +0 -103
- package/project-skills/tdd-guard/reporters/go/internal/transformer/transformer_test.go +0 -303
- package/project-skills/tdd-guard/reporters/jest/README.md +0 -102
- package/project-skills/tdd-guard/reporters/jest/package.json +0 -38
- package/project-skills/tdd-guard/reporters/jest/src/JestReporter.test-data.ts +0 -199
- package/project-skills/tdd-guard/reporters/jest/src/JestReporter.test.ts +0 -302
- package/project-skills/tdd-guard/reporters/jest/src/JestReporter.ts +0 -201
- package/project-skills/tdd-guard/reporters/jest/src/index.ts +0 -4
- package/project-skills/tdd-guard/reporters/jest/src/types.ts +0 -42
- package/project-skills/tdd-guard/reporters/jest/tsconfig.json +0 -11
- package/project-skills/tdd-guard/reporters/phpunit/.php-cs-fixer.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/README.md +0 -97
- package/project-skills/tdd-guard/reporters/phpunit/SYNC_README.md +0 -29
- package/project-skills/tdd-guard/reporters/phpunit/composer.json +0 -55
- package/project-skills/tdd-guard/reporters/phpunit/phpunit.xml.dist +0 -19
- package/project-skills/tdd-guard/reporters/phpunit/psalm.xml +0 -44
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/ErroredTestSubscriber.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/FailedTestSubscriber.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/IncompleteTestSubscriber.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/PassedTestSubscriber.php +0 -27
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/SkippedTestSubscriber.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/TestRunnerFinishedSubscriber.php +0 -24
- package/project-skills/tdd-guard/reporters/phpunit/src/PathValidator.php +0 -88
- package/project-skills/tdd-guard/reporters/phpunit/src/Storage.php +0 -26
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardExtension.php +0 -33
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardListener.php +0 -158
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardSubscriber.php +0 -35
- package/project-skills/tdd-guard/reporters/phpunit/src/TestResultCollector.php +0 -105
- package/project-skills/tdd-guard/reporters/phpunit/tests/PathValidatorTest.php +0 -74
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardExtensionFailedTest.php +0 -241
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardExtensionTest.php +0 -84
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardStorageLocationTest.php +0 -71
- package/project-skills/tdd-guard/reporters/pytest/README.md +0 -77
- package/project-skills/tdd-guard/reporters/pytest/pyproject.toml +0 -43
- package/project-skills/tdd-guard/reporters/pytest/pytest.ini.example +0 -7
- package/project-skills/tdd-guard/reporters/pytest/tdd_guard_pytest/__init__.py +0 -1
- package/project-skills/tdd-guard/reporters/pytest/tdd_guard_pytest/pytest_reporter.py +0 -134
- package/project-skills/tdd-guard/reporters/pytest/tests/__init__.py +0 -1
- package/project-skills/tdd-guard/reporters/pytest/tests/conftest.py +0 -3
- package/project-skills/tdd-guard/reporters/pytest/tests/helpers.py +0 -293
- package/project-skills/tdd-guard/reporters/pytest/tests/test_config_option.py +0 -38
- package/project-skills/tdd-guard/reporters/pytest/tests/test_path_validation.py +0 -59
- package/project-skills/tdd-guard/reporters/pytest/tests/test_plugin_config.py +0 -32
- package/project-skills/tdd-guard/reporters/pytest/tests/test_project_root.py +0 -296
- package/project-skills/tdd-guard/reporters/pytest/tests/test_pytest_reporter.py +0 -137
- package/project-skills/tdd-guard/reporters/rspec/Gemfile +0 -3
- package/project-skills/tdd-guard/reporters/rust/Cargo.lock +0 -458
- package/project-skills/tdd-guard/reporters/rust/Cargo.toml +0 -33
- package/project-skills/tdd-guard/reporters/rust/Makefile.example +0 -95
- package/project-skills/tdd-guard/reporters/rust/README.md +0 -88
- package/project-skills/tdd-guard/reporters/rust/src/error_parser.rs +0 -309
- package/project-skills/tdd-guard/reporters/rust/src/main.rs +0 -464
- package/project-skills/tdd-guard/reporters/rust/src/parser.rs +0 -225
- package/project-skills/tdd-guard/reporters/rust/src/transformer.rs +0 -409
- package/project-skills/tdd-guard/reporters/storybook/README.md +0 -108
- package/project-skills/tdd-guard/reporters/storybook/package-lock.json +0 -9482
- package/project-skills/tdd-guard/reporters/storybook/package.json +0 -43
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.test-data.ts +0 -22
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.test.ts +0 -190
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.ts +0 -88
- package/project-skills/tdd-guard/reporters/storybook/src/index.ts +0 -12
- package/project-skills/tdd-guard/reporters/storybook/src/types.ts +0 -37
- package/project-skills/tdd-guard/reporters/storybook/tsconfig.json +0 -11
- package/project-skills/tdd-guard/reporters/test/artifacts/go/failing/go.mod +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/go/failing/single_failing_test.go +0 -13
- package/project-skills/tdd-guard/reporters/test/artifacts/go/import/go.mod +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/go/import/single_import_error_test.go +0 -17
- package/project-skills/tdd-guard/reporters/test/artifacts/go/passing/go.mod +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/go/passing/single_passing_test.go +0 -13
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-failing.test.js +0 -5
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-import-error.test.js +0 -8
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-passing.test.js +0 -5
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SingleFailingTest.php +0 -11
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SingleImportErrorTest.php +0 -14
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SinglePassingTest.php +0 -11
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_failing.py +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_import_error.py +0 -6
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_passing.py +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/Cargo.lock +0 -7
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/Cargo.toml +0 -4
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/src/lib.rs +0 -14
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/Cargo.lock +0 -7
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/Cargo.toml +0 -4
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/src/lib.rs +0 -13
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/Cargo.lock +0 -7
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/Cargo.toml +0 -4
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/src/lib.rs +0 -14
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/Calculator.js +0 -4
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-failing.stories.js +0 -15
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-import-error.stories.js +0 -14
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-passing.stories.js +0 -15
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-failing.test.js +0 -7
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-import-error.test.js +0 -9
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-passing.test.js +0 -7
- package/project-skills/tdd-guard/reporters/test/factories/go.ts +0 -59
- package/project-skills/tdd-guard/reporters/test/factories/helpers.ts +0 -48
- package/project-skills/tdd-guard/reporters/test/factories/index.ts +0 -7
- package/project-skills/tdd-guard/reporters/test/factories/jest.ts +0 -51
- package/project-skills/tdd-guard/reporters/test/factories/phpunit.ts +0 -63
- package/project-skills/tdd-guard/reporters/test/factories/pytest.ts +0 -41
- package/project-skills/tdd-guard/reporters/test/factories/rust.ts +0 -158
- package/project-skills/tdd-guard/reporters/test/factories/storybook.ts +0 -198
- package/project-skills/tdd-guard/reporters/test/factories/vitest.ts +0 -51
- package/project-skills/tdd-guard/reporters/test/reporters.integration.test.ts +0 -735
- package/project-skills/tdd-guard/reporters/test/types.ts +0 -28
- package/project-skills/tdd-guard/reporters/vitest/README.md +0 -64
- package/project-skills/tdd-guard/reporters/vitest/package.json +0 -35
- package/project-skills/tdd-guard/reporters/vitest/src/VitestReporter.test-data.ts +0 -85
- package/project-skills/tdd-guard/reporters/vitest/src/VitestReporter.test.ts +0 -446
- package/project-skills/tdd-guard/reporters/vitest/src/VitestReporter.ts +0 -110
- package/project-skills/tdd-guard/reporters/vitest/src/index.ts +0 -4
- package/project-skills/tdd-guard/reporters/vitest/src/types.ts +0 -39
- package/project-skills/tdd-guard/reporters/vitest/tsconfig.json +0 -11
- package/project-skills/tdd-guard/src/cli/buildContext.test.ts +0 -200
- package/project-skills/tdd-guard/src/cli/buildContext.ts +0 -48
- package/project-skills/tdd-guard/src/cli/tdd-guard.test.ts +0 -159
- package/project-skills/tdd-guard/src/cli/tdd-guard.ts +0 -48
- package/project-skills/tdd-guard/src/config/Config.test.ts +0 -538
- package/project-skills/tdd-guard/src/config/Config.ts +0 -172
- package/project-skills/tdd-guard/src/contracts/schemas/guardSchemas.test.ts +0 -58
- package/project-skills/tdd-guard/src/contracts/schemas/guardSchemas.ts +0 -8
- package/project-skills/tdd-guard/src/contracts/schemas/lintSchemas.test.ts +0 -347
- package/project-skills/tdd-guard/src/contracts/schemas/lintSchemas.ts +0 -61
- package/project-skills/tdd-guard/src/contracts/schemas/pytestSchemas.test.ts +0 -24
- package/project-skills/tdd-guard/src/contracts/schemas/pytestSchemas.ts +0 -7
- package/project-skills/tdd-guard/src/contracts/schemas/reporterSchemas.test.ts +0 -377
- package/project-skills/tdd-guard/src/contracts/schemas/reporterSchemas.ts +0 -75
- package/project-skills/tdd-guard/src/contracts/schemas/toolSchemas.test.ts +0 -563
- package/project-skills/tdd-guard/src/contracts/schemas/toolSchemas.ts +0 -140
- package/project-skills/tdd-guard/src/contracts/types/ClientType.ts +0 -1
- package/project-skills/tdd-guard/src/contracts/types/ConfigOptions.ts +0 -12
- package/project-skills/tdd-guard/src/contracts/types/Context.ts +0 -16
- package/project-skills/tdd-guard/src/contracts/types/ModelClient.ts +0 -3
- package/project-skills/tdd-guard/src/contracts/types/ValidationResult.ts +0 -6
- package/project-skills/tdd-guard/src/guard/GuardManager.test.ts +0 -336
- package/project-skills/tdd-guard/src/guard/GuardManager.ts +0 -83
- package/project-skills/tdd-guard/src/hooks/HookEvents.test.ts +0 -107
- package/project-skills/tdd-guard/src/hooks/HookEvents.ts +0 -39
- package/project-skills/tdd-guard/src/hooks/fileTypeDetection.ts +0 -16
- package/project-skills/tdd-guard/src/hooks/postToolLint.test.ts +0 -327
- package/project-skills/tdd-guard/src/hooks/postToolLint.ts +0 -165
- package/project-skills/tdd-guard/src/hooks/processHookData.test.ts +0 -465
- package/project-skills/tdd-guard/src/hooks/processHookData.ts +0 -203
- package/project-skills/tdd-guard/src/hooks/sessionHandler.test.ts +0 -136
- package/project-skills/tdd-guard/src/hooks/sessionHandler.ts +0 -31
- package/project-skills/tdd-guard/src/hooks/userPromptHandler.test.ts +0 -131
- package/project-skills/tdd-guard/src/hooks/userPromptHandler.ts +0 -55
- package/project-skills/tdd-guard/src/index.ts +0 -19
- package/project-skills/tdd-guard/src/linters/Linter.ts +0 -5
- package/project-skills/tdd-guard/src/linters/eslint/ESLint.test.ts +0 -183
- package/project-skills/tdd-guard/src/linters/eslint/ESLint.ts +0 -82
- package/project-skills/tdd-guard/src/linters/golangci/GolangciLint.test.ts +0 -170
- package/project-skills/tdd-guard/src/linters/golangci/GolangciLint.ts +0 -148
- package/project-skills/tdd-guard/src/processors/index.ts +0 -1
- package/project-skills/tdd-guard/src/processors/lintProcessor.ts +0 -77
- package/project-skills/tdd-guard/src/processors/testResults/TestResultsProcessor.test.ts +0 -303
- package/project-skills/tdd-guard/src/processors/testResults/TestResultsProcessor.ts +0 -255
- package/project-skills/tdd-guard/src/providers/LinterProvider.test.ts +0 -43
- package/project-skills/tdd-guard/src/providers/LinterProvider.ts +0 -20
- package/project-skills/tdd-guard/src/providers/ModelClientProvider.test.ts +0 -68
- package/project-skills/tdd-guard/src/providers/ModelClientProvider.ts +0 -22
- package/project-skills/tdd-guard/src/storage/FileStorage.test.ts +0 -76
- package/project-skills/tdd-guard/src/storage/FileStorage.ts +0 -108
- package/project-skills/tdd-guard/src/storage/MemoryStorage.ts +0 -57
- package/project-skills/tdd-guard/src/storage/Storage.test.ts +0 -227
- package/project-skills/tdd-guard/src/storage/Storage.ts +0 -17
- package/project-skills/tdd-guard/src/validation/context/context.test.ts +0 -364
- package/project-skills/tdd-guard/src/validation/context/context.ts +0 -155
- package/project-skills/tdd-guard/src/validation/models/AnthropicApi.test.ts +0 -171
- package/project-skills/tdd-guard/src/validation/models/AnthropicApi.ts +0 -49
- package/project-skills/tdd-guard/src/validation/models/ClaudeAgentSdk.test.ts +0 -167
- package/project-skills/tdd-guard/src/validation/models/ClaudeAgentSdk.ts +0 -54
- package/project-skills/tdd-guard/src/validation/models/ClaudeCli.test.ts +0 -239
- package/project-skills/tdd-guard/src/validation/models/ClaudeCli.ts +0 -57
- package/project-skills/tdd-guard/src/validation/prompts/file-types.ts +0 -52
- package/project-skills/tdd-guard/src/validation/prompts/operations/edit.ts +0 -58
- package/project-skills/tdd-guard/src/validation/prompts/operations/multi-edit.ts +0 -54
- package/project-skills/tdd-guard/src/validation/prompts/operations/write.ts +0 -54
- package/project-skills/tdd-guard/src/validation/prompts/response.ts +0 -40
- package/project-skills/tdd-guard/src/validation/prompts/rules.ts +0 -51
- package/project-skills/tdd-guard/src/validation/prompts/system-prompt.ts +0 -10
- package/project-skills/tdd-guard/src/validation/prompts/tools/lint-results.ts +0 -15
- package/project-skills/tdd-guard/src/validation/prompts/tools/test-output.ts +0 -14
- package/project-skills/tdd-guard/src/validation/prompts/tools/todos.ts +0 -9
- package/project-skills/tdd-guard/src/validation/validator.test.ts +0 -268
- package/project-skills/tdd-guard/src/validation/validator.ts +0 -159
- package/project-skills/tdd-guard/test/artifacts/go/.golangci.yml +0 -6
- package/project-skills/tdd-guard/test/artifacts/go/with-issues/file-with-issues.go +0 -12
- package/project-skills/tdd-guard/test/artifacts/go/with-issues/go.mod +0 -3
- package/project-skills/tdd-guard/test/artifacts/go/without-issues/file-without-issues.go +0 -7
- package/project-skills/tdd-guard/test/artifacts/go/without-issues/go.mod +0 -3
- package/project-skills/tdd-guard/test/artifacts/javascript/eslint.config.js +0 -20
- package/project-skills/tdd-guard/test/artifacts/javascript/file-with-issues.js +0 -12
- package/project-skills/tdd-guard/test/artifacts/javascript/file-without-issues.js +0 -10
- package/project-skills/tdd-guard/test/hooks/fileTypeDetection.test.ts +0 -26
- package/project-skills/tdd-guard/test/hooks/processHookData.fileType.test.ts +0 -46
- package/project-skills/tdd-guard/test/hooks/processHookData.python.test.ts +0 -68
- package/project-skills/tdd-guard/test/integration/test-context.test.ts +0 -66
- package/project-skills/tdd-guard/test/integration/validator.core.test.ts +0 -96
- package/project-skills/tdd-guard/test/integration/validator.scenarios.test.ts +0 -497
- package/project-skills/tdd-guard/test/utils/assertions.ts +0 -29
- package/project-skills/tdd-guard/test/utils/factories/contextFactory.ts +0 -30
- package/project-skills/tdd-guard/test/utils/factories/editFactory.ts +0 -82
- package/project-skills/tdd-guard/test/utils/factories/helpers.test.ts +0 -46
- package/project-skills/tdd-guard/test/utils/factories/helpers.ts +0 -46
- package/project-skills/tdd-guard/test/utils/factories/lintFactory.ts +0 -352
- package/project-skills/tdd-guard/test/utils/factories/modelClientProviderFactory.ts +0 -21
- package/project-skills/tdd-guard/test/utils/factories/multiEditFactory.ts +0 -79
- package/project-skills/tdd-guard/test/utils/factories/operations.ts +0 -57
- package/project-skills/tdd-guard/test/utils/factories/reporterFactory.ts +0 -55
- package/project-skills/tdd-guard/test/utils/factories/scenarios/index.ts +0 -22
- package/project-skills/tdd-guard/test/utils/factories/scenarios/languages/python.ts +0 -745
- package/project-skills/tdd-guard/test/utils/factories/scenarios/languages/typescript.ts +0 -767
- package/project-skills/tdd-guard/test/utils/factories/scenarios/types.ts +0 -77
- package/project-skills/tdd-guard/test/utils/factories/scenarios/utils.ts +0 -15
- package/project-skills/tdd-guard/test/utils/factories/sessionStartFactory.ts +0 -36
- package/project-skills/tdd-guard/test/utils/factories/testDefaults.ts +0 -90
- package/project-skills/tdd-guard/test/utils/factories/testResultsFactory.ts +0 -234
- package/project-skills/tdd-guard/test/utils/factories/todoFactory.ts +0 -99
- package/project-skills/tdd-guard/test/utils/factories/userPromptSubmitFactory.ts +0 -39
- package/project-skills/tdd-guard/test/utils/factories/writeFactory.ts +0 -70
- package/project-skills/tdd-guard/test/utils/index.ts +0 -131
- package/project-skills/tdd-guard/tsconfig.build.json +0 -16
- package/project-skills/tdd-guard/tsconfig.eslint.json +0 -17
- package/project-skills/tdd-guard/tsconfig.json +0 -32
- package/project-skills/tdd-guard/tsconfig.node.json +0 -10
- package/project-skills/tdd-guard/vitest.config.ts +0 -85
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
2
|
-
import { ClaudeCli } from './ClaudeCli'
|
|
3
|
-
import { execFileSync } from 'child_process'
|
|
4
|
-
import { homedir } from 'os'
|
|
5
|
-
import { join } from 'path'
|
|
6
|
-
import * as fs from 'fs'
|
|
7
|
-
import { Config } from '../../config/Config'
|
|
8
|
-
|
|
9
|
-
vi.mock('child_process')
|
|
10
|
-
vi.mock('fs', { spy: true })
|
|
11
|
-
|
|
12
|
-
const mockExecFileSync = vi.mocked(execFileSync)
|
|
13
|
-
|
|
14
|
-
// Test constants
|
|
15
|
-
const DEFAULT_TEST_PROMPT = 'test prompt'
|
|
16
|
-
|
|
17
|
-
describe('ClaudeCli', () => {
|
|
18
|
-
let sut: Awaited<ReturnType<typeof createSut>>
|
|
19
|
-
let client: ClaudeCli
|
|
20
|
-
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
sut = createSut()
|
|
23
|
-
client = sut.client
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
describe('command construction', () => {
|
|
27
|
-
test('uses claude command', async () => {
|
|
28
|
-
const call = await sut.askAndGetCall()
|
|
29
|
-
expect(call.command).toContain('claude')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('uses correct flags', async () => {
|
|
33
|
-
const call = await sut.askAndGetCall()
|
|
34
|
-
expect(call.args).toEqual([
|
|
35
|
-
'-',
|
|
36
|
-
'--output-format',
|
|
37
|
-
'json',
|
|
38
|
-
'--max-turns',
|
|
39
|
-
'5',
|
|
40
|
-
'--model',
|
|
41
|
-
'sonnet',
|
|
42
|
-
'--disallowed-tools',
|
|
43
|
-
'TodoWrite',
|
|
44
|
-
'--strict-mcp-config',
|
|
45
|
-
])
|
|
46
|
-
})
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
describe('subprocess configuration', () => {
|
|
50
|
-
test('passes prompt via input option', async () => {
|
|
51
|
-
const prompt = 'Does this follow TDD?'
|
|
52
|
-
const call = await sut.askAndGetCall(prompt)
|
|
53
|
-
expect(call.options.input).toBe(prompt)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
test('uses utf-8 encoding', async () => {
|
|
57
|
-
const call = await sut.askAndGetCall()
|
|
58
|
-
expect(call.options.encoding).toBe('utf-8')
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
test('sets timeout to 60 seconds', async () => {
|
|
62
|
-
const call = await sut.askAndGetCall()
|
|
63
|
-
expect(call.options.timeout).toBe(60000)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
test('executes claude command from .claude subdirectory', async () => {
|
|
67
|
-
const call = await sut.askAndGetCall()
|
|
68
|
-
expect(call.options.cwd).toContain('.claude')
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
test('creates .claude directory if it does not exist', async () => {
|
|
72
|
-
const mockMkdirSync = vi.spyOn(fs, 'mkdirSync')
|
|
73
|
-
const mockExistsSync = vi.spyOn(fs, 'existsSync')
|
|
74
|
-
|
|
75
|
-
mockExistsSync.mockReturnValue(false)
|
|
76
|
-
|
|
77
|
-
await client.ask('test')
|
|
78
|
-
|
|
79
|
-
expect(mockMkdirSync).toHaveBeenCalledWith(
|
|
80
|
-
expect.stringContaining('.claude'),
|
|
81
|
-
{ recursive: true }
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
mockMkdirSync.mockRestore()
|
|
85
|
-
mockExistsSync.mockRestore()
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
describe('platform-specific shell option', () => {
|
|
90
|
-
let originalPlatform: PropertyDescriptor | undefined
|
|
91
|
-
|
|
92
|
-
beforeEach(() => {
|
|
93
|
-
originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform')
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
afterEach(() => {
|
|
97
|
-
if (originalPlatform) {
|
|
98
|
-
Object.defineProperty(process, 'platform', originalPlatform)
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
test.each([
|
|
103
|
-
['win32', true],
|
|
104
|
-
['darwin', false],
|
|
105
|
-
['linux', false],
|
|
106
|
-
])(
|
|
107
|
-
'platform %s sets shell option to %s',
|
|
108
|
-
async (platform, expectedShell) => {
|
|
109
|
-
// Windows needs shell: true to execute 'claude' (.cmd/.bat files)
|
|
110
|
-
Object.defineProperty(process, 'platform', { value: platform })
|
|
111
|
-
|
|
112
|
-
const call = await sut.askAndGetCall()
|
|
113
|
-
|
|
114
|
-
expect(call.options.shell).toBe(expectedShell)
|
|
115
|
-
}
|
|
116
|
-
)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
describe('response handling', () => {
|
|
120
|
-
test('extracts and returns the result field from CLI output', async () => {
|
|
121
|
-
const modelResponse = '```json\n{"approved": true}\n```'
|
|
122
|
-
const cliOutput = JSON.stringify({ result: modelResponse })
|
|
123
|
-
mockExecFileSync.mockReturnValue(cliOutput)
|
|
124
|
-
|
|
125
|
-
const result = await client.ask(DEFAULT_TEST_PROMPT)
|
|
126
|
-
|
|
127
|
-
expect(result).toBe(modelResponse)
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
test('extracts result field from complex CLI responses', async () => {
|
|
131
|
-
const modelResponse =
|
|
132
|
-
'Here is the analysis:\n```json\n{"approved": true}\n```\nThat concludes the review.'
|
|
133
|
-
const cliOutput = JSON.stringify({
|
|
134
|
-
result: modelResponse,
|
|
135
|
-
metadata: { model: 'sonnet' },
|
|
136
|
-
})
|
|
137
|
-
mockExecFileSync.mockReturnValue(cliOutput)
|
|
138
|
-
|
|
139
|
-
const result = await client.ask(DEFAULT_TEST_PROMPT)
|
|
140
|
-
|
|
141
|
-
expect(result).toBe(modelResponse)
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
test('returns undefined when result field is missing', async () => {
|
|
145
|
-
const cliOutput = JSON.stringify({ error: 'No result' })
|
|
146
|
-
mockExecFileSync.mockReturnValue(cliOutput)
|
|
147
|
-
|
|
148
|
-
const result = await client.ask(DEFAULT_TEST_PROMPT)
|
|
149
|
-
|
|
150
|
-
expect(result).toBeUndefined()
|
|
151
|
-
})
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
describe('error handling', () => {
|
|
155
|
-
test('throws error when execFileSync fails', async () => {
|
|
156
|
-
mockExecFileSync.mockImplementation(() => {
|
|
157
|
-
throw new Error('Command failed')
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
await expect(client.ask('test')).rejects.toThrow('Command failed')
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
test('throws error when CLI output is not valid JSON', async () => {
|
|
164
|
-
const rawOutput = 'invalid json or error message'
|
|
165
|
-
mockExecFileSync.mockReturnValue(rawOutput)
|
|
166
|
-
|
|
167
|
-
await expect(client.ask('test')).rejects.toThrow()
|
|
168
|
-
})
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
describe('security', () => {
|
|
172
|
-
test('uses execFileSync with system claude when useSystemClaude is true', async () => {
|
|
173
|
-
const localSut = createSut({ useSystemClaude: true })
|
|
174
|
-
await localSut.client.ask(DEFAULT_TEST_PROMPT)
|
|
175
|
-
|
|
176
|
-
const call = localSut.getLastCall()
|
|
177
|
-
expect(call.command).toBe('claude')
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
test('uses execFileSync with local claude path when useSystemClaude is false', async () => {
|
|
181
|
-
const localSut = createSut({ useSystemClaude: false })
|
|
182
|
-
await localSut.client.ask(DEFAULT_TEST_PROMPT)
|
|
183
|
-
|
|
184
|
-
const call = localSut.getLastCall()
|
|
185
|
-
expect(call.command).toBe(join(homedir(), '.claude', 'local', 'claude'))
|
|
186
|
-
})
|
|
187
|
-
})
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
// Test Helpers
|
|
191
|
-
function createSut(options: { useSystemClaude?: boolean } = {}) {
|
|
192
|
-
// Setup mocks
|
|
193
|
-
vi.clearAllMocks()
|
|
194
|
-
mockExecFileSync.mockReturnValue(JSON.stringify({ result: 'test' }))
|
|
195
|
-
vi.spyOn(fs, 'existsSync').mockReturnValue(true)
|
|
196
|
-
|
|
197
|
-
const config = new Config({ useSystemClaude: options.useSystemClaude })
|
|
198
|
-
const client = new ClaudeCli(config)
|
|
199
|
-
|
|
200
|
-
const mockResponse = (response: string | object): void => {
|
|
201
|
-
const jsonResponse =
|
|
202
|
-
typeof response === 'string'
|
|
203
|
-
? JSON.stringify({ result: response })
|
|
204
|
-
: JSON.stringify(response)
|
|
205
|
-
mockExecFileSync.mockReturnValue(jsonResponse)
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const getLastCall = (): {
|
|
209
|
-
command: string
|
|
210
|
-
args: string[]
|
|
211
|
-
options: Record<string, unknown>
|
|
212
|
-
} => {
|
|
213
|
-
const lastCall =
|
|
214
|
-
mockExecFileSync.mock.calls[mockExecFileSync.mock.calls.length - 1]
|
|
215
|
-
return {
|
|
216
|
-
command: lastCall[0] as string,
|
|
217
|
-
args: lastCall[1] as string[],
|
|
218
|
-
options: lastCall[2] as Record<string, unknown>,
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const askAndGetCall = async (
|
|
223
|
-
prompt = DEFAULT_TEST_PROMPT
|
|
224
|
-
): Promise<{
|
|
225
|
-
command: string
|
|
226
|
-
args: string[]
|
|
227
|
-
options: Record<string, unknown>
|
|
228
|
-
}> => {
|
|
229
|
-
await client.ask(prompt)
|
|
230
|
-
return getLastCall()
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
client,
|
|
235
|
-
mockResponse,
|
|
236
|
-
getLastCall,
|
|
237
|
-
askAndGetCall,
|
|
238
|
-
}
|
|
239
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from 'child_process'
|
|
2
|
-
import { join } from 'path'
|
|
3
|
-
import { homedir } from 'os'
|
|
4
|
-
import { existsSync, mkdirSync } from 'fs'
|
|
5
|
-
import { IModelClient } from '../../contracts/types/ModelClient'
|
|
6
|
-
import { Config } from '../../config/Config'
|
|
7
|
-
|
|
8
|
-
export class ClaudeCli implements IModelClient {
|
|
9
|
-
private readonly config: Config
|
|
10
|
-
|
|
11
|
-
constructor(config?: Config) {
|
|
12
|
-
this.config = config ?? new Config()
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async ask(prompt: string): Promise<string> {
|
|
16
|
-
const claudeBinary = this.getClaudeBinary()
|
|
17
|
-
|
|
18
|
-
const args = [
|
|
19
|
-
'-',
|
|
20
|
-
'--output-format',
|
|
21
|
-
'json',
|
|
22
|
-
'--max-turns',
|
|
23
|
-
'5',
|
|
24
|
-
'--model',
|
|
25
|
-
'sonnet',
|
|
26
|
-
'--disallowed-tools',
|
|
27
|
-
'TodoWrite',
|
|
28
|
-
'--strict-mcp-config',
|
|
29
|
-
]
|
|
30
|
-
const claudeDir = join(process.cwd(), '.claude')
|
|
31
|
-
|
|
32
|
-
if (!existsSync(claudeDir)) {
|
|
33
|
-
mkdirSync(claudeDir, { recursive: true })
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const output = execFileSync(claudeBinary, args, {
|
|
37
|
-
encoding: 'utf-8',
|
|
38
|
-
timeout: 60000,
|
|
39
|
-
input: prompt,
|
|
40
|
-
cwd: claudeDir,
|
|
41
|
-
shell: process.platform === 'win32',
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
// Parse the Claude CLI response and extract the result field
|
|
45
|
-
const response = JSON.parse(output)
|
|
46
|
-
|
|
47
|
-
return response.result
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private getClaudeBinary(): string {
|
|
51
|
-
if (this.config.useSystemClaude) {
|
|
52
|
-
return 'claude'
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return join(homedir(), '.claude', 'local', 'claude')
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export const FILE_TYPES = `## File Type Specific Rules
|
|
2
|
-
|
|
3
|
-
### Identifying File Types
|
|
4
|
-
- **Test files**: Contain \`.test.\`, \`.spec.\`, or \`test/\` in the path
|
|
5
|
-
- **Implementation files**: All other source files
|
|
6
|
-
|
|
7
|
-
### Test File Rules
|
|
8
|
-
|
|
9
|
-
#### Always Allowed:
|
|
10
|
-
- **Adding ONE new test** - This is ALWAYS allowed regardless of test output (foundation of TDD cycle)
|
|
11
|
-
- Modifying existing tests without adding new ones
|
|
12
|
-
- Setting up test infrastructure and utilities
|
|
13
|
-
|
|
14
|
-
**CRITICAL**: Adding a single test to a test file does NOT require prior test output. Writing the first failing test is the start of the TDD cycle.
|
|
15
|
-
|
|
16
|
-
#### Violations:
|
|
17
|
-
- Adding multiple new tests simultaneously
|
|
18
|
-
- Refactoring tests without running them first
|
|
19
|
-
|
|
20
|
-
#### Refactoring Tests:
|
|
21
|
-
- ONLY allowed when relevant tests are passing
|
|
22
|
-
- Moving test setup to beforeEach: Requires passing tests
|
|
23
|
-
- Extracting test helpers: Requires passing tests
|
|
24
|
-
- Blocked if tests are failing, no test output, or only irrelevant test output
|
|
25
|
-
|
|
26
|
-
**For test refactoring**: "Relevant tests" are the tests in the file being refactored
|
|
27
|
-
|
|
28
|
-
### Implementation File Rules
|
|
29
|
-
|
|
30
|
-
#### Creation Rules by Test Failure Type:
|
|
31
|
-
|
|
32
|
-
| Test Failure | Allowed Implementation |
|
|
33
|
-
|-------------|----------------------|
|
|
34
|
-
| "X is not defined" | Create empty class/function stub only |
|
|
35
|
-
| "X is not a constructor" | Create empty class only |
|
|
36
|
-
| "X is not a function" | Add method stub only |
|
|
37
|
-
| Assertion error (e.g., "expected X to be Y") | Implement logic to pass assertion |
|
|
38
|
-
| No test output | Nothing - must run test first |
|
|
39
|
-
| Irrelevant test output | Nothing - must run relevant test |
|
|
40
|
-
|
|
41
|
-
#### Refactoring Implementation:
|
|
42
|
-
- ONLY allowed when relevant tests are passing
|
|
43
|
-
- Blocked if tests are failing
|
|
44
|
-
- Blocked if no test output
|
|
45
|
-
- Blocked if test output is for unrelated code
|
|
46
|
-
|
|
47
|
-
**What are "relevant tests"?**
|
|
48
|
-
- Tests that exercise the code being refactored
|
|
49
|
-
- Tests that would fail if the refactored code was broken
|
|
50
|
-
- Tests that import or depend on the module being changed
|
|
51
|
-
- Key principle: The test output must show tests for the code you're changing
|
|
52
|
-
`
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
export const EDIT = `## Analyzing Edit Operations
|
|
2
|
-
|
|
3
|
-
This section shows the code changes being proposed. Compare the old content with the new content to identify what's being added, removed, or modified.
|
|
4
|
-
|
|
5
|
-
### Your Task
|
|
6
|
-
You are reviewing an Edit operation where existing code is being modified. You must determine if this edit violates TDD principles.
|
|
7
|
-
|
|
8
|
-
**IMPORTANT**: First identify if this is a test file or implementation file by checking the file path for \`.test.\`, \`.spec.\`, or \`test/\`.
|
|
9
|
-
|
|
10
|
-
### How to Count New Tests
|
|
11
|
-
**CRITICAL**: A test is only "new" if it doesn't exist in the old content.
|
|
12
|
-
|
|
13
|
-
1. **Compare old content vs new content character by character**
|
|
14
|
-
- Find test declarations: \`test(\`, \`it(\`, \`describe(\`
|
|
15
|
-
- A test that exists in both old and new is NOT new
|
|
16
|
-
- Only count tests that appear in new but not in old
|
|
17
|
-
- Count the NUMBER of new tests added, not the total tests in the file
|
|
18
|
-
|
|
19
|
-
2. **What counts as a new test:**
|
|
20
|
-
- A test block that wasn't in the old content
|
|
21
|
-
- NOT: Moving an existing test to a different location
|
|
22
|
-
- NOT: Renaming an existing test
|
|
23
|
-
- NOT: Reformatting or refactoring existing tests
|
|
24
|
-
|
|
25
|
-
3. **Multiple test check:**
|
|
26
|
-
- One new test = Allowed (part of TDD cycle)
|
|
27
|
-
- Two or more new tests = Violation
|
|
28
|
-
|
|
29
|
-
**Example**: If old content has 1 test and new content has 2 tests, that's adding 1 new test (allowed), NOT 2 tests total.
|
|
30
|
-
|
|
31
|
-
### Analyzing Test File Changes
|
|
32
|
-
|
|
33
|
-
**For test files**: Adding ONE new test is ALWAYS allowed - no test output required. This is the foundation of TDD.
|
|
34
|
-
|
|
35
|
-
### Analyzing Implementation File Changes
|
|
36
|
-
|
|
37
|
-
**For implementation files**:
|
|
38
|
-
|
|
39
|
-
1. **Check the test output** to understand the current failure
|
|
40
|
-
2. **Match implementation to failure type:**
|
|
41
|
-
- "not defined" → Only create empty class/function
|
|
42
|
-
- "not a constructor" → Only create empty class
|
|
43
|
-
- "not a function" → Only add method stub
|
|
44
|
-
- Assertion error (e.g., "expected 0 to be 4") → Implement minimal logic to make it pass
|
|
45
|
-
|
|
46
|
-
3. **Verify minimal implementation:**
|
|
47
|
-
- Don't add extra methods
|
|
48
|
-
- Don't add error handling unless tested
|
|
49
|
-
- Don't implement features beyond current test
|
|
50
|
-
|
|
51
|
-
### Example Analysis
|
|
52
|
-
|
|
53
|
-
**Scenario**: Test fails with "Calculator is not defined"
|
|
54
|
-
- Allowed: Add \`export class Calculator {}\`
|
|
55
|
-
- Violation: Add \`export class Calculator { add(a, b) { return a + b; } }\`
|
|
56
|
-
- **Reason**: Should only fix "not defined", not implement methods
|
|
57
|
-
|
|
58
|
-
`
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export const MULTI_EDIT = `## Analyzing MultiEdit Operations
|
|
2
|
-
|
|
3
|
-
This section shows the code changes being proposed. Compare the old content with the new content to identify what's being added, removed, or modified.
|
|
4
|
-
|
|
5
|
-
### Your Task
|
|
6
|
-
You are reviewing a MultiEdit operation where multiple edits are being applied to the same file. Each edit must be evaluated for TDD compliance.
|
|
7
|
-
|
|
8
|
-
**FIRST**: Check the file path to identify if this is a test file (\`.test.\`, \`.spec.\`, or \`test/\`) or implementation file.
|
|
9
|
-
|
|
10
|
-
### How to Analyze Multiple Edits
|
|
11
|
-
|
|
12
|
-
1. **Process edits sequentially**
|
|
13
|
-
- Each edit builds on the previous one
|
|
14
|
-
- Track cumulative changes across all edits
|
|
15
|
-
- Count total new tests across ALL edits
|
|
16
|
-
|
|
17
|
-
2. **Counting new tests across edits:**
|
|
18
|
-
- Start with the original file content
|
|
19
|
-
- Apply each edit in sequence
|
|
20
|
-
- Count tests that appear in final result but not in original
|
|
21
|
-
- Multiple new tests across all edits = Violation
|
|
22
|
-
|
|
23
|
-
3. **Common patterns to watch for:**
|
|
24
|
-
- Edit 1: Adds one test (OK)
|
|
25
|
-
- Edit 2: Adds another test (VIOLATION - 2 total new tests)
|
|
26
|
-
|
|
27
|
-
### Test File Changes
|
|
28
|
-
|
|
29
|
-
**For test files**: Adding ONE new test total across all edits is allowed - no test output required. Multiple new tests = violation.
|
|
30
|
-
|
|
31
|
-
### Implementation Changes in MultiEdit
|
|
32
|
-
|
|
33
|
-
1. **Each edit must be justified**
|
|
34
|
-
- Check if test output supports the change
|
|
35
|
-
- Verify incremental implementation
|
|
36
|
-
- No edit should over-implement
|
|
37
|
-
|
|
38
|
-
2. **Sequential dependency**
|
|
39
|
-
- Later edits may depend on earlier ones
|
|
40
|
-
- But this doesn't justify multiple new tests
|
|
41
|
-
- Each edit should still follow minimal implementation
|
|
42
|
-
|
|
43
|
-
### Example MultiEdit Analysis
|
|
44
|
-
|
|
45
|
-
**Edit 1**: Adds empty Calculator class
|
|
46
|
-
- Test output: "Calculator is not defined"
|
|
47
|
-
- Analysis: Appropriate minimal fix
|
|
48
|
-
|
|
49
|
-
**Edit 2**: Adds both add() and subtract() methods
|
|
50
|
-
- Test output: "calculator.add is not a function"
|
|
51
|
-
- Analysis: VIOLATION - Should only add add() method
|
|
52
|
-
|
|
53
|
-
**Reason**: "Over-implementation in Edit 2. Test only requires add() method but edit adds both add() and subtract(). Implement only the method causing the test failure."
|
|
54
|
-
`
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export const WRITE = `## Analyzing Write Operations
|
|
2
|
-
|
|
3
|
-
This section shows the new file being created. Analyze the content to determine if it follows TDD principles for new file creation.
|
|
4
|
-
|
|
5
|
-
### Your Task
|
|
6
|
-
You are reviewing a Write operation where a new file is being created. Determine if this violates TDD principles.
|
|
7
|
-
|
|
8
|
-
**FIRST**: Check the file path to identify if this is a test file (\`.test.\`, \`.spec.\`, or \`test/\`) or implementation file.
|
|
9
|
-
|
|
10
|
-
### Write Operation Rules
|
|
11
|
-
|
|
12
|
-
1. **Creating a test file:**
|
|
13
|
-
- Usually the first step in TDD (Red phase)
|
|
14
|
-
- Should contain only ONE test initially
|
|
15
|
-
- Multiple tests in new test file = Violation
|
|
16
|
-
- Exception: Test utilities or setup files
|
|
17
|
-
|
|
18
|
-
2. **Creating an implementation file:**
|
|
19
|
-
- Must have evidence of a failing test
|
|
20
|
-
- Check test output for justification
|
|
21
|
-
- Implementation must match test failure type
|
|
22
|
-
- No test output = Likely violation
|
|
23
|
-
|
|
24
|
-
3. **Special considerations:**
|
|
25
|
-
- Configuration files: Generally allowed
|
|
26
|
-
- Test helpers/utilities: Allowed if supporting TDD
|
|
27
|
-
- Empty stubs: Allowed if addressing test failure
|
|
28
|
-
|
|
29
|
-
### Common Write Scenarios
|
|
30
|
-
|
|
31
|
-
**Scenario 1**: Writing first test file
|
|
32
|
-
- Allowed: File with one test
|
|
33
|
-
- Violation: File with multiple tests
|
|
34
|
-
- Reason: TDD requires one test at a time
|
|
35
|
-
|
|
36
|
-
**Scenario 2**: Writing implementation without test
|
|
37
|
-
- Check for test output
|
|
38
|
-
- No output = "Premature implementation"
|
|
39
|
-
- With output = Verify it matches implementation
|
|
40
|
-
|
|
41
|
-
**Scenario 3**: Writing full implementation
|
|
42
|
-
- Test shows "not defined"
|
|
43
|
-
- Writing complete class with methods = Violation
|
|
44
|
-
- Should write minimal stub first
|
|
45
|
-
|
|
46
|
-
### Key Questions for Write Operations
|
|
47
|
-
|
|
48
|
-
1. Is this creating a test or implementation file?
|
|
49
|
-
2. If test: Does it contain only one test?
|
|
50
|
-
3. If implementation: Is there a failing test?
|
|
51
|
-
4. Does the implementation match the test failure?
|
|
52
|
-
|
|
53
|
-
## Changes to Review
|
|
54
|
-
`
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export const RESPONSE = `## Your Response
|
|
2
|
-
|
|
3
|
-
### Format
|
|
4
|
-
Respond with a JSON object:
|
|
5
|
-
\`\`\`json
|
|
6
|
-
{
|
|
7
|
-
"decision": "block" | null,
|
|
8
|
-
"reason": "Clear explanation with actionable next steps"
|
|
9
|
-
}
|
|
10
|
-
\`\`\`
|
|
11
|
-
|
|
12
|
-
### Decision Values
|
|
13
|
-
- **"block"**: Clear TDD principle violation detected
|
|
14
|
-
- **null**: Changes follow TDD principles OR insufficient information to determine
|
|
15
|
-
|
|
16
|
-
### Writing Effective Reasons
|
|
17
|
-
|
|
18
|
-
When blocking, your reason must:
|
|
19
|
-
1. **Identify the specific violation** (e.g., "Multiple test addition")
|
|
20
|
-
2. **Explain why it violates TDD** (e.g., "Adding 2 tests at once")
|
|
21
|
-
3. **Provide the correct next step** (e.g., "Add only one test first")
|
|
22
|
-
|
|
23
|
-
#### Example Block Reasons:
|
|
24
|
-
- "Multiple test addition violation - adding 2 new tests simultaneously. Write and run only ONE test at a time to maintain TDD discipline."
|
|
25
|
-
- "Over-implementation violation. Test fails with 'Calculator is not defined' but implementation adds both class AND method. Create only an empty class first, then run test again."
|
|
26
|
-
- "Refactoring without passing tests. Test output shows failures. Fix failing tests first, ensure all pass, then refactor."
|
|
27
|
-
- "Premature implementation - implementing without a failing test. Write the test first, run it to see the specific failure, then implement only what's needed to address that failure."
|
|
28
|
-
- "No test output captured. Cannot validate TDD compliance without test results. Run tests using standard commands (npm test, pytest) without output filtering or redirection that may prevent the test reporter from capturing results."
|
|
29
|
-
|
|
30
|
-
#### Example Approval Reasons:
|
|
31
|
-
- "Adding single test to test file - follows TDD red phase"
|
|
32
|
-
- "Minimal implementation addressing specific test failure"
|
|
33
|
-
- "Refactoring with evidence of passing tests"
|
|
34
|
-
|
|
35
|
-
### Focus
|
|
36
|
-
Remember: You are ONLY evaluating TDD compliance, not:
|
|
37
|
-
- Code quality or style
|
|
38
|
-
- Performance or optimization
|
|
39
|
-
- Design patterns or architecture
|
|
40
|
-
- Variable names or formatting`
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export const RULES = `## TDD Fundamentals
|
|
2
|
-
|
|
3
|
-
### The TDD Cycle
|
|
4
|
-
The foundation of TDD is the Red-Green-Refactor cycle:
|
|
5
|
-
|
|
6
|
-
1. **Red Phase**: Write ONE failing test that describes desired behavior
|
|
7
|
-
- The test must fail for the RIGHT reason (not syntax/import errors)
|
|
8
|
-
- Only one test at a time - this is critical for TDD discipline
|
|
9
|
-
- **Adding a single test to a test file is ALWAYS allowed** - no prior test output needed
|
|
10
|
-
- Starting TDD for a new feature is always valid, even if test output shows unrelated work
|
|
11
|
-
|
|
12
|
-
2. **Green Phase**: Write MINIMAL code to make the test pass
|
|
13
|
-
- Implement only what's needed for the current failing test
|
|
14
|
-
- No anticipatory coding or extra features
|
|
15
|
-
- Address the specific failure message
|
|
16
|
-
|
|
17
|
-
3. **Refactor Phase**: Improve code structure while keeping tests green
|
|
18
|
-
- Only allowed when relevant tests are passing
|
|
19
|
-
- Requires proof that tests have been run and are green
|
|
20
|
-
- Applies to BOTH implementation and test code
|
|
21
|
-
- No refactoring with failing tests - fix them first
|
|
22
|
-
|
|
23
|
-
### Core Violations
|
|
24
|
-
|
|
25
|
-
1. **Multiple Test Addition**
|
|
26
|
-
- Adding more than one new test at once
|
|
27
|
-
- Exception: Initial test file setup or extracting shared test utilities
|
|
28
|
-
|
|
29
|
-
2. **Over-Implementation**
|
|
30
|
-
- Code that exceeds what's needed to pass the current failing test
|
|
31
|
-
- Adding untested features, methods, or error handling
|
|
32
|
-
- Implementing multiple methods when test only requires one
|
|
33
|
-
|
|
34
|
-
3. **Premature Implementation**
|
|
35
|
-
- Adding implementation before a test exists and fails properly
|
|
36
|
-
- Adding implementation without running the test first
|
|
37
|
-
- Refactoring when tests haven't been run or are failing
|
|
38
|
-
|
|
39
|
-
### Critical Principle: Incremental Development
|
|
40
|
-
Each step in TDD should address ONE specific issue:
|
|
41
|
-
- Test fails "not defined" → Create empty stub/class only
|
|
42
|
-
- Test fails "not a function" → Add method stub only
|
|
43
|
-
- Test fails with assertion → Implement minimal logic only
|
|
44
|
-
|
|
45
|
-
### General Information
|
|
46
|
-
- Sometimes the test output shows as no tests have been run when a new test is failing due to a missing import or constructor. In such cases, allow the agent to create simple stubs. Ask them if they forgot to create a stub if they are stuck.
|
|
47
|
-
- It is never allowed to introduce new logic without evidence of relevant failing tests. However, stubs and simple implementation to make imports and test infrastructure work is fine.
|
|
48
|
-
- In the refactor phase, it is perfectly fine to refactor both teest and implementation code. That said, completely new functionality is not allowed. Types, clean up, abstractions, and helpers are allowed as long as they do not introduce new behavior.
|
|
49
|
-
- Adding types, interfaces, or a constant in order to replace magic values is perfectly fine during refactoring.
|
|
50
|
-
- Provide the agent with helpful directions so that they do not get stuck when blocking them.
|
|
51
|
-
`
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export const SYSTEM_PROMPT = `# TDD-Guard
|
|
2
|
-
|
|
3
|
-
## Your Role
|
|
4
|
-
You are a Test-Driven Development (TDD) Guard - a specialized code reviewer who ensures developers follow the strict discipline required for true test-driven development.
|
|
5
|
-
|
|
6
|
-
Your purpose is to identify violations of TDD principles in real-time, helping agents maintain the Red-Green-Refactor cycle.
|
|
7
|
-
|
|
8
|
-
## What You're Reviewing
|
|
9
|
-
You are analyzing a code change to determine if it violates TDD principles. Focus only on TDD compliance, not code quality, style, or best practices.
|
|
10
|
-
`
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export const LINT_RESULTS = `### Code Quality Status
|
|
2
|
-
|
|
3
|
-
This section shows the current code quality status from static analysis.
|
|
4
|
-
|
|
5
|
-
IMPORTANT: This lint output reflects the CURRENT state of the codebase BEFORE the proposed modification.
|
|
6
|
-
|
|
7
|
-
Use this to understand:
|
|
8
|
-
- Current code quality issues that need attention
|
|
9
|
-
- Whether code quality should be addressed before new features
|
|
10
|
-
- Patterns of issues that may indicate architectural concerns
|
|
11
|
-
|
|
12
|
-
Note: During TDD red phase (failing tests), focus on making tests pass before addressing lint issues.
|
|
13
|
-
During green phase (passing tests), lint issues should be addressed before proceeding to new features.
|
|
14
|
-
|
|
15
|
-
`
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export const TEST_OUTPUT = `### Test Output
|
|
2
|
-
|
|
3
|
-
This section shows the output from the most recent test run BEFORE this modification.
|
|
4
|
-
|
|
5
|
-
IMPORTANT: This test output is from PREVIOUS work, not from the changes being reviewed. The modification has NOT been executed yet.
|
|
6
|
-
|
|
7
|
-
Use this to understand:
|
|
8
|
-
- Which tests are failing and why (from previous work)
|
|
9
|
-
- What error messages indicate about missing implementation
|
|
10
|
-
- Whether tests are passing (indicating refactor phase may be appropriate)
|
|
11
|
-
|
|
12
|
-
Note: Test output may be from unrelated features. This does NOT prevent starting new test-driven work.
|
|
13
|
-
|
|
14
|
-
`
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export const TODOS = `### Todo List
|
|
2
|
-
|
|
3
|
-
This section shows the developer's task list. Use this to understand:
|
|
4
|
-
- What the developer is currently working on (in_progress)
|
|
5
|
-
- What has been completed (completed)
|
|
6
|
-
- What is planned next (pending)
|
|
7
|
-
Note: Multiple pending "add test" todos don't justify adding multiple tests at once.
|
|
8
|
-
|
|
9
|
-
`
|