xtrm-tools 2.3.0 → 2.4.1
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 +132 -111
- package/cli/dist/index.cjs +142 -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,110 +0,0 @@
|
|
|
1
|
-
import { Reporter, TestModule, TestCase, TestRunEndReason } from 'vitest/node'
|
|
2
|
-
import type { SerializedError } from '@vitest/utils'
|
|
3
|
-
import { Storage, FileStorage, Config } from 'tdd-guard'
|
|
4
|
-
import { basename } from 'node:path'
|
|
5
|
-
import type {
|
|
6
|
-
CollectedModuleData,
|
|
7
|
-
FormattedError,
|
|
8
|
-
FormattedTest,
|
|
9
|
-
ModuleDataMap,
|
|
10
|
-
ModuleResult,
|
|
11
|
-
TestRunOutput,
|
|
12
|
-
} from './types'
|
|
13
|
-
|
|
14
|
-
export class VitestReporter implements Reporter {
|
|
15
|
-
private readonly storage: Storage
|
|
16
|
-
private readonly collectedData: ModuleDataMap = new Map()
|
|
17
|
-
|
|
18
|
-
constructor(storageOrRoot?: Storage | string) {
|
|
19
|
-
this.storage =
|
|
20
|
-
typeof storageOrRoot === 'string'
|
|
21
|
-
? new FileStorage(new Config({ projectRoot: storageOrRoot }))
|
|
22
|
-
: (storageOrRoot ?? new FileStorage())
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
onTestModuleCollected(testModule: TestModule): void {
|
|
26
|
-
this.collectedData.set(testModule.moduleId, {
|
|
27
|
-
module: testModule,
|
|
28
|
-
tests: [],
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
onTestCaseResult(testCase: TestCase): void {
|
|
33
|
-
const moduleId = testCase.module.moduleId
|
|
34
|
-
if (!moduleId) return
|
|
35
|
-
|
|
36
|
-
this.collectedData.get(moduleId)?.tests.push(testCase)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async onTestRunEnd(
|
|
40
|
-
_testModules?: ReadonlyArray<TestModule>,
|
|
41
|
-
unhandledErrors?: ReadonlyArray<SerializedError>,
|
|
42
|
-
reason?: TestRunEndReason
|
|
43
|
-
): Promise<void> {
|
|
44
|
-
// _testModules contains only module metadata, we use collected data from callbacks
|
|
45
|
-
const formattedModules = formatAllModuleResults(this.collectedData)
|
|
46
|
-
const output = createTestRunOutput(
|
|
47
|
-
formattedModules,
|
|
48
|
-
unhandledErrors,
|
|
49
|
-
reason
|
|
50
|
-
)
|
|
51
|
-
await this.storage.saveTest(JSON.stringify(output, null, 2))
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function createTestRunOutput(
|
|
56
|
-
testModules: ModuleResult[],
|
|
57
|
-
unhandledErrors?: ReadonlyArray<SerializedError>,
|
|
58
|
-
reason?: TestRunEndReason
|
|
59
|
-
): TestRunOutput {
|
|
60
|
-
return {
|
|
61
|
-
testModules,
|
|
62
|
-
unhandledErrors: unhandledErrors ?? [],
|
|
63
|
-
...(reason && { reason }),
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function formatAllModuleResults(collectedData: ModuleDataMap): ModuleResult[] {
|
|
68
|
-
return Array.from(collectedData.values()).map((data) => ({
|
|
69
|
-
moduleId: data.module.moduleId,
|
|
70
|
-
tests: moduleFailedToLoad(data)
|
|
71
|
-
? createTestForFailedModule(data)
|
|
72
|
-
: formatNormalTests(data),
|
|
73
|
-
}))
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function moduleFailedToLoad(data: CollectedModuleData): boolean {
|
|
77
|
-
return data.module.errors().length > 0 && data.tests.length === 0
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function createTestForFailedModule(data: CollectedModuleData): FormattedTest[] {
|
|
81
|
-
return [
|
|
82
|
-
{
|
|
83
|
-
name: basename(data.module.moduleId),
|
|
84
|
-
fullName: data.module.moduleId,
|
|
85
|
-
state: 'failed',
|
|
86
|
-
errors: data.module.errors().map(formatError),
|
|
87
|
-
},
|
|
88
|
-
]
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function formatNormalTests(data: CollectedModuleData): FormattedTest[] {
|
|
92
|
-
return data.tests.map((test) => {
|
|
93
|
-
const result = test.result()
|
|
94
|
-
return {
|
|
95
|
-
name: test.name,
|
|
96
|
-
fullName: test.fullName,
|
|
97
|
-
state: result.state === 'pending' ? 'skipped' : result.state,
|
|
98
|
-
errors: result.errors?.map(formatError),
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function formatError(error: SerializedError): FormattedError {
|
|
104
|
-
return {
|
|
105
|
-
message: error.message,
|
|
106
|
-
stack: error.stack,
|
|
107
|
-
expected: error.expected,
|
|
108
|
-
actual: error.actual,
|
|
109
|
-
}
|
|
110
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
TestState,
|
|
3
|
-
TestRunEndReason,
|
|
4
|
-
TestModule,
|
|
5
|
-
TestCase,
|
|
6
|
-
} from 'vitest/node'
|
|
7
|
-
import type { SerializedError } from '@vitest/utils'
|
|
8
|
-
|
|
9
|
-
export type ModuleDataMap = Map<string, CollectedModuleData>
|
|
10
|
-
|
|
11
|
-
export type CollectedModuleData = {
|
|
12
|
-
module: TestModule
|
|
13
|
-
tests: TestCase[]
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type FormattedError = {
|
|
17
|
-
message: string
|
|
18
|
-
stack?: string
|
|
19
|
-
expected?: unknown
|
|
20
|
-
actual?: unknown
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type FormattedTest = {
|
|
24
|
-
name: string
|
|
25
|
-
fullName: string
|
|
26
|
-
state: TestState
|
|
27
|
-
errors?: FormattedError[]
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type ModuleResult = {
|
|
31
|
-
moduleId: string
|
|
32
|
-
tests: FormattedTest[]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export type TestRunOutput = {
|
|
36
|
-
testModules: ModuleResult[]
|
|
37
|
-
unhandledErrors: readonly SerializedError[]
|
|
38
|
-
reason?: TestRunEndReason
|
|
39
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"composite": true,
|
|
5
|
-
"outDir": "./dist",
|
|
6
|
-
"rootDir": "./src",
|
|
7
|
-
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
|
|
8
|
-
},
|
|
9
|
-
"include": ["src/**/*"],
|
|
10
|
-
"exclude": ["**/*.test.ts", "**/*.spec.ts"]
|
|
11
|
-
}
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
-
import { buildContext } from './buildContext'
|
|
3
|
-
import { MemoryStorage } from '../storage/MemoryStorage'
|
|
4
|
-
|
|
5
|
-
describe('buildContext', () => {
|
|
6
|
-
let storage: MemoryStorage
|
|
7
|
-
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
storage = new MemoryStorage()
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it('should return a context with default values when storage is empty', async () => {
|
|
13
|
-
const context = await buildContext(storage)
|
|
14
|
-
|
|
15
|
-
expect(context).toEqual({
|
|
16
|
-
modifications: '',
|
|
17
|
-
test: '',
|
|
18
|
-
todo: '',
|
|
19
|
-
lint: {
|
|
20
|
-
hasIssues: false,
|
|
21
|
-
summary: 'No lint data available',
|
|
22
|
-
issuesByFile: new Map(),
|
|
23
|
-
totalIssues: 0,
|
|
24
|
-
errorCount: 0,
|
|
25
|
-
warningCount: 0,
|
|
26
|
-
},
|
|
27
|
-
instructions: undefined,
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should return context with values from storage', async () => {
|
|
32
|
-
await storage.saveModifications('some modifications content')
|
|
33
|
-
await storage.saveTest('test code')
|
|
34
|
-
await storage.saveTodo('pending: implement feature')
|
|
35
|
-
|
|
36
|
-
const context = await buildContext(storage)
|
|
37
|
-
|
|
38
|
-
expect(context).toEqual({
|
|
39
|
-
modifications: 'some modifications content',
|
|
40
|
-
test: 'test code',
|
|
41
|
-
todo: 'pending: implement feature',
|
|
42
|
-
lint: {
|
|
43
|
-
hasIssues: false,
|
|
44
|
-
summary: 'No lint data available',
|
|
45
|
-
issuesByFile: new Map(),
|
|
46
|
-
totalIssues: 0,
|
|
47
|
-
errorCount: 0,
|
|
48
|
-
warningCount: 0,
|
|
49
|
-
},
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('should parse modifications JSON data when valid JSON is stored', async () => {
|
|
54
|
-
const modificationsData = {
|
|
55
|
-
file_path: '/src/example.ts',
|
|
56
|
-
content: 'new file content',
|
|
57
|
-
}
|
|
58
|
-
const modificationsJson = JSON.stringify(modificationsData)
|
|
59
|
-
await storage.saveModifications(modificationsJson)
|
|
60
|
-
await storage.saveTest('test code')
|
|
61
|
-
await storage.saveTodo('pending: implement feature')
|
|
62
|
-
|
|
63
|
-
const context = await buildContext(storage)
|
|
64
|
-
|
|
65
|
-
expect(context).toEqual({
|
|
66
|
-
modifications: JSON.stringify(modificationsData, null, 2),
|
|
67
|
-
test: 'test code',
|
|
68
|
-
todo: 'pending: implement feature',
|
|
69
|
-
lint: {
|
|
70
|
-
hasIssues: false,
|
|
71
|
-
summary: 'No lint data available',
|
|
72
|
-
issuesByFile: new Map(),
|
|
73
|
-
totalIssues: 0,
|
|
74
|
-
errorCount: 0,
|
|
75
|
-
warningCount: 0,
|
|
76
|
-
},
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('should pretty-print modifications JSON for better readability', async () => {
|
|
81
|
-
const modificationsData = {
|
|
82
|
-
file_path: '/src/Calculator.test.ts',
|
|
83
|
-
old_string:
|
|
84
|
-
"describe('Calculator', () => {\n test('should add two numbers correctly', () => {\n const result = calculator.add(2, 3)\n expect(result).toBe(5)\n })\n})",
|
|
85
|
-
new_string:
|
|
86
|
-
"describe('Calculator', () => {\n test('should add two numbers correctly', () => {\n const result = calculator.add(2, 3)\n expect(result).toBe(5)\n })\n \n test('should divide two numbers correctly', () => {\n const result = calculator.divide(4, 2)\n expect(result).toBe(2)\n })\n})",
|
|
87
|
-
}
|
|
88
|
-
await storage.saveModifications(JSON.stringify(modificationsData))
|
|
89
|
-
|
|
90
|
-
const context = await buildContext(storage)
|
|
91
|
-
|
|
92
|
-
// Should be pretty-printed, not a compact JSON string
|
|
93
|
-
expect(context.modifications).toBe(
|
|
94
|
-
JSON.stringify(modificationsData, null, 2)
|
|
95
|
-
)
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it('should process valid lint data when stored', async () => {
|
|
99
|
-
const lintData = {
|
|
100
|
-
timestamp: '2024-01-01T00:00:00Z',
|
|
101
|
-
files: ['/src/example.ts'],
|
|
102
|
-
issues: [
|
|
103
|
-
{
|
|
104
|
-
file: '/src/example.ts',
|
|
105
|
-
line: 10,
|
|
106
|
-
column: 5,
|
|
107
|
-
severity: 'error',
|
|
108
|
-
message: 'Missing semicolon',
|
|
109
|
-
rule: 'semi',
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
errorCount: 1,
|
|
113
|
-
warningCount: 0,
|
|
114
|
-
hasNotifiedAboutLintIssues: false,
|
|
115
|
-
}
|
|
116
|
-
await storage.saveLint(JSON.stringify(lintData))
|
|
117
|
-
|
|
118
|
-
const context = await buildContext(storage)
|
|
119
|
-
|
|
120
|
-
expect(context.lint).toEqual({
|
|
121
|
-
hasIssues: true,
|
|
122
|
-
summary: '1 lint issue found (1 error, 0 warnings)',
|
|
123
|
-
issuesByFile: new Map([
|
|
124
|
-
['/src/example.ts', [' Line 10:5 - error: Missing semicolon (semi)']],
|
|
125
|
-
]),
|
|
126
|
-
totalIssues: 1,
|
|
127
|
-
errorCount: 1,
|
|
128
|
-
warningCount: 0,
|
|
129
|
-
})
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
it('should handle invalid lint JSON gracefully', async () => {
|
|
133
|
-
await storage.saveLint('invalid json')
|
|
134
|
-
|
|
135
|
-
const context = await buildContext(storage)
|
|
136
|
-
|
|
137
|
-
// Should fall back to default lint data
|
|
138
|
-
expect(context.lint).toEqual({
|
|
139
|
-
hasIssues: false,
|
|
140
|
-
summary: 'No lint data available',
|
|
141
|
-
issuesByFile: new Map(),
|
|
142
|
-
totalIssues: 0,
|
|
143
|
-
errorCount: 0,
|
|
144
|
-
warningCount: 0,
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
it('should handle lint data that fails schema validation', async () => {
|
|
149
|
-
// Missing required fields
|
|
150
|
-
const invalidLintData = {
|
|
151
|
-
timestamp: '2024-01-01T00:00:00Z',
|
|
152
|
-
// Missing: files, issues, errorCount, warningCount, hasNotifiedAboutLintIssues
|
|
153
|
-
}
|
|
154
|
-
await storage.saveLint(JSON.stringify(invalidLintData))
|
|
155
|
-
|
|
156
|
-
const context = await buildContext(storage)
|
|
157
|
-
|
|
158
|
-
// Should fall back to default lint data
|
|
159
|
-
expect(context.lint).toEqual({
|
|
160
|
-
hasIssues: false,
|
|
161
|
-
summary: 'No lint data available',
|
|
162
|
-
issuesByFile: new Map(),
|
|
163
|
-
totalIssues: 0,
|
|
164
|
-
errorCount: 0,
|
|
165
|
-
warningCount: 0,
|
|
166
|
-
})
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it('should handle lint data with no issues', async () => {
|
|
170
|
-
const lintData = {
|
|
171
|
-
timestamp: '2024-01-01T00:00:00Z',
|
|
172
|
-
files: ['/src/example.ts'],
|
|
173
|
-
issues: [],
|
|
174
|
-
errorCount: 0,
|
|
175
|
-
warningCount: 0,
|
|
176
|
-
hasNotifiedAboutLintIssues: false,
|
|
177
|
-
}
|
|
178
|
-
await storage.saveLint(JSON.stringify(lintData))
|
|
179
|
-
|
|
180
|
-
const context = await buildContext(storage)
|
|
181
|
-
|
|
182
|
-
expect(context.lint).toEqual({
|
|
183
|
-
hasIssues: false,
|
|
184
|
-
summary: 'No lint issues found',
|
|
185
|
-
issuesByFile: new Map(),
|
|
186
|
-
totalIssues: 0,
|
|
187
|
-
errorCount: 0,
|
|
188
|
-
warningCount: 0,
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
it('should include instructions when available in storage', async () => {
|
|
193
|
-
const customInstructions = '## Custom TDD Rules\n1. Write tests first'
|
|
194
|
-
await storage.saveInstructions(customInstructions)
|
|
195
|
-
|
|
196
|
-
const context = await buildContext(storage)
|
|
197
|
-
|
|
198
|
-
expect(context.instructions).toBe(customInstructions)
|
|
199
|
-
})
|
|
200
|
-
})
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { Storage } from '../storage/Storage'
|
|
2
|
-
import { LintDataSchema } from '../contracts/schemas/lintSchemas'
|
|
3
|
-
import { Context } from '../contracts/types/Context'
|
|
4
|
-
import { processLintData } from '../processors/lintProcessor'
|
|
5
|
-
|
|
6
|
-
export async function buildContext(storage: Storage): Promise<Context> {
|
|
7
|
-
const [modifications, rawTest, todo, lint, instructions] = await Promise.all([
|
|
8
|
-
storage.getModifications(),
|
|
9
|
-
storage.getTest(),
|
|
10
|
-
storage.getTodo(),
|
|
11
|
-
storage.getLint(),
|
|
12
|
-
storage.getInstructions(),
|
|
13
|
-
])
|
|
14
|
-
|
|
15
|
-
let processedLintData
|
|
16
|
-
try {
|
|
17
|
-
if (lint) {
|
|
18
|
-
const rawLintData = LintDataSchema.parse(JSON.parse(lint))
|
|
19
|
-
processedLintData = processLintData(rawLintData)
|
|
20
|
-
} else {
|
|
21
|
-
processedLintData = processLintData()
|
|
22
|
-
}
|
|
23
|
-
} catch {
|
|
24
|
-
processedLintData = processLintData()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
modifications: formatModifications(modifications ?? ''),
|
|
29
|
-
test: rawTest ?? '',
|
|
30
|
-
todo: todo ?? '',
|
|
31
|
-
lint: processedLintData,
|
|
32
|
-
instructions: instructions ?? undefined,
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function formatModifications(modifications: string): string {
|
|
37
|
-
if (!modifications) {
|
|
38
|
-
return ''
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
const parsed = JSON.parse(modifications)
|
|
43
|
-
return JSON.stringify(parsed, null, 2)
|
|
44
|
-
} catch {
|
|
45
|
-
// If it's not valid JSON, leave it as is
|
|
46
|
-
return modifications
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect, beforeEach, afterEach } from 'vitest'
|
|
2
|
-
import { spawn } from 'child_process'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
import fs from 'fs/promises'
|
|
5
|
-
import os from 'os'
|
|
6
|
-
import { FileStorage } from '../storage/FileStorage'
|
|
7
|
-
import { Config } from '../config/Config'
|
|
8
|
-
import { ModelClientProvider } from '../providers/ModelClientProvider'
|
|
9
|
-
import { run } from './tdd-guard'
|
|
10
|
-
import { testData } from '@testUtils'
|
|
11
|
-
|
|
12
|
-
describe('tdd-guard CLI', () => {
|
|
13
|
-
const cliPath = path.join(__dirname, 'tdd-guard.ts')
|
|
14
|
-
|
|
15
|
-
describe('CLI Behavior', () => {
|
|
16
|
-
test('has shebang for direct execution', async () => {
|
|
17
|
-
const content = await fs.readFile(cliPath, 'utf-8')
|
|
18
|
-
const firstLine = content.split('\n')[0].trim()
|
|
19
|
-
|
|
20
|
-
expect(firstLine).toBe('#!/usr/bin/env node')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test('exits with status 0 on invalid JSON', async () => {
|
|
24
|
-
const invalidJson = '{ invalid json'
|
|
25
|
-
|
|
26
|
-
const { exitCode } = await runCli(invalidJson)
|
|
27
|
-
|
|
28
|
-
expect(exitCode).toBe(0)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
test('logs error to stderr on invalid JSON', async () => {
|
|
32
|
-
const invalidJson = '{ invalid json'
|
|
33
|
-
|
|
34
|
-
const { stderr } = await runCli(invalidJson)
|
|
35
|
-
|
|
36
|
-
expect(stderr).toContain('Failed to parse hook data')
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
describe('Data Persistence', () => {
|
|
41
|
-
let projectRoot: string
|
|
42
|
-
let storage: FileStorage
|
|
43
|
-
let testConfig: Config
|
|
44
|
-
let modelProvider: ModelClientProvider
|
|
45
|
-
const originalEnv = process.env
|
|
46
|
-
|
|
47
|
-
beforeEach(async () => {
|
|
48
|
-
process.env = { ...originalEnv }
|
|
49
|
-
projectRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'tdd-guard-test-'))
|
|
50
|
-
testConfig = new Config({ projectRoot })
|
|
51
|
-
storage = new FileStorage(testConfig)
|
|
52
|
-
modelProvider = testData.modelClientProvider()
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
afterEach(async () => {
|
|
56
|
-
process.env = originalEnv
|
|
57
|
-
await fs.rm(projectRoot, { recursive: true, force: true })
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
test('uses projectRoot from Config', async () => {
|
|
61
|
-
const hookData = testData.editOperation()
|
|
62
|
-
await run(JSON.stringify(hookData), testConfig, storage, modelProvider)
|
|
63
|
-
|
|
64
|
-
expect(await pathExists(testConfig.dataDir)).toBe(true)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
test('saves Edit data', async () => {
|
|
68
|
-
const hookData = testData.editOperation()
|
|
69
|
-
|
|
70
|
-
await run(JSON.stringify(hookData), testConfig, storage, modelProvider)
|
|
71
|
-
|
|
72
|
-
const savedModifications = await storage.getModifications()
|
|
73
|
-
expect(JSON.parse(savedModifications!)).toStrictEqual(hookData)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
test('saves Write data', async () => {
|
|
77
|
-
const hookData = testData.writeOperation()
|
|
78
|
-
|
|
79
|
-
await run(JSON.stringify(hookData), testConfig, storage, modelProvider)
|
|
80
|
-
|
|
81
|
-
const savedModifications = await storage.getModifications()
|
|
82
|
-
expect(JSON.parse(savedModifications!)).toStrictEqual(hookData)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
test('saves TodoWrite data', async () => {
|
|
86
|
-
const hookData = testData.todoWriteOperation()
|
|
87
|
-
|
|
88
|
-
await run(JSON.stringify(hookData), testConfig, storage, modelProvider)
|
|
89
|
-
|
|
90
|
-
const savedTodos = await storage.getTodo()
|
|
91
|
-
expect(JSON.parse(savedTodos!)).toStrictEqual(hookData)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
test('saves MultiEdit data', async () => {
|
|
95
|
-
const hookData = testData.multiEditOperation()
|
|
96
|
-
|
|
97
|
-
await run(JSON.stringify(hookData), testConfig, storage, modelProvider)
|
|
98
|
-
|
|
99
|
-
const savedModifications = await storage.getModifications()
|
|
100
|
-
expect(JSON.parse(savedModifications!)).toStrictEqual(hookData)
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
test('uses provided ModelClientProvider', async () => {
|
|
104
|
-
await storage.saveConfig(JSON.stringify({ guardEnabled: true }))
|
|
105
|
-
|
|
106
|
-
const hookData = testData.editOperation()
|
|
107
|
-
|
|
108
|
-
const result = await run(
|
|
109
|
-
JSON.stringify(hookData),
|
|
110
|
-
testConfig,
|
|
111
|
-
storage,
|
|
112
|
-
modelProvider
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
// The mock provider always returns undefined decision
|
|
116
|
-
expect(result.decision).toBe(undefined)
|
|
117
|
-
expect(result.reason).toContain('Using mock model client')
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
// Helper to check if file/directory exists
|
|
123
|
-
async function pathExists(filePath: string): Promise<boolean> {
|
|
124
|
-
return fs
|
|
125
|
-
.access(filePath)
|
|
126
|
-
.then(() => true)
|
|
127
|
-
.catch(() => false)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Helper function for CLI subprocess tests
|
|
131
|
-
async function runCli(
|
|
132
|
-
input: string
|
|
133
|
-
): Promise<{ exitCode: number; stderr: string; stdout: string }> {
|
|
134
|
-
const cliPath = path.join(__dirname, 'tdd-guard.ts')
|
|
135
|
-
|
|
136
|
-
return new Promise((resolve) => {
|
|
137
|
-
const npxPath = process.platform === 'win32' ? 'npx.cmd' : 'npx'
|
|
138
|
-
const proc = spawn(npxPath, ['tsx', cliPath], {
|
|
139
|
-
env: { ...process.env },
|
|
140
|
-
shell: process.platform === 'win32',
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
let stderr = ''
|
|
144
|
-
let stdout = ''
|
|
145
|
-
proc.stderr.on('data', (data) => {
|
|
146
|
-
stderr += data.toString()
|
|
147
|
-
})
|
|
148
|
-
proc.stdout.on('data', (data) => {
|
|
149
|
-
stdout += data.toString()
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
proc.stdin.write(input)
|
|
153
|
-
proc.stdin.end()
|
|
154
|
-
|
|
155
|
-
proc.on('close', (code) => {
|
|
156
|
-
resolve({ exitCode: code ?? 1, stderr, stdout })
|
|
157
|
-
})
|
|
158
|
-
})
|
|
159
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import 'dotenv/config'
|
|
4
|
-
import { processHookData } from '../hooks/processHookData'
|
|
5
|
-
import { Storage } from '../storage/Storage'
|
|
6
|
-
import { FileStorage } from '../storage/FileStorage'
|
|
7
|
-
import { validator } from '../validation/validator'
|
|
8
|
-
import { Config } from '../config/Config'
|
|
9
|
-
import { ModelClientProvider } from '../providers/ModelClientProvider'
|
|
10
|
-
import { ValidationResult } from '../contracts/types/ValidationResult'
|
|
11
|
-
|
|
12
|
-
export async function run(
|
|
13
|
-
input: string,
|
|
14
|
-
config?: Config,
|
|
15
|
-
storage?: Storage,
|
|
16
|
-
provider?: ModelClientProvider
|
|
17
|
-
): Promise<ValidationResult> {
|
|
18
|
-
const appConfig = config ?? new Config()
|
|
19
|
-
const actualStorage = storage ?? new FileStorage(appConfig)
|
|
20
|
-
const modelProvider = provider ?? new ModelClientProvider()
|
|
21
|
-
const modelClient = modelProvider.getModelClient(appConfig)
|
|
22
|
-
|
|
23
|
-
return processHookData(input, {
|
|
24
|
-
storage: actualStorage,
|
|
25
|
-
validator: (context) => validator(context, modelClient),
|
|
26
|
-
})
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Only run if this is the main module
|
|
30
|
-
if (require.main === module) {
|
|
31
|
-
let inputData = ''
|
|
32
|
-
process.stdin.setEncoding('utf8')
|
|
33
|
-
|
|
34
|
-
process.stdin.on('data', (chunk) => {
|
|
35
|
-
inputData += chunk
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
process.stdin.on('end', async () => {
|
|
39
|
-
try {
|
|
40
|
-
const result = await run(inputData)
|
|
41
|
-
console.log(JSON.stringify(result))
|
|
42
|
-
} catch (error) {
|
|
43
|
-
console.error('Failed to parse hook data:', error)
|
|
44
|
-
} finally {
|
|
45
|
-
process.exit(0)
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
}
|