specweave 0.28.68 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +3 -2
- package/README.md +19 -2
- package/dist/src/cli/commands/discrepancies.d.ts +89 -0
- package/dist/src/cli/commands/discrepancies.d.ts.map +1 -0
- package/dist/src/cli/commands/discrepancies.js +385 -0
- package/dist/src/cli/commands/discrepancies.js.map +1 -0
- package/dist/src/cli/commands/notifications.d.ts +70 -0
- package/dist/src/cli/commands/notifications.d.ts.map +1 -0
- package/dist/src/cli/commands/notifications.js +236 -0
- package/dist/src/cli/commands/notifications.js.map +1 -0
- package/dist/src/cli/commands/sync-logs.d.ts +54 -0
- package/dist/src/cli/commands/sync-logs.d.ts.map +1 -0
- package/dist/src/cli/commands/sync-logs.js +240 -0
- package/dist/src/cli/commands/sync-logs.js.map +1 -0
- package/dist/src/cli/commands/sync-monitor.d.ts +42 -0
- package/dist/src/cli/commands/sync-monitor.d.ts.map +1 -0
- package/dist/src/cli/commands/sync-monitor.js +191 -0
- package/dist/src/cli/commands/sync-monitor.js.map +1 -0
- package/dist/src/cli/helpers/init/brownfield-analysis.d.ts +45 -0
- package/dist/src/cli/helpers/init/brownfield-analysis.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/brownfield-analysis.js +431 -0
- package/dist/src/cli/helpers/init/brownfield-analysis.js.map +1 -0
- package/dist/src/cli/helpers/init/index.d.ts +1 -0
- package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/index.js +2 -0
- package/dist/src/cli/helpers/init/index.js.map +1 -1
- package/dist/src/cli/workers/brownfield-worker.d.ts +66 -0
- package/dist/src/cli/workers/brownfield-worker.d.ts.map +1 -0
- package/dist/src/cli/workers/brownfield-worker.js +417 -0
- package/dist/src/cli/workers/brownfield-worker.js.map +1 -0
- package/dist/src/core/background/brownfield-launcher.d.ts +86 -0
- package/dist/src/core/background/brownfield-launcher.d.ts.map +1 -0
- package/dist/src/core/background/brownfield-launcher.js +295 -0
- package/dist/src/core/background/brownfield-launcher.js.map +1 -0
- package/dist/src/core/background/index.d.ts +2 -0
- package/dist/src/core/background/index.d.ts.map +1 -1
- package/dist/src/core/background/index.js +2 -0
- package/dist/src/core/background/index.js.map +1 -1
- package/dist/src/core/background/types.d.ts +23 -2
- package/dist/src/core/background/types.d.ts.map +1 -1
- package/dist/src/core/config/index.d.ts +1 -0
- package/dist/src/core/config/index.d.ts.map +1 -1
- package/dist/src/core/config/index.js +1 -0
- package/dist/src/core/config/index.js.map +1 -1
- package/dist/src/core/config/types.d.ts +6 -0
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/dashboard/dashboard-data.d.ts +156 -0
- package/dist/src/core/dashboard/dashboard-data.d.ts.map +1 -0
- package/dist/src/core/dashboard/dashboard-data.js +191 -0
- package/dist/src/core/dashboard/dashboard-data.js.map +1 -0
- package/dist/src/core/dashboard/index.d.ts +9 -0
- package/dist/src/core/dashboard/index.d.ts.map +1 -0
- package/dist/src/core/dashboard/index.js +9 -0
- package/dist/src/core/dashboard/index.js.map +1 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts +77 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts.map +1 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js +286 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js.map +1 -0
- package/dist/src/core/discrepancy/analyzers/index.d.ts +8 -0
- package/dist/src/core/discrepancy/analyzers/index.d.ts.map +1 -0
- package/dist/src/core/discrepancy/analyzers/index.js +8 -0
- package/dist/src/core/discrepancy/analyzers/index.js.map +1 -0
- package/dist/src/core/discrepancy/analyzers/typescript-analyzer.d.ts +96 -0
- package/dist/src/core/discrepancy/analyzers/typescript-analyzer.d.ts.map +1 -0
- package/dist/src/core/discrepancy/analyzers/typescript-analyzer.js +247 -0
- package/dist/src/core/discrepancy/analyzers/typescript-analyzer.js.map +1 -0
- package/dist/src/core/discrepancy/brownfield-manager.d.ts +88 -0
- package/dist/src/core/discrepancy/brownfield-manager.d.ts.map +1 -0
- package/dist/src/core/discrepancy/brownfield-manager.js +520 -0
- package/dist/src/core/discrepancy/brownfield-manager.js.map +1 -0
- package/dist/src/core/discrepancy/brownfield-types.d.ts +174 -0
- package/dist/src/core/discrepancy/brownfield-types.d.ts.map +1 -0
- package/dist/src/core/discrepancy/brownfield-types.js +11 -0
- package/dist/src/core/discrepancy/brownfield-types.js.map +1 -0
- package/dist/src/core/discrepancy/detector.d.ts +92 -0
- package/dist/src/core/discrepancy/detector.d.ts.map +1 -0
- package/dist/src/core/discrepancy/detector.js +346 -0
- package/dist/src/core/discrepancy/detector.js.map +1 -0
- package/dist/src/core/discrepancy/increment-generator.d.ts +51 -0
- package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -0
- package/dist/src/core/discrepancy/increment-generator.js +234 -0
- package/dist/src/core/discrepancy/increment-generator.js.map +1 -0
- package/dist/src/core/discrepancy/index.d.ts +18 -0
- package/dist/src/core/discrepancy/index.d.ts.map +1 -0
- package/dist/src/core/discrepancy/index.js +24 -0
- package/dist/src/core/discrepancy/index.js.map +1 -0
- package/dist/src/core/discrepancy/severity-classifier.d.ts +81 -0
- package/dist/src/core/discrepancy/severity-classifier.d.ts.map +1 -0
- package/dist/src/core/discrepancy/severity-classifier.js +289 -0
- package/dist/src/core/discrepancy/severity-classifier.js.map +1 -0
- package/dist/src/core/discrepancy/spec-parser.d.ts +74 -0
- package/dist/src/core/discrepancy/spec-parser.d.ts.map +1 -0
- package/dist/src/core/discrepancy/spec-parser.js +213 -0
- package/dist/src/core/discrepancy/spec-parser.js.map +1 -0
- package/dist/src/core/discrepancy/update-recommender.d.ts +77 -0
- package/dist/src/core/discrepancy/update-recommender.d.ts.map +1 -0
- package/dist/src/core/discrepancy/update-recommender.js +323 -0
- package/dist/src/core/discrepancy/update-recommender.js.map +1 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts +13 -16
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +31 -112
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/logs/index.d.ts +10 -0
- package/dist/src/core/logs/index.d.ts.map +1 -0
- package/dist/src/core/logs/index.js +10 -0
- package/dist/src/core/logs/index.js.map +1 -0
- package/dist/src/core/logs/log-aggregator.d.ts +130 -0
- package/dist/src/core/logs/log-aggregator.d.ts.map +1 -0
- package/dist/src/core/logs/log-aggregator.js +206 -0
- package/dist/src/core/logs/log-aggregator.js.map +1 -0
- package/dist/src/core/logs/log-exporter.d.ts +81 -0
- package/dist/src/core/logs/log-exporter.d.ts.map +1 -0
- package/dist/src/core/logs/log-exporter.js +141 -0
- package/dist/src/core/logs/log-exporter.js.map +1 -0
- package/dist/src/core/notifications/command-integration.d.ts +82 -0
- package/dist/src/core/notifications/command-integration.d.ts.map +1 -0
- package/dist/src/core/notifications/command-integration.js +80 -0
- package/dist/src/core/notifications/command-integration.js.map +1 -0
- package/dist/src/core/notifications/index.d.ts +12 -0
- package/dist/src/core/notifications/index.d.ts.map +1 -0
- package/dist/src/core/notifications/index.js +12 -0
- package/dist/src/core/notifications/index.js.map +1 -0
- package/dist/src/core/notifications/notification-display.d.ts +70 -0
- package/dist/src/core/notifications/notification-display.d.ts.map +1 -0
- package/dist/src/core/notifications/notification-display.js +177 -0
- package/dist/src/core/notifications/notification-display.js.map +1 -0
- package/dist/src/core/notifications/notification-manager.d.ts +126 -0
- package/dist/src/core/notifications/notification-manager.d.ts.map +1 -0
- package/dist/src/core/notifications/notification-manager.js +287 -0
- package/dist/src/core/notifications/notification-manager.js.map +1 -0
- package/dist/src/core/notifications/notification-types.d.ts +159 -0
- package/dist/src/core/notifications/notification-types.d.ts.map +1 -0
- package/dist/src/core/notifications/notification-types.js +93 -0
- package/dist/src/core/notifications/notification-types.js.map +1 -0
- package/dist/src/core/scheduler/index.d.ts +11 -0
- package/dist/src/core/scheduler/index.d.ts.map +1 -0
- package/dist/src/core/scheduler/index.js +11 -0
- package/dist/src/core/scheduler/index.js.map +1 -0
- package/dist/src/core/scheduler/job-scheduler.d.ts +179 -0
- package/dist/src/core/scheduler/job-scheduler.d.ts.map +1 -0
- package/dist/src/core/scheduler/job-scheduler.js +282 -0
- package/dist/src/core/scheduler/job-scheduler.js.map +1 -0
- package/dist/src/core/scheduler/schedule-persistence.d.ts +83 -0
- package/dist/src/core/scheduler/schedule-persistence.d.ts.map +1 -0
- package/dist/src/core/scheduler/schedule-persistence.js +180 -0
- package/dist/src/core/scheduler/schedule-persistence.js.map +1 -0
- package/dist/src/core/scheduler/scheduled-job.d.ts +188 -0
- package/dist/src/core/scheduler/scheduled-job.d.ts.map +1 -0
- package/dist/src/core/scheduler/scheduled-job.js +182 -0
- package/dist/src/core/scheduler/scheduled-job.js.map +1 -0
- package/dist/src/core/sync/permission-enforcer.d.ts +206 -0
- package/dist/src/core/sync/permission-enforcer.d.ts.map +1 -0
- package/dist/src/core/sync/permission-enforcer.js +268 -0
- package/dist/src/core/sync/permission-enforcer.js.map +1 -0
- package/dist/src/core/sync/sync-audit-logger.d.ts +217 -0
- package/dist/src/core/sync/sync-audit-logger.d.ts.map +1 -0
- package/dist/src/core/sync/sync-audit-logger.js +327 -0
- package/dist/src/core/sync/sync-audit-logger.js.map +1 -0
- package/dist/src/core/sync/sync-interceptor.d.ts +190 -0
- package/dist/src/core/sync/sync-interceptor.d.ts.map +1 -0
- package/dist/src/core/sync/sync-interceptor.js +224 -0
- package/dist/src/core/sync/sync-interceptor.js.map +1 -0
- package/dist/src/core/types/increment-metadata.d.ts +5 -2
- package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
- package/dist/src/core/types/sync-config.d.ts +267 -0
- package/dist/src/core/types/sync-config.d.ts.map +1 -0
- package/dist/src/core/types/sync-config.js +304 -0
- package/dist/src/core/types/sync-config.js.map +1 -0
- package/dist/src/hooks/index.d.ts +11 -0
- package/dist/src/hooks/index.d.ts.map +1 -0
- package/dist/src/hooks/index.js +11 -0
- package/dist/src/hooks/index.js.map +1 -0
- package/dist/src/hooks/platform.d.ts +125 -0
- package/dist/src/hooks/platform.d.ts.map +1 -0
- package/dist/src/hooks/platform.js +325 -0
- package/dist/src/hooks/platform.js.map +1 -0
- package/dist/src/hooks/processor.d.ts +20 -0
- package/dist/src/hooks/processor.d.ts.map +1 -0
- package/dist/src/hooks/processor.js +317 -0
- package/dist/src/hooks/processor.js.map +1 -0
- package/dist/src/hooks/scheduler-startup.d.ts +19 -0
- package/dist/src/hooks/scheduler-startup.d.ts.map +1 -0
- package/dist/src/hooks/scheduler-startup.js +92 -0
- package/dist/src/hooks/scheduler-startup.js.map +1 -0
- package/dist/src/hooks/session-start.d.ts +16 -0
- package/dist/src/hooks/session-start.d.ts.map +1 -0
- package/dist/src/hooks/session-start.js +92 -0
- package/dist/src/hooks/session-start.js.map +1 -0
- package/dist/src/importers/duplicate-detector.d.ts +13 -2
- package/dist/src/importers/duplicate-detector.d.ts.map +1 -1
- package/dist/src/importers/duplicate-detector.js +21 -2
- package/dist/src/importers/duplicate-detector.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +41 -2
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +225 -38
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.d.ts +7 -0
- package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.js +30 -4
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
- package/dist/src/sync/ado-sync-wrapper.d.ts +137 -0
- package/dist/src/sync/ado-sync-wrapper.d.ts.map +1 -0
- package/dist/src/sync/ado-sync-wrapper.js +148 -0
- package/dist/src/sync/ado-sync-wrapper.js.map +1 -0
- package/dist/src/sync/github-sync-wrapper.d.ts +195 -0
- package/dist/src/sync/github-sync-wrapper.d.ts.map +1 -0
- package/dist/src/sync/github-sync-wrapper.js +220 -0
- package/dist/src/sync/github-sync-wrapper.js.map +1 -0
- package/dist/src/sync/jira-sync-wrapper.d.ts +155 -0
- package/dist/src/sync/jira-sync-wrapper.d.ts.map +1 -0
- package/dist/src/sync/jira-sync-wrapper.js +175 -0
- package/dist/src/sync/jira-sync-wrapper.js.map +1 -0
- package/dist/src/utils/feature-id-derivation.d.ts +58 -0
- package/dist/src/utils/feature-id-derivation.d.ts.map +1 -0
- package/dist/src/utils/feature-id-derivation.js +77 -0
- package/dist/src/utils/feature-id-derivation.js.map +1 -0
- package/package.json +3 -1
- package/plugins/specweave/commands/specweave-discrepancies.md +141 -0
- package/plugins/specweave/commands/specweave-discrepancy-to-increment.md +160 -0
- package/plugins/specweave/commands/specweave-jobs.md +45 -2
- package/plugins/specweave/commands/specweave-notifications.md +92 -0
- package/plugins/specweave/commands/specweave-sync-logs.md +131 -0
- package/plugins/specweave/commands/specweave-sync-monitor.md +57 -0
- package/plugins/specweave/hooks/hooks.json +3 -3
- package/plugins/specweave/hooks/lib/scheduler-startup.sh +72 -0
- package/plugins/specweave/hooks/universal/dispatcher.mjs +246 -0
- package/plugins/specweave/hooks/universal/session-start.cmd +16 -0
- package/plugins/specweave/hooks/universal/session-start.ps1 +16 -0
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +14 -5
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +5 -2
- package/plugins/specweave/skills/discrepancy-viewer.md +154 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +46 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +69 -0
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts +0 -26
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +0 -249
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +0 -1
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts +0 -28
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +0 -156
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +0 -1
- package/dist/src/core/sync/bidirectional-engine.d.ts +0 -119
- package/dist/src/core/sync/bidirectional-engine.d.ts.map +0 -1
- package/dist/src/core/sync/bidirectional-engine.js +0 -359
- package/dist/src/core/sync/bidirectional-engine.js.map +0 -1
- package/dist/src/core/sync/conflict-resolver.d.ts +0 -66
- package/dist/src/core/sync/conflict-resolver.d.ts.map +0 -1
- package/dist/src/core/sync/conflict-resolver.js +0 -108
- package/dist/src/core/sync/conflict-resolver.js.map +0 -1
- package/dist/src/core/sync/enhanced-content-builder.d.ts +0 -55
- package/dist/src/core/sync/enhanced-content-builder.d.ts.map +0 -1
- package/dist/src/core/sync/enhanced-content-builder.js +0 -203
- package/dist/src/core/sync/enhanced-content-builder.js.map +0 -1
- package/dist/src/core/sync/folder-mapper.d.ts +0 -71
- package/dist/src/core/sync/folder-mapper.d.ts.map +0 -1
- package/dist/src/core/sync/folder-mapper.js +0 -203
- package/dist/src/core/sync/folder-mapper.js.map +0 -1
- package/dist/src/core/sync/label-detector.d.ts +0 -66
- package/dist/src/core/sync/label-detector.d.ts.map +0 -1
- package/dist/src/core/sync/label-detector.js +0 -224
- package/dist/src/core/sync/label-detector.js.map +0 -1
- package/dist/src/core/sync/performance-optimizer.d.ts +0 -153
- package/dist/src/core/sync/performance-optimizer.d.ts.map +0 -1
- package/dist/src/core/sync/performance-optimizer.js +0 -220
- package/dist/src/core/sync/performance-optimizer.js.map +0 -1
- package/dist/src/core/sync/profile-selector.d.ts +0 -52
- package/dist/src/core/sync/profile-selector.d.ts.map +0 -1
- package/dist/src/core/sync/profile-selector.js +0 -179
- package/dist/src/core/sync/profile-selector.js.map +0 -1
- package/dist/src/core/sync/profile-validator.d.ts +0 -52
- package/dist/src/core/sync/profile-validator.d.ts.map +0 -1
- package/dist/src/core/sync/profile-validator.js +0 -170
- package/dist/src/core/sync/profile-validator.js.map +0 -1
- package/dist/src/core/sync/rate-limiter.d.ts +0 -116
- package/dist/src/core/sync/rate-limiter.d.ts.map +0 -1
- package/dist/src/core/sync/rate-limiter.js +0 -308
- package/dist/src/core/sync/rate-limiter.js.map +0 -1
- package/dist/src/core/sync/retry-handler.d.ts +0 -98
- package/dist/src/core/sync/retry-handler.d.ts.map +0 -1
- package/dist/src/core/sync/retry-handler.js +0 -196
- package/dist/src/core/sync/retry-handler.js.map +0 -1
- package/dist/src/core/sync/retry-logic.d.ts +0 -64
- package/dist/src/core/sync/retry-logic.d.ts.map +0 -1
- package/dist/src/core/sync/retry-logic.js +0 -165
- package/dist/src/core/sync/retry-logic.js.map +0 -1
- package/dist/src/core/sync/status-cache.d.ts +0 -91
- package/dist/src/core/sync/status-cache.d.ts.map +0 -1
- package/dist/src/core/sync/status-cache.js +0 -140
- package/dist/src/core/sync/status-cache.js.map +0 -1
- package/dist/src/core/sync/status-mapper.d.ts +0 -69
- package/dist/src/core/sync/status-mapper.d.ts.map +0 -1
- package/dist/src/core/sync/status-mapper.js +0 -90
- package/dist/src/core/sync/status-mapper.js.map +0 -1
- package/dist/src/core/sync/status-sync-engine.d.ts +0 -162
- package/dist/src/core/sync/status-sync-engine.d.ts.map +0 -1
- package/dist/src/core/sync/status-sync-engine.js +0 -347
- package/dist/src/core/sync/status-sync-engine.js.map +0 -1
- package/dist/src/core/sync/sync-event-logger.d.ts +0 -113
- package/dist/src/core/sync/sync-event-logger.d.ts.map +0 -1
- package/dist/src/core/sync/sync-event-logger.js +0 -141
- package/dist/src/core/sync/sync-event-logger.js.map +0 -1
- package/dist/src/core/sync/time-range-selector.d.ts +0 -48
- package/dist/src/core/sync/time-range-selector.d.ts.map +0 -1
- package/dist/src/core/sync/time-range-selector.js +0 -224
- package/dist/src/core/sync/time-range-selector.js.map +0 -1
- package/dist/src/core/sync/types.d.ts +0 -52
- package/dist/src/core/sync/types.d.ts.map +0 -1
- package/dist/src/core/sync/types.js +0 -5
- package/dist/src/core/sync/types.js.map +0 -1
- package/dist/src/core/sync/workflow-detector.d.ts +0 -95
- package/dist/src/core/sync/workflow-detector.d.ts.map +0 -1
- package/dist/src/core/sync/workflow-detector.js +0 -175
- package/dist/src/core/sync/workflow-detector.js.map +0 -1
- package/plugins/specweave-github/lib/enhanced-github-sync.js +0 -220
- package/plugins/specweave-github/lib/enhanced-github-sync.ts +0 -322
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +0 -134
- package/plugins/specweave-jira/lib/enhanced-jira-sync.ts +0 -196
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission Enforcer
|
|
3
|
+
*
|
|
4
|
+
* Validates sync operations against configured permissions before execution.
|
|
5
|
+
* Uses the existing SyncSettings from config.json (set during specweave init).
|
|
6
|
+
* Logs all permission decisions for audit.
|
|
7
|
+
*
|
|
8
|
+
* IMPORTANT: This integrates with the existing sync.settings configuration:
|
|
9
|
+
* - canUpsertInternalItems: CREATE/UPDATE internal items in external tools
|
|
10
|
+
* - canUpdateExternalItems: UPDATE items created externally
|
|
11
|
+
* - canUpdateStatus: UPDATE status field for both internal and external items
|
|
12
|
+
*
|
|
13
|
+
* @module core/sync/permission-enforcer
|
|
14
|
+
*/
|
|
15
|
+
import { SyncSettings } from '../types/sync-settings.js';
|
|
16
|
+
import { SyncPlatform } from '../types/sync-config.js';
|
|
17
|
+
import { Logger } from '../../utils/logger.js';
|
|
18
|
+
/**
|
|
19
|
+
* Sync operation types
|
|
20
|
+
*
|
|
21
|
+
* Maps to existing SyncSettings:
|
|
22
|
+
* - 'read' → always allowed (reading is safe)
|
|
23
|
+
* - 'update-status' → canUpdateStatus
|
|
24
|
+
* - 'upsert-internal' → canUpsertInternalItems
|
|
25
|
+
* - 'upsert-external' → canUpdateExternalItems
|
|
26
|
+
*/
|
|
27
|
+
export type SyncOperation = 'read' | 'update-status' | 'upsert-internal' | 'upsert-external';
|
|
28
|
+
/**
|
|
29
|
+
* Item origin - where the item was created
|
|
30
|
+
*/
|
|
31
|
+
export type ItemOrigin = 'internal' | 'external';
|
|
32
|
+
/**
|
|
33
|
+
* Permission check result
|
|
34
|
+
*/
|
|
35
|
+
export interface PermissionResult {
|
|
36
|
+
/**
|
|
37
|
+
* Whether the operation is allowed
|
|
38
|
+
*/
|
|
39
|
+
allowed: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Reason for the decision
|
|
42
|
+
*/
|
|
43
|
+
reason: string;
|
|
44
|
+
/**
|
|
45
|
+
* Platform checked
|
|
46
|
+
*/
|
|
47
|
+
platform: SyncPlatform;
|
|
48
|
+
/**
|
|
49
|
+
* Operation attempted
|
|
50
|
+
*/
|
|
51
|
+
operation: SyncOperation;
|
|
52
|
+
/**
|
|
53
|
+
* Item ID involved
|
|
54
|
+
*/
|
|
55
|
+
itemId: string;
|
|
56
|
+
/**
|
|
57
|
+
* Item origin
|
|
58
|
+
*/
|
|
59
|
+
origin: ItemOrigin;
|
|
60
|
+
/**
|
|
61
|
+
* ISO timestamp of the check
|
|
62
|
+
*/
|
|
63
|
+
timestamp: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Permission enforcer options
|
|
67
|
+
*/
|
|
68
|
+
export interface PermissionEnforcerOptions {
|
|
69
|
+
/**
|
|
70
|
+
* SyncSettings from config.json (set during specweave init)
|
|
71
|
+
* If not provided, uses defaults (all permissions disabled)
|
|
72
|
+
*/
|
|
73
|
+
settings?: SyncSettings;
|
|
74
|
+
/**
|
|
75
|
+
* Path to .specweave directory for logging
|
|
76
|
+
*/
|
|
77
|
+
specweavePath?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Logger instance
|
|
80
|
+
*/
|
|
81
|
+
logger?: Logger;
|
|
82
|
+
/**
|
|
83
|
+
* Enable decision logging to file
|
|
84
|
+
* @default true
|
|
85
|
+
*/
|
|
86
|
+
enableLogging?: boolean;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* PermissionEnforcer - Validates sync operations before execution
|
|
90
|
+
*
|
|
91
|
+
* Uses the existing SyncSettings from config.json that are configured during
|
|
92
|
+
* `specweave init`. This ensures consistency with user's sync preferences.
|
|
93
|
+
*
|
|
94
|
+
* Features:
|
|
95
|
+
* - Check permissions before any sync operation
|
|
96
|
+
* - Differentiate between internal and external items
|
|
97
|
+
* - Log all decisions for audit
|
|
98
|
+
*/
|
|
99
|
+
export declare class PermissionEnforcer {
|
|
100
|
+
private settings;
|
|
101
|
+
private readonly logPath;
|
|
102
|
+
private readonly logger;
|
|
103
|
+
private readonly enableLogging;
|
|
104
|
+
constructor(options?: PermissionEnforcerOptions);
|
|
105
|
+
/**
|
|
106
|
+
* Check if an operation is permitted for an item
|
|
107
|
+
*
|
|
108
|
+
* @param platform - Target platform (github, jira, ado)
|
|
109
|
+
* @param operation - Operation to perform
|
|
110
|
+
* @param itemId - Item ID being operated on
|
|
111
|
+
* @param origin - Whether item is internal or external
|
|
112
|
+
* @returns Permission result
|
|
113
|
+
*/
|
|
114
|
+
checkPermission(platform: SyncPlatform, operation: SyncOperation, itemId: string, origin?: ItemOrigin): PermissionResult;
|
|
115
|
+
/**
|
|
116
|
+
* Check permission and log the decision
|
|
117
|
+
*
|
|
118
|
+
* @param platform - Target platform
|
|
119
|
+
* @param operation - Operation to perform
|
|
120
|
+
* @param itemId - Item ID being operated on
|
|
121
|
+
* @param origin - Whether item is internal or external
|
|
122
|
+
* @returns Permission result
|
|
123
|
+
*/
|
|
124
|
+
checkAndLog(platform: SyncPlatform, operation: SyncOperation, itemId: string, origin?: ItemOrigin): Promise<PermissionResult>;
|
|
125
|
+
/**
|
|
126
|
+
* Convenience method: Check if upsert is allowed
|
|
127
|
+
*
|
|
128
|
+
* Automatically determines origin from itemId (ends with 'E' = external)
|
|
129
|
+
*
|
|
130
|
+
* @param platform - Target platform
|
|
131
|
+
* @param itemId - Item ID (e.g., "FS-001" or "FS-001E")
|
|
132
|
+
* @returns Permission result
|
|
133
|
+
*/
|
|
134
|
+
checkUpsertPermission(platform: SyncPlatform, itemId: string): PermissionResult;
|
|
135
|
+
/**
|
|
136
|
+
* Convenience method: Check if status update is allowed
|
|
137
|
+
*
|
|
138
|
+
* @param platform - Target platform
|
|
139
|
+
* @param itemId - Item ID
|
|
140
|
+
* @returns Permission result
|
|
141
|
+
*/
|
|
142
|
+
checkStatusUpdatePermission(platform: SyncPlatform, itemId: string): PermissionResult;
|
|
143
|
+
/**
|
|
144
|
+
* Update settings at runtime
|
|
145
|
+
*
|
|
146
|
+
* @param settings - New sync settings (partial update supported)
|
|
147
|
+
*/
|
|
148
|
+
updateSettings(settings: Partial<SyncSettings>): void;
|
|
149
|
+
/**
|
|
150
|
+
* Get current settings
|
|
151
|
+
*
|
|
152
|
+
* @returns Current sync settings
|
|
153
|
+
*/
|
|
154
|
+
getSettings(): SyncSettings;
|
|
155
|
+
/**
|
|
156
|
+
* Check if sync is enabled for any operation
|
|
157
|
+
*
|
|
158
|
+
* @returns true if any sync operation is enabled
|
|
159
|
+
*/
|
|
160
|
+
isSyncEnabled(): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Get a human-readable summary of current permissions
|
|
163
|
+
*
|
|
164
|
+
* @returns Summary object
|
|
165
|
+
*/
|
|
166
|
+
getPermissionsSummary(): {
|
|
167
|
+
canCreateInternal: boolean;
|
|
168
|
+
canUpdateExternal: boolean;
|
|
169
|
+
canUpdateStatus: boolean;
|
|
170
|
+
summary: string;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Detect item origin from ID
|
|
174
|
+
*
|
|
175
|
+
* External items have 'E' suffix (e.g., FS-001E)
|
|
176
|
+
*/
|
|
177
|
+
private detectOrigin;
|
|
178
|
+
/**
|
|
179
|
+
* Check if operation is allowed by current settings
|
|
180
|
+
*/
|
|
181
|
+
private isOperationAllowed;
|
|
182
|
+
/**
|
|
183
|
+
* Get denial reason for logging
|
|
184
|
+
*/
|
|
185
|
+
private getDenialReason;
|
|
186
|
+
/**
|
|
187
|
+
* Log permission decision to file
|
|
188
|
+
*/
|
|
189
|
+
logDecision(result: PermissionResult): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Get log file path (for testing/debugging)
|
|
192
|
+
*/
|
|
193
|
+
getLogPath(): string;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Create a PermissionEnforcer from config.json
|
|
197
|
+
*
|
|
198
|
+
* Reads the existing sync.settings from config.json that was set during
|
|
199
|
+
* `specweave init` and creates a PermissionEnforcer with those settings.
|
|
200
|
+
*
|
|
201
|
+
* @param specweavePath - Path to .specweave directory
|
|
202
|
+
* @param logger - Optional logger
|
|
203
|
+
* @returns PermissionEnforcer instance
|
|
204
|
+
*/
|
|
205
|
+
export declare function createPermissionEnforcerFromConfig(specweavePath?: string, logger?: Logger): Promise<PermissionEnforcer>;
|
|
206
|
+
//# sourceMappingURL=permission-enforcer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-enforcer.d.ts","sourceRoot":"","sources":["../../../../src/core/sync/permission-enforcer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission Enforcer
|
|
3
|
+
*
|
|
4
|
+
* Validates sync operations against configured permissions before execution.
|
|
5
|
+
* Uses the existing SyncSettings from config.json (set during specweave init).
|
|
6
|
+
* Logs all permission decisions for audit.
|
|
7
|
+
*
|
|
8
|
+
* IMPORTANT: This integrates with the existing sync.settings configuration:
|
|
9
|
+
* - canUpsertInternalItems: CREATE/UPDATE internal items in external tools
|
|
10
|
+
* - canUpdateExternalItems: UPDATE items created externally
|
|
11
|
+
* - canUpdateStatus: UPDATE status field for both internal and external items
|
|
12
|
+
*
|
|
13
|
+
* @module core/sync/permission-enforcer
|
|
14
|
+
*/
|
|
15
|
+
import { promises as fs } from 'fs';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import { DEFAULT_SYNC_SETTINGS, } from '../types/sync-settings.js';
|
|
18
|
+
import { consoleLogger } from '../../utils/logger.js';
|
|
19
|
+
/**
|
|
20
|
+
* PermissionEnforcer - Validates sync operations before execution
|
|
21
|
+
*
|
|
22
|
+
* Uses the existing SyncSettings from config.json that are configured during
|
|
23
|
+
* `specweave init`. This ensures consistency with user's sync preferences.
|
|
24
|
+
*
|
|
25
|
+
* Features:
|
|
26
|
+
* - Check permissions before any sync operation
|
|
27
|
+
* - Differentiate between internal and external items
|
|
28
|
+
* - Log all decisions for audit
|
|
29
|
+
*/
|
|
30
|
+
export class PermissionEnforcer {
|
|
31
|
+
constructor(options = {}) {
|
|
32
|
+
this.settings = options.settings ?? { ...DEFAULT_SYNC_SETTINGS };
|
|
33
|
+
const specweavePath = options.specweavePath ?? path.join(process.cwd(), '.specweave');
|
|
34
|
+
this.logPath = path.join(specweavePath, 'logs', 'sync', 'permissions.jsonl');
|
|
35
|
+
this.logger = options.logger ?? consoleLogger;
|
|
36
|
+
this.enableLogging = options.enableLogging ?? true;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if an operation is permitted for an item
|
|
40
|
+
*
|
|
41
|
+
* @param platform - Target platform (github, jira, ado)
|
|
42
|
+
* @param operation - Operation to perform
|
|
43
|
+
* @param itemId - Item ID being operated on
|
|
44
|
+
* @param origin - Whether item is internal or external
|
|
45
|
+
* @returns Permission result
|
|
46
|
+
*/
|
|
47
|
+
checkPermission(platform, operation, itemId, origin = 'internal') {
|
|
48
|
+
const allowed = this.isOperationAllowed(operation, origin);
|
|
49
|
+
const reason = allowed
|
|
50
|
+
? `Operation "${operation}" permitted for ${origin} item`
|
|
51
|
+
: this.getDenialReason(operation, origin);
|
|
52
|
+
const result = {
|
|
53
|
+
allowed,
|
|
54
|
+
reason,
|
|
55
|
+
platform,
|
|
56
|
+
operation,
|
|
57
|
+
itemId,
|
|
58
|
+
origin,
|
|
59
|
+
timestamp: new Date().toISOString(),
|
|
60
|
+
};
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check permission and log the decision
|
|
65
|
+
*
|
|
66
|
+
* @param platform - Target platform
|
|
67
|
+
* @param operation - Operation to perform
|
|
68
|
+
* @param itemId - Item ID being operated on
|
|
69
|
+
* @param origin - Whether item is internal or external
|
|
70
|
+
* @returns Permission result
|
|
71
|
+
*/
|
|
72
|
+
async checkAndLog(platform, operation, itemId, origin = 'internal') {
|
|
73
|
+
const result = this.checkPermission(platform, operation, itemId, origin);
|
|
74
|
+
// Log the decision
|
|
75
|
+
await this.logDecision(result);
|
|
76
|
+
// Log to console if denied
|
|
77
|
+
if (!result.allowed) {
|
|
78
|
+
this.logger.debug(`Permission denied: ${result.reason} (${itemId})`);
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Convenience method: Check if upsert is allowed
|
|
84
|
+
*
|
|
85
|
+
* Automatically determines origin from itemId (ends with 'E' = external)
|
|
86
|
+
*
|
|
87
|
+
* @param platform - Target platform
|
|
88
|
+
* @param itemId - Item ID (e.g., "FS-001" or "FS-001E")
|
|
89
|
+
* @returns Permission result
|
|
90
|
+
*/
|
|
91
|
+
checkUpsertPermission(platform, itemId) {
|
|
92
|
+
const origin = this.detectOrigin(itemId);
|
|
93
|
+
const operation = origin === 'external' ? 'upsert-external' : 'upsert-internal';
|
|
94
|
+
return this.checkPermission(platform, operation, itemId, origin);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Convenience method: Check if status update is allowed
|
|
98
|
+
*
|
|
99
|
+
* @param platform - Target platform
|
|
100
|
+
* @param itemId - Item ID
|
|
101
|
+
* @returns Permission result
|
|
102
|
+
*/
|
|
103
|
+
checkStatusUpdatePermission(platform, itemId) {
|
|
104
|
+
const origin = this.detectOrigin(itemId);
|
|
105
|
+
return this.checkPermission(platform, 'update-status', itemId, origin);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Update settings at runtime
|
|
109
|
+
*
|
|
110
|
+
* @param settings - New sync settings (partial update supported)
|
|
111
|
+
*/
|
|
112
|
+
updateSettings(settings) {
|
|
113
|
+
this.settings = { ...this.settings, ...settings };
|
|
114
|
+
this.logger.debug('Permission enforcer settings updated');
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get current settings
|
|
118
|
+
*
|
|
119
|
+
* @returns Current sync settings
|
|
120
|
+
*/
|
|
121
|
+
getSettings() {
|
|
122
|
+
return { ...this.settings };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if sync is enabled for any operation
|
|
126
|
+
*
|
|
127
|
+
* @returns true if any sync operation is enabled
|
|
128
|
+
*/
|
|
129
|
+
isSyncEnabled() {
|
|
130
|
+
return (this.settings.canUpsertInternalItems ||
|
|
131
|
+
this.settings.canUpdateExternalItems ||
|
|
132
|
+
this.settings.canUpdateStatus);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get a human-readable summary of current permissions
|
|
136
|
+
*
|
|
137
|
+
* @returns Summary object
|
|
138
|
+
*/
|
|
139
|
+
getPermissionsSummary() {
|
|
140
|
+
const parts = [];
|
|
141
|
+
if (this.settings.canUpsertInternalItems) {
|
|
142
|
+
parts.push('create/update internal items');
|
|
143
|
+
}
|
|
144
|
+
if (this.settings.canUpdateExternalItems) {
|
|
145
|
+
parts.push('update external items');
|
|
146
|
+
}
|
|
147
|
+
if (this.settings.canUpdateStatus) {
|
|
148
|
+
parts.push('update status');
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
canCreateInternal: this.settings.canUpsertInternalItems,
|
|
152
|
+
canUpdateExternal: this.settings.canUpdateExternalItems,
|
|
153
|
+
canUpdateStatus: this.settings.canUpdateStatus,
|
|
154
|
+
summary: parts.length > 0 ? `Allowed: ${parts.join(', ')}` : 'All sync disabled (read-only)',
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Detect item origin from ID
|
|
159
|
+
*
|
|
160
|
+
* External items have 'E' suffix (e.g., FS-001E)
|
|
161
|
+
*/
|
|
162
|
+
detectOrigin(itemId) {
|
|
163
|
+
// External items end with 'E' or have '-E-' in the ID
|
|
164
|
+
if (itemId.endsWith('E') || itemId.includes('-E-')) {
|
|
165
|
+
return 'external';
|
|
166
|
+
}
|
|
167
|
+
return 'internal';
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if operation is allowed by current settings
|
|
171
|
+
*/
|
|
172
|
+
isOperationAllowed(operation, origin) {
|
|
173
|
+
switch (operation) {
|
|
174
|
+
case 'read':
|
|
175
|
+
// Reading is always allowed
|
|
176
|
+
return true;
|
|
177
|
+
case 'update-status':
|
|
178
|
+
// Status updates controlled by canUpdateStatus
|
|
179
|
+
return this.settings.canUpdateStatus;
|
|
180
|
+
case 'upsert-internal':
|
|
181
|
+
// Creating/updating internal items controlled by canUpsertInternalItems
|
|
182
|
+
return this.settings.canUpsertInternalItems;
|
|
183
|
+
case 'upsert-external':
|
|
184
|
+
// Updating external items controlled by canUpdateExternalItems
|
|
185
|
+
return this.settings.canUpdateExternalItems;
|
|
186
|
+
default:
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get denial reason for logging
|
|
192
|
+
*/
|
|
193
|
+
getDenialReason(operation, origin) {
|
|
194
|
+
switch (operation) {
|
|
195
|
+
case 'update-status':
|
|
196
|
+
return 'Status updates disabled. Enable sync.settings.canUpdateStatus in config.';
|
|
197
|
+
case 'upsert-internal':
|
|
198
|
+
return 'Creating/updating internal items disabled. Enable sync.settings.canUpsertInternalItems in config.';
|
|
199
|
+
case 'upsert-external':
|
|
200
|
+
return 'Updating external items disabled. Enable sync.settings.canUpdateExternalItems in config.';
|
|
201
|
+
default:
|
|
202
|
+
return `Operation "${operation}" not permitted for ${origin} items.`;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Log permission decision to file
|
|
207
|
+
*/
|
|
208
|
+
async logDecision(result) {
|
|
209
|
+
if (!this.enableLogging) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
// Ensure directory exists
|
|
214
|
+
const dir = path.dirname(this.logPath);
|
|
215
|
+
await fs.mkdir(dir, { recursive: true });
|
|
216
|
+
// Append to JSONL file
|
|
217
|
+
const line = JSON.stringify(result) + '\n';
|
|
218
|
+
await fs.appendFile(this.logPath, line, 'utf-8');
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
// Log errors but don't fail the operation
|
|
222
|
+
this.logger.debug(`Failed to log permission decision: ${error}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get log file path (for testing/debugging)
|
|
227
|
+
*/
|
|
228
|
+
getLogPath() {
|
|
229
|
+
return this.logPath;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Create a PermissionEnforcer from config.json
|
|
234
|
+
*
|
|
235
|
+
* Reads the existing sync.settings from config.json that was set during
|
|
236
|
+
* `specweave init` and creates a PermissionEnforcer with those settings.
|
|
237
|
+
*
|
|
238
|
+
* @param specweavePath - Path to .specweave directory
|
|
239
|
+
* @param logger - Optional logger
|
|
240
|
+
* @returns PermissionEnforcer instance
|
|
241
|
+
*/
|
|
242
|
+
export async function createPermissionEnforcerFromConfig(specweavePath = path.join(process.cwd(), '.specweave'), logger) {
|
|
243
|
+
const configPath = path.join(specweavePath, 'config.json');
|
|
244
|
+
try {
|
|
245
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
246
|
+
const config = JSON.parse(content);
|
|
247
|
+
// Extract sync settings from config
|
|
248
|
+
const settings = {
|
|
249
|
+
canUpsertInternalItems: config?.sync?.settings?.canUpsertInternalItems ?? false,
|
|
250
|
+
canUpdateExternalItems: config?.sync?.settings?.canUpdateExternalItems ?? false,
|
|
251
|
+
canUpdateStatus: config?.sync?.settings?.canUpdateStatus ?? false,
|
|
252
|
+
};
|
|
253
|
+
return new PermissionEnforcer({
|
|
254
|
+
settings,
|
|
255
|
+
specweavePath,
|
|
256
|
+
logger,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
// Return enforcer with default (disabled) settings
|
|
261
|
+
return new PermissionEnforcer({
|
|
262
|
+
settings: DEFAULT_SYNC_SETTINGS,
|
|
263
|
+
specweavePath,
|
|
264
|
+
logger,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=permission-enforcer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-enforcer.js","sourceRoot":"","sources":["../../../../src/core/sync/permission-enforcer.ts"],"names":[],"mappings":"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"}
|