specky-sdd 3.11.1 → 3.12.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/.apm/hooks/scripts/specky-contract-context.mjs +188 -172
- package/CHANGELOG.md +30 -0
- package/README.md +20 -13
- package/apm.lock.yaml +1 -1
- package/apm.yml +3 -3
- package/config.yml +1 -1
- package/dist/cli/commands/apm.d.ts +11 -0
- package/dist/cli/commands/apm.d.ts.map +1 -1
- package/dist/cli/commands/apm.js +4 -4
- package/dist/cli/commands/apm.js.map +1 -1
- package/dist/cli/commands/compile.d.ts.map +1 -1
- package/dist/cli/commands/compile.js +33 -10
- package/dist/cli/commands/compile.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +18 -9
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/hooks.d.ts.map +1 -1
- package/dist/cli/commands/hooks.js +3 -1
- package/dist/cli/commands/hooks.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +13 -12
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/migrate-contracts.d.ts.map +1 -1
- package/dist/cli/commands/migrate-contracts.js +12 -6
- package/dist/cli/commands/migrate-contracts.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +5 -4
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/index.js +23 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/lib/apm/lock.d.ts.map +1 -1
- package/dist/cli/lib/apm/lock.js +1 -1
- package/dist/cli/lib/apm/lock.js.map +1 -1
- package/dist/cli/lib/apm/manifest.d.ts.map +1 -1
- package/dist/cli/lib/apm/manifest.js +1 -1
- package/dist/cli/lib/apm/manifest.js.map +1 -1
- package/dist/cli/lib/apm/policy.d.ts.map +1 -1
- package/dist/cli/lib/apm/policy.js +2 -2
- package/dist/cli/lib/apm/policy.js.map +1 -1
- package/dist/cli/lib/asset-copier.d.ts.map +1 -1
- package/dist/cli/lib/asset-copier.js +25 -10
- package/dist/cli/lib/asset-copier.js.map +1 -1
- package/dist/cli/lib/cursor-plugin-writer.d.ts.map +1 -1
- package/dist/cli/lib/cursor-plugin-writer.js +4 -2
- package/dist/cli/lib/cursor-plugin-writer.js.map +1 -1
- package/dist/cli/lib/gitignore-writer.d.ts.map +1 -1
- package/dist/cli/lib/gitignore-writer.js.map +1 -1
- package/dist/cli/lib/harness/compilers/agent-skills.js.map +1 -1
- package/dist/cli/lib/harness/compilers/claude.d.ts.map +1 -1
- package/dist/cli/lib/harness/compilers/claude.js +2 -4
- package/dist/cli/lib/harness/compilers/claude.js.map +1 -1
- package/dist/cli/lib/harness/compilers/common.d.ts.map +1 -1
- package/dist/cli/lib/harness/compilers/common.js +2 -6
- package/dist/cli/lib/harness/compilers/common.js.map +1 -1
- package/dist/cli/lib/harness/compilers/copilot.js.map +1 -1
- package/dist/cli/lib/harness/compilers/cursor.d.ts.map +1 -1
- package/dist/cli/lib/harness/compilers/cursor.js +2 -4
- package/dist/cli/lib/harness/compilers/cursor.js.map +1 -1
- package/dist/cli/lib/harness/compilers/opencode.d.ts.map +1 -1
- package/dist/cli/lib/harness/compilers/opencode.js +1 -3
- package/dist/cli/lib/harness/compilers/opencode.js.map +1 -1
- package/dist/cli/lib/harness/index.d.ts +1 -1
- package/dist/cli/lib/harness/index.d.ts.map +1 -1
- package/dist/cli/lib/harness/index.js +3 -3
- package/dist/cli/lib/harness/index.js.map +1 -1
- package/dist/cli/lib/harness/tool-map.d.ts.map +1 -1
- package/dist/cli/lib/harness/tool-map.js +1 -2
- package/dist/cli/lib/harness/tool-map.js.map +1 -1
- package/dist/cli/lib/harness/types.d.ts.map +1 -1
- package/dist/cli/lib/ide-detect.d.ts.map +1 -1
- package/dist/cli/lib/ide-detect.js +1 -5
- package/dist/cli/lib/ide-detect.js.map +1 -1
- package/dist/cli/lib/paths.d.ts +10 -0
- package/dist/cli/lib/paths.d.ts.map +1 -1
- package/dist/cli/lib/paths.js +1 -1
- package/dist/cli/lib/paths.js.map +1 -1
- package/dist/cli/lib/settings-merger.d.ts.map +1 -1
- package/dist/cli/lib/settings-merger.js +2 -3
- package/dist/cli/lib/settings-merger.js.map +1 -1
- package/dist/cli/lib/update-check.js +5 -2
- package/dist/cli/lib/update-check.js.map +1 -1
- package/dist/cli/lib/vscode-settings-writer.d.ts.map +1 -1
- package/dist/cli/lib/vscode-settings-writer.js +1 -1
- package/dist/cli/lib/vscode-settings-writer.js.map +1 -1
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +75 -22
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +6 -1
- package/dist/constants.js.map +1 -1
- package/dist/contracts/pipeline-profiles.d.ts.map +1 -1
- package/dist/contracts/pipeline-profiles.js +24 -12
- package/dist/contracts/pipeline-profiles.js.map +1 -1
- package/dist/contracts/tool-contracts.d.ts.map +1 -1
- package/dist/contracts/tool-contracts.js +431 -58
- package/dist/contracts/tool-contracts.js.map +1 -1
- package/dist/contracts/use-case.d.ts +1 -1
- package/dist/contracts/use-case.d.ts.map +1 -1
- package/dist/contracts/use-case.js +253 -72
- package/dist/contracts/use-case.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -48
- package/dist/index.js.map +1 -1
- package/dist/schemas/common.d.ts.map +1 -1
- package/dist/schemas/common.js +1 -3
- package/dist/schemas/common.js.map +1 -1
- package/dist/schemas/context.d.ts.map +1 -1
- package/dist/schemas/context.js +6 -3
- package/dist/schemas/context.js.map +1 -1
- package/dist/schemas/environment.d.ts.map +1 -1
- package/dist/schemas/environment.js +16 -7
- package/dist/schemas/environment.js.map +1 -1
- package/dist/schemas/feature-content.d.ts.map +1 -1
- package/dist/schemas/feature-content.js +44 -17
- package/dist/schemas/feature-content.js.map +1 -1
- package/dist/schemas/infrastructure.d.ts.map +1 -1
- package/dist/schemas/infrastructure.js +16 -7
- package/dist/schemas/infrastructure.js.map +1 -1
- package/dist/schemas/input.d.ts.map +1 -1
- package/dist/schemas/input.js +17 -11
- package/dist/schemas/input.js.map +1 -1
- package/dist/schemas/integration.d.ts.map +1 -1
- package/dist/schemas/integration.js +27 -21
- package/dist/schemas/integration.js.map +1 -1
- package/dist/schemas/metrics.d.ts.map +1 -1
- package/dist/schemas/metrics.js +6 -3
- package/dist/schemas/metrics.js.map +1 -1
- package/dist/schemas/pbt.d.ts.map +1 -1
- package/dist/schemas/pbt.js +6 -3
- package/dist/schemas/pbt.js.map +1 -1
- package/dist/schemas/pipeline.d.ts.map +1 -1
- package/dist/schemas/pipeline.js +71 -58
- package/dist/schemas/pipeline.js.map +1 -1
- package/dist/schemas/quality.d.ts.map +1 -1
- package/dist/schemas/quality.js +35 -12
- package/dist/schemas/quality.js.map +1 -1
- package/dist/schemas/routing.d.ts.map +1 -1
- package/dist/schemas/routing.js +5 -2
- package/dist/schemas/routing.js.map +1 -1
- package/dist/schemas/testing.d.ts.map +1 -1
- package/dist/schemas/testing.js +11 -5
- package/dist/schemas/testing.js.map +1 -1
- package/dist/schemas/transcript.d.ts.map +1 -1
- package/dist/schemas/transcript.js +22 -18
- package/dist/schemas/transcript.js.map +1 -1
- package/dist/schemas/utility.d.ts.map +1 -1
- package/dist/schemas/utility.js +39 -56
- package/dist/schemas/utility.js.map +1 -1
- package/dist/schemas/visualization.d.ts +12 -4
- package/dist/schemas/visualization.d.ts.map +1 -1
- package/dist/schemas/visualization.js +137 -33
- package/dist/schemas/visualization.js.map +1 -1
- package/dist/services/analysis-engine.d.ts.map +1 -1
- package/dist/services/analysis-engine.js +7 -3
- package/dist/services/analysis-engine.js.map +1 -1
- package/dist/services/audit-logger.d.ts +18 -0
- package/dist/services/audit-logger.d.ts.map +1 -1
- package/dist/services/audit-logger.js +75 -37
- package/dist/services/audit-logger.js.map +1 -1
- package/dist/services/codebase-scanner.d.ts.map +1 -1
- package/dist/services/codebase-scanner.js +1 -4
- package/dist/services/codebase-scanner.js.map +1 -1
- package/dist/services/cognitive-debt-engine.d.ts.map +1 -1
- package/dist/services/cognitive-debt-engine.js +1 -1
- package/dist/services/cognitive-debt-engine.js.map +1 -1
- package/dist/services/compliance-engine.d.ts +1 -1
- package/dist/services/compliance-engine.d.ts.map +1 -1
- package/dist/services/compliance-engine.js +210 -30
- package/dist/services/compliance-engine.js.map +1 -1
- package/dist/services/content-diagram-generator.d.ts +96 -0
- package/dist/services/content-diagram-generator.d.ts.map +1 -0
- package/dist/services/content-diagram-generator.js +372 -0
- package/dist/services/content-diagram-generator.js.map +1 -0
- package/dist/services/context-tiering-engine.d.ts +1 -1
- package/dist/services/context-tiering-engine.d.ts.map +1 -1
- package/dist/services/context-tiering-engine.js +2 -4
- package/dist/services/context-tiering-engine.js.map +1 -1
- package/dist/services/cross-analyzer.d.ts +1 -3
- package/dist/services/cross-analyzer.d.ts.map +1 -1
- package/dist/services/cross-analyzer.js +28 -28
- package/dist/services/cross-analyzer.js.map +1 -1
- package/dist/services/dependency-graph.d.ts.map +1 -1
- package/dist/services/dependency-graph.js +148 -28
- package/dist/services/dependency-graph.js.map +1 -1
- package/dist/services/design-completeness.d.ts +19 -0
- package/dist/services/design-completeness.d.ts.map +1 -0
- package/dist/services/design-completeness.js +58 -0
- package/dist/services/design-completeness.js.map +1 -0
- package/dist/services/diagram-generator.d.ts.map +1 -1
- package/dist/services/diagram-generator.js.map +1 -1
- package/dist/services/doc-generator.d.ts.map +1 -1
- package/dist/services/doc-generator.js +43 -12
- package/dist/services/doc-generator.js.map +1 -1
- package/dist/services/document-converter.d.ts +1 -1
- package/dist/services/document-converter.d.ts.map +1 -1
- package/dist/services/document-converter.js +35 -21
- package/dist/services/document-converter.js.map +1 -1
- package/dist/services/ears-validator.d.ts +1 -1
- package/dist/services/ears-validator.d.ts.map +1 -1
- package/dist/services/ears-validator.js +36 -11
- package/dist/services/ears-validator.js.map +1 -1
- package/dist/services/execution-context.d.ts +16 -3
- package/dist/services/execution-context.d.ts.map +1 -1
- package/dist/services/execution-context.js +42 -2
- package/dist/services/execution-context.js.map +1 -1
- package/dist/services/feature-package-generator.d.ts.map +1 -1
- package/dist/services/feature-package-generator.js +43 -15
- package/dist/services/feature-package-generator.js.map +1 -1
- package/dist/services/file-manager.d.ts.map +1 -1
- package/dist/services/file-manager.js +20 -6
- package/dist/services/file-manager.js.map +1 -1
- package/dist/services/git-manager.d.ts +1 -1
- package/dist/services/git-manager.d.ts.map +1 -1
- package/dist/services/git-manager.js +18 -7
- package/dist/services/git-manager.js.map +1 -1
- package/dist/services/iac-generator.d.ts +48 -1
- package/dist/services/iac-generator.d.ts.map +1 -1
- package/dist/services/iac-generator.js +655 -77
- package/dist/services/iac-generator.js.map +1 -1
- package/dist/services/intent-drift-engine.d.ts.map +1 -1
- package/dist/services/intent-drift-engine.js +19 -2
- package/dist/services/intent-drift-engine.js.map +1 -1
- package/dist/services/methodology.d.ts.map +1 -1
- package/dist/services/methodology.js +85 -21
- package/dist/services/methodology.js.map +1 -1
- package/dist/services/metrics-generator.d.ts +0 -1
- package/dist/services/metrics-generator.d.ts.map +1 -1
- package/dist/services/metrics-generator.js +28 -19
- package/dist/services/metrics-generator.js.map +1 -1
- package/dist/services/model-routing-engine.d.ts +4 -4
- package/dist/services/model-routing-engine.d.ts.map +1 -1
- package/dist/services/model-routing-engine.js +73 -72
- package/dist/services/model-routing-engine.js.map +1 -1
- package/dist/services/pbt-generator.d.ts.map +1 -1
- package/dist/services/pbt-generator.js +3 -2
- package/dist/services/pbt-generator.js.map +1 -1
- package/dist/services/rate-limiter.d.ts +8 -0
- package/dist/services/rate-limiter.d.ts.map +1 -1
- package/dist/services/rate-limiter.js +18 -0
- package/dist/services/rate-limiter.js.map +1 -1
- package/dist/services/rbac-engine.d.ts.map +1 -1
- package/dist/services/rbac-engine.js +1 -3
- package/dist/services/rbac-engine.js.map +1 -1
- package/dist/services/state-machine.d.ts +17 -2
- package/dist/services/state-machine.d.ts.map +1 -1
- package/dist/services/state-machine.js +110 -75
- package/dist/services/state-machine.js.map +1 -1
- package/dist/services/template-engine.d.ts +2 -2
- package/dist/services/template-engine.d.ts.map +1 -1
- package/dist/services/template-engine.js +6 -5
- package/dist/services/template-engine.js.map +1 -1
- package/dist/services/test-generator.d.ts +0 -2
- package/dist/services/test-generator.d.ts.map +1 -1
- package/dist/services/test-generator.js +61 -42
- package/dist/services/test-generator.js.map +1 -1
- package/dist/services/test-result-parser.d.ts.map +1 -1
- package/dist/services/test-result-parser.js +5 -4
- package/dist/services/test-result-parser.js.map +1 -1
- package/dist/services/test-traceability-mapper.d.ts.map +1 -1
- package/dist/services/test-traceability-mapper.js +16 -4
- package/dist/services/test-traceability-mapper.js.map +1 -1
- package/dist/services/transcript-parser.d.ts +1 -1
- package/dist/services/transcript-parser.d.ts.map +1 -1
- package/dist/services/transcript-parser.js +61 -27
- package/dist/services/transcript-parser.js.map +1 -1
- package/dist/services/work-item-exporter.d.ts +1 -1
- package/dist/services/work-item-exporter.d.ts.map +1 -1
- package/dist/services/work-item-exporter.js +14 -2
- package/dist/services/work-item-exporter.js.map +1 -1
- package/dist/tools/analysis.d.ts +1 -1
- package/dist/tools/analysis.d.ts.map +1 -1
- package/dist/tools/analysis.js +22 -17
- package/dist/tools/analysis.js.map +1 -1
- package/dist/tools/audit.d.ts.map +1 -1
- package/dist/tools/audit.js +4 -2
- package/dist/tools/audit.js.map +1 -1
- package/dist/tools/checkpoint.d.ts.map +1 -1
- package/dist/tools/checkpoint.js +46 -32
- package/dist/tools/checkpoint.js.map +1 -1
- package/dist/tools/context.d.ts +1 -1
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +4 -9
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/documentation.d.ts.map +1 -1
- package/dist/tools/documentation.js +60 -23
- package/dist/tools/documentation.js.map +1 -1
- package/dist/tools/environment.d.ts +2 -2
- package/dist/tools/environment.d.ts.map +1 -1
- package/dist/tools/environment.js +27 -26
- package/dist/tools/environment.js.map +1 -1
- package/dist/tools/infrastructure.d.ts +1 -1
- package/dist/tools/infrastructure.d.ts.map +1 -1
- package/dist/tools/infrastructure.js +24 -25
- package/dist/tools/infrastructure.js.map +1 -1
- package/dist/tools/input.d.ts +1 -1
- package/dist/tools/input.d.ts.map +1 -1
- package/dist/tools/input.js +31 -29
- package/dist/tools/input.js.map +1 -1
- package/dist/tools/integration.d.ts +1 -1
- package/dist/tools/integration.d.ts.map +1 -1
- package/dist/tools/integration.js +33 -44
- package/dist/tools/integration.js.map +1 -1
- package/dist/tools/metrics.d.ts +4 -4
- package/dist/tools/metrics.d.ts.map +1 -1
- package/dist/tools/metrics.js +5 -15
- package/dist/tools/metrics.js.map +1 -1
- package/dist/tools/pbt.d.ts +1 -1
- package/dist/tools/pbt.d.ts.map +1 -1
- package/dist/tools/pbt.js +6 -16
- package/dist/tools/pbt.js.map +1 -1
- package/dist/tools/pipeline-writers.d.ts +193 -0
- package/dist/tools/pipeline-writers.d.ts.map +1 -0
- package/dist/tools/pipeline-writers.js +203 -0
- package/dist/tools/pipeline-writers.js.map +1 -0
- package/dist/tools/pipeline.d.ts +1 -1
- package/dist/tools/pipeline.d.ts.map +1 -1
- package/dist/tools/pipeline.js +151 -203
- package/dist/tools/pipeline.js.map +1 -1
- package/dist/tools/quality.d.ts +3 -3
- package/dist/tools/quality.d.ts.map +1 -1
- package/dist/tools/quality.js +354 -95
- package/dist/tools/quality.js.map +1 -1
- package/dist/tools/rbac.d.ts.map +1 -1
- package/dist/tools/rbac.js +7 -4
- package/dist/tools/rbac.js.map +1 -1
- package/dist/tools/response-builder.d.ts +1 -1
- package/dist/tools/response-builder.d.ts.map +1 -1
- package/dist/tools/response-builder.js +5 -8
- package/dist/tools/response-builder.js.map +1 -1
- package/dist/tools/routing.d.ts.map +1 -1
- package/dist/tools/routing.js +3 -9
- package/dist/tools/routing.js.map +1 -1
- package/dist/tools/testing.d.ts.map +1 -1
- package/dist/tools/testing.js +36 -32
- package/dist/tools/testing.js.map +1 -1
- package/dist/tools/tool-enforcement.d.ts +2 -2
- package/dist/tools/tool-enforcement.d.ts.map +1 -1
- package/dist/tools/tool-enforcement.js +2 -1
- package/dist/tools/tool-enforcement.js.map +1 -1
- package/dist/tools/tool-result.d.ts +1 -0
- package/dist/tools/tool-result.d.ts.map +1 -1
- package/dist/tools/tool-result.js.map +1 -1
- package/dist/tools/transcript.d.ts +1 -1
- package/dist/tools/transcript.d.ts.map +1 -1
- package/dist/tools/transcript.js +161 -240
- package/dist/tools/transcript.js.map +1 -1
- package/dist/tools/turnkey.d.ts.map +1 -1
- package/dist/tools/turnkey.js +41 -17
- package/dist/tools/turnkey.js.map +1 -1
- package/dist/tools/utility.d.ts +2 -2
- package/dist/tools/utility.d.ts.map +1 -1
- package/dist/tools/utility.js +49 -38
- package/dist/tools/utility.js.map +1 -1
- package/dist/tools/visualization.d.ts.map +1 -1
- package/dist/tools/visualization.js +156 -58
- package/dist/tools/visualization.js.map +1 -1
- package/dist/types.d.ts +18 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/artifact-metadata.d.ts.map +1 -1
- package/dist/utils/artifact-metadata.js.map +1 -1
- package/dist/utils/context-helper.d.ts +1 -1
- package/dist/utils/context-helper.d.ts.map +1 -1
- package/dist/utils/context-helper.js.map +1 -1
- package/dist/utils/http-auth.d.ts.map +1 -1
- package/dist/utils/http-auth.js +1 -1
- package/dist/utils/http-auth.js.map +1 -1
- package/dist/utils/id-contracts.d.ts +21 -0
- package/dist/utils/id-contracts.d.ts.map +1 -1
- package/dist/utils/id-contracts.js +60 -1
- package/dist/utils/id-contracts.js.map +1 -1
- package/dist/utils/requirement-partition.d.ts.map +1 -1
- package/dist/utils/requirement-partition.js.map +1 -1
- package/dist/utils/routing-helper.d.ts +1 -1
- package/dist/utils/routing-helper.d.ts.map +1 -1
- package/dist/utils/routing-helper.js.map +1 -1
- package/dist/utils/safe-read.d.ts +10 -0
- package/dist/utils/safe-read.d.ts.map +1 -0
- package/dist/utils/safe-read.js +10 -0
- package/dist/utils/safe-read.js.map +1 -0
- package/dist/utils/task-parser.d.ts.map +1 -1
- package/dist/utils/task-parser.js +1 -1
- package/dist/utils/task-parser.js.map +1 -1
- package/dist/utils/test-quality.d.ts +10 -0
- package/dist/utils/test-quality.d.ts.map +1 -0
- package/dist/utils/test-quality.js +10 -0
- package/dist/utils/test-quality.js.map +1 -0
- package/dist/utils/token-table.d.ts +20 -0
- package/dist/utils/token-table.d.ts.map +1 -1
- package/dist/utils/token-table.js +2 -2
- package/dist/utils/token-table.js.map +1 -1
- package/package.json +6 -2
|
@@ -1,219 +1,235 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createHash, createHmac, timingSafeEqual } from "node:crypto";
|
|
3
|
-
import { existsSync,
|
|
3
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
4
4
|
import { relative, resolve, sep } from "node:path";
|
|
5
5
|
|
|
6
6
|
function fail(message) {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
console.error(`[specky-contract-context] ${message}`);
|
|
8
|
+
process.exit(2);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
function readHookInput() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
const fromEnvironment = process.env.SDD_HOOK_INPUT;
|
|
13
|
+
if (fromEnvironment?.trim()) return fromEnvironment;
|
|
14
|
+
if (process.stdin.isTTY) return "";
|
|
15
|
+
try {
|
|
16
|
+
return readFileSync(0, "utf8");
|
|
17
|
+
} catch {
|
|
18
|
+
return "";
|
|
19
|
+
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function parseInput(raw) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
if (!raw.trim()) return {};
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(raw);
|
|
26
|
+
} catch {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
function objects(value) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
32
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return [];
|
|
33
|
+
const record = value;
|
|
34
|
+
return [
|
|
35
|
+
record,
|
|
36
|
+
record.tool_input,
|
|
37
|
+
record.toolInput,
|
|
38
|
+
record.arguments,
|
|
39
|
+
record.input,
|
|
40
|
+
record.params,
|
|
41
|
+
record.params?.arguments,
|
|
42
|
+
record.request?.params?.arguments,
|
|
43
|
+
].filter(
|
|
44
|
+
(candidate) => typeof candidate === "object" && candidate !== null && !Array.isArray(candidate),
|
|
45
|
+
);
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
function findString(input, keys) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
49
|
+
for (const candidate of objects(input)) {
|
|
50
|
+
for (const key of keys) {
|
|
51
|
+
const value = candidate[key];
|
|
52
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
function safeRelativePath(value, label) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
if (!value || value.startsWith("/") || value.startsWith("\\") || /^[A-Za-z]:/.test(value)) {
|
|
60
|
+
fail(`${label} must be a workspace-relative path.`);
|
|
61
|
+
}
|
|
62
|
+
const segments = value.split(/[\\/]/);
|
|
63
|
+
if (segments.includes("..") || value.includes("\0")) fail(`${label} contains unsafe traversal.`);
|
|
64
|
+
return segments.filter((segment) => segment && segment !== ".").join("/");
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
function canonicalize(value) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
if (Array.isArray(value)) return value.map(canonicalize);
|
|
69
|
+
if (typeof value !== "object" || value === null) return value;
|
|
70
|
+
return Object.keys(value)
|
|
71
|
+
.sort((left, right) => left.localeCompare(right))
|
|
72
|
+
.reduce((result, key) => {
|
|
73
|
+
result[key] = canonicalize(value[key]);
|
|
74
|
+
return result;
|
|
75
|
+
}, {});
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
function fingerprintContract(contract) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
const { fingerprint: _fingerprint, ...snapshot } = contract;
|
|
80
|
+
return createHash("sha256")
|
|
81
|
+
.update(JSON.stringify(canonicalize(snapshot)))
|
|
82
|
+
.digest("hex");
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
function safeEqualHex(left, right) {
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
if (!/^[a-f0-9]{64}$/.test(left) || !/^[a-f0-9]{64}$/.test(right)) return false;
|
|
87
|
+
return timingSafeEqual(Buffer.from(left, "hex"), Buffer.from(right, "hex"));
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
function shellQuote(value) {
|
|
87
|
-
|
|
91
|
+
return `'${String(value).replaceAll("'", `'"'"'`)}'`;
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
function resolveContext() {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
95
|
+
const workspace = resolve(process.env.SPECKY_HOOK_WORKSPACE ?? process.cwd());
|
|
96
|
+
const input = parseInput(readHookInput());
|
|
97
|
+
const requestedSpecDir = process.env.SDD_SPEC_DIR ?? findString(input, ["spec_dir", "specDir"]);
|
|
98
|
+
const requestedFeatureNumber =
|
|
99
|
+
process.env.SDD_FEATURE_NUMBER ?? findString(input, ["feature_number", "featureNumber"]);
|
|
100
|
+
|
|
101
|
+
if (!requestedSpecDir || !requestedFeatureNumber) {
|
|
102
|
+
return { active: false, reason: "missing explicit SDD_SPEC_DIR/SDD_FEATURE_NUMBER context" };
|
|
103
|
+
}
|
|
104
|
+
const specDir = safeRelativePath(requestedSpecDir, "spec_dir");
|
|
105
|
+
if (!/^\d{3}$/.test(requestedFeatureNumber)) fail("feature_number must be exactly three digits.");
|
|
106
|
+
|
|
107
|
+
const specRoot = resolve(workspace, specDir);
|
|
108
|
+
if (!existsSync(specRoot)) fail(`spec root does not exist: ${specDir}`);
|
|
109
|
+
const matches = readdirSync(specRoot, { withFileTypes: true }).filter(
|
|
110
|
+
(entry) => entry.isDirectory() && entry.name.startsWith(`${requestedFeatureNumber}-`),
|
|
111
|
+
);
|
|
112
|
+
if (matches.length !== 1) {
|
|
113
|
+
fail(
|
|
114
|
+
`feature ${requestedFeatureNumber} must resolve to exactly one directory in ${specDir}; found ${matches.length}.`,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const featureName = matches[0].name.slice(4);
|
|
119
|
+
const featureDirectory = `${specDir}/${matches[0].name}`;
|
|
120
|
+
const statePath = resolve(workspace, featureDirectory, ".sdd-state.json");
|
|
121
|
+
const signaturePath = `${statePath}.sig`;
|
|
122
|
+
if (!existsSync(statePath) || !existsSync(signaturePath)) {
|
|
123
|
+
fail(
|
|
124
|
+
`feature ${requestedFeatureNumber} requires signed v5 state at ${featureDirectory}/.sdd-state.json.`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const raw = readFileSync(statePath, "utf8");
|
|
129
|
+
let state;
|
|
130
|
+
try {
|
|
131
|
+
state = JSON.parse(raw);
|
|
132
|
+
} catch {
|
|
133
|
+
fail(`state is not valid JSON: ${relative(workspace, statePath)}`);
|
|
134
|
+
}
|
|
135
|
+
if (state.version !== "5.0.0") fail(`state version ${String(state.version)} requires migration.`);
|
|
136
|
+
|
|
137
|
+
const key =
|
|
138
|
+
process.env.SDD_STATE_KEY ??
|
|
139
|
+
createHash("sha256").update(`specky-state-v1:${workspace}`).digest("hex");
|
|
140
|
+
const expectedSignature = createHmac("sha256", key).update(raw).digest("hex");
|
|
141
|
+
const storedSignature = readFileSync(signaturePath, "utf8").trim();
|
|
142
|
+
if (!safeEqualHex(storedSignature, expectedSignature))
|
|
143
|
+
fail("feature state signature verification failed.");
|
|
144
|
+
|
|
145
|
+
if (
|
|
146
|
+
state.feature?.number !== requestedFeatureNumber ||
|
|
147
|
+
state.feature?.name !== featureName ||
|
|
148
|
+
state.feature?.directory !== featureDirectory
|
|
149
|
+
) {
|
|
150
|
+
fail(`feature state identity does not match ${featureDirectory}.`);
|
|
151
|
+
}
|
|
152
|
+
if (!state.contract || fingerprintContract(state.contract) !== state.contract.fingerprint) {
|
|
153
|
+
fail("feature contract fingerprint verification failed.");
|
|
154
|
+
}
|
|
155
|
+
if (
|
|
156
|
+
!Array.isArray(state.contract.phases) ||
|
|
157
|
+
!state.contract.phases.includes(state.current_phase)
|
|
158
|
+
) {
|
|
159
|
+
fail(`current phase ${String(state.current_phase)} is not enabled by the feature contract.`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const capabilities = Array.isArray(state.contract.capabilities)
|
|
163
|
+
? state.contract.capabilities
|
|
164
|
+
: [];
|
|
165
|
+
const capabilityConfig = state.contract.capability_config ?? {};
|
|
166
|
+
const configuredCapabilities = Object.keys(capabilityConfig).sort();
|
|
167
|
+
const declaredCapabilities = [...new Set(capabilities)].sort();
|
|
168
|
+
if (JSON.stringify(configuredCapabilities) !== JSON.stringify(declaredCapabilities)) {
|
|
169
|
+
fail("capabilities and capability_config keys do not match.");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
active: true,
|
|
174
|
+
workspace,
|
|
175
|
+
specDir,
|
|
176
|
+
featureNumber: requestedFeatureNumber,
|
|
177
|
+
featureName,
|
|
178
|
+
featureDirectory,
|
|
179
|
+
statePath: relative(workspace, statePath).split(sep).join("/"),
|
|
180
|
+
phase: state.current_phase,
|
|
181
|
+
contract: state.contract,
|
|
182
|
+
gateDecision: state.gate_decision?.decision ?? "",
|
|
183
|
+
};
|
|
168
184
|
}
|
|
169
185
|
|
|
170
186
|
function printShell(context) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
187
|
+
const contract = context.contract ?? {};
|
|
188
|
+
const capabilities = Array.isArray(contract.capabilities) ? contract.capabilities : [];
|
|
189
|
+
const release = contract.capability_config?.release;
|
|
190
|
+
const tdd = contract.capability_config?.tdd;
|
|
191
|
+
const compliance = contract.capability_config?.compliance;
|
|
192
|
+
const development = contract.capability_config?.["dev-environment"];
|
|
193
|
+
const iac = contract.capability_config?.iac;
|
|
194
|
+
const values = {
|
|
195
|
+
SPECKY_CONTEXT_ACTIVE: context.active ? "1" : "0",
|
|
196
|
+
SPECKY_CONTEXT_REASON: context.reason ?? "",
|
|
197
|
+
SPECKY_SPEC_DIR: context.specDir ?? "",
|
|
198
|
+
SPECKY_FEATURE_NUMBER: context.featureNumber ?? "",
|
|
199
|
+
SPECKY_FEATURE_NAME: context.featureName ?? "",
|
|
200
|
+
SPECKY_FEATURE_DIR: context.featureDirectory ?? "",
|
|
201
|
+
SPECKY_STATE_FILE: context.statePath ?? "",
|
|
202
|
+
SPECKY_PHASE: context.phase ?? "",
|
|
203
|
+
SPECKY_CONTRACT_ID: contract.id ?? "",
|
|
204
|
+
SPECKY_CONTRACT_FINGERPRINT: contract.fingerprint ?? "",
|
|
205
|
+
SPECKY_LIFECYCLE: contract.lifecycle ?? "",
|
|
206
|
+
SPECKY_WORKLOAD: contract.workload ?? "",
|
|
207
|
+
SPECKY_EXECUTION_MODE: contract.execution_mode ?? "",
|
|
208
|
+
SPECKY_CAPABILITIES: capabilities.join(","),
|
|
209
|
+
SPECKY_GATE_DECISION: context.gateDecision ?? "",
|
|
210
|
+
SPECKY_RELEASE_ENABLED: release ? "1" : "0",
|
|
211
|
+
SPECKY_BRANCH_PREFIX: release?.branch_prefix ?? "",
|
|
212
|
+
SPECKY_BASE_BRANCH: release?.base_branch ?? "",
|
|
213
|
+
SPECKY_CHECKPOINTS_REQUIRED: release?.checkpoints ? "1" : "0",
|
|
214
|
+
SPECKY_TDD_ENABLED: tdd ? "1" : "0",
|
|
215
|
+
SPECKY_TDD_THRESHOLD: tdd ? String(tdd.coverage_threshold) : "",
|
|
216
|
+
SPECKY_COMPLIANCE_ENABLED: compliance ? "1" : "0",
|
|
217
|
+
SPECKY_COMPLIANCE_FRAMEWORKS: compliance?.frameworks?.join(",") ?? "",
|
|
218
|
+
SPECKY_DEV_ENV_ENABLED: development ? "1" : "0",
|
|
219
|
+
SPECKY_DEV_LANGUAGE: development?.language ?? "",
|
|
220
|
+
SPECKY_IAC_ENABLED: iac ? "1" : "0",
|
|
221
|
+
SPECKY_IAC_PROVIDER: iac?.provider ?? "",
|
|
222
|
+
SPECKY_IAC_CLOUD: iac?.cloud ?? "",
|
|
223
|
+
};
|
|
224
|
+
for (const [key, value] of Object.entries(values)) console.log(`${key}=${shellQuote(value)}`);
|
|
209
225
|
}
|
|
210
226
|
|
|
211
227
|
const command = process.argv[2] ?? "shell";
|
|
212
228
|
const context = resolveContext();
|
|
213
229
|
if (command === "json") {
|
|
214
|
-
|
|
230
|
+
console.log(JSON.stringify(context));
|
|
215
231
|
} else if (command === "shell") {
|
|
216
|
-
|
|
232
|
+
printShell(context);
|
|
217
233
|
} else {
|
|
218
|
-
|
|
234
|
+
fail(`unknown command ${command}`);
|
|
219
235
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.12.0] - 2026-07-20
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Backward-compatible `mode: "explicit" | "auto"` inputs for `sdd_generate_diagram` and `sdd_generate_all_diagrams`; explicit remains the default.
|
|
15
|
+
- Evidence-grounded automatic Mermaid generation for C4 context, sequence, ER, and deployment diagrams from `SPECIFICATION.md` and `DESIGN.md`.
|
|
16
|
+
- Source evidence tracking for derived actors, requirements, exchanges, use cases, components, entities, and deployment nodes.
|
|
17
|
+
- Biome lint and format integration with `biome.json` and npm scripts (`lint`, `lint:fix`, `format`).
|
|
18
|
+
- Unit tests for previously uncovered modules: `slug`, `routing-helper`, `audit-tools`, `transcript-tools`, `cli-commands`, `vscode-settings-writer`, and `agent-skills`.
|
|
19
|
+
- `.specs/001-biome-lint-integration/` spec package for dogfooding the SDD pipeline on Specky itself.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Terraform resource discovery now uses canonical `module:service` keys derived from the relevant `DESIGN.md` sections, with clause-scoped handling for exclusions such as `without`, `avoid`, and `not use`.
|
|
24
|
+
- Diagram-set auto mode synthesizes and validates the complete contracted set in memory before atomically writing `DIAGRAMS.md`.
|
|
25
|
+
- Coverage thresholds ratcheted to 89% statements, 77% branches, 95% functions, and 90% lines.
|
|
26
|
+
- Test suite expanded from 663 to 1019 tests across 99 files.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Unsupported Terraform resource types now fail preflight with an actionable error instead of emitting placeholder comments.
|
|
31
|
+
- `specky compile` now validates and reads instruction primitives through a single file descriptor, eliminating the CodeQL-reported filesystem race.
|
|
32
|
+
- Feature directory identifiers use stable forward-slash separators in user-facing MCP errors on Windows.
|
|
33
|
+
- Integration test and hook timeouts allow subprocess-heavy tests to complete under full-suite CPU contention.
|
|
34
|
+
- Biome warnings for unused imports, unused variables, optional chains, and static-only classes.
|
|
35
|
+
- `useOptionalChain` violations in `settings-merger`, `audit-logger`, `http-auth`, and `token-table`.
|
|
36
|
+
- `noUnusedVariables` violations in `pipeline.ts`, `cross-analyzer.ts`, and `vscode-settings-writer.ts`.
|
|
37
|
+
- `noUnusedFunctionParameters` violations in `metrics.ts` and `turnkey.ts`.
|
|
38
|
+
- `noStaticOnlyClass` suppressions documented for `DependencyGraph` and `MethodologyGuide`.
|
|
39
|
+
|
|
10
40
|
## [3.11.1] - 2026-07-16
|
|
11
41
|
|
|
12
42
|
### Added
|
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
| **Enterprise** | [Compliance Frameworks](#compliance-frameworks) | HIPAA, SOC2, GDPR, PCI-DSS, ISO 27001 |
|
|
61
61
|
| | [Enterprise Ready](#enterprise-ready) | Security, audit trail, quality gates |
|
|
62
62
|
| **Platform** | [The SDD Platform](#the-spec-driven-development-platform) | Built on Spec-Kit, everything included |
|
|
63
|
-
| | [Roadmap](#roadmap) | v3.
|
|
63
|
+
| | [Roadmap](#roadmap) | v3.12.0 current, future capabilities planned |
|
|
64
64
|
|
|
65
65
|
## What is Specky?
|
|
66
66
|
|
|
@@ -106,7 +106,7 @@ specky install --target=opencode # OpenCode
|
|
|
106
106
|
specky install --target=agent-skills # Skills-only shared .agents/skills bundle
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
> **Important:** Prefer `--target=...`. The legacy `--ide` flag still works for `copilot`, `claude`, `both`, and `auto`, but it is deprecated in favor of APM-style targets.
|
|
109
|
+
> **Important:** Prefer `--target=...`. The legacy `--ide` flag still works for `copilot`, `claude`, `both`, and `auto`, but it is deprecated in favor of APM-style targets. Copilot + Claude in the same workspace is supported (`--target=both` or `all`); Specky strips Claude hooks from `.claude/settings.json` so Copilot cannot cross-read them. Prefer a **single** target if you need Claude lifecycle hooks. See [docs/INSTALL.md](docs/INSTALL.md) for details.
|
|
110
110
|
|
|
111
111
|
Or per-project (for teams — pins version in `package.json`, run via `npx`):
|
|
112
112
|
|
|
@@ -215,8 +215,8 @@ Specky adds a **deterministic engine** between your intent and your code:
|
|
|
215
215
|
| EARS validation (programmatic, not AI guessing) | 6 patterns enforced at schema level |
|
|
216
216
|
| Enforced pipeline (not suggestions) | Contract-specific phases, central analysis gate, optional configured LGTM blocking |
|
|
217
217
|
| Pre/post hooks on every phase | specky-artifact-validator, specky-branch-validator, specky-phase-gate, specky-lgtm-gate |
|
|
218
|
-
| Workload-specific diagrams |
|
|
219
|
-
| Infrastructure as Code | Terraform
|
|
218
|
+
| Workload-specific diagrams | Explicit evidence validation or deterministic auto-generation from specification/design content |
|
|
219
|
+
| Infrastructure as Code | DESIGN.md-driven Terraform with exact resource templates and fail-fast preflight |
|
|
220
220
|
| Work item export | GitHub Issues, Azure Boards, Jira via MCP-to-MCP routing |
|
|
221
221
|
| 5 compliance frameworks | HIPAA, SOC2, GDPR, PCI-DSS, ISO 27001 with explicit control-ID evidence |
|
|
222
222
|
| Cross-artifact traceability | Requirement to design to task to test to code |
|
|
@@ -566,7 +566,7 @@ The AI calls:
|
|
|
566
566
|
|
|
567
567
|
- `sdd_run_analysis` → completeness audit, orphaned criteria detection
|
|
568
568
|
- `sdd_compliance_check` → evaluates the persisted SOC2 pack using evidence keyed by control ID
|
|
569
|
-
- `sdd_generate_all_diagrams` → validates
|
|
569
|
+
- `sdd_generate_all_diagrams` → validates explicit Mermaid payloads or uses `mode: "auto"` to derive the complete supported set from source evidence before an atomic write
|
|
570
570
|
|
|
571
571
|
### Step 6: Generate infrastructure and tests
|
|
572
572
|
|
|
@@ -576,7 +576,7 @@ The AI calls:
|
|
|
576
576
|
|
|
577
577
|
The AI calls:
|
|
578
578
|
|
|
579
|
-
- `sdd_generate_iac` → Terraform for the exact cloud/resources
|
|
579
|
+
- `sdd_generate_iac` → Terraform for the exact cloud/resources grounded in the relevant `DESIGN.md` sections; excluded or unsupported resources fail before files are written
|
|
580
580
|
- `sdd_generate_dockerfile` → Dockerfile/compose from the persisted development stack
|
|
581
581
|
- `sdd_generate_tests` → executable tests from fingerprinted requirement bindings
|
|
582
582
|
|
|
@@ -839,16 +839,18 @@ All artifacts are saved in [`.specs/NNN-feature/`](#where-specifications-live).
|
|
|
839
839
|
|
|
840
840
|
| Tool | Description |
|
|
841
841
|
|------|-------------|
|
|
842
|
-
| `sdd_generate_diagram` |
|
|
843
|
-
| `sdd_generate_all_diagrams` |
|
|
842
|
+
| `sdd_generate_diagram` | Explicit Mermaid validation by default, or evidence-grounded auto-generation for supported types |
|
|
843
|
+
| `sdd_generate_all_diagrams` | Explicit validation or atomic auto-generation of the complete supported contracted set |
|
|
844
844
|
| `sdd_generate_user_stories` | User stories with flow diagrams (web-application workload) |
|
|
845
845
|
| `sdd_figma_diagram` | FigJam-ready diagram via Figma MCP |
|
|
846
846
|
|
|
847
|
+
`mode: "explicit"` remains the compatibility default and requires caller-supplied Mermaid plus evidence references. `mode: "auto"` derives C4 context, sequence, ER, and deployment diagrams from `SPECIFICATION.md` and `DESIGN.md`; unsupported contracted types fail before any file is written.
|
|
848
|
+
|
|
847
849
|
### Infrastructure as Code (3)
|
|
848
850
|
|
|
849
851
|
| Tool | Description |
|
|
850
852
|
|------|-------------|
|
|
851
|
-
| `sdd_generate_iac` | Terraform
|
|
853
|
+
| `sdd_generate_iac` | Terraform from canonical `module:service` resources grounded in relevant `DESIGN.md` sections; unsupported templates fail preflight |
|
|
852
854
|
| `sdd_validate_iac` | Validation via Terraform MCP + Azure MCP |
|
|
853
855
|
| `sdd_generate_dockerfile` | Dockerfile + docker-compose from tech stack |
|
|
854
856
|
|
|
@@ -1248,6 +1250,10 @@ npm test
|
|
|
1248
1250
|
# Run tests with coverage report
|
|
1249
1251
|
npm run test:coverage
|
|
1250
1252
|
|
|
1253
|
+
# Lint and format with Biome
|
|
1254
|
+
npm run lint
|
|
1255
|
+
npm run format
|
|
1256
|
+
|
|
1251
1257
|
# Development mode (auto-reload on file changes)
|
|
1252
1258
|
npm run dev
|
|
1253
1259
|
|
|
@@ -1255,9 +1261,9 @@ npm run dev
|
|
|
1255
1261
|
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | node dist/index.js 2>/dev/null
|
|
1256
1262
|
|
|
1257
1263
|
# Run the published image from GHCR (multi-arch: linux/amd64 + linux/arm64)
|
|
1258
|
-
docker pull ghcr.io/paulasilvatech/specky:latest # or pin a release: :3.
|
|
1264
|
+
docker pull ghcr.io/paulasilvatech/specky:latest # or pin a release: :3.12.0
|
|
1259
1265
|
docker run --rm -p 3200:3200 ghcr.io/paulasilvatech/specky:latest
|
|
1260
|
-
curl http://localhost:3200/health # -> {"status":"ok","version":"3.
|
|
1266
|
+
curl http://localhost:3200/health # -> {"status":"ok","version":"3.12.0"}
|
|
1261
1267
|
|
|
1262
1268
|
# Or build and run locally from source
|
|
1263
1269
|
docker build -t specky-sdd:dev .
|
|
@@ -1272,7 +1278,7 @@ deployments (enterprise profile, token auth, TLS proxy, private packages) see
|
|
|
1272
1278
|
|
|
1273
1279
|
## Roadmap
|
|
1274
1280
|
|
|
1275
|
-
### v3.
|
|
1281
|
+
### v3.12.0 (current)
|
|
1276
1282
|
|
|
1277
1283
|
| Capability | Status |
|
|
1278
1284
|
|------------|--------|
|
|
@@ -1281,7 +1287,8 @@ deployments (enterprise profile, token auth, TLS proxy, private packages) see
|
|
|
1281
1287
|
| Target-specific install: `--target=copilot`, `claude`, `cursor`, `opencode`, or `agent-skills` | Stable |
|
|
1282
1288
|
| Copilot-safe hook manifests (no lifecycle event cross-read) | Stable |
|
|
1283
1289
|
| Phase validation on every tool with gate enforcement | Stable |
|
|
1284
|
-
|
|
|
1290
|
+
| Evidence-grounded diagram generation with explicit and auto modes | Stable |
|
|
1291
|
+
| DESIGN.md-driven Terraform with unsupported-resource preflight | Stable |
|
|
1285
1292
|
| 12-section system design template (C4 model, security, infrastructure) | Stable |
|
|
1286
1293
|
| Enriched interactive responses on all tools (progress, handoff, education) | Stable |
|
|
1287
1294
|
| Parallel documentation generation (5 types via Promise.all) | Stable |
|
package/apm.lock.yaml
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
schemaVersion: 1
|
|
3
3
|
package:
|
|
4
4
|
name: specky-sdd
|
|
5
|
-
version: 3.
|
|
5
|
+
version: 3.12.0
|
|
6
6
|
primitives:
|
|
7
7
|
.apm/agents/specky-design-architect.agent.md: sha256:54c69e392e21cbc1097fce8dd9d53d457d2a80d442390c6072c7d8dc5429c47f
|
|
8
8
|
.apm/agents/specky-implementer.agent.md: sha256:4bad0b5238d185e25011cc01de90a146d2e719ad2621c814989c5e2986f13772
|
package/apm.yml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: specky-sdd
|
|
2
|
-
version: 3.
|
|
2
|
+
version: 3.12.0
|
|
3
3
|
description: "Agentic Spec-Driven Development — 10-phase pipeline with 58 MCP tools, 13 agents, 22 prompts, 14 skills, 16 hooks, EARS notation, model routing, and enterprise security"
|
|
4
4
|
author: Paula Silva
|
|
5
5
|
license: MIT
|
|
@@ -32,7 +32,7 @@ mcp:
|
|
|
32
32
|
registry: false
|
|
33
33
|
transport: stdio
|
|
34
34
|
command: npx
|
|
35
|
-
args: ["-y", "specky-sdd@3.
|
|
35
|
+
args: ["-y", "specky-sdd@3.12.0", "serve"]
|
|
36
36
|
tools: ["sdd_*"]
|
|
37
37
|
|
|
38
38
|
dependencies:
|
|
@@ -41,7 +41,7 @@ dependencies:
|
|
|
41
41
|
registry: false
|
|
42
42
|
transport: stdio
|
|
43
43
|
command: npx
|
|
44
|
-
args: ["-y", "specky-sdd@3.
|
|
44
|
+
args: ["-y", "specky-sdd@3.12.0"]
|
|
45
45
|
tools: ["*"]
|
|
46
46
|
|
|
47
47
|
scripts:
|
package/config.yml
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* commands/apm.ts — `specky apm <subcommand>` governance surface.
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* validate Validate apm.yml against on-disk primitives + package.json.
|
|
6
|
+
* lock Write apm.lock.yaml with a sha256 for every primitive.
|
|
7
|
+
* verify-lock Recompute hashes and diff against apm.lock.yaml.
|
|
8
|
+
* policy Enforce apm-policy.yml (MCP allowlist, hooks, tool isolation).
|
|
9
|
+
* audit Run the primitive frontmatter audit.
|
|
10
|
+
* sbom Emit a CycloneDX SBOM of the packaged primitives.
|
|
11
|
+
*/
|
|
1
12
|
export declare function apmCommand(argv: string[]): number;
|
|
2
13
|
//# sourceMappingURL=apm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apm.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/apm.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apm.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/apm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAoGH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAwCjD"}
|