xtrm-tools 2.2.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 -104
- package/cli/dist/index.cjs +1078 -970
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/config/pi/extensions/beads.ts +33 -5
- package/config/pi/extensions/service-skills.ts +17 -9
- package/config/pi/install-schema.json +2 -1
- 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,155 +0,0 @@
|
|
|
1
|
-
import { Context, ProcessedLintData } from '../../contracts/types/Context'
|
|
2
|
-
import { Config } from '../../config/Config'
|
|
3
|
-
import {
|
|
4
|
-
isEditOperation,
|
|
5
|
-
isMultiEditOperation,
|
|
6
|
-
isWriteOperation,
|
|
7
|
-
ToolOperation,
|
|
8
|
-
EditOperation,
|
|
9
|
-
MultiEditOperation,
|
|
10
|
-
WriteOperation,
|
|
11
|
-
Todo,
|
|
12
|
-
} from '../../contracts/schemas/toolSchemas'
|
|
13
|
-
import { TestResultsProcessor } from '../../processors'
|
|
14
|
-
import { formatLintDataForContext } from '../../processors/lintProcessor'
|
|
15
|
-
|
|
16
|
-
// Import core prompts
|
|
17
|
-
import { SYSTEM_PROMPT } from '../prompts/system-prompt'
|
|
18
|
-
import { RULES } from '../prompts/rules'
|
|
19
|
-
import { FILE_TYPES } from '../prompts/file-types'
|
|
20
|
-
import { RESPONSE } from '../prompts/response'
|
|
21
|
-
|
|
22
|
-
// Import operation-specific context
|
|
23
|
-
import { EDIT } from '../prompts/operations/edit'
|
|
24
|
-
import { MULTI_EDIT } from '../prompts/operations/multi-edit'
|
|
25
|
-
import { WRITE } from '../prompts/operations/write'
|
|
26
|
-
import { TODOS } from '../prompts/tools/todos'
|
|
27
|
-
import { TEST_OUTPUT } from '../prompts/tools/test-output'
|
|
28
|
-
import { LINT_RESULTS } from '../prompts/tools/lint-results'
|
|
29
|
-
|
|
30
|
-
export function generateDynamicContext(
|
|
31
|
-
context: Context,
|
|
32
|
-
config?: Config
|
|
33
|
-
): string {
|
|
34
|
-
const operation: ToolOperation = JSON.parse(context.modifications)
|
|
35
|
-
const effectiveConfig = config ?? new Config()
|
|
36
|
-
|
|
37
|
-
const sections: string[] = [
|
|
38
|
-
// 1. Core sections (system prompt only for CLI)
|
|
39
|
-
getSystemPrompt(effectiveConfig),
|
|
40
|
-
context.instructions ?? RULES,
|
|
41
|
-
FILE_TYPES,
|
|
42
|
-
|
|
43
|
-
// 2. Operation-specific context and changes
|
|
44
|
-
formatOperation(operation),
|
|
45
|
-
|
|
46
|
-
// 3. Additional context
|
|
47
|
-
formatTestSection(context.test),
|
|
48
|
-
formatTodoSection(context.todo),
|
|
49
|
-
formatLintSection(context.lint),
|
|
50
|
-
|
|
51
|
-
// 4. Response format
|
|
52
|
-
RESPONSE,
|
|
53
|
-
]
|
|
54
|
-
|
|
55
|
-
return sections.filter(Boolean).join('\n')
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function formatOperation(operation: ToolOperation): string {
|
|
59
|
-
if (isEditOperation(operation)) {
|
|
60
|
-
return EDIT + formatEditOperation(operation)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (isMultiEditOperation(operation)) {
|
|
64
|
-
return MULTI_EDIT + formatMultiEditOperation(operation)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (isWriteOperation(operation)) {
|
|
68
|
-
return WRITE + formatWriteOperation(operation)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return ''
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function formatEditOperation(operation: EditOperation): string {
|
|
75
|
-
return (
|
|
76
|
-
formatSection('File Path', operation.tool_input.file_path) +
|
|
77
|
-
formatSection('Old Content', operation.tool_input.old_string) +
|
|
78
|
-
formatSection('New Content', operation.tool_input.new_string)
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function formatMultiEditOperation(operation: MultiEditOperation): string {
|
|
83
|
-
const editsFormatted = operation.tool_input.edits
|
|
84
|
-
.map((edit, index) => formatEdit(edit, index + 1))
|
|
85
|
-
.join('')
|
|
86
|
-
|
|
87
|
-
return `${formatSection(
|
|
88
|
-
'File Path',
|
|
89
|
-
operation.tool_input.file_path
|
|
90
|
-
)}\n### Edits\n${editsFormatted}`
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function formatWriteOperation(operation: WriteOperation): string {
|
|
94
|
-
return (
|
|
95
|
-
formatSection('File Path', operation.tool_input.file_path) +
|
|
96
|
-
formatSection('New File Content', operation.tool_input.content)
|
|
97
|
-
)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function formatEdit(
|
|
101
|
-
edit: { old_string: string; new_string: string },
|
|
102
|
-
index: number
|
|
103
|
-
): string {
|
|
104
|
-
return (
|
|
105
|
-
`\n#### Edit ${index}:\n` +
|
|
106
|
-
`**Old Content:**\n${codeBlock(edit.old_string)}` +
|
|
107
|
-
`**New Content:**\n${codeBlock(edit.new_string)}`
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function formatTestSection(testOutput?: string): string {
|
|
112
|
-
if (!testOutput) return ''
|
|
113
|
-
|
|
114
|
-
const output = testOutput.trim()
|
|
115
|
-
? new TestResultsProcessor().process(testOutput)
|
|
116
|
-
: 'No test output available. Tests must be run before implementing.'
|
|
117
|
-
|
|
118
|
-
return TEST_OUTPUT + codeBlock(output)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function formatTodoSection(todoJson?: string): string {
|
|
122
|
-
if (!todoJson) return ''
|
|
123
|
-
|
|
124
|
-
const todoOperation = JSON.parse(todoJson)
|
|
125
|
-
const todos: Todo[] = todoOperation.tool_input?.todos ?? []
|
|
126
|
-
|
|
127
|
-
const todoItems = todos
|
|
128
|
-
.map(
|
|
129
|
-
(todo, index) =>
|
|
130
|
-
`${index + 1}. [${todo.status}] ${todo.content} (${todo.priority})`
|
|
131
|
-
)
|
|
132
|
-
.join('\n')
|
|
133
|
-
|
|
134
|
-
return `${TODOS}${todoItems}\n`
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function formatLintSection(lintData?: ProcessedLintData): string {
|
|
138
|
-
if (!lintData) return ''
|
|
139
|
-
|
|
140
|
-
const formattedLintData = formatLintDataForContext(lintData)
|
|
141
|
-
return LINT_RESULTS + codeBlock(formattedLintData)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function formatSection(title: string, content: string): string {
|
|
145
|
-
return `\n### ${title}\n${codeBlock(content)}`
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function codeBlock(content: string): string {
|
|
149
|
-
return `\`\`\`\n${content}\n\`\`\`\n`
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function getSystemPrompt(config: Config): string {
|
|
153
|
-
// Only the CLI client requires the system prompt in the query
|
|
154
|
-
return config.validationClient === 'cli' ? SYSTEM_PROMPT : ''
|
|
155
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect, vi, beforeEach } from 'vitest'
|
|
2
|
-
import { AnthropicApi } from './AnthropicApi'
|
|
3
|
-
import Anthropic from '@anthropic-ai/sdk'
|
|
4
|
-
import { Config } from '../../config/Config'
|
|
5
|
-
import { SYSTEM_PROMPT } from '../prompts/system-prompt'
|
|
6
|
-
|
|
7
|
-
vi.mock('@anthropic-ai/sdk')
|
|
8
|
-
|
|
9
|
-
// Test constants
|
|
10
|
-
const DEFAULT_TEST_PROMPT = 'test prompt'
|
|
11
|
-
|
|
12
|
-
describe('AnthropicApi', () => {
|
|
13
|
-
let sut: Awaited<ReturnType<typeof createSut>>
|
|
14
|
-
let client: AnthropicApi
|
|
15
|
-
const apiKey = 'test-api-key'
|
|
16
|
-
const modelVersion = 'claude-3-5-sonnet-20241022'
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
sut = createSut(apiKey, modelVersion)
|
|
20
|
-
client = sut.client
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test('should implement IModelClient interface', () => {
|
|
24
|
-
expect(client.ask).toBeDefined()
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
test('should accept optional Config in constructor', () => {
|
|
28
|
-
const config = new Config()
|
|
29
|
-
const apiClient = new AnthropicApi(config)
|
|
30
|
-
expect(apiClient).toBeDefined()
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
test('should create Anthropic client with API key from config', () => {
|
|
34
|
-
expect(sut.wasCreatedWithApiKey(apiKey)).toBe(true)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
test('uses model version from config', async () => {
|
|
38
|
-
const call = await sut.askAndGetCall()
|
|
39
|
-
expect(call.model).toBe(modelVersion)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
test('includes system prompt in API call', async () => {
|
|
43
|
-
const call = await sut.askAndGetCall()
|
|
44
|
-
expect(call.system).toBe(SYSTEM_PROMPT)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
test('sets max tokens to 1024', async () => {
|
|
48
|
-
const call = await sut.askAndGetCall()
|
|
49
|
-
expect(call.max_tokens).toBe(1024)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
test('passes prompt as user message', async () => {
|
|
53
|
-
const prompt = 'Does this follow TDD?'
|
|
54
|
-
const call = await sut.askAndGetCall(prompt)
|
|
55
|
-
expect(call.messages).toEqual([
|
|
56
|
-
{
|
|
57
|
-
role: 'user',
|
|
58
|
-
content: prompt,
|
|
59
|
-
},
|
|
60
|
-
])
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
test('ask method should return text from response', async () => {
|
|
64
|
-
const expectedText = 'Model response text'
|
|
65
|
-
const result = await sut.askWithResponse(expectedText)
|
|
66
|
-
|
|
67
|
-
expect(result).toBe(expectedText)
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
test('ask method should throw error when API call fails', async () => {
|
|
71
|
-
await expect(sut.askWithError('API error')).rejects.toThrow('API error')
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
test('ask method should handle empty content array', async () => {
|
|
75
|
-
sut.mockCreate.mockResolvedValue({ content: [] })
|
|
76
|
-
|
|
77
|
-
await expect(client.ask(DEFAULT_TEST_PROMPT)).rejects.toThrow()
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
test('ask method should handle missing text property', async () => {
|
|
81
|
-
sut.mockCreate.mockResolvedValue({ content: [{ type: 'image' }] })
|
|
82
|
-
|
|
83
|
-
await expect(client.ask(DEFAULT_TEST_PROMPT)).rejects.toThrow()
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
// Test Helpers
|
|
88
|
-
interface MessageCreateParams {
|
|
89
|
-
model: string
|
|
90
|
-
system: string
|
|
91
|
-
max_tokens: number
|
|
92
|
-
messages: Array<{ role: string; content: string }>
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function createSut(apiKey?: string, modelVersion?: string) {
|
|
96
|
-
vi.clearAllMocks()
|
|
97
|
-
|
|
98
|
-
const mockCreate = vi.fn().mockResolvedValue({
|
|
99
|
-
content: [{ text: 'Model response' }],
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
const mockAnthropicConstructor = vi.mocked(Anthropic)
|
|
103
|
-
mockAnthropicConstructor.mockImplementation(
|
|
104
|
-
() =>
|
|
105
|
-
({
|
|
106
|
-
messages: {
|
|
107
|
-
create: mockCreate,
|
|
108
|
-
},
|
|
109
|
-
}) as unknown as Anthropic
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
const config = new Config({ anthropicApiKey: apiKey, modelVersion })
|
|
113
|
-
const client = new AnthropicApi(config)
|
|
114
|
-
|
|
115
|
-
const mockResponse = (text: string): void => {
|
|
116
|
-
mockCreate.mockResolvedValue({
|
|
117
|
-
content: [{ text }],
|
|
118
|
-
})
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const getLastCall = (): MessageCreateParams => {
|
|
122
|
-
const lastCall = mockCreate.mock.calls[mockCreate.mock.calls.length - 1]
|
|
123
|
-
const params = lastCall[0]
|
|
124
|
-
return {
|
|
125
|
-
model: params.model,
|
|
126
|
-
system: params.system,
|
|
127
|
-
max_tokens: params.max_tokens,
|
|
128
|
-
messages: params.messages,
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const askAndGetCall = async (
|
|
133
|
-
prompt = DEFAULT_TEST_PROMPT
|
|
134
|
-
): Promise<MessageCreateParams> => {
|
|
135
|
-
await client.ask(prompt)
|
|
136
|
-
return getLastCall()
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const wasCreatedWithApiKey = (key: string): boolean => {
|
|
140
|
-
return mockAnthropicConstructor.mock.calls.some(
|
|
141
|
-
(call) => call[0]?.apiKey === key
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const askWithResponse = async (
|
|
146
|
-
responseText: string
|
|
147
|
-
): Promise<string | undefined> => {
|
|
148
|
-
mockResponse(responseText)
|
|
149
|
-
return client.ask(DEFAULT_TEST_PROMPT)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const askWithError = async (
|
|
153
|
-
errorMessage: string
|
|
154
|
-
): Promise<string | undefined> => {
|
|
155
|
-
mockCreate.mockRejectedValue(new Error(errorMessage))
|
|
156
|
-
return client.ask(DEFAULT_TEST_PROMPT)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return {
|
|
160
|
-
client,
|
|
161
|
-
mockCreate,
|
|
162
|
-
mockAnthropicConstructor,
|
|
163
|
-
config,
|
|
164
|
-
mockResponse,
|
|
165
|
-
getLastCall,
|
|
166
|
-
askAndGetCall,
|
|
167
|
-
wasCreatedWithApiKey,
|
|
168
|
-
askWithResponse,
|
|
169
|
-
askWithError,
|
|
170
|
-
}
|
|
171
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import Anthropic from '@anthropic-ai/sdk'
|
|
2
|
-
import { Config } from '../../config/Config'
|
|
3
|
-
import { IModelClient } from '../../contracts/types/ModelClient'
|
|
4
|
-
import { SYSTEM_PROMPT } from '../prompts/system-prompt'
|
|
5
|
-
|
|
6
|
-
export class AnthropicApi implements IModelClient {
|
|
7
|
-
private readonly config: Config
|
|
8
|
-
private readonly client: Anthropic
|
|
9
|
-
|
|
10
|
-
constructor(config?: Config) {
|
|
11
|
-
this.config = config ?? new Config()
|
|
12
|
-
this.client = new Anthropic({
|
|
13
|
-
apiKey: this.config.anthropicApiKey,
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async ask(prompt: string): Promise<string> {
|
|
18
|
-
const response = await this.client.messages.create({
|
|
19
|
-
model: this.config.modelVersion,
|
|
20
|
-
system: SYSTEM_PROMPT,
|
|
21
|
-
max_tokens: 1024,
|
|
22
|
-
messages: [
|
|
23
|
-
{
|
|
24
|
-
role: 'user',
|
|
25
|
-
content: prompt,
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
return extractTextFromResponse(response)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface MessageResponse {
|
|
35
|
-
content: Array<{ text?: string; type?: string }>
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function extractTextFromResponse(response: MessageResponse): string {
|
|
39
|
-
if (response.content.length === 0) {
|
|
40
|
-
throw new Error('No content in response')
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const firstContent = response.content[0]
|
|
44
|
-
if (!('text' in firstContent) || !firstContent.text) {
|
|
45
|
-
throw new Error('Response content does not contain text')
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return firstContent.text
|
|
49
|
-
}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect, vi, beforeEach } from 'vitest'
|
|
2
|
-
import { ClaudeAgentSdk } from './ClaudeAgentSdk'
|
|
3
|
-
import { Config } from '../../config/Config'
|
|
4
|
-
import { IModelClient } from '../../contracts/types/ModelClient'
|
|
5
|
-
import { query, type SDKResultMessage } from '@anthropic-ai/claude-agent-sdk'
|
|
6
|
-
import { SYSTEM_PROMPT } from '../prompts/system-prompt'
|
|
7
|
-
|
|
8
|
-
describe('ClaudeAgentSdk', () => {
|
|
9
|
-
describe('constructor', () => {
|
|
10
|
-
test('implements the IModelClient interface', () => {
|
|
11
|
-
const client: IModelClient = new ClaudeAgentSdk()
|
|
12
|
-
expect(client.ask).toBeDefined()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
test('accepts optional Config in constructor', () => {
|
|
16
|
-
const config = new Config()
|
|
17
|
-
const client = new ClaudeAgentSdk(config)
|
|
18
|
-
expect(client['config']).toBe(config)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
test('uses default Config when not provided', () => {
|
|
22
|
-
const client = new ClaudeAgentSdk()
|
|
23
|
-
expect(client['config']).toBeInstanceOf(Config)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
test('accepts query function as second parameter', () => {
|
|
27
|
-
const customQuery = vi.fn()
|
|
28
|
-
const config = new Config()
|
|
29
|
-
const client = new ClaudeAgentSdk(config, customQuery)
|
|
30
|
-
expect(client['queryFn']).toBe(customQuery)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
test('uses query from @anthropic-ai/claude-agent-sdk when not provided', () => {
|
|
34
|
-
const client = new ClaudeAgentSdk()
|
|
35
|
-
expect(client['queryFn']).toBe(query)
|
|
36
|
-
})
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
describe('query invocation', () => {
|
|
40
|
-
const prompt = 'test prompt'
|
|
41
|
-
const message = createSDKResultMessage()
|
|
42
|
-
const modelVersion = 'claude-opus-4-1'
|
|
43
|
-
const config = new Config({ modelVersion })
|
|
44
|
-
const { client, getUsedOptions, getUsedPrompt } = setupClient(
|
|
45
|
-
message,
|
|
46
|
-
config
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
beforeEach(async () => {
|
|
50
|
-
await client.ask(prompt)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
test('calls queryFn with correct prompt', async () => {
|
|
54
|
-
expect(getUsedPrompt()).toBe(prompt)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test('sets maxTurns to 1', async () => {
|
|
58
|
-
expect(getUsedOptions().maxTurns).toBe(1)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
test('sets allowedTools to empty array', async () => {
|
|
62
|
-
expect(getUsedOptions().allowedTools).toEqual([])
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
test('sets disallowedTools to prevent file operations and other tools', async () => {
|
|
66
|
-
const expectedDisallowedTools = [
|
|
67
|
-
'Read',
|
|
68
|
-
'Edit',
|
|
69
|
-
'MultiEdit',
|
|
70
|
-
'Write',
|
|
71
|
-
'Grep',
|
|
72
|
-
'Glob',
|
|
73
|
-
'Bash',
|
|
74
|
-
'WebFetch',
|
|
75
|
-
'WebSearch',
|
|
76
|
-
'Task',
|
|
77
|
-
'TodoWrite',
|
|
78
|
-
]
|
|
79
|
-
expect(getUsedOptions().disallowedTools).toEqual(expectedDisallowedTools)
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
test('sets maxThinkingTokens to 0', async () => {
|
|
83
|
-
expect(getUsedOptions().maxThinkingTokens).toBe(0)
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
test('uses model version from config', async () => {
|
|
87
|
-
expect(getUsedOptions().model).toBe(modelVersion)
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
test('sets strictMcpConfig to true', async () => {
|
|
91
|
-
expect(getUsedOptions().strictMcpConfig).toBe(true)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
test('uses SYSTEM_PROMPT for systemPrompt', async () => {
|
|
95
|
-
expect(getUsedOptions().systemPrompt).toBe(SYSTEM_PROMPT)
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
test('sets cwd to config dataDir', async () => {
|
|
99
|
-
// Prevents hook trigggers and keeps queries out of project history
|
|
100
|
-
expect(getUsedOptions().cwd).toBe(config.dataDir)
|
|
101
|
-
})
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
describe('result handling', () => {
|
|
105
|
-
test('returns result from successful response', async () => {
|
|
106
|
-
const { client } = setupClient({ result: 'test result' })
|
|
107
|
-
|
|
108
|
-
await expect(client.ask('test')).resolves.toBe('test result')
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
test('throws error when query returns error subtype', async () => {
|
|
112
|
-
const { client } = setupClient({ subtype: 'error_max_turns' })
|
|
113
|
-
|
|
114
|
-
await expect(client.ask('test')).rejects.toThrow(
|
|
115
|
-
'Claude Agent SDK error: error_max_turns'
|
|
116
|
-
)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
test('throws error when no result message is received', async () => {
|
|
120
|
-
const { client } = setupClient({ type: 'other', data: 'something' })
|
|
121
|
-
|
|
122
|
-
await expect(client.ask('test')).rejects.toThrow(
|
|
123
|
-
'Claude Agent SDK error: No result message received'
|
|
124
|
-
)
|
|
125
|
-
})
|
|
126
|
-
})
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
// Test Helpers
|
|
130
|
-
function setupClient(
|
|
131
|
-
messageOverrides: Partial<SDKResultMessage> = {},
|
|
132
|
-
config: Config = new Config()
|
|
133
|
-
) {
|
|
134
|
-
const customQuery = createMockQuery(messageOverrides)
|
|
135
|
-
const client = new ClaudeAgentSdk(config, customQuery)
|
|
136
|
-
|
|
137
|
-
const getLastCall = () => customQuery.mock.lastCall![0]
|
|
138
|
-
const getUsedOptions = () => getLastCall().options
|
|
139
|
-
const getUsedPrompt = () => getLastCall().prompt
|
|
140
|
-
|
|
141
|
-
return {
|
|
142
|
-
client,
|
|
143
|
-
customQuery,
|
|
144
|
-
config,
|
|
145
|
-
getUsedOptions,
|
|
146
|
-
getUsedPrompt,
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function createMockQuery(messageOverrides: Partial<SDKResultMessage> = {}) {
|
|
151
|
-
return vi.fn().mockReturnValue({
|
|
152
|
-
async *[Symbol.asyncIterator]() {
|
|
153
|
-
yield createSDKResultMessage(messageOverrides)
|
|
154
|
-
},
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function createSDKResultMessage(
|
|
159
|
-
overrides: Partial<SDKResultMessage> = {}
|
|
160
|
-
): SDKResultMessage {
|
|
161
|
-
return {
|
|
162
|
-
type: 'result',
|
|
163
|
-
subtype: 'success',
|
|
164
|
-
result: 'default result',
|
|
165
|
-
...overrides,
|
|
166
|
-
} as SDKResultMessage
|
|
167
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { Config } from '../../config/Config'
|
|
2
|
-
import { query, type Options } from '@anthropic-ai/claude-agent-sdk'
|
|
3
|
-
import { IModelClient } from '../../contracts/types/ModelClient'
|
|
4
|
-
import { SYSTEM_PROMPT } from '../prompts/system-prompt'
|
|
5
|
-
|
|
6
|
-
export class ClaudeAgentSdk implements IModelClient {
|
|
7
|
-
constructor(
|
|
8
|
-
private readonly config: Config = new Config(),
|
|
9
|
-
private readonly queryFn: typeof query = query
|
|
10
|
-
) {}
|
|
11
|
-
|
|
12
|
-
async ask(prompt: string): Promise<string> {
|
|
13
|
-
const queryResult = this.queryFn({
|
|
14
|
-
prompt,
|
|
15
|
-
options: this.getQueryOptions(),
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
for await (const message of queryResult) {
|
|
19
|
-
if (message.type !== 'result') continue
|
|
20
|
-
|
|
21
|
-
if (message.subtype === 'success') {
|
|
22
|
-
return message.result
|
|
23
|
-
}
|
|
24
|
-
throw new Error(`Claude Agent SDK error: ${message.subtype}`)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
throw new Error('Claude Agent SDK error: No result message received')
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
private getQueryOptions(): Options {
|
|
31
|
-
return {
|
|
32
|
-
maxTurns: 1,
|
|
33
|
-
systemPrompt: SYSTEM_PROMPT,
|
|
34
|
-
allowedTools: [],
|
|
35
|
-
disallowedTools: [
|
|
36
|
-
'Read',
|
|
37
|
-
'Edit',
|
|
38
|
-
'MultiEdit',
|
|
39
|
-
'Write',
|
|
40
|
-
'Grep',
|
|
41
|
-
'Glob',
|
|
42
|
-
'Bash',
|
|
43
|
-
'WebFetch',
|
|
44
|
-
'WebSearch',
|
|
45
|
-
'Task',
|
|
46
|
-
'TodoWrite',
|
|
47
|
-
],
|
|
48
|
-
maxThinkingTokens: 0,
|
|
49
|
-
model: this.config.modelVersion,
|
|
50
|
-
strictMcpConfig: true,
|
|
51
|
-
cwd: this.config.dataDir,
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|