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
package/README.md
CHANGED
|
@@ -1,171 +1,192 @@
|
|
|
1
1
|
# XTRM-Tools
|
|
2
2
|
|
|
3
|
-
**Claude Code
|
|
3
|
+
> **Claude Code plugin** — workflow enforcement, code quality gates, issue tracking, and development automation.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Version 2.3.0** | [Complete Guide](XTRM-GUIDE.md) | [Changelog](CHANGELOG.md)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
This repository contains production-ready extensions to enhance Claude's capabilities with prompt improvement, task delegation, development workflow automation, and quality gates. The `xtrm` CLI provides a robust, modular "Plug & Play" installation engine for project-specific tools.
|
|
7
|
+
---
|
|
10
8
|
|
|
11
9
|
## Quick Start
|
|
12
10
|
|
|
13
11
|
```bash
|
|
14
12
|
# Install globally (one-time)
|
|
15
|
-
|
|
16
|
-
cd xtrm-tools/cli
|
|
17
|
-
npm install && npm run build
|
|
18
|
-
npm link
|
|
13
|
+
npm install -g github:Jaggerxtrm/xtrm-tools@latest
|
|
19
14
|
|
|
20
|
-
#
|
|
21
|
-
xtrm
|
|
22
|
-
```
|
|
15
|
+
# Install the plugin
|
|
16
|
+
xtrm install all
|
|
23
17
|
|
|
24
|
-
|
|
18
|
+
# Verify
|
|
19
|
+
claude plugin list
|
|
20
|
+
# → xtrm-tools@xtrm-tools Version: 2.3.0 Status: ✔ enabled
|
|
21
|
+
```
|
|
25
22
|
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
- [Configuration](#configuration)
|
|
31
|
-
- [Version History](#version-history)
|
|
32
|
-
- [License](#license)
|
|
23
|
+
**One-line run:**
|
|
24
|
+
```bash
|
|
25
|
+
npx -y github:Jaggerxtrm/xtrm-tools install all
|
|
26
|
+
```
|
|
33
27
|
|
|
34
28
|
---
|
|
35
29
|
|
|
36
|
-
##
|
|
30
|
+
## What's Included
|
|
37
31
|
|
|
38
|
-
|
|
32
|
+
### Core Enforcement
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
| Component | Purpose |
|
|
35
|
+
|-----------|---------|
|
|
36
|
+
| **Main Guard** | PR-only workflow — blocks direct commits on `main`/`master` |
|
|
37
|
+
| **Beads Gates** | Issue tracking — edit/commit/stop gates, memory prompts |
|
|
38
|
+
| **Quality Gates** | Auto linting (ESLint, tsc, ruff, mypy) on file edits |
|
|
39
|
+
| **GitNexus** | Knowledge graph context for code exploration |
|
|
45
40
|
|
|
46
|
-
###
|
|
47
|
-
Code quality enforcement via the **Pi Extension** (`quality-gates.ts`), which fires on every mutating file tool result.
|
|
48
|
-
- **TypeScript/JS**: delegates to project-local `.claude/hooks/quality-check.cjs` (ESLint + tsc)
|
|
49
|
-
- **Python**: delegates to project-local `.claude/hooks/quality-check.py` (ruff + mypy)
|
|
50
|
-
- Exit code 2 = blocking — Claude must fix before continuing.
|
|
51
|
-
- No classic hook entry required; runs automatically when the Pi extension is loaded.
|
|
41
|
+
### Skills
|
|
52
42
|
|
|
53
|
-
|
|
43
|
+
| Skill | Type | Purpose |
|
|
44
|
+
|-------|------|---------|
|
|
45
|
+
| `using-xtrm` | Project | Session operating manual |
|
|
46
|
+
| `documenting` | Global | SSOT documentation with drift detection |
|
|
47
|
+
| `delegating` | Global | Task delegation to cost-optimized agents |
|
|
48
|
+
| `orchestrating-agents` | Global | Multi-model collaboration |
|
|
54
49
|
|
|
55
|
-
|
|
56
|
-
Task intake and service routing for Docker service projects.
|
|
57
|
-
- **Invocation**: `/scope "task description"` or automatic via SessionStart hook.
|
|
58
|
-
- **Purpose**: Gives Claude persistent, service-specific expertise without re-explaining architecture. Emits structured scope plans and detects codebase drift via PostToolUse hooks.
|
|
59
|
-
|
|
60
|
-
### Core Project Hooks
|
|
50
|
+
---
|
|
61
51
|
|
|
62
|
-
|
|
63
|
-
- **Trigger**: PreToolUse (Write|Edit|MultiEdit|Serena edit tools|Bash)
|
|
64
|
-
- **Purpose**: Enforces PR-only merge workflow with full git protection. Blocks direct commits and dangerous `git checkout` / `git push` commands on protected branches (`main/master`).
|
|
65
|
-
- **Post-Push (`main-guard-post-push.mjs`)**: After pushing a feature branch, reminds to use `gh pr merge --squash` and sync local via `git reset --hard origin/main`.
|
|
52
|
+
## Plugin Structure
|
|
66
53
|
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
|
|
54
|
+
```
|
|
55
|
+
plugins/xtrm-tools/
|
|
56
|
+
├── .claude-plugin/plugin.json # Manifest
|
|
57
|
+
├── hooks → ../../hooks # All hook scripts + hooks.json
|
|
58
|
+
├── skills → ../../skills # Auto-discovered skills
|
|
59
|
+
└── .mcp.json → ../../.mcp.json # MCP servers
|
|
60
|
+
```
|
|
71
61
|
|
|
72
|
-
|
|
73
|
-
- **Trigger**: PreToolUse (edit/commit), PostToolUse (claim sync), Stop (memory + stop gate), PreCompact, SessionStart
|
|
74
|
-
- **Purpose**: Ensures all work is tracked to a `bd` issue. Blocks file edits without an active claim.
|
|
75
|
-
- **Claim sync (`beads-claim-sync.mjs`)**: PostToolUse hook that syncs claim state after `bd update --claim` shell commands.
|
|
76
|
-
- **Compaction**: `PreCompact` and `SessionStart` hooks preserve `in_progress` beads state across `/compact` events. Hook blocking messages are quieted and compacted to save tokens.
|
|
62
|
+
All hook paths use `${CLAUDE_PLUGIN_ROOT}` — works from any installation location.
|
|
77
63
|
|
|
78
64
|
---
|
|
79
65
|
|
|
80
|
-
##
|
|
66
|
+
## Policy System
|
|
81
67
|
|
|
82
|
-
|
|
68
|
+
Policies are the **single source of truth** for all enforcement rules. Located in `policies/`, they compile to both Claude hooks and Pi extensions.
|
|
83
69
|
|
|
84
|
-
###
|
|
85
|
-
Maintains Single Source of Truth (SSOT) documentation system with drift detection.
|
|
86
|
-
- **Invocation**: `/document [task]`
|
|
87
|
-
- **Purpose**: Creates, updates, and validates SSOT documentation. Auto-generates INDEX blocks for rapid navigation. A Stop hook fires at session end to detect stale memories based on the `tracks:` frontmatter field.
|
|
70
|
+
### Policy Files
|
|
88
71
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
|
|
72
|
+
| Policy | Runtime | Purpose |
|
|
73
|
+
|--------|---------|---------|
|
|
74
|
+
| `main-guard.json` | both | PR-only workflow |
|
|
75
|
+
| `beads.json` | both | Issue tracking gates |
|
|
76
|
+
| `quality-gates.json` | pi | Linting/typechecking |
|
|
77
|
+
| `branch-state.json` | claude | Branch context injection |
|
|
78
|
+
| `gitnexus.json` | claude | Knowledge graph enrichment |
|
|
93
79
|
|
|
94
|
-
###
|
|
95
|
-
Orchestrates task handoff and "handshaking" between Gemini and Qwen CLI agents.
|
|
96
|
-
- **Invocation**: `/orchestrate [workflow-type] [task]`
|
|
97
|
-
- **Purpose**: Facilitates multi-model collaboration, adversarial reviews, and deep cross-validation of complex logic. Workflows include collaborative design, adversarial security review, troubleshooting, and single handshakes.
|
|
80
|
+
### Compiler
|
|
98
81
|
|
|
99
|
-
|
|
82
|
+
```bash
|
|
83
|
+
node scripts/compile-policies.mjs # Generate hooks.json
|
|
84
|
+
node scripts/compile-policies.mjs --check # CI drift detection
|
|
85
|
+
```
|
|
100
86
|
|
|
101
|
-
|
|
87
|
+
---
|
|
102
88
|
|
|
103
|
-
|
|
89
|
+
## CLI Commands
|
|
104
90
|
|
|
105
|
-
```
|
|
106
|
-
|
|
91
|
+
```
|
|
92
|
+
xtrm <command> [options]
|
|
107
93
|
```
|
|
108
94
|
|
|
109
|
-
|
|
95
|
+
| Command | Description |
|
|
96
|
+
|---------|-------------|
|
|
97
|
+
| `install all` | Full plugin + beads + gitnexus |
|
|
98
|
+
| `install basic` | Plugin + skills (no beads) |
|
|
99
|
+
| `install project <name>` | Install project skill |
|
|
100
|
+
| `project init` | Initialize project (gitnexus + bd) |
|
|
101
|
+
| `status` | Read-only diff view |
|
|
102
|
+
| `clean` | Remove orphaned hooks |
|
|
103
|
+
|
|
104
|
+
### Flags
|
|
105
|
+
|
|
106
|
+
| Flag | Description |
|
|
107
|
+
|------|-------------|
|
|
108
|
+
| `--yes`, `-y` | Non-interactive mode |
|
|
109
|
+
| `--dry-run` | Preview only |
|
|
110
|
+
| `--prune` | Force-replace hooks |
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
npm install -g github:Jaggerxtrm/xtrm-tools@latest
|
|
112
|
+
---
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
## Hooks Reference
|
|
115
|
+
|
|
116
|
+
### Event Types
|
|
117
|
+
|
|
118
|
+
| Event | When |
|
|
119
|
+
|-------|------|
|
|
120
|
+
| `SessionStart` | Session begins |
|
|
121
|
+
| `PreToolUse` | Before tool invocation |
|
|
122
|
+
| `PostToolUse` | After tool completes |
|
|
123
|
+
| `Stop` | Session ends |
|
|
124
|
+
| `PreCompact` | Before compaction |
|
|
125
|
+
|
|
126
|
+
### Main Guard
|
|
127
|
+
|
|
128
|
+
- Blocks `git commit`/`push` on protected branches
|
|
129
|
+
- Blocks direct file edits on `main`/`master`
|
|
130
|
+
- Post-push reminder: `gh pr merge --squash`
|
|
131
|
+
|
|
132
|
+
### Beads Gates
|
|
133
|
+
|
|
134
|
+
| Hook | Behavior |
|
|
135
|
+
|------|----------|
|
|
136
|
+
| Edit Gate | Requires claimed issue to edit files |
|
|
137
|
+
| Commit Gate | Prompts to close issue before commit |
|
|
138
|
+
| Stop Gate | Blocks session end with unclosed issues |
|
|
139
|
+
| Memory Gate | Prompts to persist insights when closing |
|
|
118
140
|
|
|
119
141
|
---
|
|
120
142
|
|
|
121
|
-
##
|
|
143
|
+
## MCP Servers
|
|
122
144
|
|
|
123
|
-
|
|
124
|
-
xtrm <command> [options]
|
|
125
|
-
```
|
|
145
|
+
Configured in `.mcp.json` (xtrm-managed only):
|
|
126
146
|
|
|
127
|
-
|
|
|
128
|
-
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
147
|
+
| Server | Purpose |
|
|
148
|
+
|--------|---------|
|
|
149
|
+
| `gitnexus` | Knowledge graph |
|
|
150
|
+
| `github-grep` | Code search |
|
|
151
|
+
| `deepwiki` | DeepWiki docs search |
|
|
152
|
+
|
|
153
|
+
Official Claude plugins are installed during `xtrm install all`:
|
|
154
|
+
- `serena@claude-plugins-official`
|
|
155
|
+
- `context7@claude-plugins-official`
|
|
156
|
+
- `github@claude-plugins-official`
|
|
157
|
+
- `ralph-loop@claude-plugins-official`
|
|
136
158
|
|
|
137
159
|
---
|
|
138
160
|
|
|
139
|
-
##
|
|
161
|
+
## Issue Tracking (Beads)
|
|
140
162
|
|
|
141
|
-
|
|
163
|
+
```bash
|
|
164
|
+
bd ready # Find unblocked work
|
|
165
|
+
bd update <id> --claim # Claim an issue
|
|
166
|
+
bd close <id> --reason "Done" # Close when done
|
|
167
|
+
```
|
|
142
168
|
|
|
143
|
-
|
|
169
|
+
---
|
|
144
170
|
|
|
145
|
-
|
|
146
|
-
- **serena**: Code analysis (requires `uvx`)
|
|
147
|
-
- **context7**: Documentation lookup (requires `CONTEXT7_API_KEY`)
|
|
148
|
-
- **github-grep**: Code search
|
|
149
|
-
- **deepwiki**: Technical documentation
|
|
150
|
-
- **gitnexus**: Knowledge graph code intelligence (registered during `xtrm project init`)
|
|
171
|
+
## Documentation
|
|
151
172
|
|
|
152
|
-
|
|
173
|
+
- **[XTRM-GUIDE.md](XTRM-GUIDE.md)** — Complete reference guide
|
|
174
|
+
- **[CHANGELOG.md](CHANGELOG.md)** — Full version history
|
|
175
|
+
- **[ROADMAP.md](ROADMAP.md)** — Planned features
|
|
153
176
|
|
|
154
177
|
---
|
|
155
178
|
|
|
156
179
|
## Version History
|
|
157
180
|
|
|
158
181
|
| Version | Date | Highlights |
|
|
159
|
-
|
|
160
|
-
| 2.
|
|
161
|
-
| 2.
|
|
162
|
-
| 2.
|
|
163
|
-
|
|
|
164
|
-
| 2.1.14 | 2026-03-15 | Rewrote gitnexus-hook as PostToolUse with Serena; added `using-xtrm` skill |
|
|
165
|
-
| 2.1.9 | 2026-03-15 | `main-guard` enforced PR-only workflow, `--squash` requirement, npm publish |
|
|
182
|
+
|---------|------|------------|
|
|
183
|
+
| 2.3.0 | 2026-03-17 | Plugin structure, policy compiler, Pi extension parity |
|
|
184
|
+
| 2.2.0 | 2026-03-17 | Pi extensions: quality-gates, beads, main-guard |
|
|
185
|
+
| 2.0.0 | 2026-03-12 | CLI rebrand, project skills engine |
|
|
186
|
+
| 1.7.0 | 2026-02-25 | GitNexus integration |
|
|
166
187
|
|
|
167
|
-
|
|
188
|
+
---
|
|
168
189
|
|
|
169
190
|
## License
|
|
170
191
|
|
|
171
|
-
MIT License
|
|
192
|
+
MIT License
|
package/cli/dist/index.cjs
CHANGED
|
@@ -37236,13 +37236,24 @@ async function calculateDiff(repoRoot, systemRoot, pruneMode = false) {
|
|
|
37236
37236
|
"qwen-commands": { missing: [], outdated: [], drifted: [], total: 0 },
|
|
37237
37237
|
"antigravity-workflows": { missing: [], outdated: [], drifted: [], total: 0 }
|
|
37238
37238
|
};
|
|
37239
|
+
const manifestPath = (0, import_path4.join)(systemRoot, ".jaggers-sync-manifest.json");
|
|
37240
|
+
let installedHashes = null;
|
|
37241
|
+
try {
|
|
37242
|
+
if (await import_fs_extra3.default.pathExists(manifestPath)) {
|
|
37243
|
+
const manifest = await import_fs_extra3.default.readJson(manifestPath);
|
|
37244
|
+
if (manifest.fileHashes && typeof manifest.fileHashes === "object") {
|
|
37245
|
+
installedHashes = manifest.fileHashes;
|
|
37246
|
+
}
|
|
37247
|
+
}
|
|
37248
|
+
} catch {
|
|
37249
|
+
}
|
|
37239
37250
|
if (isAgentsSkills) {
|
|
37240
37251
|
const repoPath = (0, import_path4.join)(repoRoot, "skills");
|
|
37241
37252
|
if (!await import_fs_extra3.default.pathExists(repoPath)) return changeSet;
|
|
37242
37253
|
const items = (await import_fs_extra3.default.readdir(repoPath)).filter((i) => !IGNORED_ITEMS.has(i));
|
|
37243
37254
|
changeSet.skills.total = items.length;
|
|
37244
37255
|
for (const item of items) {
|
|
37245
|
-
await compareItem("skills", item, (0, import_path4.join)(repoPath, item), (0, import_path4.join)(systemRoot, item), changeSet, pruneMode);
|
|
37256
|
+
await compareItem("skills", item, (0, import_path4.join)(repoPath, item), (0, import_path4.join)(systemRoot, item), changeSet, pruneMode, installedHashes);
|
|
37246
37257
|
}
|
|
37247
37258
|
return changeSet;
|
|
37248
37259
|
}
|
|
@@ -37269,7 +37280,8 @@ async function calculateDiff(repoRoot, systemRoot, pruneMode = false) {
|
|
|
37269
37280
|
(0, import_path4.join)(repoPath, item),
|
|
37270
37281
|
(0, import_path4.join)(systemPath, item),
|
|
37271
37282
|
changeSet,
|
|
37272
|
-
pruneMode
|
|
37283
|
+
pruneMode,
|
|
37284
|
+
installedHashes
|
|
37273
37285
|
);
|
|
37274
37286
|
}
|
|
37275
37287
|
}
|
|
@@ -37281,12 +37293,12 @@ async function calculateDiff(repoRoot, systemRoot, pruneMode = false) {
|
|
|
37281
37293
|
const itemRepoPath = (0, import_path4.join)(repoRoot, paths.repo);
|
|
37282
37294
|
const itemSystemPath = (0, import_path4.join)(systemRoot, paths.sys);
|
|
37283
37295
|
if (await import_fs_extra3.default.pathExists(itemRepoPath)) {
|
|
37284
|
-
await compareItem("config", name, itemRepoPath, itemSystemPath, changeSet);
|
|
37296
|
+
await compareItem("config", name, itemRepoPath, itemSystemPath, changeSet, false, installedHashes);
|
|
37285
37297
|
}
|
|
37286
37298
|
}
|
|
37287
37299
|
return changeSet;
|
|
37288
37300
|
}
|
|
37289
|
-
async function compareItem(category, item, repoPath, systemPath, changeSet, pruneMode = false) {
|
|
37301
|
+
async function compareItem(category, item, repoPath, systemPath, changeSet, pruneMode = false, installedHashes = null) {
|
|
37290
37302
|
const cat = changeSet[category];
|
|
37291
37303
|
if (!await import_fs_extra3.default.pathExists(systemPath)) {
|
|
37292
37304
|
cat.missing.push(item);
|
|
@@ -37304,12 +37316,22 @@ async function compareItem(category, item, repoPath, systemPath, changeSet, prun
|
|
|
37304
37316
|
return;
|
|
37305
37317
|
}
|
|
37306
37318
|
if (repoHash !== systemHash) {
|
|
37307
|
-
const
|
|
37308
|
-
const
|
|
37309
|
-
if (
|
|
37310
|
-
|
|
37319
|
+
const manifestKey = `${category}/${item}`;
|
|
37320
|
+
const installedHash = installedHashes?.[manifestKey];
|
|
37321
|
+
if (installedHash !== void 0) {
|
|
37322
|
+
if (systemHash !== installedHash) {
|
|
37323
|
+
cat.drifted.push(item);
|
|
37324
|
+
} else {
|
|
37325
|
+
cat.outdated.push(item);
|
|
37326
|
+
}
|
|
37311
37327
|
} else {
|
|
37312
|
-
|
|
37328
|
+
const repoMtime = await getNewestMtime(repoPath);
|
|
37329
|
+
const systemMtime = await getNewestMtime(systemPath);
|
|
37330
|
+
if (systemMtime > repoMtime + 2e3) {
|
|
37331
|
+
cat.drifted.push(item);
|
|
37332
|
+
} else {
|
|
37333
|
+
cat.outdated.push(item);
|
|
37334
|
+
}
|
|
37313
37335
|
}
|
|
37314
37336
|
}
|
|
37315
37337
|
}
|
|
@@ -40508,7 +40530,32 @@ async function cleanupBackup(backup) {
|
|
|
40508
40530
|
}
|
|
40509
40531
|
|
|
40510
40532
|
// src/core/sync-executor.ts
|
|
40511
|
-
|
|
40533
|
+
async function syncMcpForTargets(repoRoot, targets, isDryRun = false, selectedMcpServers) {
|
|
40534
|
+
const synced = /* @__PURE__ */ new Set();
|
|
40535
|
+
let count = 0;
|
|
40536
|
+
for (const target of targets) {
|
|
40537
|
+
const agent = detectAgent(target);
|
|
40538
|
+
if (!agent || synced.has(agent)) continue;
|
|
40539
|
+
const coreConfig = loadCanonicalMcpConfig(repoRoot);
|
|
40540
|
+
const mcpToSync = { mcpServers: { ...coreConfig.mcpServers } };
|
|
40541
|
+
if (selectedMcpServers && selectedMcpServers.length > 0) {
|
|
40542
|
+
const optionalConfig = loadCanonicalMcpConfig(repoRoot, true);
|
|
40543
|
+
for (const name of selectedMcpServers) {
|
|
40544
|
+
if (optionalConfig.mcpServers[name]) {
|
|
40545
|
+
mcpToSync.mcpServers[name] = optionalConfig.mcpServers[name];
|
|
40546
|
+
}
|
|
40547
|
+
}
|
|
40548
|
+
}
|
|
40549
|
+
if (!isDryRun) {
|
|
40550
|
+
await syncMcpServersWithCli(agent, mcpToSync, isDryRun, false);
|
|
40551
|
+
} else {
|
|
40552
|
+
console.log(kleur_default.cyan(` [DRY RUN] MCP sync for ${agent}`));
|
|
40553
|
+
}
|
|
40554
|
+
synced.add(agent);
|
|
40555
|
+
count++;
|
|
40556
|
+
}
|
|
40557
|
+
return count;
|
|
40558
|
+
}
|
|
40512
40559
|
function extractHookCommandPath(command) {
|
|
40513
40560
|
const quoted = command.match(/"([^"]+)"/);
|
|
40514
40561
|
if (quoted?.[1]) return quoted[1];
|
|
@@ -40544,7 +40591,7 @@ async function filterHooksByInstalledScripts(hooksConfig) {
|
|
|
40544
40591
|
}
|
|
40545
40592
|
return hooksConfig;
|
|
40546
40593
|
}
|
|
40547
|
-
async function executeSync(repoRoot, systemRoot, changeSet, mode, actionType, isDryRun = false,
|
|
40594
|
+
async function executeSync(repoRoot, systemRoot, changeSet, mode, actionType, isDryRun = false, options) {
|
|
40548
40595
|
const normalizedRoot = import_path8.default.normalize(systemRoot).replace(/\\/g, "/");
|
|
40549
40596
|
const isAgentsSkills = normalizedRoot.includes(".agents/skills");
|
|
40550
40597
|
const isClaude = systemRoot.includes(".claude") || systemRoot.includes("Claude");
|
|
@@ -40555,27 +40602,9 @@ async function executeSync(repoRoot, systemRoot, changeSet, mode, actionType, is
|
|
|
40555
40602
|
let count = 0;
|
|
40556
40603
|
const adapter = new ConfigAdapter(systemRoot);
|
|
40557
40604
|
const backups = [];
|
|
40605
|
+
const newHashes = {};
|
|
40558
40606
|
try {
|
|
40559
40607
|
const agent = detectAgent(systemRoot);
|
|
40560
|
-
if (agent && actionType === "sync" && !syncedMcpAgents.has(agent) && !options?.skipMcp) {
|
|
40561
|
-
const coreConfig = loadCanonicalMcpConfig(repoRoot);
|
|
40562
|
-
const mcpToSync = { mcpServers: { ...coreConfig.mcpServers } };
|
|
40563
|
-
if (selectedMcpServers && selectedMcpServers.length > 0) {
|
|
40564
|
-
const optionalConfig = loadCanonicalMcpConfig(repoRoot, true);
|
|
40565
|
-
for (const name of selectedMcpServers) {
|
|
40566
|
-
if (optionalConfig.mcpServers[name]) {
|
|
40567
|
-
mcpToSync.mcpServers[name] = optionalConfig.mcpServers[name];
|
|
40568
|
-
}
|
|
40569
|
-
}
|
|
40570
|
-
}
|
|
40571
|
-
if (!isDryRun) {
|
|
40572
|
-
await syncMcpServersWithCli(agent, mcpToSync, isDryRun, false);
|
|
40573
|
-
} else {
|
|
40574
|
-
console.log(kleur_default.cyan(` [DRY RUN] MCP sync for ${agent}`));
|
|
40575
|
-
}
|
|
40576
|
-
syncedMcpAgents.add(agent);
|
|
40577
|
-
count++;
|
|
40578
|
-
}
|
|
40579
40608
|
for (const category of categories) {
|
|
40580
40609
|
const itemsToProcess = [];
|
|
40581
40610
|
if (actionType === "sync") {
|
|
@@ -40608,6 +40637,11 @@ async function executeSync(repoRoot, systemRoot, changeSet, mode, actionType, is
|
|
|
40608
40637
|
src = import_path8.default.join(repoRoot, "config", "settings.json");
|
|
40609
40638
|
dest = import_path8.default.join(systemRoot, "settings.json");
|
|
40610
40639
|
const agent2 = detectAgent(systemRoot);
|
|
40640
|
+
if (agent2 === "claude") {
|
|
40641
|
+
if (!isDryRun) console.log(kleur_default.dim(` (settings.json skipped \u2014 managed by xtrm-tools plugin)`));
|
|
40642
|
+
count++;
|
|
40643
|
+
continue;
|
|
40644
|
+
}
|
|
40611
40645
|
console.log(kleur_default.gray(` --> config/settings.json`));
|
|
40612
40646
|
if (!isDryRun && await import_fs_extra8.default.pathExists(dest)) {
|
|
40613
40647
|
backups.push(await createBackup(dest));
|
|
@@ -40697,6 +40731,9 @@ async function executeSync(repoRoot, systemRoot, changeSet, mode, actionType, is
|
|
|
40697
40731
|
await import_fs_extra8.default.copy(src, dest);
|
|
40698
40732
|
}
|
|
40699
40733
|
}
|
|
40734
|
+
if (!isDryRun && actionType === "sync") {
|
|
40735
|
+
newHashes[`${category}/${item}`] = await hashDirectory(src);
|
|
40736
|
+
}
|
|
40700
40737
|
count++;
|
|
40701
40738
|
}
|
|
40702
40739
|
}
|
|
@@ -40707,7 +40744,8 @@ async function executeSync(repoRoot, systemRoot, changeSet, mode, actionType, is
|
|
|
40707
40744
|
...existing,
|
|
40708
40745
|
lastSync: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40709
40746
|
repoRoot,
|
|
40710
|
-
items: count
|
|
40747
|
+
items: count,
|
|
40748
|
+
fileHashes: { ...existing.fileHashes ?? {}, ...newHashes }
|
|
40711
40749
|
}, { spaces: 2 });
|
|
40712
40750
|
}
|
|
40713
40751
|
for (const backup of backups) {
|
|
@@ -41846,6 +41884,7 @@ function isGitnexusInstalled() {
|
|
|
41846
41884
|
async function needsSettingsSync(repoRoot, target) {
|
|
41847
41885
|
const normalizedTarget = target.replace(/\\/g, "/").toLowerCase();
|
|
41848
41886
|
if (normalizedTarget.includes(".agents/skills")) return false;
|
|
41887
|
+
if (detectAgent(target) === "claude") return false;
|
|
41849
41888
|
const hooksTemplatePath = import_path13.default.join(repoRoot, "config", "hooks.json");
|
|
41850
41889
|
if (!await import_fs_extra13.default.pathExists(hooksTemplatePath)) return false;
|
|
41851
41890
|
const requiredEvents = Object.keys((await import_fs_extra13.default.readJson(hooksTemplatePath)).hooks ?? {});
|
|
@@ -41864,12 +41903,63 @@ async function needsSettingsSync(repoRoot, target) {
|
|
|
41864
41903
|
}
|
|
41865
41904
|
return requiredEvents.some((event) => !(event in targetHooks));
|
|
41866
41905
|
}
|
|
41906
|
+
var OFFICIAL_CLAUDE_MARKETPLACE = "https://github.com/anthropics/claude-plugins-official";
|
|
41907
|
+
var OFFICIAL_CLAUDE_PLUGINS = [
|
|
41908
|
+
"serena@claude-plugins-official",
|
|
41909
|
+
"context7@claude-plugins-official",
|
|
41910
|
+
"github@claude-plugins-official",
|
|
41911
|
+
"ralph-loop@claude-plugins-official"
|
|
41912
|
+
];
|
|
41913
|
+
async function installOfficialClaudePlugins(dryRun) {
|
|
41914
|
+
console.log(t.bold("\n \u2699 official Claude plugins (serena/context7/github/ralph-loop)"));
|
|
41915
|
+
if (dryRun) {
|
|
41916
|
+
console.log(t.accent(" [DRY RUN] Would register claude-plugins-official marketplace and install official plugins\n"));
|
|
41917
|
+
return;
|
|
41918
|
+
}
|
|
41919
|
+
(0, import_child_process5.spawnSync)("claude", ["plugin", "marketplace", "add", OFFICIAL_CLAUDE_MARKETPLACE, "--scope", "user"], { stdio: "pipe" });
|
|
41920
|
+
const listResult = (0, import_child_process5.spawnSync)("claude", ["plugin", "list"], { encoding: "utf8", stdio: "pipe" });
|
|
41921
|
+
const installedOutput = listResult.stdout ?? "";
|
|
41922
|
+
let installedCount = 0;
|
|
41923
|
+
let alreadyInstalledCount = 0;
|
|
41924
|
+
for (const pluginId of OFFICIAL_CLAUDE_PLUGINS) {
|
|
41925
|
+
if (installedOutput.includes(pluginId)) {
|
|
41926
|
+
alreadyInstalledCount += 1;
|
|
41927
|
+
continue;
|
|
41928
|
+
}
|
|
41929
|
+
const result = (0, import_child_process5.spawnSync)("claude", ["plugin", "install", pluginId, "--scope", "user"], { stdio: "inherit" });
|
|
41930
|
+
if (result.status === 0) {
|
|
41931
|
+
installedCount += 1;
|
|
41932
|
+
} else {
|
|
41933
|
+
console.log(t.warning(` ! Failed to install ${pluginId}. Install manually: claude plugin install ${pluginId} --scope user`));
|
|
41934
|
+
}
|
|
41935
|
+
}
|
|
41936
|
+
console.log(t.success(` \u2713 Official plugins ready (${installedCount} installed, ${alreadyInstalledCount} already present)
|
|
41937
|
+
`));
|
|
41938
|
+
}
|
|
41939
|
+
async function installPlugin(repoRoot, dryRun) {
|
|
41940
|
+
console.log(t.bold("\n \u2699 xtrm-tools (Claude Code plugin)"));
|
|
41941
|
+
if (dryRun) {
|
|
41942
|
+
console.log(t.accent(" [DRY RUN] Would register xtrm-tools marketplace and install plugin\n"));
|
|
41943
|
+
await installOfficialClaudePlugins(true);
|
|
41944
|
+
return;
|
|
41945
|
+
}
|
|
41946
|
+
(0, import_child_process5.spawnSync)("claude", ["plugin", "marketplace", "add", repoRoot, "--scope", "user"], { stdio: "pipe" });
|
|
41947
|
+
const listResult = (0, import_child_process5.spawnSync)("claude", ["plugin", "list"], { encoding: "utf8", stdio: "pipe" });
|
|
41948
|
+
if (listResult.stdout?.includes("xtrm-tools@xtrm-tools")) {
|
|
41949
|
+
(0, import_child_process5.spawnSync)("claude", ["plugin", "uninstall", "xtrm-tools@xtrm-tools"], { stdio: "inherit" });
|
|
41950
|
+
}
|
|
41951
|
+
(0, import_child_process5.spawnSync)("claude", ["plugin", "install", "xtrm-tools@xtrm-tools", "--scope", "user"], { stdio: "inherit" });
|
|
41952
|
+
console.log(t.success(" \u2713 xtrm-tools plugin installed"));
|
|
41953
|
+
await installOfficialClaudePlugins(false);
|
|
41954
|
+
}
|
|
41867
41955
|
async function runGlobalInstall(flags, installOpts = {}) {
|
|
41868
41956
|
const { dryRun, yes, noMcp, force } = flags;
|
|
41869
41957
|
const effectiveYes = yes || process.argv.includes("--yes") || process.argv.includes("-y");
|
|
41870
41958
|
const repoRoot = await findRepoRoot();
|
|
41871
41959
|
const ctx = await getContext({ selector: "all", createMissingDirs: !dryRun });
|
|
41872
41960
|
const { targets, syncMode } = ctx;
|
|
41961
|
+
const claudeTargets = targets.filter((t2) => detectAgent(t2) === "claude");
|
|
41962
|
+
const otherTargets = targets.filter((t2) => detectAgent(t2) !== "claude");
|
|
41873
41963
|
let skipBeads = installOpts.excludeBeads ?? false;
|
|
41874
41964
|
if (installOpts.checkBeads && !skipBeads) {
|
|
41875
41965
|
console.log(t.bold("\n \u2699 beads + dolt (workflow enforcement backend)"));
|
|
@@ -41941,8 +42031,14 @@ async function runGlobalInstall(flags, installOpts = {}) {
|
|
|
41941
42031
|
console.log(t.muted(" \u2139 Skipped. Install later with: npm install -g gitnexus\n"));
|
|
41942
42032
|
}
|
|
41943
42033
|
}
|
|
42034
|
+
for (const _claudeTarget of claudeTargets) {
|
|
42035
|
+
await installPlugin(repoRoot, dryRun);
|
|
42036
|
+
}
|
|
42037
|
+
if (otherTargets.length === 0) {
|
|
42038
|
+
return;
|
|
42039
|
+
}
|
|
41944
42040
|
const diffTasks = new Listr(
|
|
41945
|
-
|
|
42041
|
+
otherTargets.map((target) => ({
|
|
41946
42042
|
title: formatTargetLabel(target),
|
|
41947
42043
|
task: async (listCtx, task) => {
|
|
41948
42044
|
try {
|
|
@@ -41950,10 +42046,6 @@ async function runGlobalInstall(flags, installOpts = {}) {
|
|
|
41950
42046
|
if (skipBeads) {
|
|
41951
42047
|
changeSet = filterBeadsFromChangeSet(changeSet);
|
|
41952
42048
|
}
|
|
41953
|
-
const hasSettingsDiff = changeSet.config.missing.includes("settings.json") || changeSet.config.outdated.includes("settings.json") || changeSet.config.drifted.includes("settings.json");
|
|
41954
|
-
if (!hasSettingsDiff && await needsSettingsSync(repoRoot, target)) {
|
|
41955
|
-
changeSet.config.outdated.push("settings.json");
|
|
41956
|
-
}
|
|
41957
42049
|
const totalChanges = Object.values(changeSet).reduce(
|
|
41958
42050
|
(sum, c) => sum + c.missing.length + c.outdated.length + c.drifted.length,
|
|
41959
42051
|
0
|
|
@@ -41998,11 +42090,13 @@ async function runGlobalInstall(flags, installOpts = {}) {
|
|
|
41998
42090
|
}
|
|
41999
42091
|
}
|
|
42000
42092
|
let totalCount = 0;
|
|
42093
|
+
if (!noMcp) {
|
|
42094
|
+
await syncMcpForTargets(repoRoot, otherTargets, dryRun);
|
|
42095
|
+
}
|
|
42001
42096
|
for (const { target, changeSet, skippedDrifted } of allChanges) {
|
|
42002
42097
|
console.log(t.bold(`
|
|
42003
42098
|
${sym.arrow} ${formatTargetLabel(target)}`));
|
|
42004
|
-
const count = await executeSync(repoRoot, target, changeSet, syncMode, "sync", dryRun,
|
|
42005
|
-
skipMcp: noMcp,
|
|
42099
|
+
const count = await executeSync(repoRoot, target, changeSet, syncMode, "sync", dryRun, {
|
|
42006
42100
|
force
|
|
42007
42101
|
});
|
|
42008
42102
|
totalCount += count;
|
|
@@ -42045,6 +42139,8 @@ function createInstallCommand() {
|
|
|
42045
42139
|
createMissingDirs: !dryRun
|
|
42046
42140
|
});
|
|
42047
42141
|
const { targets, syncMode } = ctx;
|
|
42142
|
+
const claudeTargets = targets.filter((t2) => detectAgent(t2) === "claude");
|
|
42143
|
+
const otherTargets = targets.filter((t2) => detectAgent(t2) !== "claude");
|
|
42048
42144
|
let skipBeads = false;
|
|
42049
42145
|
if (!backport) {
|
|
42050
42146
|
console.log(t.bold("\n \u2699 beads + dolt (workflow enforcement backend)"));
|
|
@@ -42092,8 +42188,13 @@ function createInstallCommand() {
|
|
|
42092
42188
|
}
|
|
42093
42189
|
}
|
|
42094
42190
|
}
|
|
42191
|
+
if (!backport) {
|
|
42192
|
+
for (const _claudeTarget of claudeTargets) {
|
|
42193
|
+
await installPlugin(repoRoot, dryRun);
|
|
42194
|
+
}
|
|
42195
|
+
}
|
|
42095
42196
|
const diffTasks = new Listr(
|
|
42096
|
-
|
|
42197
|
+
otherTargets.map((target) => ({
|
|
42097
42198
|
title: formatTargetLabel(target),
|
|
42098
42199
|
task: async (listCtx, task) => {
|
|
42099
42200
|
try {
|
|
@@ -42128,20 +42229,8 @@ function createInstallCommand() {
|
|
|
42128
42229
|
);
|
|
42129
42230
|
const diffCtx = await diffTasks.run({ allChanges: [] });
|
|
42130
42231
|
const allChanges = diffCtx.allChanges;
|
|
42131
|
-
if (!backport
|
|
42132
|
-
|
|
42133
|
-
skills: { missing: [], outdated: [], drifted: [], total: 0 },
|
|
42134
|
-
hooks: { missing: [], outdated: [], drifted: [], total: 0 },
|
|
42135
|
-
config: { missing: [], outdated: [], drifted: [], total: 0 },
|
|
42136
|
-
commands: { missing: [], outdated: [], drifted: [], total: 0 },
|
|
42137
|
-
"qwen-commands": { missing: [], outdated: [], drifted: [], total: 0 },
|
|
42138
|
-
"antigravity-workflows": { missing: [], outdated: [], drifted: [], total: 0 }
|
|
42139
|
-
};
|
|
42140
|
-
for (const target of targets) {
|
|
42141
|
-
console.log(t.bold(`
|
|
42142
|
-
${sym.arrow} ${formatTargetLabel(target)}`));
|
|
42143
|
-
await executeSync(repoRoot, target, emptyChangeSet, syncMode, "sync", false);
|
|
42144
|
-
}
|
|
42232
|
+
if (!backport) {
|
|
42233
|
+
await syncMcpForTargets(repoRoot, otherTargets, dryRun);
|
|
42145
42234
|
}
|
|
42146
42235
|
if (allChanges.length === 0) {
|
|
42147
42236
|
console.log("\n" + t.boldGreen("\u2713 Files are up-to-date") + "\n");
|