specweave 0.24.11 → 0.26.2
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/CLAUDE.md +742 -26
- package/bin/specweave.js +14 -0
- package/dist/plugins/specweave-github/lib/CodeValidator.js +2 -2
- package/dist/plugins/specweave-github/lib/CodeValidator.js.map +1 -1
- package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js +1 -1
- package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +28 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +64 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-issue-updater.js +1 -1
- package/dist/plugins/specweave-github/lib/github-issue-updater.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.js +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-increment-changes.js +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-increment-changes.js.map +1 -1
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js +7 -6
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.js +1 -1
- package/dist/plugins/specweave-jira/lib/jira-epic-sync.js.map +1 -1
- package/dist/src/adapters/adapter-base.js +1 -1
- package/dist/src/adapters/adapter-base.js.map +1 -1
- package/dist/src/adapters/adapter-loader.js +1 -1
- package/dist/src/adapters/adapter-loader.js.map +1 -1
- package/dist/src/adapters/agents-md-generator.js +1 -1
- package/dist/src/adapters/agents-md-generator.js.map +1 -1
- package/dist/src/adapters/claude/adapter.js +1 -1
- package/dist/src/adapters/claude/adapter.js.map +1 -1
- package/dist/src/adapters/claude-md-generator.js +1 -1
- package/dist/src/adapters/claude-md-generator.js.map +1 -1
- package/dist/src/adapters/codex/adapter.js +1 -1
- package/dist/src/adapters/codex/adapter.js.map +1 -1
- package/dist/src/adapters/cursor/adapter.js +1 -1
- package/dist/src/adapters/cursor/adapter.js.map +1 -1
- package/dist/src/adapters/doc-generator.js +1 -1
- package/dist/src/adapters/doc-generator.js.map +1 -1
- package/dist/src/adapters/gemini/adapter.js +1 -1
- package/dist/src/adapters/gemini/adapter.js.map +1 -1
- package/dist/src/adapters/generic/adapter.js +1 -1
- package/dist/src/adapters/generic/adapter.js.map +1 -1
- package/dist/src/cli/commands/cicd-monitor.js +1 -1
- package/dist/src/cli/commands/cicd-monitor.js.map +1 -1
- package/dist/src/cli/commands/delete-feature.d.ts +14 -0
- package/dist/src/cli/commands/delete-feature.d.ts.map +1 -0
- package/dist/src/cli/commands/delete-feature.js +87 -0
- package/dist/src/cli/commands/delete-feature.js.map +1 -0
- package/dist/src/cli/commands/detect-specs.js +1 -1
- package/dist/src/cli/commands/detect-specs.js.map +1 -1
- package/dist/src/cli/commands/import-external.js +1 -1
- package/dist/src/cli/commands/import-external.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +45 -47
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/install.js +1 -1
- package/dist/src/cli/commands/install.js.map +1 -1
- package/dist/src/cli/commands/list.js +1 -1
- package/dist/src/cli/commands/list.js.map +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.js +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.js.map +1 -1
- package/dist/src/cli/commands/migrate-to-profiles.js +1 -1
- package/dist/src/cli/commands/migrate-to-profiles.js.map +1 -1
- package/dist/src/cli/commands/plan/agent-invoker.js +1 -1
- package/dist/src/cli/commands/repair-status-desync.js +1 -1
- package/dist/src/cli/commands/repair-status-desync.js.map +1 -1
- package/dist/src/cli/commands/revert-wip-limit.js +1 -1
- package/dist/src/cli/commands/revert-wip-limit.js.map +1 -1
- package/dist/src/cli/commands/sync-specs.js +1 -1
- package/dist/src/cli/commands/sync-specs.js.map +1 -1
- package/dist/src/cli/helpers/init/initial-increment-generator.js +1 -1
- package/dist/src/cli/helpers/init/initial-increment-generator.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js +15 -36
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +12 -31
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.d.ts +6 -1
- package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.js.map +1 -1
- package/dist/src/config/import-config.js +1 -1
- package/dist/src/config/import-config.js.map +1 -1
- package/dist/src/config/types.d.ts +203 -1208
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/core/ac-test-validator-cli.js +1 -1
- package/dist/src/core/ac-test-validator-cli.js.map +1 -1
- package/dist/src/core/ac-test-validator.js +1 -1
- package/dist/src/core/ac-test-validator.js.map +1 -1
- package/dist/src/core/brownfield/analyzer.js +1 -1
- package/dist/src/core/brownfield/analyzer.js.map +1 -1
- package/dist/src/core/brownfield/importer.js +1 -1
- package/dist/src/core/brownfield/importer.js.map +1 -1
- package/dist/src/core/cicd/config-loader.js +1 -1
- package/dist/src/core/cicd/config-loader.js.map +1 -1
- package/dist/src/core/cicd/notifier.js +1 -1
- package/dist/src/core/cicd/notifier.js.map +1 -1
- package/dist/src/core/cicd/parent-repo-validator.js +1 -1
- package/dist/src/core/cicd/parent-repo-validator.js.map +1 -1
- package/dist/src/core/cicd/state-manager.js +1 -1
- package/dist/src/core/cicd/state-manager.js.map +1 -1
- package/dist/src/core/config/types.d.ts +46 -12
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js +0 -5
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/config-manager.js +1 -1
- package/dist/src/core/config-manager.js.map +1 -1
- package/dist/src/core/cost-tracker.js +1 -1
- package/dist/src/core/cost-tracker.js.map +1 -1
- package/dist/src/core/deduplication/command-deduplicator.js +1 -1
- package/dist/src/core/deduplication/command-deduplicator.js.map +1 -1
- package/dist/src/core/feature-deleter/audit-logger.d.ts +30 -0
- package/dist/src/core/feature-deleter/audit-logger.d.ts.map +1 -0
- package/dist/src/core/feature-deleter/audit-logger.js +77 -0
- package/dist/src/core/feature-deleter/audit-logger.js.map +1 -0
- package/dist/src/core/feature-deleter/confirmation-manager.d.ts +39 -0
- package/dist/src/core/feature-deleter/confirmation-manager.d.ts.map +1 -0
- package/dist/src/core/feature-deleter/confirmation-manager.js +89 -0
- package/dist/src/core/feature-deleter/confirmation-manager.js.map +1 -0
- package/dist/src/core/feature-deleter/deletion-transaction.d.ts +51 -0
- package/dist/src/core/feature-deleter/deletion-transaction.d.ts.map +1 -0
- package/dist/src/core/feature-deleter/deletion-transaction.js +185 -0
- package/dist/src/core/feature-deleter/deletion-transaction.js.map +1 -0
- package/dist/src/core/feature-deleter/git-service.d.ts +43 -0
- package/dist/src/core/feature-deleter/git-service.d.ts.map +1 -0
- package/dist/src/core/feature-deleter/git-service.js +127 -0
- package/dist/src/core/feature-deleter/git-service.js.map +1 -0
- package/dist/src/core/feature-deleter/github-service.d.ts +36 -0
- package/dist/src/core/feature-deleter/github-service.d.ts.map +1 -0
- package/dist/src/core/feature-deleter/github-service.js +102 -0
- package/dist/src/core/feature-deleter/github-service.js.map +1 -0
- package/dist/src/core/feature-deleter/index.d.ts +35 -0
- package/dist/src/core/feature-deleter/index.d.ts.map +1 -0
- package/dist/src/core/feature-deleter/index.js +199 -0
- package/dist/src/core/feature-deleter/index.js.map +1 -0
- package/dist/src/core/feature-deleter/types.d.ts +179 -0
- package/dist/src/core/feature-deleter/types.d.ts.map +1 -0
- package/dist/src/core/feature-deleter/types.js +7 -0
- package/dist/src/core/feature-deleter/types.js.map +1 -0
- package/dist/src/core/feature-deleter/validator.d.ts +46 -0
- package/dist/src/core/feature-deleter/validator.d.ts.map +1 -0
- package/dist/src/core/feature-deleter/validator.js +231 -0
- package/dist/src/core/feature-deleter/validator.js.map +1 -0
- package/dist/src/core/hooks/HealthReporter.js +1 -1
- package/dist/src/core/hooks/HealthReporter.js.map +1 -1
- package/dist/src/core/hooks/HookAutoFixer.js +1 -1
- package/dist/src/core/hooks/HookAutoFixer.js.map +1 -1
- package/dist/src/core/hooks/HookScanner.js +1 -1
- package/dist/src/core/hooks/HookScanner.js.map +1 -1
- package/dist/src/core/i18n/language-manager.js +1 -1
- package/dist/src/core/i18n/language-manager.js.map +1 -1
- package/dist/src/core/i18n/locale-manager.js +1 -1
- package/dist/src/core/i18n/locale-manager.js.map +1 -1
- package/dist/src/core/i18n/system-prompt-injector.js +1 -1
- package/dist/src/core/i18n/system-prompt-injector.js.map +1 -1
- package/dist/src/core/increment/ac-status-manager.d.ts.map +1 -1
- package/dist/src/core/increment/ac-status-manager.js +18 -4
- package/dist/src/core/increment/ac-status-manager.js.map +1 -1
- package/dist/src/core/increment/active-increment-manager.js +1 -1
- package/dist/src/core/increment/active-increment-manager.js.map +1 -1
- package/dist/src/core/increment/completion-validator.js +1 -1
- package/dist/src/core/increment/completion-validator.js.map +1 -1
- package/dist/src/core/increment/conflict-resolver.js +1 -1
- package/dist/src/core/increment/conflict-resolver.js.map +1 -1
- package/dist/src/core/increment/desync-detector.js +1 -1
- package/dist/src/core/increment/desync-detector.js.map +1 -1
- package/dist/src/core/increment/discipline-checker.js +1 -1
- package/dist/src/core/increment/discipline-checker.js.map +1 -1
- package/dist/src/core/increment/duplicate-detector.js +1 -1
- package/dist/src/core/increment/duplicate-detector.js.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +1 -1
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/increment/increment-reopener.js +1 -1
- package/dist/src/core/increment/increment-reopener.js.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +1 -1
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/increment/metadata-validator.js +1 -1
- package/dist/src/core/increment/metadata-validator.js.map +1 -1
- package/dist/src/core/increment/recent-work-scanner.js +1 -1
- package/dist/src/core/increment/recent-work-scanner.js.map +1 -1
- package/dist/src/core/increment/spec-frontmatter-updater.js +1 -1
- package/dist/src/core/increment/spec-frontmatter-updater.js.map +1 -1
- package/dist/src/core/increment/status-auto-transition.js +1 -1
- package/dist/src/core/increment/status-auto-transition.js.map +1 -1
- package/dist/src/core/increment-status.js +1 -1
- package/dist/src/core/increment-status.js.map +1 -1
- package/dist/src/core/living-docs/content-distributor.js +1 -1
- package/dist/src/core/living-docs/content-distributor.js.map +1 -1
- package/dist/src/core/living-docs/cross-linker.js +1 -1
- package/dist/src/core/living-docs/cross-linker.js.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +1 -1
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.js +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +14 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +72 -13
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/project-detector.js +1 -1
- package/dist/src/core/living-docs/project-detector.js.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.js +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.js.map +1 -1
- package/dist/src/core/logging/prompt-logger.js +1 -1
- package/dist/src/core/logging/prompt-logger.js.map +1 -1
- package/dist/src/core/plugin-loader.js +1 -1
- package/dist/src/core/plugin-loader.js.map +1 -1
- package/dist/src/core/project-manager.js +1 -1
- package/dist/src/core/project-manager.js.map +1 -1
- package/dist/src/core/qa/qa-runner.js +1 -1
- package/dist/src/core/qa/qa-runner.js.map +1 -1
- package/dist/src/core/repo-structure/folder-detector.js +1 -1
- package/dist/src/core/repo-structure/folder-detector.js.map +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-bulk-discovery.js +20 -5
- package/dist/src/core/repo-structure/repo-bulk-discovery.js.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js +29 -14
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/core/repo-structure/setup-state-manager.js +1 -1
- package/dist/src/core/repo-structure/setup-state-manager.js.map +1 -1
- package/dist/src/core/spec-detector.js +1 -1
- package/dist/src/core/spec-detector.js.map +1 -1
- package/dist/src/core/specs/spec-metadata-manager.js +1 -1
- package/dist/src/core/specs/spec-metadata-manager.js.map +1 -1
- package/dist/src/core/status-line/status-line-updater.js +1 -1
- package/dist/src/core/status-line/status-line-updater.js.map +1 -1
- package/dist/src/core/status-line-validator.js +1 -1
- package/dist/src/core/status-line-validator.js.map +1 -1
- package/dist/src/core/sync/bidirectional-engine.js +1 -1
- package/dist/src/core/sync/bidirectional-engine.js.map +1 -1
- package/dist/src/core/sync/profile-manager.js +1 -1
- package/dist/src/core/sync/profile-manager.js.map +1 -1
- package/dist/src/core/sync/project-context.js +1 -1
- package/dist/src/core/sync/project-context.js.map +1 -1
- package/dist/src/core/sync/sync-event-logger.js +1 -1
- package/dist/src/core/sync/sync-event-logger.js.map +1 -1
- package/dist/src/core/types/config.js +1 -1
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/core/us-completion-detector.d.ts +124 -0
- package/dist/src/core/us-completion-detector.d.ts.map +1 -0
- package/dist/src/core/us-completion-detector.js +270 -0
- package/dist/src/core/us-completion-detector.js.map +1 -0
- package/dist/src/core/utils/permission-checker.js +1 -1
- package/dist/src/core/utils/permission-checker.js.map +1 -1
- package/dist/src/core/workflow/autonomous-executor.js +1 -1
- package/dist/src/core/workflow/autonomous-executor.js.map +1 -1
- package/dist/src/core/workflow/backlog-scanner.js +1 -1
- package/dist/src/core/workflow/backlog-scanner.js.map +1 -1
- package/dist/src/core/workflow/cost-estimator.js +1 -1
- package/dist/src/core/workflow/cost-estimator.js.map +1 -1
- package/dist/src/core/workflow/state-manager.js +1 -1
- package/dist/src/core/workflow/state-manager.js.map +1 -1
- package/dist/src/importers/duplicate-detector.js +1 -1
- package/dist/src/importers/duplicate-detector.js.map +1 -1
- package/dist/src/importers/item-converter.js +1 -1
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/init/architecture/types.d.ts +33 -140
- package/dist/src/init/architecture/types.d.ts.map +1 -1
- package/dist/src/init/compliance/types.d.ts +30 -27
- package/dist/src/init/compliance/types.d.ts.map +1 -1
- package/dist/src/init/repo/types.d.ts +11 -34
- package/dist/src/init/repo/types.d.ts.map +1 -1
- package/dist/src/init/research/src/config/types.d.ts +15 -82
- package/dist/src/init/research/src/config/types.d.ts.map +1 -1
- package/dist/src/init/research/types.d.ts +38 -93
- package/dist/src/init/research/types.d.ts.map +1 -1
- package/dist/src/init/team/types.d.ts +4 -42
- package/dist/src/init/team/types.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.d.ts +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.js +3 -3
- package/dist/src/integrations/jira/jira-incremental-mapper.js.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.js +1 -1
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
- package/dist/src/living-docs/id-registry.js +1 -1
- package/dist/src/living-docs/id-registry.js.map +1 -1
- package/dist/src/sync/external-item-sync-service.js +1 -1
- package/dist/src/sync/external-item-sync-service.js.map +1 -1
- package/dist/src/sync/format-preservation-sync.d.ts.map +1 -1
- package/dist/src/sync/format-preservation-sync.js +23 -5
- package/dist/src/sync/format-preservation-sync.js.map +1 -1
- package/dist/src/sync/frontmatter-updater.d.ts +57 -0
- package/dist/src/sync/frontmatter-updater.d.ts.map +1 -0
- package/dist/src/sync/frontmatter-updater.js +147 -0
- package/dist/src/sync/frontmatter-updater.js.map +1 -0
- package/dist/src/sync/sync-coordinator.d.ts +22 -1
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +268 -21
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/sync/sync-metadata.js +1 -1
- package/dist/src/sync/sync-metadata.js.map +1 -1
- package/dist/src/types/living-docs-us-file.d.ts +18 -0
- package/dist/src/types/living-docs-us-file.d.ts.map +1 -1
- package/dist/src/types/living-docs-us-file.js.map +1 -1
- package/dist/src/utils/agents-md-compiler.js +1 -1
- package/dist/src/utils/agents-md-compiler.js.map +1 -1
- package/dist/src/utils/auto-install.js +1 -1
- package/dist/src/utils/auto-install.js.map +1 -1
- package/dist/src/utils/cost-reporter.js +1 -1
- package/dist/src/utils/cost-reporter.js.map +1 -1
- package/dist/src/utils/docs-preview/config-generator.js +1 -1
- package/dist/src/utils/docs-preview/config-generator.js.map +1 -1
- package/dist/src/utils/docs-preview/docusaurus-setup.js +1 -1
- package/dist/src/utils/docs-preview/docusaurus-setup.js.map +1 -1
- package/dist/src/utils/docs-preview/package-installer.js +1 -1
- package/dist/src/utils/docs-preview/package-installer.js.map +1 -1
- package/dist/src/utils/docs-preview/sidebar-builder.js +1 -1
- package/dist/src/utils/docs-preview/sidebar-builder.js.map +1 -1
- package/dist/src/utils/env-file-generator.js +1 -1
- package/dist/src/utils/env-file-generator.js.map +1 -1
- package/dist/src/utils/external-resource-validator.js +1 -1
- package/dist/src/utils/external-resource-validator.js.map +1 -1
- package/dist/src/utils/fs-native.d.ts +51 -5
- package/dist/src/utils/fs-native.d.ts.map +1 -1
- package/dist/src/utils/fs-native.js +100 -5
- package/dist/src/utils/fs-native.js.map +1 -1
- package/dist/src/utils/plugin-validator.js +1 -1
- package/dist/src/utils/plugin-validator.js.map +1 -1
- package/dist/src/utils/project-detection.js +1 -1
- package/dist/src/utils/project-detection.js.map +1 -1
- package/dist/src/utils/project-validator.js +1 -1
- package/dist/src/utils/project-validator.js.map +1 -1
- package/dist/src/utils/spec-parser.js +1 -1
- package/dist/src/utils/spec-parser.js.map +1 -1
- package/dist/src/utils/spec-splitter.js +1 -1
- package/dist/src/utils/spec-splitter.js.map +1 -1
- package/dist/src/validators/ac-coverage-validator.js +1 -1
- package/dist/src/validators/ac-coverage-validator.js.map +1 -1
- package/package.json +5 -6
- package/plugins/specweave/.claude-plugin/plugin.json +17 -11
- package/plugins/specweave/agents/architect/AGENT.md +115 -45
- package/plugins/specweave/agents/code-standards-detective/AGENT.md +47 -0
- package/plugins/specweave/agents/docs-writer/AGENT.md +134 -1
- package/plugins/specweave/agents/increment-quality-judge-v2/AGENT.md +1 -0
- package/plugins/specweave/agents/infrastructure/AGENT.md +48 -1
- package/plugins/specweave/agents/performance/AGENT.md +46 -0
- package/plugins/specweave/agents/pm/AGENT.md +115 -3
- package/plugins/specweave/agents/qa-lead/AGENT.md +40 -1
- package/plugins/specweave/agents/reflective-reviewer/AGENT.md +5 -0
- package/plugins/specweave/agents/security/AGENT.md +45 -0
- package/plugins/specweave/agents/tdd-orchestrator/AGENT.md +128 -1
- package/plugins/specweave/agents/tech-lead/AGENT.md +138 -1
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +76 -6
- package/plugins/specweave/agents/translator/AGENT.md +132 -0
- package/plugins/specweave/commands/specweave-sync-progress.md +616 -0
- package/plugins/specweave/hooks/hooks.json +0 -9
- package/plugins/specweave/hooks/lib/update-status-line.sh +19 -0
- package/plugins/specweave/hooks/post-edit-write-consolidated.sh +335 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +133 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +58 -19
- package/plugins/specweave/hooks/post-task-completion.sh +100 -9
- package/plugins/specweave/hooks/pre-edit-spec.sh +0 -11
- package/plugins/specweave/hooks/pre-edit-write-consolidated.sh +225 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +11 -0
- package/plugins/specweave/hooks/pre-write-spec.sh +0 -11
- package/plugins/specweave/hooks/shared/bulk-operation-detector.sh +167 -0
- package/plugins/specweave/lib/hooks/consolidated-sync.js +78 -3
- package/plugins/specweave/lib/hooks/us-completion-orchestrator.js +135 -0
- package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js +18 -4
- package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js.map +1 -1
- package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js +1 -1
- package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js.map +1 -1
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +1 -1
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -1
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +1 -1
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -1
- package/plugins/specweave/skills/code-reviewer/SKILL.md +1 -1
- package/plugins/specweave/skills/progress-sync/SKILL.md +405 -0
- package/plugins/specweave-ado/lib/ado-project-detector.js +1 -1
- package/plugins/specweave-ado/lib/ado-project-detector.ts +1 -1
- package/plugins/specweave-ado/lib/conflict-resolver.js +1 -1
- package/plugins/specweave-ado/lib/conflict-resolver.ts +1 -1
- package/plugins/specweave-backend/agents/database-optimizer/AGENT.md +1 -1
- package/plugins/specweave-frontend/agents/frontend-architect/AGENT.md +5 -0
- package/plugins/specweave-github/.claude-plugin/plugin.json +1 -15
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +480 -0
- package/plugins/specweave-github/hooks/README.md +34 -25
- package/plugins/specweave-github/lib/CodeValidator.js +1 -1
- package/plugins/specweave-github/lib/CodeValidator.ts +2 -2
- package/plugins/specweave-github/lib/ThreeLayerSyncManager.js +1 -1
- package/plugins/specweave-github/lib/ThreeLayerSyncManager.ts +1 -1
- package/plugins/specweave-github/lib/github-client-v2.js +59 -1
- package/plugins/specweave-github/lib/github-client-v2.ts +82 -1
- package/plugins/specweave-github/lib/github-issue-updater.js +1 -1
- package/plugins/specweave-github/lib/github-issue-updater.ts +1 -1
- package/plugins/specweave-github/lib/github-sync-bidirectional.js +1 -1
- package/plugins/specweave-github/lib/github-sync-bidirectional.ts +1 -1
- package/plugins/specweave-github/lib/github-sync-increment-changes.js +1 -1
- package/plugins/specweave-github/lib/github-sync-increment-changes.ts +1 -1
- package/plugins/specweave-github/lib/user-story-issue-builder.js +4 -4
- package/plugins/specweave-github/lib/user-story-issue-builder.ts +7 -6
- package/plugins/specweave-infrastructure/agents/devops/AGENT.md +48 -1
- package/plugins/specweave-infrastructure/agents/network-engineer/AGENT.md +6 -1
- package/plugins/specweave-infrastructure/agents/observability-engineer/AGENT.md +6 -1
- package/plugins/specweave-infrastructure/agents/performance-engineer/AGENT.md +6 -1
- package/plugins/specweave-infrastructure/agents/sre/AGENT.md +5 -0
- package/plugins/specweave-jira/lib/jira-epic-sync.js +1 -1
- package/plugins/specweave-jira/lib/jira-epic-sync.ts +1 -1
- package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +5 -0
- package/plugins/specweave-kubernetes/agents/kubernetes-architect/AGENT.md +47 -2
- package/plugins/specweave-ml/agents/data-scientist/AGENT.md +1 -1
- package/plugins/specweave-ml/agents/ml-engineer/AGENT.md +5 -0
- package/plugins/specweave-ml/agents/mlops-engineer/AGENT.md +6 -1
- package/plugins/specweave-payments/agents/payment-integration/AGENT.md +1 -1
- package/plugins/specweave-release/commands/specweave-release-npm.md +130 -2
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +198 -0
- package/plugins/specweave-ado/hooks/hooks.json +0 -15
- package/plugins/specweave-github/hooks/hooks.json +0 -15
- package/plugins/specweave-jira/hooks/hooks.json +0 -15
- package/plugins/specweave-release/hooks/hooks.json +0 -15
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Post-Edit/Write Consolidated Hook: Update Status Line After spec.md or tasks.md Changes
|
|
4
|
+
#
|
|
5
|
+
# Purpose: Unified hook for both Edit and Write tools
|
|
6
|
+
# Triggers: After Edit/Write modifies spec.md (AC updates) or tasks.md (task completion)
|
|
7
|
+
# Action: Updates status line cache to reflect latest AC/task progress
|
|
8
|
+
#
|
|
9
|
+
# CONSOLIDATION (v0.25.0):
|
|
10
|
+
# - Replaces post-edit-spec.sh and post-write-spec.sh (identical code)
|
|
11
|
+
# - Reduces hook overhead by 50% (2 post-hooks → 1)
|
|
12
|
+
# - Single point of maintenance
|
|
13
|
+
# - Combined with pre-edit-write-consolidated.sh, reduces 4 hooks → 2 hooks
|
|
14
|
+
#
|
|
15
|
+
# This ensures status line stays in sync when ACs are marked complete via Edit tool
|
|
16
|
+
# (not just TodoWrite, which only tracks internal todo lists)
|
|
17
|
+
#
|
|
18
|
+
# EMERGENCY FIXES (v0.24.3):
|
|
19
|
+
# - Kill switch: Set SPECWEAVE_DISABLE_HOOKS=1 to disable ALL hooks
|
|
20
|
+
# - Circuit breaker: Auto-disable after 3 consecutive failures
|
|
21
|
+
# - File locking: Prevent concurrent executions (max 1 at a time)
|
|
22
|
+
# - Aggressive debouncing: Increased from 1s to 5s
|
|
23
|
+
# - Complete error isolation: Never let errors reach Claude Code
|
|
24
|
+
#
|
|
25
|
+
# TIER 1 IMPROVEMENTS (v0.24.2):
|
|
26
|
+
# - Debouncing: Skip if updated less than 5 seconds ago (90% overhead reduction)
|
|
27
|
+
# - File mtime detection: Check recently modified spec.md/tasks.md as fallback
|
|
28
|
+
# - Non-blocking: Run update-status-line.sh in background
|
|
29
|
+
# - Smart detection: Only update if spec/tasks files actually changed
|
|
30
|
+
#
|
|
31
|
+
# Previous fix (v0.24.1): Enhanced file detection for increment completion
|
|
32
|
+
# - Detects changes via TOOL_USE_CONTENT, TOOL_RESULT, and argument parsing
|
|
33
|
+
# - Always updates status line for ANY spec.md/tasks.md change in increments folder
|
|
34
|
+
|
|
35
|
+
# CRITICAL: Remove set -e to prevent hook errors from crashing Claude Code
|
|
36
|
+
set +e
|
|
37
|
+
|
|
38
|
+
# Find project root (must be BEFORE recursion guard to get PROJECT_ROOT)
|
|
39
|
+
find_project_root() {
|
|
40
|
+
local dir="$PWD"
|
|
41
|
+
while [[ "$dir" != "/" ]]; do
|
|
42
|
+
if [[ -d "$dir/.specweave" ]]; then
|
|
43
|
+
echo "$dir"
|
|
44
|
+
return 0
|
|
45
|
+
fi
|
|
46
|
+
dir=$(dirname "$dir")
|
|
47
|
+
done
|
|
48
|
+
echo "$PWD"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
PROJECT_ROOT=$(find_project_root)
|
|
52
|
+
LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
|
|
53
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
54
|
+
|
|
55
|
+
# ============================================================================
|
|
56
|
+
# RECURSION PREVENTION (CRITICAL - v0.26.0 - FILE-BASED GUARD)
|
|
57
|
+
# ============================================================================
|
|
58
|
+
# PROBLEM: Hooks that write files trigger other hooks, causing infinite loops.
|
|
59
|
+
# OLD SOLUTION (v0.25.1): Environment variable SPECWEAVE_IN_HOOK=1
|
|
60
|
+
# WHY IT FAILED: Background processes (&) create NEW shells that don't inherit env vars!
|
|
61
|
+
#
|
|
62
|
+
# NEW SOLUTION (v0.26.0): File-based recursion guard
|
|
63
|
+
# - Guard file exists = already inside hook chain
|
|
64
|
+
# - Works across ALL processes (not just current shell)
|
|
65
|
+
# - Atomic operation (mkdir -p ensures thread safety)
|
|
66
|
+
# - Cleanup guaranteed by trap EXIT
|
|
67
|
+
#
|
|
68
|
+
# See: .specweave/increments/0051-*/reports/GITHUB-COMMENT-RECURSION-ROOT-CAUSE-2025-11-24.md
|
|
69
|
+
# See: ADR-0073 (Hook Recursion Prevention Strategy)
|
|
70
|
+
|
|
71
|
+
RECURSION_GUARD_FILE="$PROJECT_ROOT/.specweave/state/.hook-recursion-guard"
|
|
72
|
+
|
|
73
|
+
if [[ -f "$RECURSION_GUARD_FILE" ]]; then
|
|
74
|
+
# Silent exit - we're already inside a hook chain
|
|
75
|
+
# This is NORMAL and prevents recursion (not an error!)
|
|
76
|
+
exit 0
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# Don't create guard file here - we only CHECK it
|
|
80
|
+
# Guard file is ONLY created by post-task-completion.sh (the entry point)
|
|
81
|
+
# All other hooks just check for its existence
|
|
82
|
+
|
|
83
|
+
# EMERGENCY KILL SWITCH: Disable all hooks if env variable set
|
|
84
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Ensure state and logs directories exist
|
|
89
|
+
mkdir -p "$PROJECT_ROOT/.specweave/state" "$LOGS_DIR" 2>/dev/null || true
|
|
90
|
+
|
|
91
|
+
# EMERGENCY CIRCUIT BREAKER: Track consecutive failures
|
|
92
|
+
CIRCUIT_BREAKER_FILE="$PROJECT_ROOT/.specweave/state/.hook-circuit-breaker"
|
|
93
|
+
CIRCUIT_BREAKER_THRESHOLD=3
|
|
94
|
+
|
|
95
|
+
if [[ -f "$CIRCUIT_BREAKER_FILE" ]]; then
|
|
96
|
+
FAILURE_COUNT=$(cat "$CIRCUIT_BREAKER_FILE" 2>/dev/null || echo 0)
|
|
97
|
+
if (( FAILURE_COUNT >= CIRCUIT_BREAKER_THRESHOLD )); then
|
|
98
|
+
echo "[$(date)] CIRCUIT BREAKER OPEN: Hooks disabled after $FAILURE_COUNT failures. Run: rm $CIRCUIT_BREAKER_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
99
|
+
exit 0
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# EMERGENCY FILE LOCK: Prevent concurrent executions
|
|
104
|
+
LOCK_FILE="$PROJECT_ROOT/.specweave/state/.hook-post-edit-write.lock"
|
|
105
|
+
LOCK_TIMEOUT=5 # seconds
|
|
106
|
+
|
|
107
|
+
# Try to acquire lock with timeout
|
|
108
|
+
LOCK_ACQUIRED=false
|
|
109
|
+
for i in {1..5}; do
|
|
110
|
+
if mkdir "$LOCK_FILE" 2>/dev/null; then
|
|
111
|
+
LOCK_ACQUIRED=true
|
|
112
|
+
trap 'rmdir "$LOCK_FILE" 2>/dev/null || true' EXIT
|
|
113
|
+
break
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# Check if lock is stale (older than LOCK_TIMEOUT seconds)
|
|
117
|
+
if [[ -d "$LOCK_FILE" ]]; then
|
|
118
|
+
LOCK_AGE=$(($(date +%s) - $(stat -f "%m" "$LOCK_FILE" 2>/dev/null || echo 0)))
|
|
119
|
+
if (( LOCK_AGE > LOCK_TIMEOUT )); then
|
|
120
|
+
rmdir "$LOCK_FILE" 2>/dev/null || true
|
|
121
|
+
continue
|
|
122
|
+
fi
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
sleep 0.2
|
|
126
|
+
done
|
|
127
|
+
|
|
128
|
+
if [[ "$LOCK_ACQUIRED" == "false" ]]; then
|
|
129
|
+
echo "[$(date)] post-edit-write: Could not acquire lock, skipping" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
130
|
+
exit 0
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# Log rotation: Keep debug log under 100KB
|
|
134
|
+
if [[ -f "$DEBUG_LOG" ]] && [[ $(wc -c < "$DEBUG_LOG" 2>/dev/null || echo 0) -gt 102400 ]]; then
|
|
135
|
+
tail -100 "$DEBUG_LOG" > "$DEBUG_LOG.tmp" 2>/dev/null || true
|
|
136
|
+
mv "$DEBUG_LOG.tmp" "$DEBUG_LOG" 2>/dev/null || true
|
|
137
|
+
echo "[$(date)] Log rotated" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# ============================================================================
|
|
141
|
+
# BURST WRITE DETECTION (v0.26.2 - Prevent Write Storms)
|
|
142
|
+
# ============================================================================
|
|
143
|
+
# Problem: Architect agent creating multiple ADRs in one response (6+ writes/minute)
|
|
144
|
+
# Solution: Detect burst writes and throttle if necessary
|
|
145
|
+
# Incident: 2025-11-24 (Increment 0052 - architect created 6 ADRs at once)
|
|
146
|
+
BURST_TIMESTAMPS_FILE="$PROJECT_ROOT/.specweave/state/.write-timestamps"
|
|
147
|
+
BURST_WINDOW=10 # seconds
|
|
148
|
+
BURST_THRESHOLD=5 # max writes in window
|
|
149
|
+
BURST_THROTTLE=2 # seconds to wait if burst detected
|
|
150
|
+
|
|
151
|
+
# Record this write timestamp
|
|
152
|
+
mkdir -p "$(dirname "$BURST_TIMESTAMPS_FILE")" 2>/dev/null || true
|
|
153
|
+
echo "$(date +%s)" >> "$BURST_TIMESTAMPS_FILE" 2>/dev/null || true
|
|
154
|
+
|
|
155
|
+
# Count writes in the last BURST_WINDOW seconds
|
|
156
|
+
if [[ -f "$BURST_TIMESTAMPS_FILE" ]]; then
|
|
157
|
+
NOW=$(date +%s)
|
|
158
|
+
CUTOFF=$((NOW - BURST_WINDOW))
|
|
159
|
+
|
|
160
|
+
# Clean up old timestamps (older than BURST_WINDOW)
|
|
161
|
+
grep -v "^$" "$BURST_TIMESTAMPS_FILE" 2>/dev/null | \
|
|
162
|
+
awk -v cutoff="$CUTOFF" '$1 > cutoff' > "$BURST_TIMESTAMPS_FILE.tmp" 2>/dev/null || true
|
|
163
|
+
mv "$BURST_TIMESTAMPS_FILE.tmp" "$BURST_TIMESTAMPS_FILE" 2>/dev/null || true
|
|
164
|
+
|
|
165
|
+
# Count recent writes
|
|
166
|
+
RECENT_WRITES=$(wc -l < "$BURST_TIMESTAMPS_FILE" 2>/dev/null || echo 0)
|
|
167
|
+
|
|
168
|
+
if (( RECENT_WRITES > BURST_THRESHOLD )); then
|
|
169
|
+
echo "[$(date)] ⚠️ BURST DETECTED: $RECENT_WRITES writes in ${BURST_WINDOW}s (threshold: $BURST_THRESHOLD)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
170
|
+
echo "[$(date)] Throttling for ${BURST_THROTTLE}s to prevent overload..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
171
|
+
sleep "$BURST_THROTTLE"
|
|
172
|
+
fi
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# ============================================================================
|
|
176
|
+
# TIER 1 FIX: Debouncing (Prevent Redundant Updates)
|
|
177
|
+
# ============================================================================
|
|
178
|
+
# Skip update if we updated less than 5 seconds ago (INCREASED FROM 1s)
|
|
179
|
+
# This handles rapid consecutive changes (e.g., 10 tasks marked complete quickly)
|
|
180
|
+
LAST_UPDATE_FILE="$PROJECT_ROOT/.specweave/state/.last-status-update"
|
|
181
|
+
DEBOUNCE_SECONDS=5
|
|
182
|
+
|
|
183
|
+
if [[ -f "$LAST_UPDATE_FILE" ]]; then
|
|
184
|
+
LAST_UPDATE=$(cat "$LAST_UPDATE_FILE" 2>/dev/null || echo 0)
|
|
185
|
+
NOW=$(date +%s)
|
|
186
|
+
TIME_SINCE_UPDATE=$((NOW - LAST_UPDATE))
|
|
187
|
+
|
|
188
|
+
if (( TIME_SINCE_UPDATE < DEBOUNCE_SECONDS )); then
|
|
189
|
+
echo "[$(date)] post-edit-write: Debounced (${TIME_SINCE_UPDATE}s since last update)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
190
|
+
exit 0 # Skip this update
|
|
191
|
+
fi
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
# ============================================================================
|
|
195
|
+
# TIER 2: Check for PreToolUse Signal (Primary Detection Method)
|
|
196
|
+
# ============================================================================
|
|
197
|
+
PENDING_FILE="$PROJECT_ROOT/.specweave/state/.pending-status-update"
|
|
198
|
+
METRICS_FILE="$PROJECT_ROOT/.specweave/state/hook-metrics.jsonl"
|
|
199
|
+
DETECTED_FILE=""
|
|
200
|
+
DETECTION_METHOD="none"
|
|
201
|
+
|
|
202
|
+
# First, check if PreToolUse hook left a signal
|
|
203
|
+
if [[ -f "$PENDING_FILE" ]]; then
|
|
204
|
+
DETECTED_FILE=$(cat "$PENDING_FILE" 2>/dev/null || echo "")
|
|
205
|
+
# Delete pending file immediately (consume signal)
|
|
206
|
+
rm "$PENDING_FILE" 2>/dev/null || true
|
|
207
|
+
|
|
208
|
+
if [[ -n "$DETECTED_FILE" ]]; then
|
|
209
|
+
DETECTION_METHOD="pretooluse"
|
|
210
|
+
echo "[$(date)] post-edit-write: File from PreToolUse signal: $DETECTED_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
211
|
+
|
|
212
|
+
# Record Tier 2 success metric
|
|
213
|
+
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
214
|
+
echo "{\"timestamp\":\"$TIMESTAMP\",\"hook\":\"post-edit-write\",\"event\":\"tier2_success\",\"method\":\"pretooluse\"}" >> "$METRICS_FILE" 2>/dev/null || true
|
|
215
|
+
fi
|
|
216
|
+
fi
|
|
217
|
+
|
|
218
|
+
# ============================================================================
|
|
219
|
+
# TIER 1 FALLBACK: Environment Variable Detection
|
|
220
|
+
# ============================================================================
|
|
221
|
+
# If PreToolUse didn't provide signal, fall back to Tier 1 methods
|
|
222
|
+
if [[ -z "$DETECTED_FILE" ]]; then
|
|
223
|
+
# Method 1: TOOL_USE_CONTENT environment variable
|
|
224
|
+
if [[ -n "${TOOL_USE_CONTENT:-}" ]]; then
|
|
225
|
+
DETECTED_FILE="$TOOL_USE_CONTENT"
|
|
226
|
+
DETECTION_METHOD="env_content"
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
# Method 2: TOOL_RESULT environment variable
|
|
230
|
+
if [[ -z "$DETECTED_FILE" ]] && [[ -n "${TOOL_RESULT:-}" ]]; then
|
|
231
|
+
DETECTED_FILE=$(echo "$TOOL_RESULT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
|
|
232
|
+
DETECTION_METHOD="env_result"
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
# Method 3: TOOL_USE_ARGS
|
|
236
|
+
if [[ -z "$DETECTED_FILE" ]] && [[ -n "${TOOL_USE_ARGS:-}" ]]; then
|
|
237
|
+
DETECTED_FILE=$(echo "$TOOL_USE_ARGS" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
|
|
238
|
+
DETECTION_METHOD="env_args"
|
|
239
|
+
fi
|
|
240
|
+
|
|
241
|
+
# Log env var detection (for metrics)
|
|
242
|
+
if [[ -n "$DETECTED_FILE" ]]; then
|
|
243
|
+
echo "[$(date)] post-edit-write: File from env vars ($DETECTION_METHOD): $DETECTED_FILE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
244
|
+
fi
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
# Check if we detected a spec.md or tasks.md change in increments folder
|
|
248
|
+
SHOULD_UPDATE=false
|
|
249
|
+
|
|
250
|
+
if [[ -n "$DETECTED_FILE" ]]; then
|
|
251
|
+
# Check if the file is spec.md or tasks.md
|
|
252
|
+
if [[ "$DETECTED_FILE" == *"/spec.md" ]] || [[ "$DETECTED_FILE" == *"/tasks.md" ]]; then
|
|
253
|
+
# Check if it's in an increment folder
|
|
254
|
+
if [[ "$DETECTED_FILE" == *"/.specweave/increments/"* ]]; then
|
|
255
|
+
SHOULD_UPDATE=true
|
|
256
|
+
echo "[$(date)] post-edit-write: Increment file changed - will update status line" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
257
|
+
fi
|
|
258
|
+
fi
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
# ============================================================================
|
|
262
|
+
# TIER 1 FIX: File Modification Time Detection (Fallback)
|
|
263
|
+
# ============================================================================
|
|
264
|
+
# If we couldn't detect the file via environment variables, check which files
|
|
265
|
+
# were modified recently (within last 2 seconds) instead of blindly updating
|
|
266
|
+
if [[ -z "$DETECTED_FILE" ]]; then
|
|
267
|
+
echo "[$(date)] post-edit-write: Env vars empty - checking file mtimes" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
268
|
+
|
|
269
|
+
NOW=$(date +%s)
|
|
270
|
+
INCREMENTS_DIR="$PROJECT_ROOT/.specweave/increments"
|
|
271
|
+
|
|
272
|
+
# Check for recently modified spec.md or tasks.md files
|
|
273
|
+
if [[ -d "$INCREMENTS_DIR" ]]; then
|
|
274
|
+
for file in "$INCREMENTS_DIR"/*/spec.md "$INCREMENTS_DIR"/*/tasks.md; do
|
|
275
|
+
if [[ -f "$file" ]]; then
|
|
276
|
+
# Get file modification time (platform-specific)
|
|
277
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
278
|
+
MTIME=$(stat -f "%m" "$file" 2>/dev/null || echo 0)
|
|
279
|
+
else
|
|
280
|
+
MTIME=$(stat -c "%Y" "$file" 2>/dev/null || echo 0)
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
# If file was modified in last 2 seconds, consider it the changed file
|
|
284
|
+
TIME_DIFF=$((NOW - MTIME))
|
|
285
|
+
if (( TIME_DIFF <= 2 )); then
|
|
286
|
+
DETECTED_FILE="$file"
|
|
287
|
+
echo "[$(date)] post-edit-write: Detected recent modification: $file (${TIME_DIFF}s ago)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
288
|
+
SHOULD_UPDATE=true
|
|
289
|
+
break
|
|
290
|
+
fi
|
|
291
|
+
fi
|
|
292
|
+
done
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
# If still no file detected, skip update (not a spec/tasks change)
|
|
296
|
+
if [[ -z "$DETECTED_FILE" ]]; then
|
|
297
|
+
echo "[$(date)] post-edit-write: No spec/tasks modifications detected - skipping" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
298
|
+
exit 0
|
|
299
|
+
fi
|
|
300
|
+
fi
|
|
301
|
+
|
|
302
|
+
# ============================================================================
|
|
303
|
+
# TIER 1 FIX: Non-Blocking Background Update with COMPLETE ERROR ISOLATION
|
|
304
|
+
# ============================================================================
|
|
305
|
+
# Update status line if needed
|
|
306
|
+
if [[ "$SHOULD_UPDATE" == "true" ]]; then
|
|
307
|
+
echo "[$(date)] post-edit-write: Running update-status-line.sh (background)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
308
|
+
|
|
309
|
+
# Record update time BEFORE spawning background process
|
|
310
|
+
# This ensures debouncing works even if update hasn't completed yet
|
|
311
|
+
echo "$(date +%s)" > "$LAST_UPDATE_FILE"
|
|
312
|
+
|
|
313
|
+
# Run status line update in background with COMPLETE error isolation
|
|
314
|
+
# This prevents Edit/Write tool from waiting for status line computation
|
|
315
|
+
(
|
|
316
|
+
set +e # Disable error propagation
|
|
317
|
+
|
|
318
|
+
if "$PROJECT_ROOT/plugins/specweave/hooks/lib/update-status-line.sh" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null; then
|
|
319
|
+
echo "[$(date)] post-edit-write: Status line updated successfully" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
320
|
+
# Reset circuit breaker on success
|
|
321
|
+
echo "0" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
|
|
322
|
+
else
|
|
323
|
+
echo "[$(date)] post-edit-write: Warning - status line update failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
324
|
+
# Increment circuit breaker
|
|
325
|
+
CURRENT_FAILURES=$(cat "$CIRCUIT_BREAKER_FILE" 2>/dev/null || echo 0)
|
|
326
|
+
echo "$((CURRENT_FAILURES + 1))" > "$CIRCUIT_BREAKER_FILE" 2>/dev/null || true
|
|
327
|
+
fi
|
|
328
|
+
) &
|
|
329
|
+
|
|
330
|
+
# Disown the background process so it's not killed when hook exits
|
|
331
|
+
disown 2>/dev/null || true
|
|
332
|
+
fi
|
|
333
|
+
|
|
334
|
+
# Always exit 0 to prevent hook errors from crashing Claude Code
|
|
335
|
+
exit 0
|
|
@@ -25,6 +25,32 @@ fi
|
|
|
25
25
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
|
|
26
26
|
INCREMENT_DIR="$PROJECT_ROOT/.specweave/increments/$INCREMENT_ID"
|
|
27
27
|
|
|
28
|
+
# ============================================================================
|
|
29
|
+
# RECURSION PREVENTION (v0.26.1 - CRITICAL)
|
|
30
|
+
# ============================================================================
|
|
31
|
+
# PROBLEM: consolidated-sync.js does Edit/Write operations which trigger hooks.
|
|
32
|
+
# If no guard exists, those hooks will run full sync → more Edit/Write → INFINITE LOOP.
|
|
33
|
+
#
|
|
34
|
+
# SOLUTION: Create recursion guard file BEFORE calling any sync scripts.
|
|
35
|
+
# Other hooks check this file and exit early if it exists.
|
|
36
|
+
#
|
|
37
|
+
# See: ADR-0073 (Hook Recursion Prevention Strategy)
|
|
38
|
+
# See: .specweave/increments/0051-*/reports/GITHUB-COMMENT-RECURSION-ROOT-CAUSE-2025-11-24.md
|
|
39
|
+
|
|
40
|
+
RECURSION_GUARD_FILE="$PROJECT_ROOT/.specweave/state/.hook-recursion-guard"
|
|
41
|
+
|
|
42
|
+
if [[ -f "$RECURSION_GUARD_FILE" ]]; then
|
|
43
|
+
# Silent exit - we're already inside a hook chain
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Create guard file (atomic operation)
|
|
48
|
+
mkdir -p "$PROJECT_ROOT/.specweave/state" 2>/dev/null || true
|
|
49
|
+
touch "$RECURSION_GUARD_FILE"
|
|
50
|
+
|
|
51
|
+
# Ensure guard file is ALWAYS removed when script exits (even on error)
|
|
52
|
+
trap 'rm -f "$RECURSION_GUARD_FILE" 2>/dev/null || true' EXIT SIGINT SIGTERM
|
|
53
|
+
|
|
28
54
|
# Check if increment exists
|
|
29
55
|
if [ ! -d "$INCREMENT_DIR" ]; then
|
|
30
56
|
echo "⚠️ $HOOK_NAME: Increment $INCREMENT_ID not found" >&2
|
|
@@ -233,4 +259,111 @@ else
|
|
|
233
259
|
echo ""
|
|
234
260
|
fi
|
|
235
261
|
|
|
262
|
+
# ============================================================================
|
|
263
|
+
# GITHUB SYNC (v0.26.1 - CRITICAL FIX)
|
|
264
|
+
# ============================================================================
|
|
265
|
+
# After living docs sync, create GitHub issues for user stories.
|
|
266
|
+
# This is the AUTOMATIC GitHub sync that runs once per increment completion.
|
|
267
|
+
#
|
|
268
|
+
# CRITICAL: This was MISSING in v0.26.0, causing GitHub issues to NEVER be
|
|
269
|
+
# created automatically. The consolidated-sync.js has the full logic for:
|
|
270
|
+
# - Creating GitHub issues for user stories (with 3-layer idempotency)
|
|
271
|
+
# - Syncing task completion comments to existing issues
|
|
272
|
+
# - Format preservation sync for external tools
|
|
273
|
+
#
|
|
274
|
+
# GATE SYSTEM (4 gates - all checked inside consolidated-sync.js):
|
|
275
|
+
# - GATE 1: canUpsertInternalItems (living docs sync enabled)
|
|
276
|
+
# - GATE 2: canUpdateExternalItems (external tool sync enabled)
|
|
277
|
+
# - GATE 3: autoSyncOnCompletion (automatic sync enabled)
|
|
278
|
+
# - GATE 4: sync.github.enabled (GitHub-specific sync enabled)
|
|
279
|
+
#
|
|
280
|
+
# RECURSION SAFETY:
|
|
281
|
+
# - Recursion guard created at script start (line 49)
|
|
282
|
+
# - consolidated-sync.js does Edit/Write operations
|
|
283
|
+
# - Other hooks see the guard and exit early
|
|
284
|
+
# - Guard removed via trap on script exit
|
|
285
|
+
#
|
|
286
|
+
# USER PROJECT COMPATIBILITY:
|
|
287
|
+
# - Script detection works for: development, dist/, node_modules/, marketplace
|
|
288
|
+
# - Works in both SpecWeave framework repo AND user projects using SpecWeave
|
|
289
|
+
# - GITHUB_TOKEN loaded from project's .env file
|
|
290
|
+
#
|
|
291
|
+
# See: Root cause analysis in initial implementation planning
|
|
292
|
+
# See: ADR-0073 (Hook Recursion Prevention Strategy)
|
|
293
|
+
|
|
294
|
+
if command -v node &> /dev/null; then
|
|
295
|
+
echo ""
|
|
296
|
+
echo "🔗 Creating GitHub issues for user stories..."
|
|
297
|
+
|
|
298
|
+
# ========================================================================
|
|
299
|
+
# LOCATE CONSOLIDATED SYNC SCRIPT
|
|
300
|
+
# ========================================================================
|
|
301
|
+
# Find consolidated-sync.js in order of preference:
|
|
302
|
+
# 1. In-place compiled (development, esbuild output)
|
|
303
|
+
# 2. Local dist (development, tsc output)
|
|
304
|
+
# 3. node_modules (installed as dependency) ← USER PROJECTS
|
|
305
|
+
# 4. Plugin marketplace (Claude Code global installation)
|
|
306
|
+
|
|
307
|
+
CONSOLIDATED_SCRIPT=""
|
|
308
|
+
if [ -f "$PROJECT_ROOT/plugins/specweave/lib/hooks/consolidated-sync.js" ]; then
|
|
309
|
+
# Development: Use in-place compiled hooks (esbuild, not tsc)
|
|
310
|
+
CONSOLIDATED_SCRIPT="$PROJECT_ROOT/plugins/specweave/lib/hooks/consolidated-sync.js"
|
|
311
|
+
echo " 🔧 Using in-place compiled hook (development mode)"
|
|
312
|
+
elif [ -f "$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/consolidated-sync.js" ]; then
|
|
313
|
+
# Development: Use project's compiled files (has node_modules)
|
|
314
|
+
CONSOLIDATED_SCRIPT="$PROJECT_ROOT/dist/plugins/specweave/lib/hooks/consolidated-sync.js"
|
|
315
|
+
echo " 🔧 Using local dist (development mode)"
|
|
316
|
+
elif [ -f "$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/consolidated-sync.js" ]; then
|
|
317
|
+
# Installed as dependency: Use node_modules version (MOST USER PROJECTS)
|
|
318
|
+
CONSOLIDATED_SCRIPT="$PROJECT_ROOT/node_modules/specweave/dist/plugins/specweave/lib/hooks/consolidated-sync.js"
|
|
319
|
+
echo " 📦 Using node_modules version"
|
|
320
|
+
elif [ -n "${CLAUDE_PLUGIN_ROOT}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/lib/hooks/consolidated-sync.js" ]; then
|
|
321
|
+
# Fallback: Plugin marketplace (may fail if deps missing)
|
|
322
|
+
CONSOLIDATED_SCRIPT="${CLAUDE_PLUGIN_ROOT}/lib/hooks/consolidated-sync.js"
|
|
323
|
+
echo " 🌐 Using plugin marketplace version"
|
|
324
|
+
fi
|
|
325
|
+
|
|
326
|
+
# ========================================================================
|
|
327
|
+
# EXECUTE GITHUB SYNC
|
|
328
|
+
# ========================================================================
|
|
329
|
+
# Run consolidated sync to create GitHub issues and sync task completion.
|
|
330
|
+
# Non-blocking: Errors logged but don't crash hook (increment already closed)
|
|
331
|
+
#
|
|
332
|
+
# CRITICAL: Do NOT set SKIP_GITHUB_SYNC=true here!
|
|
333
|
+
# That flag is ONLY for post-task-completion hook to prevent duplicate comments.
|
|
334
|
+
# On increment completion, we WANT GitHub sync to run.
|
|
335
|
+
|
|
336
|
+
if [ -n "$CONSOLIDATED_SCRIPT" ]; then
|
|
337
|
+
# Load GITHUB_TOKEN from .env for gh CLI authentication
|
|
338
|
+
if [ -f "$PROJECT_ROOT/.env" ]; then
|
|
339
|
+
# Extract GITHUB_TOKEN from .env (handles various formats)
|
|
340
|
+
GITHUB_TOKEN_FROM_ENV=$(grep -E '^GITHUB_TOKEN=' "$PROJECT_ROOT/.env" 2>/dev/null | head -1 | cut -d'=' -f2- | sed 's/^["'\'']//' | sed 's/["'\'']$//')
|
|
341
|
+
if [ -n "$GITHUB_TOKEN_FROM_ENV" ]; then
|
|
342
|
+
export GITHUB_TOKEN="$GITHUB_TOKEN_FROM_ENV"
|
|
343
|
+
echo " 🔑 GitHub token loaded from .env"
|
|
344
|
+
fi
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
# Run consolidated sync (synchronous - user sees immediate feedback)
|
|
348
|
+
# This creates GitHub issues, syncs comments, and performs format preservation
|
|
349
|
+
if (cd "$PROJECT_ROOT" && node "$CONSOLIDATED_SCRIPT" "$INCREMENT_ID") 2>&1; then
|
|
350
|
+
echo " ✅ GitHub sync complete"
|
|
351
|
+
echo ""
|
|
352
|
+
else
|
|
353
|
+
echo " ⚠️ Failed to sync GitHub issues (non-blocking - you can run /specweave-github:sync manually)" >&2
|
|
354
|
+
echo " 💡 Check that sync.github.enabled=true in .specweave/config.json" >&2
|
|
355
|
+
echo ""
|
|
356
|
+
fi
|
|
357
|
+
else
|
|
358
|
+
echo " ⚠️ consolidated-sync.js not found in any location - skipping GitHub sync" >&2
|
|
359
|
+
echo " 💡 To manually sync: /specweave-github:sync" >&2
|
|
360
|
+
echo ""
|
|
361
|
+
fi
|
|
362
|
+
else
|
|
363
|
+
echo ""
|
|
364
|
+
echo " ⚠️ Node.js not found - skipping GitHub sync" >&2
|
|
365
|
+
echo " 💡 Install Node.js to enable automatic GitHub sync" >&2
|
|
366
|
+
echo ""
|
|
367
|
+
fi
|
|
368
|
+
|
|
236
369
|
exit 0
|
|
@@ -22,12 +22,7 @@
|
|
|
22
22
|
# EMERGENCY FIX v0.24.3: Remove set -e - it causes Claude Code crashes!
|
|
23
23
|
set +e
|
|
24
24
|
|
|
25
|
-
#
|
|
26
|
-
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
27
|
-
exit 0
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
# Find project root
|
|
25
|
+
# Find project root (must be BEFORE recursion guard to get PROJECT_ROOT)
|
|
31
26
|
find_project_root() {
|
|
32
27
|
local dir="$PWD"
|
|
33
28
|
while [[ "$dir" != "/" ]]; do
|
|
@@ -45,27 +40,71 @@ LOGS_DIR="$PROJECT_ROOT/.specweave/logs"
|
|
|
45
40
|
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
46
41
|
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
47
42
|
|
|
48
|
-
#
|
|
49
|
-
|
|
43
|
+
# ============================================================================
|
|
44
|
+
# RECURSION PREVENTION (CRITICAL - v0.26.0 - FILE-BASED GUARD)
|
|
45
|
+
# ============================================================================
|
|
46
|
+
# NEW SOLUTION (v0.26.0): File-based recursion guard
|
|
47
|
+
# See: ADR-0073 (Hook Recursion Prevention Strategy)
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
MODIFIED_FILE=""
|
|
49
|
+
RECURSION_GUARD_FILE="$PROJECT_ROOT/.specweave/state/.hook-recursion-guard"
|
|
53
50
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
if [[ -f "$RECURSION_GUARD_FILE" ]]; then
|
|
52
|
+
# Silent exit - we're already inside a hook chain
|
|
53
|
+
exit 0
|
|
57
54
|
fi
|
|
58
55
|
|
|
59
|
-
#
|
|
60
|
-
if [[
|
|
61
|
-
|
|
56
|
+
# EMERGENCY KILL SWITCH
|
|
57
|
+
if [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]]; then
|
|
58
|
+
exit 0
|
|
62
59
|
fi
|
|
63
60
|
|
|
64
|
-
#
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
# Ensure logs directory exists
|
|
62
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
63
|
+
|
|
64
|
+
# ============================================================================
|
|
65
|
+
# READ STDIN (v0.26.1 - CRITICAL FIX)
|
|
66
|
+
# ============================================================================
|
|
67
|
+
# PostToolUse hooks receive JSON data from Claude Code via STDIN, NOT env vars!
|
|
68
|
+
# This was the critical bug: hook was looking for environment variables that don't exist.
|
|
69
|
+
#
|
|
70
|
+
# Example STDIN data:
|
|
71
|
+
# {"tool": "Edit", "tool_input": {"file_path": "/path/to/file.md", ...}}
|
|
72
|
+
# {"tool": "Write", "tool_input": {"file_path": "/path/to/file.md", ...}}
|
|
73
|
+
|
|
74
|
+
STDIN_DATA=$(mktemp)
|
|
75
|
+
cat > "$STDIN_DATA"
|
|
76
|
+
|
|
77
|
+
echo "[$(date)] post-metadata-change: Hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
78
|
+
echo "[$(date)] Input JSON:" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
79
|
+
cat "$STDIN_DATA" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
80
|
+
echo "" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
81
|
+
|
|
82
|
+
# ============================================================================
|
|
83
|
+
# EARLY EXIT OPTIMIZATION (v0.25.0): Ultra-Fast Rejection of Non-Metadata Changes
|
|
84
|
+
# ============================================================================
|
|
85
|
+
# This hook should ONLY run for metadata.json changes.
|
|
86
|
+
# 99.9% of Edit/Write operations are NOT metadata.json.
|
|
87
|
+
# Do fastest possible check first to minimize overhead.
|
|
88
|
+
|
|
89
|
+
# Quick check: If STDIN doesn't contain "metadata.json", exit immediately
|
|
90
|
+
if ! grep -q "metadata\.json" "$STDIN_DATA" 2>/dev/null; then
|
|
91
|
+
echo "[$(date)] post-metadata-change: Not metadata.json - exiting" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
92
|
+
rm -f "$STDIN_DATA"
|
|
93
|
+
exit 0 # Fast path: Not metadata.json
|
|
67
94
|
fi
|
|
68
95
|
|
|
96
|
+
echo "[$(date)] post-metadata-change: metadata.json detected in input" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
97
|
+
|
|
98
|
+
# ============================================================================
|
|
99
|
+
# EXTRACT FILE PATH FROM STDIN JSON
|
|
100
|
+
# ============================================================================
|
|
101
|
+
|
|
102
|
+
# Parse file_path from JSON (handles both Edit and Write tool formats)
|
|
103
|
+
MODIFIED_FILE=$(grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' "$STDIN_DATA" | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "")
|
|
104
|
+
|
|
105
|
+
# Clean up temp file
|
|
106
|
+
rm -f "$STDIN_DATA"
|
|
107
|
+
|
|
69
108
|
echo "[$(date)] post-metadata-change: Detected file: ${MODIFIED_FILE:-<none>}" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
70
109
|
|
|
71
110
|
# Check if this is a metadata.json change in an increment folder
|