xtrm-tools 2.0.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/CHANGELOG.md +496 -0
- package/README.md +762 -0
- package/cli/dist/index.cjs +55245 -0
- package/cli/dist/index.cjs.map +1 -0
- package/cli/dist/index.d.cts +2 -0
- package/cli/package.json +43 -0
- package/config/.env.example +40 -0
- package/config/hooks.json +36 -0
- package/config/mcp_servers.json +46 -0
- package/config/mcp_servers_optional.json +53 -0
- package/config/settings.json +70 -0
- package/hooks/README.md +156 -0
- package/hooks/__pycache__/agent_context.cpython-314.pyc +0 -0
- package/hooks/agent_context.py +105 -0
- package/hooks/gitnexus/gitnexus-hook.cjs +133 -0
- package/hooks/serena-workflow-reminder.py +74 -0
- package/hooks/skill-discovery.py +90 -0
- package/hooks/skill-suggestion.py +112 -0
- package/hooks/test_agent_context.py +112 -0
- package/hooks/type-safety-enforcement.py +107 -0
- package/package.json +48 -0
- package/project-skills/main-guard/.claude/hooks/main-guard.cjs +188 -0
- package/project-skills/main-guard/.claude/settings.json +16 -0
- package/project-skills/main-guard/.claude/skills/using-main-guard/SKILL.md +135 -0
- package/project-skills/main-guard/README.md +163 -0
- package/project-skills/py-quality-gate/.claude/hooks/quality-check.py +311 -0
- package/project-skills/py-quality-gate/.claude/settings.json +16 -0
- package/project-skills/py-quality-gate/.claude/skills/using-py-quality-gate/SKILL.md +112 -0
- package/project-skills/py-quality-gate/README.md +147 -0
- package/project-skills/service-skills-set/.claude/git-hooks/__pycache__/doc_reminder.cpython-314.pyc +0 -0
- package/project-skills/service-skills-set/.claude/git-hooks/__pycache__/skill_staleness.cpython-314.pyc +0 -0
- package/project-skills/service-skills-set/.claude/git-hooks/doc_reminder.py +67 -0
- package/project-skills/service-skills-set/.claude/git-hooks/skill_staleness.py +194 -0
- package/project-skills/service-skills-set/.claude/service-registry.json +4 -0
- package/project-skills/service-skills-set/.claude/settings.json +37 -0
- package/project-skills/service-skills-set/.claude/skills/creating-service-skills/SKILL.md +433 -0
- package/project-skills/service-skills-set/.claude/skills/creating-service-skills/references/script_quality_standards.md +412 -0
- package/project-skills/service-skills-set/.claude/skills/creating-service-skills/references/service_skill_system_guide.md +264 -0
- package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/bootstrap.py +308 -0
- package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/deep_dive.py +304 -0
- package/project-skills/service-skills-set/.claude/skills/creating-service-skills/scripts/scaffolder.py +482 -0
- package/project-skills/service-skills-set/.claude/skills/scoping-service-skills/SKILL.md +231 -0
- package/project-skills/service-skills-set/.claude/skills/scoping-service-skills/scripts/scope.py +74 -0
- package/project-skills/service-skills-set/.claude/skills/updating-service-skills/SKILL.md +136 -0
- package/project-skills/service-skills-set/.claude/skills/updating-service-skills/scripts/__pycache__/drift_detector.cpython-314.pyc +0 -0
- package/project-skills/service-skills-set/.claude/skills/updating-service-skills/scripts/drift_detector.py +222 -0
- package/project-skills/service-skills-set/.claude/skills/using-service-skills/SKILL.md +108 -0
- package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/__pycache__/cataloger.cpython-314.pyc +0 -0
- package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/__pycache__/skill_activator.cpython-314.pyc +0 -0
- package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/cataloger.py +74 -0
- package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/skill_activator.py +152 -0
- package/project-skills/service-skills-set/README.md +93 -0
- package/project-skills/service-skills-set/__pycache__/install-service-skills.cpython-314.pyc +0 -0
- package/project-skills/service-skills-set/install-service-skills.py +163 -0
- package/project-skills/service-skills-set/service-skills-readme.md +236 -0
- package/project-skills/tdd-guard/.claude/settings.json +38 -0
- package/project-skills/tdd-guard/.claude/skills/using-tdd-guard/SKILL.md +74 -0
- package/project-skills/tdd-guard/CLAUDE.md +98 -0
- package/project-skills/tdd-guard/CONTRIBUTING.md +38 -0
- package/project-skills/tdd-guard/DEVELOPMENT.md +127 -0
- package/project-skills/tdd-guard/LICENSE +21 -0
- package/project-skills/tdd-guard/README.md +396 -0
- package/project-skills/tdd-guard/docs/adr/001-claude-session-subdirectory.md +52 -0
- package/project-skills/tdd-guard/docs/adr/002-secure-claude-binary-path.md +56 -0
- package/project-skills/tdd-guard/docs/adr/003-remove-configurable-data-directory.md +56 -0
- package/project-skills/tdd-guard/docs/adr/004-monorepo-architecture.md +64 -0
- package/project-skills/tdd-guard/docs/adr/005-claude-project-dir-support.md +55 -0
- package/project-skills/tdd-guard/docs/adr/006-phpunit-separate-repository.md +93 -0
- package/project-skills/tdd-guard/docs/adr/007-golangci-lint-path-support.md +83 -0
- package/project-skills/tdd-guard/docs/adr/008-storybook-reporter-design.md +182 -0
- package/project-skills/tdd-guard/docs/assets/tdd-guard-demo-screenshot.gif +0 -0
- package/project-skills/tdd-guard/docs/config-migration.md +143 -0
- package/project-skills/tdd-guard/docs/configuration.md +137 -0
- package/project-skills/tdd-guard/docs/custom-instructions.md +43 -0
- package/project-skills/tdd-guard/docs/enforcement.md +46 -0
- package/project-skills/tdd-guard/docs/ignore-patterns.md +81 -0
- package/project-skills/tdd-guard/docs/linting.md +109 -0
- package/project-skills/tdd-guard/docs/quick-commands.md +52 -0
- package/project-skills/tdd-guard/docs/session-management.md +75 -0
- package/project-skills/tdd-guard/docs/storybook-vitest-addon.md +120 -0
- package/project-skills/tdd-guard/docs/validation-model.md +63 -0
- package/project-skills/tdd-guard/eslint.config.mjs +140 -0
- package/project-skills/tdd-guard/package-lock.json +16937 -0
- package/project-skills/tdd-guard/package.json +102 -0
- package/project-skills/tdd-guard/reporters/go/README.md +67 -0
- package/project-skills/tdd-guard/reporters/go/cmd/tdd-guard-go/main.go +127 -0
- package/project-skills/tdd-guard/reporters/go/cmd/tdd-guard-go/main_test.go +280 -0
- package/project-skills/tdd-guard/reporters/go/go.mod +3 -0
- package/project-skills/tdd-guard/reporters/go/go.sum +0 -0
- package/project-skills/tdd-guard/reporters/go/internal/formatter/formatter.go +126 -0
- package/project-skills/tdd-guard/reporters/go/internal/formatter/formatter_test.go +264 -0
- package/project-skills/tdd-guard/reporters/go/internal/io/tee_reader.go +26 -0
- package/project-skills/tdd-guard/reporters/go/internal/io/tee_reader_test.go +37 -0
- package/project-skills/tdd-guard/reporters/go/internal/parser/mixed_reader.go +94 -0
- package/project-skills/tdd-guard/reporters/go/internal/parser/mixed_reader_test.go +198 -0
- package/project-skills/tdd-guard/reporters/go/internal/parser/parser.go +245 -0
- package/project-skills/tdd-guard/reporters/go/internal/parser/parser_test.go +547 -0
- package/project-skills/tdd-guard/reporters/go/internal/storage/storage.go +35 -0
- package/project-skills/tdd-guard/reporters/go/internal/storage/storage_test.go +113 -0
- package/project-skills/tdd-guard/reporters/go/internal/transformer/transformer.go +103 -0
- package/project-skills/tdd-guard/reporters/go/internal/transformer/transformer_test.go +303 -0
- package/project-skills/tdd-guard/reporters/jest/README.md +102 -0
- package/project-skills/tdd-guard/reporters/jest/package.json +38 -0
- package/project-skills/tdd-guard/reporters/phpunit/.php-cs-fixer.php +28 -0
- package/project-skills/tdd-guard/reporters/phpunit/README.md +97 -0
- package/project-skills/tdd-guard/reporters/phpunit/SYNC_README.md +29 -0
- package/project-skills/tdd-guard/reporters/phpunit/composer.json +55 -0
- package/project-skills/tdd-guard/reporters/phpunit/phpunit.xml.dist +19 -0
- package/project-skills/tdd-guard/reporters/phpunit/psalm.xml +44 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/ErroredTestSubscriber.php +28 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/FailedTestSubscriber.php +28 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/IncompleteTestSubscriber.php +28 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/PassedTestSubscriber.php +27 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/SkippedTestSubscriber.php +28 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/TestRunnerFinishedSubscriber.php +24 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/PathValidator.php +88 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/Storage.php +26 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardExtension.php +33 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardListener.php +158 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardSubscriber.php +35 -0
- package/project-skills/tdd-guard/reporters/phpunit/src/TestResultCollector.php +105 -0
- package/project-skills/tdd-guard/reporters/phpunit/tests/PathValidatorTest.php +74 -0
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardExtensionFailedTest.php +241 -0
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardExtensionTest.php +84 -0
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardStorageLocationTest.php +71 -0
- package/project-skills/tdd-guard/reporters/pytest/README.md +77 -0
- package/project-skills/tdd-guard/reporters/pytest/pyproject.toml +43 -0
- package/project-skills/tdd-guard/reporters/pytest/pytest.ini.example +7 -0
- package/project-skills/tdd-guard/reporters/pytest/tdd_guard_pytest/__init__.py +1 -0
- package/project-skills/tdd-guard/reporters/pytest/tdd_guard_pytest/pytest_reporter.py +134 -0
- package/project-skills/tdd-guard/reporters/pytest/tests/__init__.py +1 -0
- package/project-skills/tdd-guard/reporters/pytest/tests/conftest.py +3 -0
- package/project-skills/tdd-guard/reporters/pytest/tests/helpers.py +293 -0
- package/project-skills/tdd-guard/reporters/pytest/tests/test_config_option.py +38 -0
- package/project-skills/tdd-guard/reporters/pytest/tests/test_path_validation.py +59 -0
- package/project-skills/tdd-guard/reporters/pytest/tests/test_plugin_config.py +32 -0
- package/project-skills/tdd-guard/reporters/pytest/tests/test_project_root.py +296 -0
- package/project-skills/tdd-guard/reporters/pytest/tests/test_pytest_reporter.py +137 -0
- package/project-skills/tdd-guard/reporters/rspec/Gemfile +3 -0
- package/project-skills/tdd-guard/reporters/rust/Cargo.lock +458 -0
- package/project-skills/tdd-guard/reporters/rust/Cargo.toml +33 -0
- package/project-skills/tdd-guard/reporters/rust/Makefile.example +95 -0
- package/project-skills/tdd-guard/reporters/rust/README.md +88 -0
- package/project-skills/tdd-guard/reporters/rust/src/error_parser.rs +309 -0
- package/project-skills/tdd-guard/reporters/rust/src/main.rs +464 -0
- package/project-skills/tdd-guard/reporters/rust/src/parser.rs +225 -0
- package/project-skills/tdd-guard/reporters/rust/src/transformer.rs +409 -0
- package/project-skills/tdd-guard/reporters/storybook/README.md +108 -0
- package/project-skills/tdd-guard/reporters/storybook/package-lock.json +9482 -0
- package/project-skills/tdd-guard/reporters/storybook/package.json +43 -0
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.test-data.ts +22 -0
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.test.ts +190 -0
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.ts +88 -0
- package/project-skills/tdd-guard/reporters/storybook/src/index.ts +12 -0
- package/project-skills/tdd-guard/reporters/storybook/src/types.ts +37 -0
- package/project-skills/tdd-guard/reporters/storybook/tsconfig.json +11 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/go/failing/go.mod +3 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/go/failing/single_failing_test.go +13 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/go/import/go.mod +3 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/go/import/single_import_error_test.go +17 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/go/passing/go.mod +3 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/go/passing/single_passing_test.go +13 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-failing.test.js +5 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-import-error.test.js +8 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-passing.test.js +5 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SingleFailingTest.php +11 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SingleImportErrorTest.php +14 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SinglePassingTest.php +11 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_failing.py +3 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_import_error.py +6 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_passing.py +3 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/Cargo.lock +7 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/Cargo.toml +4 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/src/lib.rs +14 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/Cargo.lock +7 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/Cargo.toml +4 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/src/lib.rs +13 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/Cargo.lock +7 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/Cargo.toml +4 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/src/lib.rs +14 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/Calculator.js +4 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-failing.stories.js +15 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-import-error.stories.js +14 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-passing.stories.js +15 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-failing.test.js +7 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-import-error.test.js +9 -0
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-passing.test.js +7 -0
- package/project-skills/tdd-guard/reporters/test/factories/go.ts +59 -0
- package/project-skills/tdd-guard/reporters/test/factories/helpers.ts +48 -0
- package/project-skills/tdd-guard/reporters/test/factories/index.ts +7 -0
- package/project-skills/tdd-guard/reporters/test/factories/jest.ts +51 -0
- package/project-skills/tdd-guard/reporters/test/factories/phpunit.ts +63 -0
- package/project-skills/tdd-guard/reporters/test/factories/pytest.ts +41 -0
- package/project-skills/tdd-guard/reporters/test/factories/rust.ts +158 -0
- package/project-skills/tdd-guard/reporters/test/factories/storybook.ts +198 -0
- package/project-skills/tdd-guard/reporters/test/factories/vitest.ts +51 -0
- package/project-skills/tdd-guard/reporters/test/reporters.integration.test.ts +735 -0
- package/project-skills/tdd-guard/reporters/test/types.ts +28 -0
- package/project-skills/tdd-guard/reporters/vitest/README.md +64 -0
- package/project-skills/tdd-guard/reporters/vitest/package.json +35 -0
- package/project-skills/tdd-guard/src/cli/buildContext.test.ts +200 -0
- package/project-skills/tdd-guard/src/cli/buildContext.ts +48 -0
- package/project-skills/tdd-guard/src/cli/tdd-guard.test.ts +159 -0
- package/project-skills/tdd-guard/src/cli/tdd-guard.ts +48 -0
- package/project-skills/tdd-guard/src/config/Config.test.ts +538 -0
- package/project-skills/tdd-guard/src/config/Config.ts +172 -0
- package/project-skills/tdd-guard/src/contracts/schemas/guardSchemas.test.ts +58 -0
- package/project-skills/tdd-guard/src/contracts/schemas/guardSchemas.ts +8 -0
- package/project-skills/tdd-guard/src/contracts/schemas/lintSchemas.test.ts +347 -0
- package/project-skills/tdd-guard/src/contracts/schemas/lintSchemas.ts +61 -0
- package/project-skills/tdd-guard/src/contracts/schemas/pytestSchemas.test.ts +24 -0
- package/project-skills/tdd-guard/src/contracts/schemas/pytestSchemas.ts +7 -0
- package/project-skills/tdd-guard/src/contracts/schemas/reporterSchemas.test.ts +377 -0
- package/project-skills/tdd-guard/src/contracts/schemas/reporterSchemas.ts +75 -0
- package/project-skills/tdd-guard/src/contracts/schemas/toolSchemas.test.ts +563 -0
- package/project-skills/tdd-guard/src/contracts/schemas/toolSchemas.ts +140 -0
- package/project-skills/tdd-guard/src/contracts/types/ClientType.ts +1 -0
- package/project-skills/tdd-guard/src/contracts/types/ConfigOptions.ts +12 -0
- package/project-skills/tdd-guard/src/contracts/types/Context.ts +16 -0
- package/project-skills/tdd-guard/src/contracts/types/ModelClient.ts +3 -0
- package/project-skills/tdd-guard/src/contracts/types/ValidationResult.ts +6 -0
- package/project-skills/tdd-guard/src/guard/GuardManager.test.ts +336 -0
- package/project-skills/tdd-guard/src/guard/GuardManager.ts +83 -0
- package/project-skills/tdd-guard/src/hooks/HookEvents.test.ts +107 -0
- package/project-skills/tdd-guard/src/hooks/HookEvents.ts +39 -0
- package/project-skills/tdd-guard/src/hooks/fileTypeDetection.ts +16 -0
- package/project-skills/tdd-guard/src/hooks/postToolLint.test.ts +327 -0
- package/project-skills/tdd-guard/src/hooks/postToolLint.ts +165 -0
- package/project-skills/tdd-guard/src/hooks/processHookData.test.ts +465 -0
- package/project-skills/tdd-guard/src/hooks/processHookData.ts +203 -0
- package/project-skills/tdd-guard/src/hooks/sessionHandler.test.ts +136 -0
- package/project-skills/tdd-guard/src/hooks/sessionHandler.ts +31 -0
- package/project-skills/tdd-guard/src/hooks/userPromptHandler.test.ts +131 -0
- package/project-skills/tdd-guard/src/hooks/userPromptHandler.ts +55 -0
- package/project-skills/tdd-guard/src/index.ts +19 -0
- package/project-skills/tdd-guard/src/linters/Linter.ts +5 -0
- package/project-skills/tdd-guard/src/linters/eslint/ESLint.test.ts +183 -0
- package/project-skills/tdd-guard/src/linters/eslint/ESLint.ts +82 -0
- package/project-skills/tdd-guard/src/linters/golangci/GolangciLint.test.ts +170 -0
- package/project-skills/tdd-guard/src/linters/golangci/GolangciLint.ts +148 -0
- package/project-skills/tdd-guard/src/processors/index.ts +1 -0
- package/project-skills/tdd-guard/src/processors/lintProcessor.ts +77 -0
- package/project-skills/tdd-guard/src/processors/testResults/TestResultsProcessor.test.ts +303 -0
- package/project-skills/tdd-guard/src/processors/testResults/TestResultsProcessor.ts +255 -0
- package/project-skills/tdd-guard/src/providers/LinterProvider.test.ts +43 -0
- package/project-skills/tdd-guard/src/providers/LinterProvider.ts +20 -0
- package/project-skills/tdd-guard/src/providers/ModelClientProvider.test.ts +68 -0
- package/project-skills/tdd-guard/src/providers/ModelClientProvider.ts +22 -0
- package/project-skills/tdd-guard/src/storage/FileStorage.test.ts +76 -0
- package/project-skills/tdd-guard/src/storage/FileStorage.ts +108 -0
- package/project-skills/tdd-guard/src/storage/MemoryStorage.ts +57 -0
- package/project-skills/tdd-guard/src/storage/Storage.test.ts +227 -0
- package/project-skills/tdd-guard/src/storage/Storage.ts +17 -0
- package/project-skills/tdd-guard/src/validation/context/context.test.ts +364 -0
- package/project-skills/tdd-guard/src/validation/context/context.ts +155 -0
- package/project-skills/tdd-guard/src/validation/models/AnthropicApi.test.ts +171 -0
- package/project-skills/tdd-guard/src/validation/models/AnthropicApi.ts +49 -0
- package/project-skills/tdd-guard/src/validation/models/ClaudeAgentSdk.test.ts +167 -0
- package/project-skills/tdd-guard/src/validation/models/ClaudeAgentSdk.ts +54 -0
- package/project-skills/tdd-guard/src/validation/models/ClaudeCli.test.ts +239 -0
- package/project-skills/tdd-guard/src/validation/models/ClaudeCli.ts +57 -0
- package/project-skills/tdd-guard/src/validation/prompts/file-types.ts +52 -0
- package/project-skills/tdd-guard/src/validation/prompts/operations/edit.ts +58 -0
- package/project-skills/tdd-guard/src/validation/prompts/operations/multi-edit.ts +54 -0
- package/project-skills/tdd-guard/src/validation/prompts/operations/write.ts +54 -0
- package/project-skills/tdd-guard/src/validation/prompts/response.ts +40 -0
- package/project-skills/tdd-guard/src/validation/prompts/rules.ts +51 -0
- package/project-skills/tdd-guard/src/validation/prompts/system-prompt.ts +10 -0
- package/project-skills/tdd-guard/src/validation/prompts/tools/lint-results.ts +15 -0
- package/project-skills/tdd-guard/src/validation/prompts/tools/test-output.ts +14 -0
- package/project-skills/tdd-guard/src/validation/prompts/tools/todos.ts +9 -0
- package/project-skills/tdd-guard/src/validation/validator.test.ts +268 -0
- package/project-skills/tdd-guard/src/validation/validator.ts +159 -0
- package/project-skills/tdd-guard/test/artifacts/go/.golangci.yml +6 -0
- package/project-skills/tdd-guard/test/artifacts/go/with-issues/file-with-issues.go +12 -0
- package/project-skills/tdd-guard/test/artifacts/go/with-issues/go.mod +3 -0
- package/project-skills/tdd-guard/test/artifacts/go/without-issues/file-without-issues.go +7 -0
- package/project-skills/tdd-guard/test/artifacts/go/without-issues/go.mod +3 -0
- package/project-skills/tdd-guard/test/artifacts/javascript/eslint.config.js +20 -0
- package/project-skills/tdd-guard/test/artifacts/javascript/file-with-issues.js +12 -0
- package/project-skills/tdd-guard/test/artifacts/javascript/file-without-issues.js +10 -0
- package/project-skills/tdd-guard/test/hooks/fileTypeDetection.test.ts +26 -0
- package/project-skills/tdd-guard/test/hooks/processHookData.fileType.test.ts +46 -0
- package/project-skills/tdd-guard/test/hooks/processHookData.python.test.ts +68 -0
- package/project-skills/tdd-guard/test/integration/test-context.test.ts +66 -0
- package/project-skills/tdd-guard/test/integration/validator.core.test.ts +96 -0
- package/project-skills/tdd-guard/test/integration/validator.scenarios.test.ts +497 -0
- package/project-skills/tdd-guard/test/utils/assertions.ts +29 -0
- package/project-skills/tdd-guard/test/utils/factories/contextFactory.ts +30 -0
- package/project-skills/tdd-guard/test/utils/factories/editFactory.ts +82 -0
- package/project-skills/tdd-guard/test/utils/factories/helpers.test.ts +46 -0
- package/project-skills/tdd-guard/test/utils/factories/helpers.ts +46 -0
- package/project-skills/tdd-guard/test/utils/factories/lintFactory.ts +352 -0
- package/project-skills/tdd-guard/test/utils/factories/modelClientProviderFactory.ts +21 -0
- package/project-skills/tdd-guard/test/utils/factories/multiEditFactory.ts +79 -0
- package/project-skills/tdd-guard/test/utils/factories/operations.ts +57 -0
- package/project-skills/tdd-guard/test/utils/factories/reporterFactory.ts +55 -0
- package/project-skills/tdd-guard/test/utils/factories/scenarios/index.ts +22 -0
- package/project-skills/tdd-guard/test/utils/factories/scenarios/languages/python.ts +745 -0
- package/project-skills/tdd-guard/test/utils/factories/scenarios/languages/typescript.ts +767 -0
- package/project-skills/tdd-guard/test/utils/factories/scenarios/types.ts +77 -0
- package/project-skills/tdd-guard/test/utils/factories/scenarios/utils.ts +15 -0
- package/project-skills/tdd-guard/test/utils/factories/sessionStartFactory.ts +36 -0
- package/project-skills/tdd-guard/test/utils/factories/testDefaults.ts +90 -0
- package/project-skills/tdd-guard/test/utils/factories/testResultsFactory.ts +234 -0
- package/project-skills/tdd-guard/test/utils/factories/todoFactory.ts +99 -0
- package/project-skills/tdd-guard/test/utils/factories/userPromptSubmitFactory.ts +39 -0
- package/project-skills/tdd-guard/test/utils/factories/writeFactory.ts +70 -0
- package/project-skills/tdd-guard/test/utils/index.ts +131 -0
- package/project-skills/tdd-guard/tsconfig.build.json +16 -0
- package/project-skills/tdd-guard/tsconfig.eslint.json +17 -0
- package/project-skills/tdd-guard/tsconfig.json +32 -0
- package/project-skills/tdd-guard/tsconfig.node.json +10 -0
- package/project-skills/tdd-guard/vitest.config.ts +85 -0
- package/project-skills/ts-quality-gate/.claude/hooks/hook-config.json +66 -0
- package/project-skills/ts-quality-gate/.claude/hooks/quality-check.cjs +1251 -0
- package/project-skills/ts-quality-gate/.claude/settings.json +16 -0
- package/project-skills/ts-quality-gate/.claude/skills/using-ts-quality-gate/SKILL.md +81 -0
- package/project-skills/ts-quality-gate/README.md +115 -0
- package/skills/README.txt +31 -0
- package/skills/clean-code/SKILL.md +201 -0
- package/skills/delegating/SKILL.md +196 -0
- package/skills/delegating/config.yaml +210 -0
- package/skills/delegating/references/orchestration-protocols.md +41 -0
- package/skills/docker-expert/SKILL.md +409 -0
- package/skills/documenting/CHANGELOG.md +23 -0
- package/skills/documenting/README.md +148 -0
- package/skills/documenting/SKILL.md +113 -0
- package/skills/documenting/examples/example_pattern.md +70 -0
- package/skills/documenting/examples/example_reference.md +70 -0
- package/skills/documenting/examples/example_ssot_analytics.md +64 -0
- package/skills/documenting/examples/example_workflow.md +141 -0
- package/skills/documenting/references/changelog-format.md +97 -0
- package/skills/documenting/references/metadata-schema.md +136 -0
- package/skills/documenting/references/taxonomy.md +81 -0
- package/skills/documenting/references/versioning-rules.md +78 -0
- package/skills/documenting/scripts/__pycache__/drift_detector.cpython-314.pyc +0 -0
- package/skills/documenting/scripts/__pycache__/orchestrator.cpython-314.pyc +0 -0
- package/skills/documenting/scripts/__pycache__/validate_metadata.cpython-314.pyc +0 -0
- package/skills/documenting/scripts/bump_version.sh +60 -0
- package/skills/documenting/scripts/changelog/__init__.py +0 -0
- package/skills/documenting/scripts/changelog/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/documenting/scripts/changelog/__pycache__/add_entry.cpython-314.pyc +0 -0
- package/skills/documenting/scripts/changelog/__pycache__/bump_release.cpython-314.pyc +0 -0
- package/skills/documenting/scripts/changelog/__pycache__/validate_changelog.cpython-314.pyc +0 -0
- package/skills/documenting/scripts/changelog/add_entry.py +216 -0
- package/skills/documenting/scripts/changelog/bump_release.py +117 -0
- package/skills/documenting/scripts/changelog/init_changelog.py +54 -0
- package/skills/documenting/scripts/changelog/validate_changelog.py +128 -0
- package/skills/documenting/scripts/drift_detector.py +266 -0
- package/skills/documenting/scripts/generate_template.py +311 -0
- package/skills/documenting/scripts/list_by_category.sh +84 -0
- package/skills/documenting/scripts/orchestrator.py +255 -0
- package/skills/documenting/scripts/validate_metadata.py +242 -0
- package/skills/documenting/templates/CHANGELOG.md.template +13 -0
- package/skills/documenting/tests/__pycache__/test_changelog.cpython-314-pytest-9.0.2.pyc +0 -0
- package/skills/documenting/tests/__pycache__/test_drift_detector.cpython-314-pytest-9.0.2.pyc +0 -0
- package/skills/documenting/tests/__pycache__/test_orchestrator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/skills/documenting/tests/__pycache__/test_validate_metadata.cpython-314-pytest-9.0.2.pyc +0 -0
- package/skills/documenting/tests/integration_test.sh +70 -0
- package/skills/documenting/tests/test_changelog.py +201 -0
- package/skills/documenting/tests/test_drift_detector.py +80 -0
- package/skills/documenting/tests/test_orchestrator.py +52 -0
- package/skills/documenting/tests/test_validate_metadata.py +64 -0
- package/skills/find-skills/SKILL.md +133 -0
- package/skills/gitnexus-debugging/SKILL.md +85 -0
- package/skills/gitnexus-exploring/SKILL.md +75 -0
- package/skills/gitnexus-impact-analysis/SKILL.md +94 -0
- package/skills/gitnexus-refactoring/SKILL.md +113 -0
- package/skills/hook-development/SKILL.md +797 -0
- package/skills/hook-development/examples/load-context.sh +55 -0
- package/skills/hook-development/examples/quality-check.js +1168 -0
- package/skills/hook-development/examples/validate-bash.sh +43 -0
- package/skills/hook-development/examples/validate-write.sh +38 -0
- package/skills/hook-development/references/advanced.md +527 -0
- package/skills/hook-development/references/migration.md +369 -0
- package/skills/hook-development/references/patterns.md +412 -0
- package/skills/hook-development/scripts/README.md +164 -0
- package/skills/hook-development/scripts/hook-linter.sh +153 -0
- package/skills/hook-development/scripts/test-hook.sh +252 -0
- package/skills/hook-development/scripts/validate-hook-schema.sh +159 -0
- package/skills/obsidian-cli/SKILL.md +106 -0
- package/skills/orchestrating-agents/SKILL.md +135 -0
- package/skills/orchestrating-agents/config.yaml +45 -0
- package/skills/orchestrating-agents/references/agent-context-integration.md +37 -0
- package/skills/orchestrating-agents/references/examples.md +45 -0
- package/skills/orchestrating-agents/references/handover-protocol.md +31 -0
- package/skills/orchestrating-agents/references/workflows.md +42 -0
- package/skills/orchestrating-agents/scripts/detect_neighbors.py +23 -0
- package/skills/prompt-improving/README.md +162 -0
- package/skills/prompt-improving/SKILL.md +74 -0
- package/skills/prompt-improving/references/analysis_commands.md +24 -0
- package/skills/prompt-improving/references/chain_of_thought.md +24 -0
- package/skills/prompt-improving/references/mcp_definitions.md +20 -0
- package/skills/prompt-improving/references/multishot.md +23 -0
- package/skills/prompt-improving/references/xml_core.md +60 -0
- package/skills/python-testing/SKILL.md +815 -0
- package/skills/senior-backend/SKILL.md +209 -0
- package/skills/senior-backend/references/api_design_patterns.md +103 -0
- package/skills/senior-backend/references/backend_security_practices.md +103 -0
- package/skills/senior-backend/references/database_optimization_guide.md +103 -0
- package/skills/senior-backend/scripts/api_load_tester.py +114 -0
- package/skills/senior-backend/scripts/api_scaffolder.py +114 -0
- package/skills/senior-backend/scripts/database_migration_tool.py +114 -0
- package/skills/senior-data-scientist/SKILL.md +226 -0
- package/skills/senior-data-scientist/references/experiment_design_frameworks.md +80 -0
- package/skills/senior-data-scientist/references/feature_engineering_patterns.md +80 -0
- package/skills/senior-data-scientist/references/statistical_methods_advanced.md +80 -0
- package/skills/senior-data-scientist/scripts/experiment_designer.py +100 -0
- package/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py +100 -0
- package/skills/senior-data-scientist/scripts/model_evaluation_suite.py +100 -0
- package/skills/senior-devops/SKILL.md +209 -0
- package/skills/senior-devops/references/cicd_pipeline_guide.md +103 -0
- package/skills/senior-devops/references/deployment_strategies.md +103 -0
- package/skills/senior-devops/references/infrastructure_as_code.md +103 -0
- package/skills/senior-devops/scripts/deployment_manager.py +114 -0
- package/skills/senior-devops/scripts/pipeline_generator.py +114 -0
- package/skills/senior-devops/scripts/terraform_scaffolder.py +114 -0
- package/skills/senior-security/SKILL.md +209 -0
- package/skills/senior-security/references/cryptography_implementation.md +103 -0
- package/skills/senior-security/references/penetration_testing_guide.md +103 -0
- package/skills/senior-security/references/security_architecture_patterns.md +103 -0
- package/skills/senior-security/scripts/pentest_automator.py +114 -0
- package/skills/senior-security/scripts/security_auditor.py +114 -0
- package/skills/senior-security/scripts/threat_modeler.py +114 -0
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/SKILL.md +479 -0
- package/skills/skill-creator/agents/analyzer.md +274 -0
- package/skills/skill-creator/agents/comparator.md +202 -0
- package/skills/skill-creator/agents/grader.md +223 -0
- package/skills/skill-creator/assets/eval_review.html +146 -0
- package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/skill-creator/references/schemas.md +430 -0
- package/skills/skill-creator/scripts/__init__.py +0 -0
- package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/skill-creator/scripts/generate_report.py +326 -0
- package/skills/skill-creator/scripts/improve_description.py +248 -0
- package/skills/skill-creator/scripts/package_skill.py +136 -0
- package/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/skills/skill-creator/scripts/run_eval.py +310 -0
- package/skills/skill-creator/scripts/run_loop.py +332 -0
- package/skills/skill-creator/scripts/utils.py +47 -0
- package/skills/using-TDD/SKILL.md +410 -0
- package/skills/using-serena-lsp/README.md +8 -0
- package/skills/using-serena-lsp/REFERENCE.md +194 -0
- package/skills/using-serena-lsp/SKILL.md +82 -0
package/project-skills/service-skills-set/.claude/skills/scoping-service-skills/scripts/scope.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
scope.py — Read service-registry.json and output a formatted service catalog.
|
|
4
|
+
|
|
5
|
+
Used by the /scope skill to provide registry data for agent reasoning before
|
|
6
|
+
any files are touched. The agent uses this output to map a task description
|
|
7
|
+
to the relevant registered service(s).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def find_registry() -> Path | None:
|
|
17
|
+
# 1. CLAUDE_PROJECT_DIR env var (set by Claude Code hooks)
|
|
18
|
+
project_dir = os.environ.get("CLAUDE_PROJECT_DIR")
|
|
19
|
+
if project_dir:
|
|
20
|
+
p = Path(project_dir) / ".claude" / "skills" / "service-registry.json"
|
|
21
|
+
if p.exists():
|
|
22
|
+
return p
|
|
23
|
+
|
|
24
|
+
# 2. Walk up from CWD until .git boundary
|
|
25
|
+
cwd = Path.cwd()
|
|
26
|
+
for parent in [cwd, *cwd.parents]:
|
|
27
|
+
p = parent / ".claude" / "skills" / "service-registry.json"
|
|
28
|
+
if p.exists():
|
|
29
|
+
return p
|
|
30
|
+
if (parent / ".git").exists():
|
|
31
|
+
break
|
|
32
|
+
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def main() -> None:
|
|
37
|
+
registry_path = find_registry()
|
|
38
|
+
|
|
39
|
+
if not registry_path:
|
|
40
|
+
print("ERROR: service-registry.json not found.")
|
|
41
|
+
print("Run /creating-service-skills to set up service skills first.")
|
|
42
|
+
sys.exit(1)
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
with open(registry_path, encoding="utf-8") as f:
|
|
46
|
+
registry = json.load(f)
|
|
47
|
+
except json.JSONDecodeError as e:
|
|
48
|
+
print(f"ERROR: service-registry.json is malformed: {e}")
|
|
49
|
+
sys.exit(1)
|
|
50
|
+
|
|
51
|
+
services = registry.get("services", {})
|
|
52
|
+
if not services:
|
|
53
|
+
print("Registry is empty — no services registered.")
|
|
54
|
+
sys.exit(0)
|
|
55
|
+
|
|
56
|
+
print(f"Registry : {registry_path}")
|
|
57
|
+
print(f"Version : {registry.get('version', 'unknown')}")
|
|
58
|
+
print(f"Services : {len(services)} registered")
|
|
59
|
+
print("─" * 60)
|
|
60
|
+
|
|
61
|
+
for service_id, info in services.items():
|
|
62
|
+
territories = ", ".join(info.get("territory", [])) or "—"
|
|
63
|
+
print(f"\n[{service_id}]")
|
|
64
|
+
print(f" Container : {info.get('container', 'unknown')}")
|
|
65
|
+
print(f" Territory : {territories}")
|
|
66
|
+
print(f" Skill : {info.get('skill_path', 'unknown')}")
|
|
67
|
+
print(f" Description: {info.get('description', '—')}")
|
|
68
|
+
|
|
69
|
+
print("\n" + "─" * 60)
|
|
70
|
+
print("Map the task description to the service(s) above, then load their skills.")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
main()
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: updating-service-skills
|
|
3
|
+
description: >-
|
|
4
|
+
Detect implementation drift and sync expert persona documentation.
|
|
5
|
+
Activates automatically via PostToolUse hook when files in a registered
|
|
6
|
+
service territory are modified. Use when a skill's documentation has
|
|
7
|
+
fallen behind the actual implementation.
|
|
8
|
+
hooks:
|
|
9
|
+
PostToolUse:
|
|
10
|
+
- matcher: "Write|Edit"
|
|
11
|
+
hooks:
|
|
12
|
+
- type: command
|
|
13
|
+
command: "python3 \"$CLAUDE_PROJECT_DIR/.claude/skills/updating-service-skills/scripts/drift_detector.py\" check-hook"
|
|
14
|
+
timeout: 10
|
|
15
|
+
allowed-tools: Read, Write, Grep, Glob
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Updating Service Skills
|
|
19
|
+
|
|
20
|
+
## Role: The Librarian
|
|
21
|
+
|
|
22
|
+
You are the **Service Skills Librarian**. Your job is to keep expert persona
|
|
23
|
+
documentation in sync with the actual implementation as the codebase evolves.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Automatic Drift Detection
|
|
28
|
+
|
|
29
|
+
After any `Write` or `Edit` operation, the `PostToolUse` hook runs
|
|
30
|
+
`drift_detector.py check-hook`. It reads the modified file path from stdin JSON
|
|
31
|
+
and checks whether it falls within a registered service territory.
|
|
32
|
+
|
|
33
|
+
If drift is detected, you will see this in your context:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
[Skill Sync]: Implementation drift detected in 'db-expert'.
|
|
37
|
+
File 'src/db/users.ts' was modified.
|
|
38
|
+
Use '/updating-service-skills' to sync the Database Expert documentation.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Manual Sync Process
|
|
44
|
+
|
|
45
|
+
### Step 1 — Scan for all drift
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python3 "$CLAUDE_PROJECT_DIR/.claude/skills/updating-service-skills/scripts/drift_detector.py" scan
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Step 2 — Read the current skill
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Read: .claude/skills/<service-id>/SKILL.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Step 3 — Analyze changes using Serena tools
|
|
58
|
+
|
|
59
|
+
Use Serena LSP tools (not raw file reads) to understand what changed:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
get_symbols_overview(<modified-file>, depth=1)
|
|
63
|
+
find_symbol(<changed-function>, include_body=True)
|
|
64
|
+
search_for_pattern("<new-pattern>")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Step 4 — Update the skill documentation
|
|
68
|
+
|
|
69
|
+
- Add new patterns or conventions discovered
|
|
70
|
+
- Update Failure Modes table if new exception handlers added
|
|
71
|
+
- Update log patterns in `scripts/log_hunter.py` if new log strings found
|
|
72
|
+
- Update territory patterns in `service-registry.json` if scope expanded
|
|
73
|
+
- Preserve `<!-- SEMANTIC_START --> ... <!-- SEMANTIC_END -->` blocks
|
|
74
|
+
|
|
75
|
+
### Step 5 — Mark as synced
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
python3 "$CLAUDE_PROJECT_DIR/.claude/skills/updating-service-skills/scripts/drift_detector.py" \
|
|
79
|
+
sync <service-id>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Drift Scenarios
|
|
85
|
+
|
|
86
|
+
### New error pattern added to codebase
|
|
87
|
+
|
|
88
|
+
1. `search_for_pattern("raise.*New.*Error|logger.error.*new")` to find it
|
|
89
|
+
2. Add to `scripts/log_hunter.py` PATTERNS list with correct severity
|
|
90
|
+
3. Update Troubleshooting table in SKILL.md
|
|
91
|
+
|
|
92
|
+
### Territory expanded (new directory added)
|
|
93
|
+
|
|
94
|
+
1. Check if current glob patterns in `service-registry.json` cover new files
|
|
95
|
+
2. If not, update `territory` array in `service-registry.json`
|
|
96
|
+
3. Sync timestamp
|
|
97
|
+
|
|
98
|
+
### Major refactor changes conventions
|
|
99
|
+
|
|
100
|
+
1. `get_symbols_overview` on all changed files
|
|
101
|
+
2. Rewrite relevant Guidelines section in SKILL.md
|
|
102
|
+
3. Update health_probe.py if table structure or ports changed
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Tool Restrictions
|
|
107
|
+
|
|
108
|
+
Write to:
|
|
109
|
+
- ✅ `.claude/skills/*/SKILL.md` — skill documentation updates
|
|
110
|
+
- ✅ `.claude/skills/service-registry.json` — territory and sync timestamp updates
|
|
111
|
+
|
|
112
|
+
Do not:
|
|
113
|
+
- ❌ Modify source code (read-only access to service territories)
|
|
114
|
+
- ❌ Delete skills or registry entries
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Sync Output Format
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
✅ Skill Synced: `<service-id>`
|
|
122
|
+
|
|
123
|
+
Updated:
|
|
124
|
+
- log_hunter.py: added 2 new patterns from exception handlers
|
|
125
|
+
- SKILL.md: Failure Modes table updated with OAuth expiry scenario
|
|
126
|
+
- Territory: unchanged
|
|
127
|
+
|
|
128
|
+
Next sync: triggers on next modification to <territory-patterns>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Related Skills
|
|
134
|
+
|
|
135
|
+
- `/using-service-skills` — Discover and activate expert personas
|
|
136
|
+
- `/creating-service-skills` — Scaffold new expert personas
|
|
Binary file
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Drift detector — PostToolUse hook for updating-service-skills.
|
|
4
|
+
|
|
5
|
+
Checks whether a modified file belongs to a registered service territory.
|
|
6
|
+
If so, notifies Claude to sync the skill documentation.
|
|
7
|
+
|
|
8
|
+
Configured via updating-service-skills/SKILL.md frontmatter hooks:
|
|
9
|
+
PostToolUse → matcher: "Write|Edit" → command: drift_detector.py check-hook
|
|
10
|
+
|
|
11
|
+
Subcommands:
|
|
12
|
+
check-hook Read file_path from stdin JSON (PostToolUse hook mode)
|
|
13
|
+
check <file> Check a specific file path from CLI
|
|
14
|
+
sync <service-id> Mark service as synced (update registry timestamp)
|
|
15
|
+
scan Scan all territories for drifted services
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import sys
|
|
20
|
+
from datetime import datetime, timezone
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
# Bootstrap lives in creating-service-skills — shared utility
|
|
24
|
+
BOOTSTRAP_DIR = Path(__file__).parent.parent.parent / "creating-service-skills" / "scripts"
|
|
25
|
+
sys.path.insert(0, str(BOOTSTRAP_DIR))
|
|
26
|
+
|
|
27
|
+
from bootstrap import ( # noqa: E402
|
|
28
|
+
RootResolutionError,
|
|
29
|
+
find_service_for_path,
|
|
30
|
+
get_project_root,
|
|
31
|
+
get_service,
|
|
32
|
+
load_registry,
|
|
33
|
+
save_registry,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def check_drift(file_path: str, project_root: str | None = None) -> dict:
|
|
38
|
+
"""Check if a file change causes drift in any registered service territory."""
|
|
39
|
+
if project_root is None:
|
|
40
|
+
try:
|
|
41
|
+
project_root = get_project_root()
|
|
42
|
+
except RootResolutionError:
|
|
43
|
+
return {"drift": False, "reason": "Cannot resolve project root"}
|
|
44
|
+
|
|
45
|
+
# Normalize to relative path
|
|
46
|
+
fp = Path(file_path)
|
|
47
|
+
if fp.is_absolute():
|
|
48
|
+
try:
|
|
49
|
+
fp = fp.relative_to(project_root)
|
|
50
|
+
file_path = str(fp)
|
|
51
|
+
except ValueError:
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
service_id = find_service_for_path(file_path, project_root)
|
|
55
|
+
if not service_id:
|
|
56
|
+
return {"drift": False, "reason": "No service owns this file"}
|
|
57
|
+
|
|
58
|
+
service = get_service(service_id, project_root)
|
|
59
|
+
if not service:
|
|
60
|
+
return {"drift": False, "reason": "Service not found in registry"}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
"drift": True,
|
|
64
|
+
"service_id": service_id,
|
|
65
|
+
"service_name": service.get("name", service_id),
|
|
66
|
+
"skill_path": service.get("skill_path"),
|
|
67
|
+
"last_sync": service.get("last_sync", ""),
|
|
68
|
+
"file_path": file_path,
|
|
69
|
+
"message": (
|
|
70
|
+
f"[Skill Sync]: Implementation drift detected in '{service_id}'. "
|
|
71
|
+
f"File '{file_path}' was modified. "
|
|
72
|
+
f"Use '/updating-service-skills' to sync the {service.get('name', service_id)} documentation."
|
|
73
|
+
),
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def check_drift_from_hook_stdin() -> None:
|
|
78
|
+
"""
|
|
79
|
+
PostToolUse hook mode: reads file_path from stdin JSON.
|
|
80
|
+
|
|
81
|
+
The PostToolUse hook delivers stdin JSON with shape:
|
|
82
|
+
{"tool_name": "Write", "tool_input": {"file_path": "/abs/path"}, ...}
|
|
83
|
+
|
|
84
|
+
Outputs drift message to stdout (shown to Claude via PostToolUse additionalContext).
|
|
85
|
+
Exits 0 always — drift detection is advisory, never blocking.
|
|
86
|
+
"""
|
|
87
|
+
try:
|
|
88
|
+
data = json.load(sys.stdin)
|
|
89
|
+
except (json.JSONDecodeError, EOFError):
|
|
90
|
+
sys.exit(0)
|
|
91
|
+
|
|
92
|
+
tool_input = data.get("tool_input", {})
|
|
93
|
+
file_path = tool_input.get("file_path", "")
|
|
94
|
+
|
|
95
|
+
if not file_path:
|
|
96
|
+
sys.exit(0)
|
|
97
|
+
|
|
98
|
+
result = check_drift(file_path)
|
|
99
|
+
|
|
100
|
+
if result.get("drift"):
|
|
101
|
+
# Output additionalContext for Claude via PostToolUse JSON format
|
|
102
|
+
output = {
|
|
103
|
+
"hookSpecificOutput": {
|
|
104
|
+
"hookEventName": "PostToolUse",
|
|
105
|
+
"additionalContext": result["message"],
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
print(json.dumps(output))
|
|
109
|
+
|
|
110
|
+
sys.exit(0)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def update_sync_time(service_id: str, project_root: str | None = None) -> bool:
|
|
114
|
+
"""Update last_sync timestamp for a service in the registry."""
|
|
115
|
+
try:
|
|
116
|
+
registry = load_registry(project_root)
|
|
117
|
+
except Exception:
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
if "services" not in registry or service_id not in registry["services"]:
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
registry["services"][service_id]["last_sync"] = (
|
|
124
|
+
datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
save_registry(registry, project_root)
|
|
129
|
+
return True
|
|
130
|
+
except Exception:
|
|
131
|
+
return False
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def scan_drift(project_root: str | None = None) -> list[dict]:
|
|
135
|
+
"""Scan all territories and identify services with files modified since last sync."""
|
|
136
|
+
if project_root is None:
|
|
137
|
+
try:
|
|
138
|
+
project_root = get_project_root()
|
|
139
|
+
except RootResolutionError:
|
|
140
|
+
return []
|
|
141
|
+
|
|
142
|
+
root = Path(project_root)
|
|
143
|
+
registry = load_registry(project_root)
|
|
144
|
+
drifted: list[dict] = []
|
|
145
|
+
|
|
146
|
+
for service_id, service in registry.get("services", {}).items():
|
|
147
|
+
last_sync_str = service.get("last_sync", "")
|
|
148
|
+
if not last_sync_str:
|
|
149
|
+
continue
|
|
150
|
+
try:
|
|
151
|
+
sync_time = datetime.fromisoformat(last_sync_str.replace("Z", "+00:00"))
|
|
152
|
+
except ValueError:
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
for pattern in service.get("territory", []):
|
|
156
|
+
for fp in root.glob(pattern):
|
|
157
|
+
if fp.is_file():
|
|
158
|
+
try:
|
|
159
|
+
mtime = datetime.fromtimestamp(fp.stat().st_mtime, tz=timezone.utc)
|
|
160
|
+
if mtime > sync_time:
|
|
161
|
+
drifted.append(
|
|
162
|
+
{
|
|
163
|
+
"service_id": service_id,
|
|
164
|
+
"service_name": service.get("name", service_id),
|
|
165
|
+
"file_path": str(fp.relative_to(root)),
|
|
166
|
+
"last_sync": last_sync_str,
|
|
167
|
+
}
|
|
168
|
+
)
|
|
169
|
+
except (OSError, ValueError):
|
|
170
|
+
continue
|
|
171
|
+
|
|
172
|
+
return drifted
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def main() -> None:
|
|
176
|
+
if len(sys.argv) < 2:
|
|
177
|
+
print("Usage: python drift_detector.py <command> [args...]")
|
|
178
|
+
print(" check-hook — Read file from stdin JSON (PostToolUse hook mode)")
|
|
179
|
+
print(" check <file> — Check a specific file path")
|
|
180
|
+
print(" sync <service-id> — Mark service as synced")
|
|
181
|
+
print(" scan — Scan all territories for drift")
|
|
182
|
+
sys.exit(1)
|
|
183
|
+
|
|
184
|
+
cmd = sys.argv[1]
|
|
185
|
+
|
|
186
|
+
if cmd == "check-hook":
|
|
187
|
+
check_drift_from_hook_stdin()
|
|
188
|
+
|
|
189
|
+
elif cmd == "check" and len(sys.argv) > 2:
|
|
190
|
+
result = check_drift(sys.argv[2])
|
|
191
|
+
if result.get("drift"):
|
|
192
|
+
print(result["message"])
|
|
193
|
+
else:
|
|
194
|
+
print(f"No drift: {result.get('reason', 'OK')}")
|
|
195
|
+
|
|
196
|
+
elif cmd == "sync" and len(sys.argv) > 2:
|
|
197
|
+
service_id = sys.argv[2]
|
|
198
|
+
if update_sync_time(service_id):
|
|
199
|
+
print(f"✓ Synced: {service_id}")
|
|
200
|
+
else:
|
|
201
|
+
print(f"✗ Failed to sync: {service_id}")
|
|
202
|
+
sys.exit(1)
|
|
203
|
+
|
|
204
|
+
elif cmd == "scan":
|
|
205
|
+
drifted = scan_drift()
|
|
206
|
+
if drifted:
|
|
207
|
+
print(f"Found {len(drifted)} drifted service(s):")
|
|
208
|
+
for item in drifted:
|
|
209
|
+
print(
|
|
210
|
+
f" {item['service_id']}: {item['file_path']} "
|
|
211
|
+
f"(last sync: {item['last_sync']})"
|
|
212
|
+
)
|
|
213
|
+
else:
|
|
214
|
+
print("No drift detected.")
|
|
215
|
+
|
|
216
|
+
else:
|
|
217
|
+
print(f"Unknown command: {cmd}")
|
|
218
|
+
sys.exit(1)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if __name__ == "__main__":
|
|
222
|
+
main()
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: using-service-skills
|
|
3
|
+
description: >-
|
|
4
|
+
Service catalog discovery and expert persona activation.
|
|
5
|
+
At session start, a catalog of registered expert personas is injected
|
|
6
|
+
automatically. Use this skill to discover, understand, and activate
|
|
7
|
+
the right expert for any task.
|
|
8
|
+
allowed-tools: Read, Glob
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Using Service Skills
|
|
12
|
+
|
|
13
|
+
## Role: The Concierge
|
|
14
|
+
|
|
15
|
+
You are the **Service Skills Concierge**. Your job is to help users discover and
|
|
16
|
+
activate expert personas registered in `.claude/skills/service-registry.json`.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## How the Catalog Works
|
|
21
|
+
|
|
22
|
+
At session start, the `SessionStart` hook (configured in `.claude/settings.json`)
|
|
23
|
+
runs `cataloger.py` and injects a lightweight XML block into your context:
|
|
24
|
+
|
|
25
|
+
```xml
|
|
26
|
+
<project_service_catalog>
|
|
27
|
+
Available expert personas:
|
|
28
|
+
- db-expert: SQL & schema optimization (Path: .claude/skills/db-expert/SKILL.md)
|
|
29
|
+
- auth-service: JWT authentication expert (Path: .claude/skills/auth-service/SKILL.md)
|
|
30
|
+
</project_service_catalog>
|
|
31
|
+
<instruction>To activate an expert, read its SKILL.md from the provided path.</instruction>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This costs ~150 tokens per session regardless of how many experts are registered
|
|
35
|
+
(Progressive Disclosure: full skill bodies are loaded only when needed).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Workflow
|
|
40
|
+
|
|
41
|
+
### 1. Check the Injected Catalog
|
|
42
|
+
|
|
43
|
+
When a user asks about a service or starts a related task, check whether a
|
|
44
|
+
`<project_service_catalog>` block is present in your context.
|
|
45
|
+
|
|
46
|
+
If no catalog was injected (e.g. first run, no services registered), generate one:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python3 "$CLAUDE_PROJECT_DIR/.claude/skills/using-service-skills/scripts/cataloger.py"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2. Activate an Expert Persona
|
|
53
|
+
|
|
54
|
+
When a task matches an expert's domain, read that skill's SKILL.md:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Read: .claude/skills/<service-id>/SKILL.md
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Then adopt the expert's persona, constraints, and knowledge for the duration
|
|
61
|
+
of the task.
|
|
62
|
+
|
|
63
|
+
**Example:**
|
|
64
|
+
```
|
|
65
|
+
User: "Optimize this database query"
|
|
66
|
+
You: [Catalog shows db-expert matches]
|
|
67
|
+
[Read .claude/skills/db-expert/SKILL.md]
|
|
68
|
+
[Apply Senior Database Engineer persona and expertise]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 3. Handle Missing Experts
|
|
72
|
+
|
|
73
|
+
If no registered expert covers the user's need:
|
|
74
|
+
1. Inform the user no expert exists for this domain
|
|
75
|
+
2. Offer to create one: "I can create a service skill using `/creating-service-skills`"
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Session Start Hook
|
|
80
|
+
|
|
81
|
+
The catalog injection is **not** handled by skill frontmatter hooks (SessionStart
|
|
82
|
+
is not supported in skill-level hooks). It is configured in `.claude/settings.json`:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"hooks": {
|
|
87
|
+
"SessionStart": [{
|
|
88
|
+
"hooks": [{
|
|
89
|
+
"type": "command",
|
|
90
|
+
"command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/skills/using-service-skills/scripts/cataloger.py\""
|
|
91
|
+
}]
|
|
92
|
+
}]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Tool Restrictions
|
|
100
|
+
|
|
101
|
+
Read-only — no write access:
|
|
102
|
+
- ✅ `Read` — read SKILL.md files to activate expert personas
|
|
103
|
+
- ✅ `Glob` — browse `.claude/skills/` directory
|
|
104
|
+
|
|
105
|
+
## Related Skills
|
|
106
|
+
|
|
107
|
+
- `/creating-service-skills` — Scaffold new expert personas
|
|
108
|
+
- `/updating-service-skills` — Sync skills when implementation drifts
|
|
Binary file
|
|
Binary file
|
package/project-skills/service-skills-set/.claude/skills/using-service-skills/scripts/cataloger.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Cataloger — SessionStart hook for using-service-skills.
|
|
4
|
+
|
|
5
|
+
Reads .claude/skills/service-registry.json and prints a lightweight XML
|
|
6
|
+
service catalog block (~150 tokens) to stdout. The SessionStart hook
|
|
7
|
+
injects this as additional context so Claude knows which expert personas
|
|
8
|
+
are available without loading full skill bodies (Progressive Disclosure).
|
|
9
|
+
|
|
10
|
+
Configured in .claude/settings.json:
|
|
11
|
+
"SessionStart": [{"hooks": [{"type": "command",
|
|
12
|
+
"command": "python3 \\"$CLAUDE_PROJECT_DIR/.claude/skills/using-service-skills/scripts/cataloger.py\\""}]}]
|
|
13
|
+
|
|
14
|
+
Output format:
|
|
15
|
+
<project_service_catalog>
|
|
16
|
+
Available expert personas:
|
|
17
|
+
- db-expert: SQL & schema expert (Path: .claude/skills/db-expert/SKILL.md)
|
|
18
|
+
</project_service_catalog>
|
|
19
|
+
<instruction>To activate an expert, read its SKILL.md from the provided path.</instruction>
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import sys
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
# Bootstrap lives in creating-service-skills — shared utility
|
|
26
|
+
BOOTSTRAP_DIR = Path(__file__).parent.parent.parent / "creating-service-skills" / "scripts"
|
|
27
|
+
sys.path.insert(0, str(BOOTSTRAP_DIR))
|
|
28
|
+
|
|
29
|
+
from bootstrap import RootResolutionError, list_services # noqa: E402
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def generate_catalog() -> str:
|
|
33
|
+
"""
|
|
34
|
+
Generate the service catalog XML block.
|
|
35
|
+
|
|
36
|
+
Returns empty string if no services are registered or project root
|
|
37
|
+
cannot be determined (fails gracefully — never breaks session start).
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
services = list_services()
|
|
41
|
+
except (RootResolutionError, Exception):
|
|
42
|
+
return ""
|
|
43
|
+
|
|
44
|
+
if not services:
|
|
45
|
+
return ""
|
|
46
|
+
|
|
47
|
+
lines = [
|
|
48
|
+
"<project_service_catalog>",
|
|
49
|
+
"Available expert personas:",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
for service_id, data in sorted(services.items()):
|
|
53
|
+
description = data.get("description", data.get("name", service_id))
|
|
54
|
+
skill_path = data.get("skill_path", f".claude/skills/{service_id}/SKILL.md")
|
|
55
|
+
lines.append(f"- {service_id}: {description} (Path: {skill_path})")
|
|
56
|
+
|
|
57
|
+
lines.append("</project_service_catalog>")
|
|
58
|
+
lines.append(
|
|
59
|
+
"<instruction>To activate an expert, read its SKILL.md from the provided path.</instruction>"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
return "\n".join(lines)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def main() -> None:
|
|
66
|
+
"""Print catalog to stdout — injected as SessionStart additional context."""
|
|
67
|
+
catalog = generate_catalog()
|
|
68
|
+
if catalog:
|
|
69
|
+
print(catalog)
|
|
70
|
+
# Silent if no services registered — don't break session start
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
main()
|