@planu/cli 0.63.7 → 0.64.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/dist/config/license-plans.json +16 -1
- package/dist/engine/a2a/capability-card.d.ts +16 -0
- package/dist/engine/a2a/capability-card.d.ts.map +1 -0
- package/dist/engine/a2a/capability-card.js +69 -0
- package/dist/engine/a2a/capability-card.js.map +1 -0
- package/dist/engine/a2a/delegate.d.ts +15 -0
- package/dist/engine/a2a/delegate.d.ts.map +1 -0
- package/dist/engine/a2a/delegate.js +47 -0
- package/dist/engine/a2a/delegate.js.map +1 -0
- package/dist/engine/a2a/fallback.d.ts +12 -0
- package/dist/engine/a2a/fallback.d.ts.map +1 -0
- package/dist/engine/a2a/fallback.js +52 -0
- package/dist/engine/a2a/fallback.js.map +1 -0
- package/dist/engine/a2a/index.d.ts +5 -0
- package/dist/engine/a2a/index.d.ts.map +1 -0
- package/dist/engine/a2a/index.js +6 -0
- package/dist/engine/a2a/index.js.map +1 -0
- package/dist/engine/a2a/task-manager.d.ts +39 -0
- package/dist/engine/a2a/task-manager.d.ts.map +1 -0
- package/dist/engine/a2a/task-manager.js +84 -0
- package/dist/engine/a2a/task-manager.js.map +1 -0
- package/dist/engine/ac-gap-detector/analyze-gaps.d.ts +13 -0
- package/dist/engine/ac-gap-detector/analyze-gaps.d.ts.map +1 -0
- package/dist/engine/ac-gap-detector/analyze-gaps.js +43 -0
- package/dist/engine/ac-gap-detector/analyze-gaps.js.map +1 -0
- package/dist/engine/ac-gap-detector/constants.d.ts +22 -0
- package/dist/engine/ac-gap-detector/constants.d.ts.map +1 -0
- package/dist/engine/ac-gap-detector/constants.js +143 -0
- package/dist/engine/ac-gap-detector/constants.js.map +1 -0
- package/dist/engine/ac-gap-detector/gap-rules.d.ts +16 -0
- package/dist/engine/ac-gap-detector/gap-rules.d.ts.map +1 -0
- package/dist/engine/ac-gap-detector/gap-rules.js +180 -0
- package/dist/engine/ac-gap-detector/gap-rules.js.map +1 -0
- package/dist/engine/ac-gap-detector/pattern-matcher.d.ts +16 -0
- package/dist/engine/ac-gap-detector/pattern-matcher.d.ts.map +1 -0
- package/dist/engine/ac-gap-detector/pattern-matcher.js +62 -0
- package/dist/engine/ac-gap-detector/pattern-matcher.js.map +1 -0
- package/dist/engine/ac-gap-detector.d.ts +3 -0
- package/dist/engine/ac-gap-detector.d.ts.map +1 -0
- package/dist/engine/ac-gap-detector.js +5 -0
- package/dist/engine/ac-gap-detector.js.map +1 -0
- package/dist/engine/audit-trail/attestation.d.ts +11 -0
- package/dist/engine/audit-trail/attestation.d.ts.map +1 -0
- package/dist/engine/audit-trail/attestation.js +47 -0
- package/dist/engine/audit-trail/attestation.js.map +1 -0
- package/dist/engine/audit-trail/index.d.ts +6 -0
- package/dist/engine/audit-trail/index.d.ts.map +1 -0
- package/dist/engine/audit-trail/index.js +6 -0
- package/dist/engine/audit-trail/index.js.map +1 -0
- package/dist/engine/audit-trail/logger.d.ts +17 -0
- package/dist/engine/audit-trail/logger.d.ts.map +1 -0
- package/dist/engine/audit-trail/logger.js +78 -0
- package/dist/engine/audit-trail/logger.js.map +1 -0
- package/dist/engine/audit-trail/query.d.ts +7 -0
- package/dist/engine/audit-trail/query.d.ts.map +1 -0
- package/dist/engine/audit-trail/query.js +61 -0
- package/dist/engine/audit-trail/query.js.map +1 -0
- package/dist/engine/audit-trail/utils.d.ts +18 -0
- package/dist/engine/audit-trail/utils.d.ts.map +1 -0
- package/dist/engine/audit-trail/utils.js +44 -0
- package/dist/engine/audit-trail/utils.js.map +1 -0
- package/dist/engine/audit-trail/verifier.d.ts +10 -0
- package/dist/engine/audit-trail/verifier.d.ts.map +1 -0
- package/dist/engine/audit-trail/verifier.js +78 -0
- package/dist/engine/audit-trail/verifier.js.map +1 -0
- package/dist/engine/auth/config.d.ts +20 -0
- package/dist/engine/auth/config.d.ts.map +1 -0
- package/dist/engine/auth/config.js +49 -0
- package/dist/engine/auth/config.js.map +1 -0
- package/dist/engine/auth/index.d.ts +6 -0
- package/dist/engine/auth/index.d.ts.map +1 -0
- package/dist/engine/auth/index.js +7 -0
- package/dist/engine/auth/index.js.map +1 -0
- package/dist/engine/auth/middleware.d.ts +19 -0
- package/dist/engine/auth/middleware.d.ts.map +1 -0
- package/dist/engine/auth/middleware.js +64 -0
- package/dist/engine/auth/middleware.js.map +1 -0
- package/dist/engine/auth/pkce.d.ts +17 -0
- package/dist/engine/auth/pkce.d.ts.map +1 -0
- package/dist/engine/auth/pkce.js +33 -0
- package/dist/engine/auth/pkce.js.map +1 -0
- package/dist/engine/auth/scope-mapper.d.ts +21 -0
- package/dist/engine/auth/scope-mapper.d.ts.map +1 -0
- package/dist/engine/auth/scope-mapper.js +124 -0
- package/dist/engine/auth/scope-mapper.js.map +1 -0
- package/dist/engine/auth/token-validator.d.ts +15 -0
- package/dist/engine/auth/token-validator.d.ts.map +1 -0
- package/dist/engine/auth/token-validator.js +121 -0
- package/dist/engine/auth/token-validator.js.map +1 -0
- package/dist/engine/ci-generator/index.d.ts.map +1 -1
- package/dist/engine/ci-generator/index.js +8 -2
- package/dist/engine/ci-generator/index.js.map +1 -1
- package/dist/engine/ci-generator/yaml-builder.d.ts +7 -2
- package/dist/engine/ci-generator/yaml-builder.d.ts.map +1 -1
- package/dist/engine/ci-generator/yaml-builder.js +49 -1
- package/dist/engine/ci-generator/yaml-builder.js.map +1 -1
- package/dist/engine/design-to-spec/ac-generator.d.ts +21 -0
- package/dist/engine/design-to-spec/ac-generator.d.ts.map +1 -0
- package/dist/engine/design-to-spec/ac-generator.js +185 -0
- package/dist/engine/design-to-spec/ac-generator.js.map +1 -0
- package/dist/engine/design-to-spec/index.d.ts +11 -0
- package/dist/engine/design-to-spec/index.d.ts.map +1 -0
- package/dist/engine/design-to-spec/index.js +19 -0
- package/dist/engine/design-to-spec/index.js.map +1 -0
- package/dist/engine/design-to-spec/parser.d.ts +7 -0
- package/dist/engine/design-to-spec/parser.d.ts.map +1 -0
- package/dist/engine/design-to-spec/parser.js +290 -0
- package/dist/engine/design-to-spec/parser.js.map +1 -0
- package/dist/engine/design-to-spec/spec-builder.d.ts +12 -0
- package/dist/engine/design-to-spec/spec-builder.d.ts.map +1 -0
- package/dist/engine/design-to-spec/spec-builder.js +148 -0
- package/dist/engine/design-to-spec/spec-builder.js.map +1 -0
- package/dist/engine/design-to-spec/ui-contract-builder.d.ts +17 -0
- package/dist/engine/design-to-spec/ui-contract-builder.d.ts.map +1 -0
- package/dist/engine/design-to-spec/ui-contract-builder.js +175 -0
- package/dist/engine/design-to-spec/ui-contract-builder.js.map +1 -0
- package/dist/engine/elicitation/builder.d.ts +37 -0
- package/dist/engine/elicitation/builder.d.ts.map +1 -0
- package/dist/engine/elicitation/builder.js +115 -0
- package/dist/engine/elicitation/builder.js.map +1 -0
- package/dist/engine/elicitation/fallback.d.ts +20 -0
- package/dist/engine/elicitation/fallback.d.ts.map +1 -0
- package/dist/engine/elicitation/fallback.js +72 -0
- package/dist/engine/elicitation/fallback.js.map +1 -0
- package/dist/engine/elicitation/index.d.ts +4 -0
- package/dist/engine/elicitation/index.d.ts.map +1 -0
- package/dist/engine/elicitation/index.js +5 -0
- package/dist/engine/elicitation/index.js.map +1 -0
- package/dist/engine/elicitation/response-parser.d.ts +9 -0
- package/dist/engine/elicitation/response-parser.d.ts.map +1 -0
- package/dist/engine/elicitation/response-parser.js +163 -0
- package/dist/engine/elicitation/response-parser.js.map +1 -0
- package/dist/engine/federation/cross-repo-resolver.d.ts +21 -0
- package/dist/engine/federation/cross-repo-resolver.d.ts.map +1 -0
- package/dist/engine/federation/cross-repo-resolver.js +75 -0
- package/dist/engine/federation/cross-repo-resolver.js.map +1 -0
- package/dist/engine/federation/drift-checker.d.ts +19 -0
- package/dist/engine/federation/drift-checker.d.ts.map +1 -0
- package/dist/engine/federation/drift-checker.js +114 -0
- package/dist/engine/federation/drift-checker.js.map +1 -0
- package/dist/engine/federation/federation-store.d.ts +25 -0
- package/dist/engine/federation/federation-store.d.ts.map +1 -0
- package/dist/engine/federation/federation-store.js +58 -0
- package/dist/engine/federation/federation-store.js.map +1 -0
- package/dist/engine/federation/index.d.ts +4 -0
- package/dist/engine/federation/index.d.ts.map +1 -0
- package/dist/engine/federation/index.js +5 -0
- package/dist/engine/federation/index.js.map +1 -0
- package/dist/engine/github/spec-ac-analyzer.d.ts +40 -0
- package/dist/engine/github/spec-ac-analyzer.d.ts.map +1 -0
- package/dist/engine/github/spec-ac-analyzer.js +181 -0
- package/dist/engine/github/spec-ac-analyzer.js.map +1 -0
- package/dist/engine/hooks/handlers/on-impl-change.d.ts +3 -1
- package/dist/engine/hooks/handlers/on-impl-change.d.ts.map +1 -1
- package/dist/engine/hooks/handlers/on-impl-change.js +25 -1
- package/dist/engine/hooks/handlers/on-impl-change.js.map +1 -1
- package/dist/engine/infrastructure/component-mapper.d.ts +9 -0
- package/dist/engine/infrastructure/component-mapper.d.ts.map +1 -0
- package/dist/engine/infrastructure/component-mapper.js +162 -0
- package/dist/engine/infrastructure/component-mapper.js.map +1 -0
- package/dist/engine/infrastructure/cost-estimator.d.ts +6 -0
- package/dist/engine/infrastructure/cost-estimator.d.ts.map +1 -0
- package/dist/engine/infrastructure/cost-estimator.js +48 -0
- package/dist/engine/infrastructure/cost-estimator.js.map +1 -0
- package/dist/engine/infrastructure/docker-compose-generator.d.ts +6 -0
- package/dist/engine/infrastructure/docker-compose-generator.d.ts.map +1 -0
- package/dist/engine/infrastructure/docker-compose-generator.js +201 -0
- package/dist/engine/infrastructure/docker-compose-generator.js.map +1 -0
- package/dist/engine/infrastructure/index.d.ts +15 -0
- package/dist/engine/infrastructure/index.d.ts.map +1 -0
- package/dist/engine/infrastructure/index.js +67 -0
- package/dist/engine/infrastructure/index.js.map +1 -0
- package/dist/engine/infrastructure/kubernetes-generator.d.ts +6 -0
- package/dist/engine/infrastructure/kubernetes-generator.d.ts.map +1 -0
- package/dist/engine/infrastructure/kubernetes-generator.js +141 -0
- package/dist/engine/infrastructure/kubernetes-generator.js.map +1 -0
- package/dist/engine/infrastructure/railway-generator.d.ts +6 -0
- package/dist/engine/infrastructure/railway-generator.d.ts.map +1 -0
- package/dist/engine/infrastructure/railway-generator.js +87 -0
- package/dist/engine/infrastructure/railway-generator.js.map +1 -0
- package/dist/engine/infrastructure/signal-detector.d.ts +7 -0
- package/dist/engine/infrastructure/signal-detector.d.ts.map +1 -0
- package/dist/engine/infrastructure/signal-detector.js +174 -0
- package/dist/engine/infrastructure/signal-detector.js.map +1 -0
- package/dist/engine/infrastructure/terraform-generator.d.ts +6 -0
- package/dist/engine/infrastructure/terraform-generator.d.ts.map +1 -0
- package/dist/engine/infrastructure/terraform-generator.js +241 -0
- package/dist/engine/infrastructure/terraform-generator.js.map +1 -0
- package/dist/engine/living-spec/annotation-parser.d.ts.map +1 -1
- package/dist/engine/living-spec/annotation-parser.js.map +1 -1
- package/dist/engine/living-spec/auto-updater.d.ts +58 -0
- package/dist/engine/living-spec/auto-updater.d.ts.map +1 -0
- package/dist/engine/living-spec/auto-updater.js +311 -0
- package/dist/engine/living-spec/auto-updater.js.map +1 -0
- package/dist/engine/living-spec/conflict-resolver.d.ts +46 -0
- package/dist/engine/living-spec/conflict-resolver.d.ts.map +1 -0
- package/dist/engine/living-spec/conflict-resolver.js +301 -0
- package/dist/engine/living-spec/conflict-resolver.js.map +1 -0
- package/dist/engine/living-spec/hash-tracker.d.ts.map +1 -1
- package/dist/engine/living-spec/hash-tracker.js.map +1 -1
- package/dist/engine/living-spec/index.d.ts +1 -0
- package/dist/engine/living-spec/index.d.ts.map +1 -1
- package/dist/engine/living-spec/index.js +1 -0
- package/dist/engine/living-spec/index.js.map +1 -1
- package/dist/engine/living-spec/signature-tracker.d.ts.map +1 -1
- package/dist/engine/living-spec/signature-tracker.js.map +1 -1
- package/dist/engine/observability/config.d.ts +16 -0
- package/dist/engine/observability/config.d.ts.map +1 -0
- package/dist/engine/observability/config.js +44 -0
- package/dist/engine/observability/config.js.map +1 -0
- package/dist/engine/observability/index.d.ts +7 -0
- package/dist/engine/observability/index.d.ts.map +1 -0
- package/dist/engine/observability/index.js +8 -0
- package/dist/engine/observability/index.js.map +1 -0
- package/dist/engine/observability/metrics.d.ts +12 -0
- package/dist/engine/observability/metrics.d.ts.map +1 -0
- package/dist/engine/observability/metrics.js +61 -0
- package/dist/engine/observability/metrics.js.map +1 -0
- package/dist/engine/observability/noop-tracer.d.ts +13 -0
- package/dist/engine/observability/noop-tracer.d.ts.map +1 -0
- package/dist/engine/observability/noop-tracer.js +41 -0
- package/dist/engine/observability/noop-tracer.js.map +1 -0
- package/dist/engine/observability/otel-tracer.d.ts +19 -0
- package/dist/engine/observability/otel-tracer.d.ts.map +1 -0
- package/dist/engine/observability/otel-tracer.js +134 -0
- package/dist/engine/observability/otel-tracer.js.map +1 -0
- package/dist/engine/observability/span-helpers.d.ts +28 -0
- package/dist/engine/observability/span-helpers.d.ts.map +1 -0
- package/dist/engine/observability/span-helpers.js +68 -0
- package/dist/engine/observability/span-helpers.js.map +1 -0
- package/dist/engine/observability/tracer.d.ts +26 -0
- package/dist/engine/observability/tracer.d.ts.map +1 -0
- package/dist/engine/observability/tracer.js +45 -0
- package/dist/engine/observability/tracer.js.map +1 -0
- package/dist/engine/rbac/index.d.ts +3 -0
- package/dist/engine/rbac/index.d.ts.map +1 -0
- package/dist/engine/rbac/index.js +4 -0
- package/dist/engine/rbac/index.js.map +1 -0
- package/dist/engine/rbac/permission-checker.d.ts +21 -0
- package/dist/engine/rbac/permission-checker.d.ts.map +1 -0
- package/dist/engine/rbac/permission-checker.js +74 -0
- package/dist/engine/rbac/permission-checker.js.map +1 -0
- package/dist/engine/rbac/roles.d.ts +12 -0
- package/dist/engine/rbac/roles.d.ts.map +1 -0
- package/dist/engine/rbac/roles.js +37 -0
- package/dist/engine/rbac/roles.js.map +1 -0
- package/dist/engine/shared/ac-extractor.d.ts +9 -0
- package/dist/engine/shared/ac-extractor.d.ts.map +1 -0
- package/dist/engine/shared/ac-extractor.js +36 -0
- package/dist/engine/shared/ac-extractor.js.map +1 -0
- package/dist/engine/shared/line-diff.d.ts +11 -0
- package/dist/engine/shared/line-diff.d.ts.map +1 -0
- package/dist/engine/shared/line-diff.js +32 -0
- package/dist/engine/shared/line-diff.js.map +1 -0
- package/dist/engine/spec-decomposer/analyzer.d.ts +18 -0
- package/dist/engine/spec-decomposer/analyzer.d.ts.map +1 -0
- package/dist/engine/spec-decomposer/analyzer.js +263 -0
- package/dist/engine/spec-decomposer/analyzer.js.map +1 -0
- package/dist/engine/spec-decomposer/file-mapper.d.ts +17 -0
- package/dist/engine/spec-decomposer/file-mapper.d.ts.map +1 -0
- package/dist/engine/spec-decomposer/file-mapper.js +96 -0
- package/dist/engine/spec-decomposer/file-mapper.js.map +1 -0
- package/dist/engine/spec-decomposer/index.d.ts +14 -0
- package/dist/engine/spec-decomposer/index.d.ts.map +1 -0
- package/dist/engine/spec-decomposer/index.js +50 -0
- package/dist/engine/spec-decomposer/index.js.map +1 -0
- package/dist/engine/spec-decomposer/ownership-resolver.d.ts +7 -0
- package/dist/engine/spec-decomposer/ownership-resolver.d.ts.map +1 -0
- package/dist/engine/spec-decomposer/ownership-resolver.js +169 -0
- package/dist/engine/spec-decomposer/ownership-resolver.js.map +1 -0
- package/dist/engine/spec-observability/index.d.ts +4 -0
- package/dist/engine/spec-observability/index.d.ts.map +1 -0
- package/dist/engine/spec-observability/index.js +4 -0
- package/dist/engine/spec-observability/index.js.map +1 -0
- package/dist/engine/spec-observability/metrics.d.ts +8 -0
- package/dist/engine/spec-observability/metrics.d.ts.map +1 -0
- package/dist/engine/spec-observability/metrics.js +116 -0
- package/dist/engine/spec-observability/metrics.js.map +1 -0
- package/dist/engine/spec-observability/tracker.d.ts +22 -0
- package/dist/engine/spec-observability/tracker.d.ts.map +1 -0
- package/dist/engine/spec-observability/tracker.js +77 -0
- package/dist/engine/spec-observability/tracker.js.map +1 -0
- package/dist/engine/spec-reader.d.ts +7 -0
- package/dist/engine/spec-reader.d.ts.map +1 -0
- package/dist/engine/spec-reader.js +23 -0
- package/dist/engine/spec-reader.js.map +1 -0
- package/dist/engine/spec-repair.d.ts +10 -0
- package/dist/engine/spec-repair.d.ts.map +1 -0
- package/dist/engine/spec-repair.js +388 -0
- package/dist/engine/spec-repair.js.map +1 -0
- package/dist/engine/spec-versioning/brancher.d.ts +17 -0
- package/dist/engine/spec-versioning/brancher.d.ts.map +1 -0
- package/dist/engine/spec-versioning/brancher.js +113 -0
- package/dist/engine/spec-versioning/brancher.js.map +1 -0
- package/dist/engine/spec-versioning/differ.d.ts +19 -0
- package/dist/engine/spec-versioning/differ.d.ts.map +1 -0
- package/dist/engine/spec-versioning/differ.js +151 -0
- package/dist/engine/spec-versioning/differ.js.map +1 -0
- package/dist/engine/spec-versioning/index.d.ts +5 -0
- package/dist/engine/spec-versioning/index.d.ts.map +1 -0
- package/dist/engine/spec-versioning/index.js +6 -0
- package/dist/engine/spec-versioning/index.js.map +1 -0
- package/dist/engine/spec-versioning/merger.d.ts +18 -0
- package/dist/engine/spec-versioning/merger.d.ts.map +1 -0
- package/dist/engine/spec-versioning/merger.js +113 -0
- package/dist/engine/spec-versioning/merger.js.map +1 -0
- package/dist/engine/spec-versioning/version-store.d.ts +18 -0
- package/dist/engine/spec-versioning/version-store.d.ts.map +1 -0
- package/dist/engine/spec-versioning/version-store.js +96 -0
- package/dist/engine/spec-versioning/version-store.js.map +1 -0
- package/dist/engine/well-known/discovery.d.ts +7 -0
- package/dist/engine/well-known/discovery.d.ts.map +1 -0
- package/dist/engine/well-known/discovery.js +109 -0
- package/dist/engine/well-known/discovery.js.map +1 -0
- package/dist/engine/well-known/index.d.ts +6 -0
- package/dist/engine/well-known/index.d.ts.map +1 -0
- package/dist/engine/well-known/index.js +5 -0
- package/dist/engine/well-known/index.js.map +1 -0
- package/dist/engine/well-known/manifest-generator.d.ts +7 -0
- package/dist/engine/well-known/manifest-generator.d.ts.map +1 -0
- package/dist/engine/well-known/manifest-generator.js +60 -0
- package/dist/engine/well-known/manifest-generator.js.map +1 -0
- package/dist/engine/well-known/manifest-schema.d.ts +92 -0
- package/dist/engine/well-known/manifest-schema.d.ts.map +1 -0
- package/dist/engine/well-known/manifest-schema.js +70 -0
- package/dist/engine/well-known/manifest-schema.js.map +1 -0
- package/dist/resources/spec-granular.d.ts +33 -0
- package/dist/resources/spec-granular.d.ts.map +1 -0
- package/dist/resources/spec-granular.js +299 -0
- package/dist/resources/spec-granular.js.map +1 -0
- package/dist/storage/federation-store.d.ts +29 -0
- package/dist/storage/federation-store.d.ts.map +1 -0
- package/dist/storage/federation-store.js +111 -0
- package/dist/storage/federation-store.js.map +1 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/rbac-store.d.ts +8 -0
- package/dist/storage/rbac-store.d.ts.map +1 -0
- package/dist/storage/rbac-store.js +75 -0
- package/dist/storage/rbac-store.js.map +1 -0
- package/dist/storage/spec-observability-store.d.ts +16 -0
- package/dist/storage/spec-observability-store.d.ts.map +1 -0
- package/dist/storage/spec-observability-store.js +55 -0
- package/dist/storage/spec-observability-store.js.map +1 -0
- package/dist/tools/a2a-handler.d.ts +14 -0
- package/dist/tools/a2a-handler.d.ts.map +1 -0
- package/dist/tools/a2a-handler.js +100 -0
- package/dist/tools/a2a-handler.js.map +1 -0
- package/dist/tools/assign-role-handler.d.ts +3 -0
- package/dist/tools/assign-role-handler.d.ts.map +1 -0
- package/dist/tools/assign-role-handler.js +25 -0
- package/dist/tools/assign-role-handler.js.map +1 -0
- package/dist/tools/audit-trail-handler.d.ts +4 -0
- package/dist/tools/audit-trail-handler.d.ts.map +1 -0
- package/dist/tools/audit-trail-handler.js +91 -0
- package/dist/tools/audit-trail-handler.js.map +1 -0
- package/dist/tools/auto-update-spec.d.ts +3 -0
- package/dist/tools/auto-update-spec.d.ts.map +1 -0
- package/dist/tools/auto-update-spec.js +43 -0
- package/dist/tools/auto-update-spec.js.map +1 -0
- package/dist/tools/branch-spec.d.ts +3 -0
- package/dist/tools/branch-spec.d.ts.map +1 -0
- package/dist/tools/branch-spec.js +68 -0
- package/dist/tools/branch-spec.js.map +1 -0
- package/dist/tools/configure-auth-handler.d.ts +15 -0
- package/dist/tools/configure-auth-handler.d.ts.map +1 -0
- package/dist/tools/configure-auth-handler.js +113 -0
- package/dist/tools/configure-auth-handler.js.map +1 -0
- package/dist/tools/configure-observability.d.ts +14 -0
- package/dist/tools/configure-observability.d.ts.map +1 -0
- package/dist/tools/configure-observability.js +96 -0
- package/dist/tools/configure-observability.js.map +1 -0
- package/dist/tools/configure-roles-handler.d.ts +4 -0
- package/dist/tools/configure-roles-handler.d.ts.map +1 -0
- package/dist/tools/configure-roles-handler.js +36 -0
- package/dist/tools/configure-roles-handler.js.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/architecture-adapter.d.ts +7 -0
- package/dist/tools/create-spec-hu/ac-adapters/architecture-adapter.d.ts.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/architecture-adapter.js +114 -0
- package/dist/tools/create-spec-hu/ac-adapters/architecture-adapter.js.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/database-adapter.d.ts +7 -0
- package/dist/tools/create-spec-hu/ac-adapters/database-adapter.d.ts.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/database-adapter.js +48 -0
- package/dist/tools/create-spec-hu/ac-adapters/database-adapter.js.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/index.d.ts +14 -0
- package/dist/tools/create-spec-hu/ac-adapters/index.d.ts.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/index.js +28 -0
- package/dist/tools/create-spec-hu/ac-adapters/index.js.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/stack-adapter.d.ts +7 -0
- package/dist/tools/create-spec-hu/ac-adapters/stack-adapter.d.ts.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/stack-adapter.js +99 -0
- package/dist/tools/create-spec-hu/ac-adapters/stack-adapter.js.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/testing-adapter.d.ts +7 -0
- package/dist/tools/create-spec-hu/ac-adapters/testing-adapter.d.ts.map +1 -0
- package/dist/tools/create-spec-hu/ac-adapters/testing-adapter.js +62 -0
- package/dist/tools/create-spec-hu/ac-adapters/testing-adapter.js.map +1 -0
- package/dist/tools/create-spec-hu/hu-body-generators.d.ts.map +1 -1
- package/dist/tools/create-spec-hu/hu-body-generators.js +41 -19
- package/dist/tools/create-spec-hu/hu-body-generators.js.map +1 -1
- package/dist/tools/create-spec-tech/ficha-content.d.ts.map +1 -1
- package/dist/tools/create-spec-tech/ficha-content.js +235 -5
- package/dist/tools/create-spec-tech/ficha-content.js.map +1 -1
- package/dist/tools/decompose-spec.d.ts +7 -0
- package/dist/tools/decompose-spec.d.ts.map +1 -0
- package/dist/tools/decompose-spec.js +49 -0
- package/dist/tools/decompose-spec.js.map +1 -0
- package/dist/tools/design-to-spec.d.ts +12 -0
- package/dist/tools/design-to-spec.d.ts.map +1 -0
- package/dist/tools/design-to-spec.js +73 -0
- package/dist/tools/design-to-spec.js.map +1 -0
- package/dist/tools/detect-ac-gaps.d.ts +7 -0
- package/dist/tools/detect-ac-gaps.d.ts.map +1 -0
- package/dist/tools/detect-ac-gaps.js +63 -0
- package/dist/tools/detect-ac-gaps.js.map +1 -0
- package/dist/tools/discover-registry.d.ts +8 -0
- package/dist/tools/discover-registry.d.ts.map +1 -0
- package/dist/tools/discover-registry.js +79 -0
- package/dist/tools/discover-registry.js.map +1 -0
- package/dist/tools/federate-specs.d.ts +6 -0
- package/dist/tools/federate-specs.d.ts.map +1 -0
- package/dist/tools/federate-specs.js +41 -0
- package/dist/tools/federate-specs.js.map +1 -0
- package/dist/tools/federation-status.d.ts +6 -0
- package/dist/tools/federation-status.d.ts.map +1 -0
- package/dist/tools/federation-status.js +56 -0
- package/dist/tools/federation-status.js.map +1 -0
- package/dist/tools/generate-annotations.d.ts.map +1 -1
- package/dist/tools/generate-annotations.js +3 -1
- package/dist/tools/generate-annotations.js.map +1 -1
- package/dist/tools/generate-infrastructure.d.ts +3 -0
- package/dist/tools/generate-infrastructure.d.ts.map +1 -0
- package/dist/tools/generate-infrastructure.js +60 -0
- package/dist/tools/generate-infrastructure.js.map +1 -0
- package/dist/tools/merge-spec-branch.d.ts +3 -0
- package/dist/tools/merge-spec-branch.d.ts.map +1 -0
- package/dist/tools/merge-spec-branch.js +103 -0
- package/dist/tools/merge-spec-branch.js.map +1 -0
- package/dist/tools/publish-registry.d.ts +8 -0
- package/dist/tools/publish-registry.d.ts.map +1 -0
- package/dist/tools/publish-registry.js +76 -0
- package/dist/tools/publish-registry.js.map +1 -0
- package/dist/tools/register-a2a-tools.d.ts +3 -0
- package/dist/tools/register-a2a-tools.d.ts.map +1 -0
- package/dist/tools/register-a2a-tools.js +66 -0
- package/dist/tools/register-a2a-tools.js.map +1 -0
- package/dist/tools/register-audit-trail-tools.d.ts +3 -0
- package/dist/tools/register-audit-trail-tools.d.ts.map +1 -0
- package/dist/tools/register-audit-trail-tools.js +62 -0
- package/dist/tools/register-audit-trail-tools.js.map +1 -0
- package/dist/tools/register-decompose-tools.d.ts +3 -0
- package/dist/tools/register-decompose-tools.d.ts.map +1 -0
- package/dist/tools/register-decompose-tools.js +31 -0
- package/dist/tools/register-decompose-tools.js.map +1 -0
- package/dist/tools/register-federation-tools.d.ts +6 -0
- package/dist/tools/register-federation-tools.d.ts.map +1 -0
- package/dist/tools/register-federation-tools.js +48 -0
- package/dist/tools/register-federation-tools.js.map +1 -0
- package/dist/tools/register-infrastructure-tools.d.ts +3 -0
- package/dist/tools/register-infrastructure-tools.d.ts.map +1 -0
- package/dist/tools/register-infrastructure-tools.js +34 -0
- package/dist/tools/register-infrastructure-tools.js.map +1 -0
- package/dist/tools/register-living-spec-tools.d.ts.map +1 -1
- package/dist/tools/register-living-spec-tools.js +2 -8
- package/dist/tools/register-living-spec-tools.js.map +1 -1
- package/dist/tools/register-observability-tools.d.ts +3 -0
- package/dist/tools/register-observability-tools.d.ts.map +1 -0
- package/dist/tools/register-observability-tools.js +48 -0
- package/dist/tools/register-observability-tools.js.map +1 -0
- package/dist/tools/register-rbac-tools.d.ts +3 -0
- package/dist/tools/register-rbac-tools.d.ts.map +1 -0
- package/dist/tools/register-rbac-tools.js +36 -0
- package/dist/tools/register-rbac-tools.js.map +1 -0
- package/dist/tools/register-spec-observability-tools.d.ts +3 -0
- package/dist/tools/register-spec-observability-tools.d.ts.map +1 -0
- package/dist/tools/register-spec-observability-tools.js +24 -0
- package/dist/tools/register-spec-observability-tools.js.map +1 -0
- package/dist/tools/register-versioning-tools.d.ts +3 -0
- package/dist/tools/register-versioning-tools.d.ts.map +1 -0
- package/dist/tools/register-versioning-tools.js +93 -0
- package/dist/tools/register-versioning-tools.js.map +1 -0
- package/dist/tools/register-well-known-tools.d.ts +3 -0
- package/dist/tools/register-well-known-tools.d.ts.map +1 -0
- package/dist/tools/register-well-known-tools.js +36 -0
- package/dist/tools/register-well-known-tools.js.map +1 -0
- package/dist/tools/repair-spec.d.ts +9 -0
- package/dist/tools/repair-spec.d.ts.map +1 -0
- package/dist/tools/repair-spec.js +93 -0
- package/dist/tools/repair-spec.js.map +1 -0
- package/dist/tools/resolve-spec-conflict.d.ts +7 -0
- package/dist/tools/resolve-spec-conflict.d.ts.map +1 -0
- package/dist/tools/resolve-spec-conflict.js +63 -0
- package/dist/tools/resolve-spec-conflict.js.map +1 -0
- package/dist/tools/response-helpers.d.ts +42 -0
- package/dist/tools/response-helpers.d.ts.map +1 -1
- package/dist/tools/response-helpers.js +29 -0
- package/dist/tools/response-helpers.js.map +1 -1
- package/dist/tools/schemas/auth-schema.d.ts +12 -0
- package/dist/tools/schemas/auth-schema.d.ts.map +1 -0
- package/dist/tools/schemas/auth-schema.js +38 -0
- package/dist/tools/schemas/auth-schema.js.map +1 -0
- package/dist/tools/schemas/rbac.d.ts +26 -0
- package/dist/tools/schemas/rbac.d.ts.map +1 -0
- package/dist/tools/schemas/rbac.js +25 -0
- package/dist/tools/schemas/rbac.js.map +1 -0
- package/dist/tools/schemas/well-known.d.ts +12 -0
- package/dist/tools/schemas/well-known.d.ts.map +1 -0
- package/dist/tools/schemas/well-known.js +31 -0
- package/dist/tools/schemas/well-known.js.map +1 -0
- package/dist/tools/snapshot-spec-hashes.d.ts.map +1 -1
- package/dist/tools/snapshot-spec-hashes.js.map +1 -1
- package/dist/tools/spec-usage-report.d.ts +3 -0
- package/dist/tools/spec-usage-report.d.ts.map +1 -0
- package/dist/tools/spec-usage-report.js +95 -0
- package/dist/tools/spec-usage-report.js.map +1 -0
- package/dist/tools/start-hooks.d.ts.map +1 -1
- package/dist/tools/start-hooks.js +93 -16
- package/dist/tools/start-hooks.js.map +1 -1
- package/dist/tools/version-spec.d.ts +3 -0
- package/dist/tools/version-spec.d.ts.map +1 -0
- package/dist/tools/version-spec.js +54 -0
- package/dist/tools/version-spec.js.map +1 -0
- package/dist/types/a2a.d.ts +125 -0
- package/dist/types/a2a.d.ts.map +1 -0
- package/dist/types/a2a.js +3 -0
- package/dist/types/a2a.js.map +1 -0
- package/dist/types/ac-gap.d.ts +57 -0
- package/dist/types/ac-gap.d.ts.map +1 -0
- package/dist/types/ac-gap.js +3 -0
- package/dist/types/ac-gap.js.map +1 -0
- package/dist/types/audit-trail.d.ts +77 -0
- package/dist/types/audit-trail.d.ts.map +1 -0
- package/dist/types/audit-trail.js +3 -0
- package/dist/types/audit-trail.js.map +1 -0
- package/dist/types/auth.d.ts +82 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +3 -0
- package/dist/types/auth.js.map +1 -0
- package/dist/types/ci.d.ts +10 -25
- package/dist/types/ci.d.ts.map +1 -1
- package/dist/types/design-to-spec.d.ts +89 -0
- package/dist/types/design-to-spec.d.ts.map +1 -0
- package/dist/types/design-to-spec.js +3 -0
- package/dist/types/design-to-spec.js.map +1 -0
- package/dist/types/elicitation.d.ts +109 -0
- package/dist/types/elicitation.d.ts.map +1 -0
- package/dist/types/elicitation.js +3 -0
- package/dist/types/elicitation.js.map +1 -0
- package/dist/types/federation.d.ts +95 -0
- package/dist/types/federation.d.ts.map +1 -0
- package/dist/types/federation.js +3 -0
- package/dist/types/federation.js.map +1 -0
- package/dist/types/file-hooks.d.ts +8 -6
- package/dist/types/file-hooks.d.ts.map +1 -1
- package/dist/types/github.d.ts +17 -0
- package/dist/types/github.d.ts.map +1 -1
- package/dist/types/index.d.ts +16 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +16 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/infrastructure.d.ts +71 -0
- package/dist/types/infrastructure.d.ts.map +1 -0
- package/dist/types/infrastructure.js +3 -0
- package/dist/types/infrastructure.js.map +1 -0
- package/dist/types/living-spec.d.ts +100 -0
- package/dist/types/living-spec.d.ts.map +1 -1
- package/dist/types/observability.d.ts +105 -0
- package/dist/types/observability.d.ts.map +1 -0
- package/dist/types/observability.js +3 -0
- package/dist/types/observability.js.map +1 -0
- package/dist/types/rbac.d.ts +51 -0
- package/dist/types/rbac.d.ts.map +1 -0
- package/dist/types/rbac.js +4 -0
- package/dist/types/rbac.js.map +1 -0
- package/dist/types/resources.d.ts +20 -0
- package/dist/types/resources.d.ts.map +1 -0
- package/dist/types/resources.js +3 -0
- package/dist/types/resources.js.map +1 -0
- package/dist/types/spec/repair.d.ts +33 -0
- package/dist/types/spec/repair.d.ts.map +1 -0
- package/dist/types/spec/repair.js +3 -0
- package/dist/types/spec/repair.js.map +1 -0
- package/dist/types/spec-decomposer.d.ts +108 -0
- package/dist/types/spec-decomposer.d.ts.map +1 -0
- package/dist/types/spec-decomposer.js +4 -0
- package/dist/types/spec-decomposer.js.map +1 -0
- package/dist/types/spec-observability.d.ts +71 -0
- package/dist/types/spec-observability.d.ts.map +1 -0
- package/dist/types/spec-observability.js +4 -0
- package/dist/types/spec-observability.js.map +1 -0
- package/dist/types/spec-versioning.d.ts +117 -0
- package/dist/types/spec-versioning.d.ts.map +1 -0
- package/dist/types/spec-versioning.js +3 -0
- package/dist/types/spec-versioning.js.map +1 -0
- package/dist/types/well-known.d.ts +70 -0
- package/dist/types/well-known.d.ts.map +1 -0
- package/dist/types/well-known.js +3 -0
- package/dist/types/well-known.js.map +1 -0
- package/package.json +1 -1
- package/src/config/license-plans.json +16 -1
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engine/living-spec/auto-updater.ts — SPEC-170: Auto-update specs from code changes
|
|
3
|
+
*
|
|
4
|
+
* Pure functions that analyse a git-style code diff, map changed functions to
|
|
5
|
+
* acceptance criteria, and propose (or apply) spec updates.
|
|
6
|
+
*
|
|
7
|
+
* Design:
|
|
8
|
+
* - mapDiffToAcs: heuristic matching between diff functions and AC text
|
|
9
|
+
* - generateSpecUpdate: applies proposals onto existing spec content
|
|
10
|
+
* - autoUpdateSpecFromCode: orchestrates the full pipeline
|
|
11
|
+
*/
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Diff parsing
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Extract function-level changes from a unified diff string.
|
|
17
|
+
* Detects `+function`, `-function`, `+async function`, `+export function`, etc.
|
|
18
|
+
*/
|
|
19
|
+
export function parseDiffFunctions(diff) {
|
|
20
|
+
const functions = [];
|
|
21
|
+
const lines = diff.split('\n');
|
|
22
|
+
const funcPattern = /^([+-])\s*(?:export\s+)?(?:async\s+)?(?:function\s+(\w+)|(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\(?)/;
|
|
23
|
+
for (const line of lines) {
|
|
24
|
+
const match = funcPattern.exec(line);
|
|
25
|
+
if (!match) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const prefix = match[1];
|
|
29
|
+
const name = match[2] ?? match[3] ?? '';
|
|
30
|
+
if (!name) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const changeType = prefix === '+' ? 'added' : 'removed';
|
|
34
|
+
const snippet = line.slice(1).trim();
|
|
35
|
+
// Merge with previous entry if same name appears as both removed then added (= modified)
|
|
36
|
+
const existing = functions.find((f) => f.name === name);
|
|
37
|
+
if (existing) {
|
|
38
|
+
existing.changeType = 'modified';
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
functions.push({ name, changeType, snippet });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return functions;
|
|
45
|
+
}
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// AC extraction helpers
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
/**
|
|
50
|
+
* Extract acceptance criteria lines from spec markdown content.
|
|
51
|
+
* Looks for ALL checklist items (`- [ ] ...` or `- [x] ...`) in the document,
|
|
52
|
+
* regardless of section. Returns them with sequential numeric counters.
|
|
53
|
+
*
|
|
54
|
+
* Note: differs from the shared `extractAcceptanceCriteria` (ac-extractor.ts) which
|
|
55
|
+
* requires an explicit "Acceptance Criteria" section header and is used for diffing.
|
|
56
|
+
*/
|
|
57
|
+
export function extractAcsFromSpec(specContent) {
|
|
58
|
+
const acs = [];
|
|
59
|
+
let counter = 0;
|
|
60
|
+
for (const line of specContent.split('\n')) {
|
|
61
|
+
const acMatch = /^-\s+\[[ xX]\]\s+(.+)$/.exec(line.trim());
|
|
62
|
+
if (acMatch) {
|
|
63
|
+
counter++;
|
|
64
|
+
acs.push({ number: counter, description: (acMatch[1] ?? '').trim() });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return acs;
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Keyword-based confidence scoring
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
/**
|
|
73
|
+
* Compute a similarity score (0-1) between a function name and an AC description.
|
|
74
|
+
* Uses word overlap and camelCase decomposition.
|
|
75
|
+
*/
|
|
76
|
+
function scoreSimilarity(funcName, acDescription) {
|
|
77
|
+
// Decompose camelCase into words
|
|
78
|
+
const funcWords = funcName
|
|
79
|
+
.replace(/([A-Z])/g, ' $1')
|
|
80
|
+
.toLowerCase()
|
|
81
|
+
.split(/[\s_-]+/)
|
|
82
|
+
.filter(Boolean);
|
|
83
|
+
const acWords = acDescription
|
|
84
|
+
.toLowerCase()
|
|
85
|
+
.replace(/[^a-z0-9\s]/g, ' ')
|
|
86
|
+
.split(/\s+/)
|
|
87
|
+
.filter((w) => w.length > 2);
|
|
88
|
+
if (funcWords.length === 0 || acWords.length === 0) {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
const funcSet = new Set(funcWords);
|
|
92
|
+
const matches = acWords.filter((w) => funcSet.has(w)).length;
|
|
93
|
+
return matches / Math.max(funcWords.length, acWords.length);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Determine confidence level from a numeric score.
|
|
97
|
+
*/
|
|
98
|
+
function scoreToConfidence(score) {
|
|
99
|
+
if (score >= 0.4) {
|
|
100
|
+
return 'high';
|
|
101
|
+
}
|
|
102
|
+
if (score >= 0.2) {
|
|
103
|
+
return 'medium';
|
|
104
|
+
}
|
|
105
|
+
return 'low';
|
|
106
|
+
}
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// Core mapping
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
/**
|
|
111
|
+
* Map diff functions to acceptance criteria using keyword heuristics.
|
|
112
|
+
*
|
|
113
|
+
* For each changed function:
|
|
114
|
+
* - If it matches one or more ACs → emit 'mark-covered' or 'update-progress'
|
|
115
|
+
* - If removed and matches an AC → emit 'flag-obsolete'
|
|
116
|
+
* - If no AC matches at all → emit 'suggest-new-ac'
|
|
117
|
+
*/
|
|
118
|
+
export function mapDiffToAcs(functions, acs, config = { minConfidence: 'low', suggestNewAcs: true, flagObsolete: true }) {
|
|
119
|
+
const mappings = [];
|
|
120
|
+
const confidenceOrder = { high: 3, medium: 2, low: 1 };
|
|
121
|
+
const minOrder = confidenceOrder[config.minConfidence];
|
|
122
|
+
for (const fn of functions) {
|
|
123
|
+
let bestScore = 0;
|
|
124
|
+
let bestAc = null;
|
|
125
|
+
for (const ac of acs) {
|
|
126
|
+
const score = scoreSimilarity(fn.name, ac.description);
|
|
127
|
+
if (score > bestScore) {
|
|
128
|
+
bestScore = score;
|
|
129
|
+
bestAc = ac;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const confidence = scoreToConfidence(bestScore);
|
|
133
|
+
const order = confidenceOrder[confidence];
|
|
134
|
+
if (bestAc !== null && order >= minOrder) {
|
|
135
|
+
const updateType = resolveUpdateType(fn.changeType, confidence);
|
|
136
|
+
if (config.flagObsolete || updateType !== 'flag-obsolete') {
|
|
137
|
+
mappings.push({
|
|
138
|
+
diffFunction: fn,
|
|
139
|
+
acNumber: bestAc.number,
|
|
140
|
+
acDescription: bestAc.description,
|
|
141
|
+
updateType,
|
|
142
|
+
confidence,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (fn.changeType === 'added' && config.suggestNewAcs) {
|
|
147
|
+
// New function with no matching AC → suggest a new AC
|
|
148
|
+
mappings.push({
|
|
149
|
+
diffFunction: fn,
|
|
150
|
+
acNumber: 0,
|
|
151
|
+
acDescription: '',
|
|
152
|
+
updateType: 'suggest-new-ac',
|
|
153
|
+
confidence: 'low',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return mappings;
|
|
158
|
+
}
|
|
159
|
+
/** Determine the update type from change type and confidence. */
|
|
160
|
+
function resolveUpdateType(changeType, confidence) {
|
|
161
|
+
if (changeType === 'removed') {
|
|
162
|
+
return 'flag-obsolete';
|
|
163
|
+
}
|
|
164
|
+
if (confidence === 'high') {
|
|
165
|
+
return 'mark-covered';
|
|
166
|
+
}
|
|
167
|
+
return 'update-progress';
|
|
168
|
+
}
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// Spec content patching
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
/**
|
|
173
|
+
* Build SpecUpdateProposals from AcMappings.
|
|
174
|
+
*/
|
|
175
|
+
export function buildProposals(mappings, specId) {
|
|
176
|
+
const proposals = [];
|
|
177
|
+
for (const mapping of mappings) {
|
|
178
|
+
if (mapping.updateType === 'suggest-new-ac') {
|
|
179
|
+
proposals.push({
|
|
180
|
+
acNumber: 0,
|
|
181
|
+
description: `New function "${mapping.diffFunction.name}" has no matching AC — consider adding one`,
|
|
182
|
+
action: 'suggest-new-ac',
|
|
183
|
+
patch: `- [ ] [AUTO] Implement \`${mapping.diffFunction.name}\``,
|
|
184
|
+
});
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (mapping.updateType === 'flag-obsolete') {
|
|
188
|
+
proposals.push({
|
|
189
|
+
acNumber: mapping.acNumber,
|
|
190
|
+
description: `Function "${mapping.diffFunction.name}" was removed — AC-${mapping.acNumber} may be obsolete`,
|
|
191
|
+
action: 'flag-obsolete',
|
|
192
|
+
patch: `<!-- POSSIBLY OBSOLETE: AC-${mapping.acNumber} (${mapping.acDescription}) — function "${mapping.diffFunction.name}" was removed. Verify. -->`,
|
|
193
|
+
});
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (mapping.updateType === 'mark-covered') {
|
|
197
|
+
proposals.push({
|
|
198
|
+
acNumber: mapping.acNumber,
|
|
199
|
+
description: `Function "${mapping.diffFunction.name}" implements AC-${mapping.acNumber} — mark as covered`,
|
|
200
|
+
action: 'mark-covered',
|
|
201
|
+
patch: `<!-- AUTO-COVERED by ${specId} via \`${mapping.diffFunction.name}\` -->`,
|
|
202
|
+
});
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
// update-progress
|
|
206
|
+
proposals.push({
|
|
207
|
+
acNumber: mapping.acNumber,
|
|
208
|
+
description: `Function "${mapping.diffFunction.name}" modified — AC-${mapping.acNumber} progress updated`,
|
|
209
|
+
action: 'update-progress',
|
|
210
|
+
patch: `<!-- PROGRESS UPDATE: AC-${mapping.acNumber} affected by \`${mapping.diffFunction.name}\` change -->`,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return proposals;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Apply proposals onto existing spec content and return the updated string.
|
|
217
|
+
*
|
|
218
|
+
* Strategy: append a changelog section at the end of the spec with all patches.
|
|
219
|
+
* Marking individual ACs in-place would require complex line manipulation, so
|
|
220
|
+
* instead we append a structured "Auto-sync changelog" section.
|
|
221
|
+
*/
|
|
222
|
+
export function generateSpecUpdate(proposals, specContent) {
|
|
223
|
+
if (proposals.length === 0) {
|
|
224
|
+
return specContent;
|
|
225
|
+
}
|
|
226
|
+
const now = new Date().toISOString();
|
|
227
|
+
const lines = [
|
|
228
|
+
'',
|
|
229
|
+
'<!-- AUTO-SYNC CHANGELOG — generated by auto_update_spec -->',
|
|
230
|
+
`<!-- ${now} -->`,
|
|
231
|
+
];
|
|
232
|
+
for (const proposal of proposals) {
|
|
233
|
+
lines.push(`<!-- [${proposal.action.toUpperCase()}] AC-${proposal.acNumber || 'NEW'}: ${proposal.description} -->`);
|
|
234
|
+
if (proposal.patch) {
|
|
235
|
+
lines.push(proposal.patch);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
lines.push('<!-- END AUTO-SYNC CHANGELOG -->');
|
|
239
|
+
return `${specContent}\n${lines.join('\n')}\n`;
|
|
240
|
+
}
|
|
241
|
+
// ---------------------------------------------------------------------------
|
|
242
|
+
// Main orchestrator
|
|
243
|
+
// ---------------------------------------------------------------------------
|
|
244
|
+
/**
|
|
245
|
+
* Analyse a code diff and produce auto-update proposals for a spec.
|
|
246
|
+
*
|
|
247
|
+
* @param specId - The spec to update.
|
|
248
|
+
* @param codeDiff - Unified diff string. If empty, returns empty result.
|
|
249
|
+
* @param specContent - Current markdown content of the spec.
|
|
250
|
+
* @param autoApply - When true, apply proposals and return the updated content.
|
|
251
|
+
* @param config - Optional configuration overrides.
|
|
252
|
+
*/
|
|
253
|
+
export function autoUpdateSpecFromCode(specId, codeDiff, specContent, autoApply = false, config = { minConfidence: 'low', suggestNewAcs: true, flagObsolete: true }) {
|
|
254
|
+
const analyzedAt = new Date().toISOString();
|
|
255
|
+
if (!codeDiff.trim()) {
|
|
256
|
+
return {
|
|
257
|
+
specId,
|
|
258
|
+
mappings: [],
|
|
259
|
+
proposals: [],
|
|
260
|
+
updatedSpecContent: null,
|
|
261
|
+
applied: false,
|
|
262
|
+
summary: 'No code diff provided — nothing to analyse.',
|
|
263
|
+
analyzedAt,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
const functions = parseDiffFunctions(codeDiff);
|
|
267
|
+
const acs = extractAcsFromSpec(specContent);
|
|
268
|
+
const mappings = mapDiffToAcs(functions, acs, config);
|
|
269
|
+
const proposals = buildProposals(mappings, specId);
|
|
270
|
+
let updatedSpecContent = null;
|
|
271
|
+
let applied = false;
|
|
272
|
+
if (autoApply && proposals.length > 0) {
|
|
273
|
+
updatedSpecContent = generateSpecUpdate(proposals, specContent);
|
|
274
|
+
applied = true;
|
|
275
|
+
}
|
|
276
|
+
const summary = buildSummary(functions, mappings, proposals, applied);
|
|
277
|
+
return {
|
|
278
|
+
specId,
|
|
279
|
+
mappings,
|
|
280
|
+
proposals,
|
|
281
|
+
updatedSpecContent,
|
|
282
|
+
applied,
|
|
283
|
+
summary,
|
|
284
|
+
analyzedAt,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
// Private helpers
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
function buildSummary(functions, mappings, proposals, applied) {
|
|
291
|
+
const added = functions.filter((f) => f.changeType === 'added').length;
|
|
292
|
+
const modified = functions.filter((f) => f.changeType === 'modified').length;
|
|
293
|
+
const removed = functions.filter((f) => f.changeType === 'removed').length;
|
|
294
|
+
const newAcCount = proposals.filter((p) => p.action === 'suggest-new-ac').length;
|
|
295
|
+
const coveredCount = proposals.filter((p) => p.action === 'mark-covered').length;
|
|
296
|
+
const obsoleteCount = proposals.filter((p) => p.action === 'flag-obsolete').length;
|
|
297
|
+
const progressCount = proposals.filter((p) => p.action === 'update-progress').length;
|
|
298
|
+
const parts = [
|
|
299
|
+
`Analysed ${functions.length} function change(s): ${added} added, ${modified} modified, ${removed} removed.`,
|
|
300
|
+
`Mapped to ${mappings.length} AC(s).`,
|
|
301
|
+
`Proposals: ${coveredCount} mark-covered, ${progressCount} update-progress, ${obsoleteCount} flag-obsolete, ${newAcCount} suggest-new-ac.`,
|
|
302
|
+
];
|
|
303
|
+
if (applied) {
|
|
304
|
+
parts.push('Changes applied to spec content.');
|
|
305
|
+
}
|
|
306
|
+
else if (proposals.length > 0) {
|
|
307
|
+
parts.push('Use autoApply=true to apply changes.');
|
|
308
|
+
}
|
|
309
|
+
return parts.join(' ');
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=auto-updater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-updater.js","sourceRoot":"","sources":["../../../src/engine/living-spec/auto-updater.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,SAAS,GAAmB,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE/B,MAAM,WAAW,GACf,4GAA4G,CAAC;IAE/G,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAc,CAAC;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAErC,yFAAyF;QACzF,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACxD,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,MAAM,GAAG,GAA0B,EAAE,CAAC;IACtC,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;YACV,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,mCAAmC;AACnC,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,aAAqB;IAC9D,iCAAiC;IACjC,MAAM,SAAS,GAAG,QAAQ;SACvB,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;SAC1B,WAAW,EAAE;SACb,KAAK,CAAC,SAAS,CAAC;SAChB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,OAAO,GAAG,aAAa;SAC1B,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE/B,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAE7D,OAAO,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,KAAa;IACtC,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;QACjB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;QACjB,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,SAAyB,EACzB,GAA0B,EAC1B,SAA2B,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;IAE5F,MAAM,QAAQ,GAAgB,EAAE,CAAC;IACjC,MAAM,eAAe,GAA8C,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAClG,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAEvD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,MAAM,GAA+B,IAAI,CAAC;QAE9C,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;YACvD,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;gBACtB,SAAS,GAAG,KAAK,CAAC;gBAClB,MAAM,GAAG,EAAE,CAAC;YACd,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QAE1C,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;YACzC,MAAM,UAAU,GAAG,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAChE,IAAI,MAAM,CAAC,YAAY,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;gBAC1D,QAAQ,CAAC,IAAI,CAAC;oBACZ,YAAY,EAAE,EAAE;oBAChB,QAAQ,EAAE,MAAM,CAAC,MAAM;oBACvB,aAAa,EAAE,MAAM,CAAC,WAAW;oBACjC,UAAU;oBACV,UAAU;iBACX,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,IAAI,EAAE,CAAC,UAAU,KAAK,OAAO,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAC7D,sDAAsD;YACtD,QAAQ,CAAC,IAAI,CAAC;gBACZ,YAAY,EAAE,EAAE;gBAChB,QAAQ,EAAE,CAAC;gBACX,aAAa,EAAE,EAAE;gBACjB,UAAU,EAAE,gBAAgB;gBAC5B,UAAU,EAAE,KAAK;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,iEAAiE;AACjE,SAAS,iBAAiB,CACxB,UAAsC,EACtC,UAAqC;IAErC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QAC1B,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAqB,EAAE,MAAc;IAClE,MAAM,SAAS,GAAyB,EAAE,CAAC;IAE3C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,UAAU,KAAK,gBAAgB,EAAE,CAAC;YAC5C,SAAS,CAAC,IAAI,CAAC;gBACb,QAAQ,EAAE,CAAC;gBACX,WAAW,EAAE,iBAAiB,OAAO,CAAC,YAAY,CAAC,IAAI,4CAA4C;gBACnG,MAAM,EAAE,gBAAgB;gBACxB,KAAK,EAAE,4BAA4B,OAAO,CAAC,YAAY,CAAC,IAAI,IAAI;aACjE,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,OAAO,CAAC,UAAU,KAAK,eAAe,EAAE,CAAC;YAC3C,SAAS,CAAC,IAAI,CAAC;gBACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,WAAW,EAAE,aAAa,OAAO,CAAC,YAAY,CAAC,IAAI,sBAAsB,OAAO,CAAC,QAAQ,kBAAkB;gBAC3G,MAAM,EAAE,eAAe;gBACvB,KAAK,EAAE,8BAA8B,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,aAAa,iBAAiB,OAAO,CAAC,YAAY,CAAC,IAAI,4BAA4B;aACtJ,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,OAAO,CAAC,UAAU,KAAK,cAAc,EAAE,CAAC;YAC1C,SAAS,CAAC,IAAI,CAAC;gBACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,WAAW,EAAE,aAAa,OAAO,CAAC,YAAY,CAAC,IAAI,mBAAmB,OAAO,CAAC,QAAQ,oBAAoB;gBAC1G,MAAM,EAAE,cAAc;gBACtB,KAAK,EAAE,wBAAwB,MAAM,UAAU,OAAO,CAAC,YAAY,CAAC,IAAI,QAAQ;aACjF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,kBAAkB;QAClB,SAAS,CAAC,IAAI,CAAC;YACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,WAAW,EAAE,aAAa,OAAO,CAAC,YAAY,CAAC,IAAI,mBAAmB,OAAO,CAAC,QAAQ,mBAAmB;YACzG,MAAM,EAAE,iBAAiB;YACzB,KAAK,EAAE,4BAA4B,OAAO,CAAC,QAAQ,kBAAkB,OAAO,CAAC,YAAY,CAAC,IAAI,eAAe;SAC9G,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAA+B,EAAE,WAAmB;IACrF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,KAAK,GAAa;QACtB,EAAE;QACF,8DAA8D;QAC9D,QAAQ,GAAG,MAAM;KAClB,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CACR,SAAS,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,QAAQ,CAAC,QAAQ,IAAI,KAAK,KAAK,QAAQ,CAAC,WAAW,MAAM,CACxG,CAAC;QACF,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAE/C,OAAO,GAAG,WAAW,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjD,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAc,EACd,QAAgB,EAChB,WAAmB,EACnB,SAAS,GAAG,KAAK,EACjB,SAA2B,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;IAE5F,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE5C,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QACrB,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,EAAE;YACZ,SAAS,EAAE,EAAE;YACb,kBAAkB,EAAE,IAAI;YACxB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,6CAA6C;YACtD,UAAU;SACX,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEnD,IAAI,kBAAkB,GAAkB,IAAI,CAAC;IAC7C,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,kBAAkB,GAAG,kBAAkB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAChE,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAEtE,OAAO;QACL,MAAM;QACN,QAAQ;QACR,SAAS;QACT,kBAAkB;QAClB,OAAO;QACP,OAAO;QACP,UAAU;KACX,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,SAAS,YAAY,CACnB,SAAyB,EACzB,QAAqB,EACrB,SAA+B,EAC/B,OAAgB;IAEhB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;IAC7E,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IAE3E,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,MAAM,CAAC;IACjF,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC,MAAM,CAAC;IACjF,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,MAAM,CAAC;IACnF,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,iBAAiB,CAAC,CAAC,MAAM,CAAC;IAErF,MAAM,KAAK,GAAa;QACtB,YAAY,SAAS,CAAC,MAAM,wBAAwB,KAAK,WAAW,QAAQ,cAAc,OAAO,WAAW;QAC5G,aAAa,QAAQ,CAAC,MAAM,SAAS;QACrC,cAAc,YAAY,kBAAkB,aAAa,qBAAqB,aAAa,mBAAmB,UAAU,kBAAkB;KAC3I,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engine/living-spec/conflict-resolver.ts — SPEC-172: Merge conflict resolution
|
|
3
|
+
*
|
|
4
|
+
* Pure functions for detecting and resolving conflicts between spec changes and
|
|
5
|
+
* code changes that occur simultaneously. Supports configurable resolution policies
|
|
6
|
+
* and generates git-style conflict markers for unresolved conflicts.
|
|
7
|
+
*/
|
|
8
|
+
import type { ConflictCategory, ConflictItem, MergeConflictResolution, CodeDiff, MergeSpecDiff, ResolvedConflict, ResolutionPolicy } from '../../types/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* Compute a simple line-level diff between two spec strings.
|
|
11
|
+
* Delegates to the shared line-diff utility and adds change detection.
|
|
12
|
+
*/
|
|
13
|
+
export declare function computeSpecDiff(originalSpec: string, newSpec: string): MergeSpecDiff;
|
|
14
|
+
/**
|
|
15
|
+
* Build a CodeDiff from a list of changed file paths.
|
|
16
|
+
* File paths prefixed with '+' are added, '-' removed, otherwise modified.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildCodeDiff(codeChanges: string[]): CodeDiff;
|
|
19
|
+
/**
|
|
20
|
+
* Categorize a conflict item as semantic, structural, or cosmetic.
|
|
21
|
+
*
|
|
22
|
+
* - semantic: spec acceptance criteria directly contradict code behavior
|
|
23
|
+
* - structural: additions/removals that create structural mismatches
|
|
24
|
+
* - cosmetic: naming differences, whitespace, or formatting changes only
|
|
25
|
+
*/
|
|
26
|
+
export declare function categorizeConflict(conflict: ConflictItem): ConflictCategory;
|
|
27
|
+
/**
|
|
28
|
+
* Detect conflicts between a spec diff and a code diff.
|
|
29
|
+
* Returns conflict items representing mismatches that need resolution.
|
|
30
|
+
*/
|
|
31
|
+
export declare function detectConflicts(specDiff: MergeSpecDiff, codeDiff: CodeDiff): ConflictItem[];
|
|
32
|
+
/**
|
|
33
|
+
* Attempt to auto-resolve a single conflict using the given policy.
|
|
34
|
+
* Returns null if the policy requires human review (always-ask).
|
|
35
|
+
*/
|
|
36
|
+
export declare function autoResolve(conflict: ConflictItem, policy: ResolutionPolicy): ResolvedConflict | null;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve spec conflicts between an original spec, a new spec version, and code changes.
|
|
39
|
+
* Returns a MergeConflictResolution with auto-resolved conflicts and those pending human review.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveSpecConflict(originalSpec: string, newSpec: string, codeChanges: string[], specId: string, policy?: ResolutionPolicy): MergeConflictResolution;
|
|
42
|
+
/**
|
|
43
|
+
* Generate git-style conflict markers for unresolved conflicts.
|
|
44
|
+
*/
|
|
45
|
+
export declare function generateConflictMarkers(pendingConflicts: ConflictItem[], originalSpec: string, newSpec: string): string[];
|
|
46
|
+
//# sourceMappingURL=conflict-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-resolver.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/conflict-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,EACvB,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAO9B;;;GAGG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAgBpF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,QAAQ,CAiB7D;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,gBAAgB,CAqB3E;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,GAAG,YAAY,EAAE,CAoF3F;AAMD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,gBAAgB,GACvB,gBAAgB,GAAG,IAAI,CAgDzB;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,gBAA+B,GACtC,uBAAuB,CA8BzB;AAMD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,YAAY,EAAE,EAChC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CAwBV"}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engine/living-spec/conflict-resolver.ts — SPEC-172: Merge conflict resolution
|
|
3
|
+
*
|
|
4
|
+
* Pure functions for detecting and resolving conflicts between spec changes and
|
|
5
|
+
* code changes that occur simultaneously. Supports configurable resolution policies
|
|
6
|
+
* and generates git-style conflict markers for unresolved conflicts.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from 'node:crypto';
|
|
9
|
+
import { computeLineDiff } from '../shared/line-diff.js';
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Diff utilities
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
/**
|
|
14
|
+
* Compute a simple line-level diff between two spec strings.
|
|
15
|
+
* Delegates to the shared line-diff utility and adds change detection.
|
|
16
|
+
*/
|
|
17
|
+
export function computeSpecDiff(originalSpec, newSpec) {
|
|
18
|
+
const { added, removed } = computeLineDiff(originalSpec, newSpec);
|
|
19
|
+
const changed = [];
|
|
20
|
+
// Detect changed lines: lines whose prefix (first word) matches but content differs
|
|
21
|
+
for (const addedLine of added) {
|
|
22
|
+
const prefix = addedLine.split(' ')[0] ?? '';
|
|
23
|
+
if (prefix.length > 3) {
|
|
24
|
+
const matchingRemoved = removed.find((r) => r.startsWith(prefix));
|
|
25
|
+
if (matchingRemoved !== undefined) {
|
|
26
|
+
changed.push(`${matchingRemoved} → ${addedLine}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { added, removed, changed };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Build a CodeDiff from a list of changed file paths.
|
|
34
|
+
* File paths prefixed with '+' are added, '-' removed, otherwise modified.
|
|
35
|
+
*/
|
|
36
|
+
export function buildCodeDiff(codeChanges) {
|
|
37
|
+
const addedFiles = [];
|
|
38
|
+
const removedFiles = [];
|
|
39
|
+
const modifiedFiles = [];
|
|
40
|
+
const diffLines = [...codeChanges];
|
|
41
|
+
for (const change of codeChanges) {
|
|
42
|
+
if (change.startsWith('+')) {
|
|
43
|
+
addedFiles.push(change.slice(1).trim());
|
|
44
|
+
}
|
|
45
|
+
else if (change.startsWith('-')) {
|
|
46
|
+
removedFiles.push(change.slice(1).trim());
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
modifiedFiles.push(change.trim());
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { addedFiles, removedFiles, modifiedFiles, diffLines };
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Conflict categorization
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
/**
|
|
58
|
+
* Categorize a conflict item as semantic, structural, or cosmetic.
|
|
59
|
+
*
|
|
60
|
+
* - semantic: spec acceptance criteria directly contradict code behavior
|
|
61
|
+
* - structural: additions/removals that create structural mismatches
|
|
62
|
+
* - cosmetic: naming differences, whitespace, or formatting changes only
|
|
63
|
+
*/
|
|
64
|
+
export function categorizeConflict(conflict) {
|
|
65
|
+
const specLower = conflict.specSide.toLowerCase();
|
|
66
|
+
const codeLower = conflict.codeSide.toLowerCase();
|
|
67
|
+
// Structural: one side has addition/removal the other lacks
|
|
68
|
+
const structuralKeywords = ['added', 'removed', 'deleted', 'new function', 'missing'];
|
|
69
|
+
for (const kw of structuralKeywords) {
|
|
70
|
+
if (codeLower.includes(kw) || specLower.includes(kw)) {
|
|
71
|
+
return 'structural';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Cosmetic: only naming/casing differences
|
|
75
|
+
const specNormalized = specLower.replace(/[\s_-]/g, '');
|
|
76
|
+
const codeNormalized = codeLower.replace(/[\s_-]/g, '');
|
|
77
|
+
if (specNormalized === codeNormalized) {
|
|
78
|
+
return 'cosmetic';
|
|
79
|
+
}
|
|
80
|
+
// Default: semantic
|
|
81
|
+
return 'semantic';
|
|
82
|
+
}
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Conflict detection
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
/**
|
|
87
|
+
* Detect conflicts between a spec diff and a code diff.
|
|
88
|
+
* Returns conflict items representing mismatches that need resolution.
|
|
89
|
+
*/
|
|
90
|
+
export function detectConflicts(specDiff, codeDiff) {
|
|
91
|
+
const conflicts = [];
|
|
92
|
+
const now = new Date().toISOString();
|
|
93
|
+
// Structural: spec adds ACs but code removes files
|
|
94
|
+
if (specDiff.added.length > 0 && codeDiff.removedFiles.length > 0) {
|
|
95
|
+
for (const addedLine of specDiff.added) {
|
|
96
|
+
if (isAcceptanceCriterion(addedLine)) {
|
|
97
|
+
for (const removedFile of codeDiff.removedFiles) {
|
|
98
|
+
const id = generateConflictId(addedLine, removedFile);
|
|
99
|
+
conflicts.push({
|
|
100
|
+
id,
|
|
101
|
+
specId: '',
|
|
102
|
+
description: `Spec adds AC but code removed file: ${removedFile}`,
|
|
103
|
+
specSide: addedLine,
|
|
104
|
+
codeSide: `removed file: ${removedFile}`,
|
|
105
|
+
category: 'structural',
|
|
106
|
+
detectedAt: now,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Structural: spec removes ACs but code adds files implementing them
|
|
113
|
+
if (specDiff.removed.length > 0 && codeDiff.addedFiles.length > 0) {
|
|
114
|
+
for (const removedLine of specDiff.removed) {
|
|
115
|
+
if (isAcceptanceCriterion(removedLine)) {
|
|
116
|
+
for (const addedFile of codeDiff.addedFiles) {
|
|
117
|
+
const id = generateConflictId(removedLine, addedFile);
|
|
118
|
+
conflicts.push({
|
|
119
|
+
id,
|
|
120
|
+
specId: '',
|
|
121
|
+
description: `Spec removes AC but code added file: ${addedFile}`,
|
|
122
|
+
specSide: `removed: ${removedLine}`,
|
|
123
|
+
codeSide: `added file: ${addedFile}`,
|
|
124
|
+
category: 'structural',
|
|
125
|
+
detectedAt: now,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Semantic: spec changed existing ACs while code also modified files
|
|
132
|
+
if (specDiff.changed.length > 0 && codeDiff.modifiedFiles.length > 0) {
|
|
133
|
+
for (const changedLine of specDiff.changed) {
|
|
134
|
+
const id = generateConflictId(changedLine, codeDiff.modifiedFiles.join(','));
|
|
135
|
+
conflicts.push({
|
|
136
|
+
id,
|
|
137
|
+
specId: '',
|
|
138
|
+
description: `Spec AC changed while code was also modified`,
|
|
139
|
+
specSide: changedLine,
|
|
140
|
+
codeSide: `modified files: ${codeDiff.modifiedFiles.join(', ')}`,
|
|
141
|
+
category: 'semantic',
|
|
142
|
+
detectedAt: now,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Cosmetic: spec has renamed items that differ only in casing/format from code
|
|
147
|
+
for (const addedLine of specDiff.added) {
|
|
148
|
+
for (const modifiedFile of codeDiff.modifiedFiles) {
|
|
149
|
+
const baseName = modifiedFile
|
|
150
|
+
.replace(/\.[^.]+$/, '')
|
|
151
|
+
.split('/')
|
|
152
|
+
.pop() ?? '';
|
|
153
|
+
if (isCosmeticMismatch(addedLine, baseName)) {
|
|
154
|
+
const id = generateConflictId(addedLine, modifiedFile);
|
|
155
|
+
conflicts.push({
|
|
156
|
+
id,
|
|
157
|
+
specId: '',
|
|
158
|
+
description: `Cosmetic naming mismatch between spec and code`,
|
|
159
|
+
specSide: addedLine,
|
|
160
|
+
codeSide: modifiedFile,
|
|
161
|
+
category: 'cosmetic',
|
|
162
|
+
detectedAt: now,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return conflicts;
|
|
168
|
+
}
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// Auto-resolution
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
/**
|
|
173
|
+
* Attempt to auto-resolve a single conflict using the given policy.
|
|
174
|
+
* Returns null if the policy requires human review (always-ask).
|
|
175
|
+
*/
|
|
176
|
+
export function autoResolve(conflict, policy) {
|
|
177
|
+
if (policy === 'always-ask') {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
const now = new Date().toISOString();
|
|
181
|
+
if (policy === 'code-wins') {
|
|
182
|
+
// Cosmetic conflicts are always safe to auto-resolve with code-wins
|
|
183
|
+
// Structural and semantic: code wins for implementation details
|
|
184
|
+
if (conflict.category === 'semantic' && !isImplementationDetail(conflict)) {
|
|
185
|
+
return null; // Semantic AC conflicts need human review even with code-wins
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
conflict,
|
|
189
|
+
appliedPolicy: policy,
|
|
190
|
+
winner: 'code',
|
|
191
|
+
explanation: `code-wins policy: code state accepted for ${conflict.category} conflict`,
|
|
192
|
+
resolvedAt: now,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (policy === 'spec-wins') {
|
|
196
|
+
// Spec wins for acceptance criteria by definition
|
|
197
|
+
if (conflict.category === 'structural' && conflict.codeSide.startsWith('removed file')) {
|
|
198
|
+
return null; // Cannot auto-resolve structural removal without human verification
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
conflict,
|
|
202
|
+
appliedPolicy: policy,
|
|
203
|
+
winner: 'spec',
|
|
204
|
+
explanation: `spec-wins policy: spec state accepted for ${conflict.category} conflict`,
|
|
205
|
+
resolvedAt: now,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// policy === 'most-recent': cosmetic conflicts resolve to spec; others need human review
|
|
209
|
+
if (conflict.category === 'cosmetic') {
|
|
210
|
+
return {
|
|
211
|
+
conflict,
|
|
212
|
+
appliedPolicy: policy,
|
|
213
|
+
winner: 'spec',
|
|
214
|
+
explanation: `most-recent policy: spec is treated as most recent for cosmetic conflicts`,
|
|
215
|
+
resolvedAt: now,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
// For semantic/structural, most-recent cannot determine winner without timestamps
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
// Main orchestrator
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
/**
|
|
225
|
+
* Resolve spec conflicts between an original spec, a new spec version, and code changes.
|
|
226
|
+
* Returns a MergeConflictResolution with auto-resolved conflicts and those pending human review.
|
|
227
|
+
*/
|
|
228
|
+
export function resolveSpecConflict(originalSpec, newSpec, codeChanges, specId, policy = 'always-ask') {
|
|
229
|
+
const specDiff = computeSpecDiff(originalSpec, newSpec);
|
|
230
|
+
const codeDiff = buildCodeDiff(codeChanges);
|
|
231
|
+
const rawConflicts = detectConflicts(specDiff, codeDiff);
|
|
232
|
+
// Attach specId to all conflicts
|
|
233
|
+
const conflicts = rawConflicts.map((c) => ({ ...c, specId }));
|
|
234
|
+
const autoResolved = [];
|
|
235
|
+
const pendingReview = [];
|
|
236
|
+
for (const conflict of conflicts) {
|
|
237
|
+
const resolution = autoResolve(conflict, policy);
|
|
238
|
+
if (resolution !== null) {
|
|
239
|
+
autoResolved.push(resolution);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
pendingReview.push(conflict);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const conflictMarkers = generateConflictMarkers(pendingReview, originalSpec, newSpec);
|
|
246
|
+
return {
|
|
247
|
+
specId,
|
|
248
|
+
autoResolved,
|
|
249
|
+
pendingReview,
|
|
250
|
+
conflictMarkers,
|
|
251
|
+
resolvedAt: new Date().toISOString(),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Conflict marker generation
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
/**
|
|
258
|
+
* Generate git-style conflict markers for unresolved conflicts.
|
|
259
|
+
*/
|
|
260
|
+
export function generateConflictMarkers(pendingConflicts, originalSpec, newSpec) {
|
|
261
|
+
if (pendingConflicts.length === 0) {
|
|
262
|
+
return [];
|
|
263
|
+
}
|
|
264
|
+
const markers = [];
|
|
265
|
+
for (const conflict of pendingConflicts) {
|
|
266
|
+
markers.push(`<<<< SPEC (${conflict.id})`, conflict.specSide, `====`, conflict.codeSide, `>>>> CODE`, `# Conflict: ${conflict.description} (category: ${conflict.category})`, '');
|
|
267
|
+
}
|
|
268
|
+
// Suppress unused variable warnings — params are available for future context use
|
|
269
|
+
void originalSpec;
|
|
270
|
+
void newSpec;
|
|
271
|
+
return markers;
|
|
272
|
+
}
|
|
273
|
+
// ---------------------------------------------------------------------------
|
|
274
|
+
// Private helpers
|
|
275
|
+
// ---------------------------------------------------------------------------
|
|
276
|
+
function generateConflictId(a, b) {
|
|
277
|
+
// Content-based hash: same inputs always produce the same conflict ID,
|
|
278
|
+
// enabling idempotent conflict detection across multiple runs.
|
|
279
|
+
return createHash('sha256').update(`${a}:${b}`).digest('hex').slice(0, 12);
|
|
280
|
+
}
|
|
281
|
+
function isAcceptanceCriterion(line) {
|
|
282
|
+
const lower = line.toLowerCase();
|
|
283
|
+
return (lower.includes('- [ ]') ||
|
|
284
|
+
lower.includes('- [x]') ||
|
|
285
|
+
lower.includes('ac-') ||
|
|
286
|
+
lower.startsWith('acceptance'));
|
|
287
|
+
}
|
|
288
|
+
function isCosmeticMismatch(specLine, codeName) {
|
|
289
|
+
const specNorm = specLine.toLowerCase().replace(/[\s_-]/g, '');
|
|
290
|
+
const codeNorm = codeName.toLowerCase().replace(/[\s_-]/g, '');
|
|
291
|
+
return (specNorm !== codeNorm &&
|
|
292
|
+
specNorm.length > 3 &&
|
|
293
|
+
codeNorm.length > 3 &&
|
|
294
|
+
(specNorm.includes(codeNorm) || codeNorm.includes(specNorm)));
|
|
295
|
+
}
|
|
296
|
+
function isImplementationDetail(conflict) {
|
|
297
|
+
const implKeywords = ['implementation', 'refactor', 'rename', 'move', 'extract'];
|
|
298
|
+
const lower = conflict.description.toLowerCase();
|
|
299
|
+
return implKeywords.some((kw) => lower.includes(kw));
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=conflict-resolver.js.map
|