speckeeper 0.10.1 → 0.11.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/README.md +1 -0
- package/cli-contract.yaml +206 -208
- package/dist/cli.js +1505 -80
- package/dist/cli.js.map +1 -1
- package/dist/{config-api-CLVjdgIP.d.ts → config-api-coyCX1SB.d.ts} +21 -1
- package/dist/dsl/index.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +75 -3
- package/dist/index.js.map +1 -1
- package/docs/cli-reference.md +107 -154
- package/docs/design/cli-commands.md +36 -0
- package/docs/design/functional-requirements.md +101 -3
- package/docs/design/nonfunctional-requirements.md +3 -3
- package/docs/design/test-refs.md +26 -0
- package/package.json +3 -3
|
@@ -848,6 +848,26 @@ declare function getSpecsFromConfig(specs: SpecEntry[] | undefined, modelId: str
|
|
|
848
848
|
* Pure function — no global state.
|
|
849
849
|
*/
|
|
850
850
|
declare function findModelTypeFromConfig(specs: SpecEntry[] | undefined, specId: string): string | null;
|
|
851
|
+
/**
|
|
852
|
+
* Load spec data from a YAML or JSON file.
|
|
853
|
+
* Supports two formats:
|
|
854
|
+
* - Single-model shorthand: `{ model: "term", specs: [...] }`
|
|
855
|
+
* - Multi-model entries: `{ entries: [{ model: "...", specs: [...] }, ...] }`
|
|
856
|
+
*
|
|
857
|
+
* Each spec is validated against the model's Zod schema.
|
|
858
|
+
*
|
|
859
|
+
* @param yamlPath - Path to the .yaml / .yml / .json file
|
|
860
|
+
* @param models - Array of Model instances to resolve `model` field against
|
|
861
|
+
*/
|
|
862
|
+
declare function loadYamlSpecs(yamlPath: string, models: Model<any>[]): SpecModule;
|
|
863
|
+
/**
|
|
864
|
+
* Load all YAML / JSON spec files from a directory.
|
|
865
|
+
* Scans for `*.yaml`, `*.yml`, `*.json` files, excluding `_models/` subdirectory.
|
|
866
|
+
*
|
|
867
|
+
* @param dirPath - Directory to scan (typically `design/`)
|
|
868
|
+
* @param models - Array of Model instances
|
|
869
|
+
*/
|
|
870
|
+
declare function loadYamlDir(dirPath: string, models: Model<any>[]): SpecModule[];
|
|
851
871
|
|
|
852
872
|
/** Artifact scan configuration */
|
|
853
873
|
interface ArtifactConfig {
|
|
@@ -1080,4 +1100,4 @@ declare function createLintRule<T>(config: {
|
|
|
1080
1100
|
*/
|
|
1081
1101
|
declare function loadSpeckeeperConfig(configPath?: string): Promise<ResolvedSpeckeeperConfig | null>;
|
|
1082
1102
|
|
|
1083
|
-
export { type SpeckeeperConfigInput as $, type ArtifactConfig as A, type BaseModelInstance as B, type CheckContext as C, type DDLValidationMapping as D, type ExportContext as E, type ModelDefinitionInput as F, type ModelLevel as G, RELATION_TYPES as H, type InferModelType as I, type JsonSchemaExporter as J, type ReferenceDefinition as K, type LintContext as L, type ModelDefinition as M, ReferenceDefinitionSchema as N, type OpenAPIValidationMapping as O, type Relation as P, RelationSchema as Q, RELATION_CONSTRAINTS as R, type SourceConfig as S, type RelationValidationError as T, RelationsFieldSchema as U, type RenderContext as V, type Renderer as W, type ResolvedSpeckeeperConfig as X, type SourceMatch as Y, type SourceScanner as Z, type SpecModule as _, type CheckResult$1 as a, buildRegistryFromConfig as a0, createLintRule as a1, createMarkdownExporter as a2, createMermaidExporter as a3, defineConfig as a4, defineModel as a5, defineSpecs as a6, detectCycles as a7, findModelTypeFromConfig as a8, getLevelIndex as a9, getSpecsFromConfig as aa, inferModelIdFromSpecId as ab, loadSpeckeeperConfig as ac,
|
|
1103
|
+
export { type SpeckeeperConfigInput as $, type ArtifactConfig as A, type BaseModelInstance as B, type CheckContext as C, type DDLValidationMapping as D, type ExportContext as E, type ModelDefinitionInput as F, type ModelLevel as G, RELATION_TYPES as H, type InferModelType as I, type JsonSchemaExporter as J, type ReferenceDefinition as K, type LintContext as L, type ModelDefinition as M, ReferenceDefinitionSchema as N, type OpenAPIValidationMapping as O, type Relation as P, RelationSchema as Q, RELATION_CONSTRAINTS as R, type SourceConfig as S, type RelationValidationError as T, RelationsFieldSchema as U, type RenderContext as V, type Renderer as W, type ResolvedSpeckeeperConfig as X, type SourceMatch as Y, type SourceScanner as Z, type SpecModule as _, type CheckResult$1 as a, buildRegistryFromConfig as a0, createLintRule as a1, createMarkdownExporter as a2, createMermaidExporter as a3, defineConfig as a4, defineModel as a5, defineSpecs as a6, detectCycles as a7, findModelTypeFromConfig as a8, getLevelIndex as a9, getSpecsFromConfig as aa, inferModelIdFromSpecId as ab, loadSpeckeeperConfig as ac, loadYamlDir as ad, loadYamlSpecs as ae, mergeSpecs as af, validateRelationLevel as ag, type MetaModelRegistry as b, type LintRule$1 as c, type LintIssue as d, type SpecEntry as e, type CheckError as f, CheckErrorSchema as g, type CheckResult as h, CheckResultSchema as i, type CheckWarning as j, CheckWarningSchema as k, type CoverageChecker as l, type CoverageResult as m, type DeepValidationConfig as n, type DeepValidationRule as o, type Exporter as p, type ExternalChecker as q, LintIssueSchema as r, type LintResult as s, type LintRule as t, type LookupKeyConfig as u, type MarkdownExporter as v, type MergedDesign as w, type MermaidExporter as x, type MetaModelConfig as y, Model as z };
|
package/dist/dsl/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { t as LintRule, p as Exporter, l as CoverageChecker, A as ArtifactConfig, Y as SourceMatch, Z as SourceScanner, n as DeepValidationConfig, h as CheckResult, S as SourceConfig } from '../config-api-
|
|
2
|
+
import { t as LintRule, p as Exporter, l as CoverageChecker, A as ArtifactConfig, Y as SourceMatch, Z as SourceScanner, n as DeepValidationConfig, h as CheckResult, S as SourceConfig } from '../config-api-coyCX1SB.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Core DSL — Base spec schema
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { C as CheckContext, a as CheckResult, E as ExportContext, M as ModelDefinition, b as MetaModelRegistry, L as LintContext, c as LintRule, d as LintIssue, S as SourceConfig, e as SpecEntry } from './config-api-
|
|
3
|
-
export { A as ArtifactConfig, B as BaseModelInstance, f as CheckError, g as CheckErrorSchema, h as CheckResult, i as CheckResultSchema, j as CheckWarning, k as CheckWarningSchema, l as CoverageChecker, m as CoverageResult, D as DDLValidationMapping, n as DeepValidationConfig, o as DeepValidationRule, p as Exporter, q as ExternalChecker, I as InferModelType, J as JsonSchemaExporter, r as LintIssueSchema, s as LintResult, t as LintRule, u as LookupKeyConfig, v as MarkdownExporter, w as MergedDesign, x as MermaidExporter, y as MetaModelConfig, z as Model, F as ModelDefinitionInput, G as ModelLevel, O as OpenAPIValidationMapping, R as RELATION_CONSTRAINTS, H as RELATION_TYPES, K as ReferenceDefinition, N as ReferenceDefinitionSchema, P as Relation, Q as RelationSchema, T as RelationValidationError, U as RelationsFieldSchema, V as RenderContext, W as Renderer, X as ResolvedSpeckeeperConfig, Y as SourceMatch, Z as SourceScanner, _ as SpecModule, $ as SpeckeeperConfigInput, a0 as buildRegistryFromConfig, a1 as createLintRule, a2 as createMarkdownExporter, a3 as createMermaidExporter, a4 as defineConfig, a5 as defineModel, a6 as defineSpecs, a7 as detectCycles, a8 as findModelTypeFromConfig, a9 as getLevelIndex, aa as getSpecsFromConfig, ab as inferModelIdFromSpecId, ac as loadSpeckeeperConfig, ad as
|
|
2
|
+
import { C as CheckContext, a as CheckResult, E as ExportContext, M as ModelDefinition, b as MetaModelRegistry, L as LintContext, c as LintRule, d as LintIssue, S as SourceConfig, e as SpecEntry } from './config-api-coyCX1SB.js';
|
|
3
|
+
export { A as ArtifactConfig, B as BaseModelInstance, f as CheckError, g as CheckErrorSchema, h as CheckResult, i as CheckResultSchema, j as CheckWarning, k as CheckWarningSchema, l as CoverageChecker, m as CoverageResult, D as DDLValidationMapping, n as DeepValidationConfig, o as DeepValidationRule, p as Exporter, q as ExternalChecker, I as InferModelType, J as JsonSchemaExporter, r as LintIssueSchema, s as LintResult, t as LintRule, u as LookupKeyConfig, v as MarkdownExporter, w as MergedDesign, x as MermaidExporter, y as MetaModelConfig, z as Model, F as ModelDefinitionInput, G as ModelLevel, O as OpenAPIValidationMapping, R as RELATION_CONSTRAINTS, H as RELATION_TYPES, K as ReferenceDefinition, N as ReferenceDefinitionSchema, P as Relation, Q as RelationSchema, T as RelationValidationError, U as RelationsFieldSchema, V as RenderContext, W as Renderer, X as ResolvedSpeckeeperConfig, Y as SourceMatch, Z as SourceScanner, _ as SpecModule, $ as SpeckeeperConfigInput, a0 as buildRegistryFromConfig, a1 as createLintRule, a2 as createMarkdownExporter, a3 as createMermaidExporter, a4 as defineConfig, a5 as defineModel, a6 as defineSpecs, a7 as detectCycles, a8 as findModelTypeFromConfig, a9 as getLevelIndex, aa as getSpecsFromConfig, ab as inferModelIdFromSpecId, ac as loadSpeckeeperConfig, ad as loadYamlDir, ae as loadYamlSpecs, af as mergeSpecs, ag as validateRelationLevel } from './config-api-coyCX1SB.js';
|
|
4
4
|
|
|
5
5
|
declare const PhaseSchema: z.ZodEnum<["REQ", "HLD", "LLD", "IMPL", "OPS", "CI"]>;
|
|
6
6
|
type Phase = z.infer<typeof PhaseSchema>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { readFileSync, readdirSync, statSync, existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
3
|
+
import { extname, join, resolve, dirname } from 'path';
|
|
4
4
|
import { parse } from 'yaml';
|
|
5
5
|
import { createHash } from 'crypto';
|
|
6
6
|
import { glob } from 'glob';
|
|
@@ -645,6 +645,78 @@ function findModelTypeFromConfig(specs, specId) {
|
|
|
645
645
|
}
|
|
646
646
|
return null;
|
|
647
647
|
}
|
|
648
|
+
function isMultiModelFormat(data) {
|
|
649
|
+
return "entries" in data && Array.isArray(data.entries);
|
|
650
|
+
}
|
|
651
|
+
function resolveModel(modelId, models, filePath) {
|
|
652
|
+
const found = models.find((m) => m.id === modelId);
|
|
653
|
+
if (!found) {
|
|
654
|
+
const available = models.map((m) => m.id).join(", ");
|
|
655
|
+
throw new Error(
|
|
656
|
+
`Unknown model "${modelId}" in ${filePath}. Available models: ${available}`
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
return found;
|
|
660
|
+
}
|
|
661
|
+
function validateSpecs(model, specs, filePath) {
|
|
662
|
+
const validated = [];
|
|
663
|
+
for (let i = 0; i < specs.length; i++) {
|
|
664
|
+
const raw = specs[i];
|
|
665
|
+
const result = model.safeParse(raw);
|
|
666
|
+
if (!result.success) {
|
|
667
|
+
const specId = raw?.id ?? `[index ${i}]`;
|
|
668
|
+
const issues = result.error.issues.map((iss) => ` - ${iss.path.join(".")}: ${iss.message}`).join("\n");
|
|
669
|
+
throw new Error(
|
|
670
|
+
`Validation failed for spec "${specId}" (model: ${model.id}) in ${filePath}:
|
|
671
|
+
${issues}`
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
validated.push(result.data);
|
|
675
|
+
}
|
|
676
|
+
return validated;
|
|
677
|
+
}
|
|
678
|
+
function loadYamlSpecs(yamlPath, models) {
|
|
679
|
+
const ext = extname(yamlPath).toLowerCase();
|
|
680
|
+
const raw = readFileSync(yamlPath, "utf-8");
|
|
681
|
+
let data;
|
|
682
|
+
try {
|
|
683
|
+
data = ext === ".json" ? JSON.parse(raw) : parse(raw);
|
|
684
|
+
} catch (err) {
|
|
685
|
+
throw new Error(
|
|
686
|
+
`Failed to parse ${yamlPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
const groups = isMultiModelFormat(data) ? data.entries : [data];
|
|
690
|
+
const entries = groups.map((group) => {
|
|
691
|
+
const model = resolveModel(group.model, models, yamlPath);
|
|
692
|
+
const validatedData = validateSpecs(model, group.specs, yamlPath);
|
|
693
|
+
return { model, data: validatedData };
|
|
694
|
+
});
|
|
695
|
+
return { entries };
|
|
696
|
+
}
|
|
697
|
+
function loadYamlDir(dirPath, models) {
|
|
698
|
+
const YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yaml", ".yml", ".json"]);
|
|
699
|
+
const results = [];
|
|
700
|
+
let entries;
|
|
701
|
+
try {
|
|
702
|
+
entries = readdirSync(dirPath);
|
|
703
|
+
} catch {
|
|
704
|
+
return results;
|
|
705
|
+
}
|
|
706
|
+
for (const entry of entries) {
|
|
707
|
+
if (entry === "_models") continue;
|
|
708
|
+
const fullPath = join(dirPath, entry);
|
|
709
|
+
const ext = extname(entry).toLowerCase();
|
|
710
|
+
if (!YAML_EXTENSIONS.has(ext)) continue;
|
|
711
|
+
try {
|
|
712
|
+
if (!statSync(fullPath).isFile()) continue;
|
|
713
|
+
} catch {
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
results.push(loadYamlSpecs(fullPath, models));
|
|
717
|
+
}
|
|
718
|
+
return results;
|
|
719
|
+
}
|
|
648
720
|
|
|
649
721
|
// src/core/model-registry.ts
|
|
650
722
|
var globalRegistry = {
|
|
@@ -1180,6 +1252,6 @@ function generateSpecsPath(baseDir, category, filename) {
|
|
|
1180
1252
|
return join(baseDir, category, filename);
|
|
1181
1253
|
}
|
|
1182
1254
|
|
|
1183
|
-
export { CheckErrorSchema, CheckResultSchema, CheckWarningSchema, ConcretizationSlotSchema, ID_PATTERNS, LinkSchema, LintIssueSchema, Model, PhaseSchema, PrioritySchema, RELATION_CONSTRAINTS, RELATION_TYPES, ReferenceDefinitionSchema, RelationSchema, RelationsFieldSchema, batchWriteFiles, buildRegistryFromConfig, checkBatchDrift, checkExternalSsot, checkFileDrift, checkReferenceIntegrity, computeHash, createAPIRefId, createActorId, createBatchRefId, createBoundaryId, createComponentId, createDTORequirementId, createEntityId, createErrorCaseId, createEventRequirementId, createFormId, createIaCRefId, createLayerId, createLintRule, createMarkdownExporter, createMermaidExporter, createProcessFlowId, createRelationId, createRequirementId, createRuleId, createScreenId, createStateId, createTableRefId, createTermId, createTransitionId, createUIComponentId, createUseCaseId, defineConfig, defineModel, defineSpecs, detectCycles, ensureDir, exportAllModels, exportMarkdown, exportMermaid, findConfigFile, findDefinitionFiles, findFiles, findModelTypeFromConfig, findTypeScriptFiles, generateDocsPath, generateSpecsPath, getAllInstances, getAllModelDefinitions, getAllModelInstances, getExpectedOutputDirs, getGlobalModelRegistry, getLevelIndex, getModelDefinition, getModelInstance, getModelRegistryStats, getOutputPaths, getSpecsFromConfig, inferModelIdFromSpecId, lintAllModels, lintModel, loadConfig, loadSpeckeeperConfig, mergeSpecs, registerModelDefinition, registerModelDefinitions, registerModelInstance, resetModelInstances, resetModelRegistry, resolveReference, validateConfig, validateOutputPaths, validateRelationLevel, writeFile, writeJsonFile };
|
|
1255
|
+
export { CheckErrorSchema, CheckResultSchema, CheckWarningSchema, ConcretizationSlotSchema, ID_PATTERNS, LinkSchema, LintIssueSchema, Model, PhaseSchema, PrioritySchema, RELATION_CONSTRAINTS, RELATION_TYPES, ReferenceDefinitionSchema, RelationSchema, RelationsFieldSchema, batchWriteFiles, buildRegistryFromConfig, checkBatchDrift, checkExternalSsot, checkFileDrift, checkReferenceIntegrity, computeHash, createAPIRefId, createActorId, createBatchRefId, createBoundaryId, createComponentId, createDTORequirementId, createEntityId, createErrorCaseId, createEventRequirementId, createFormId, createIaCRefId, createLayerId, createLintRule, createMarkdownExporter, createMermaidExporter, createProcessFlowId, createRelationId, createRequirementId, createRuleId, createScreenId, createStateId, createTableRefId, createTermId, createTransitionId, createUIComponentId, createUseCaseId, defineConfig, defineModel, defineSpecs, detectCycles, ensureDir, exportAllModels, exportMarkdown, exportMermaid, findConfigFile, findDefinitionFiles, findFiles, findModelTypeFromConfig, findTypeScriptFiles, generateDocsPath, generateSpecsPath, getAllInstances, getAllModelDefinitions, getAllModelInstances, getExpectedOutputDirs, getGlobalModelRegistry, getLevelIndex, getModelDefinition, getModelInstance, getModelRegistryStats, getOutputPaths, getSpecsFromConfig, inferModelIdFromSpecId, lintAllModels, lintModel, loadConfig, loadSpeckeeperConfig, loadYamlDir, loadYamlSpecs, mergeSpecs, registerModelDefinition, registerModelDefinitions, registerModelInstance, resetModelInstances, resetModelRegistry, resolveReference, validateConfig, validateOutputPaths, validateRelationLevel, writeFile, writeJsonFile };
|
|
1184
1256
|
//# sourceMappingURL=index.js.map
|
|
1185
1257
|
//# sourceMappingURL=index.js.map
|