speckeeper 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/config-loader.ts","../src/utils/file-writer.ts","../src/core/relation.ts","../src/core/model.ts","../src/cli/build.ts","../src/utils/model-loader.ts","../src/cli/lint.ts","../src/cli/drift.ts","../src/cli/check.ts","../src/cli/new.ts","../src/cli/impact.ts","../src/cli/init.ts","../src/cli/index.ts"],"names":["parseYaml","existsSync","dirname","readFileSync","chalk","join","resolve","getSpecsFromRegistry","models","model","writeFileSync","__filename","__dirname","readdirSync","statSync","mkdirSync"],"mappings":";;;;;;;;;;;AAgHA,IAAM,aAAA,GAAkC;AAAA,EACtC,MAAA,EAAQ,KAAA;AAAA,EACR,SAAA,EAAW,QAAA;AAAA;AAAA,EACX,OAAA,EAAS,MAAA;AAAA,EACT,QAAA,EAAU;AACZ,CAAA;AAyFA,IAAM,YAAA,GAAe;AAAA,EACnB,wBAAA;AAAA,EACA,uBAAA;AAAA,EACA,wBAAA;AAAA,EACA,sBAAA;AAAA,EACA;AACF,CAAA;AAEO,SAAS,cAAA,CAAe,QAAA,GAAmB,OAAA,CAAQ,GAAA,EAAI,EAAkB;AAC9E,EAAA,IAAI,UAAA,GAAa,QAAA;AAEjB,EAAA,OAAO,UAAA,KAAe,OAAA,CAAQ,UAAU,CAAA,EAAG;AACzC,IAAA,KAAA,MAAW,cAAc,YAAA,EAAc;AACrC,MAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,UAAA,EAAY,UAAU,CAAA;AACjD,MAAA,IAAI,UAAA,CAAW,UAAU,CAAA,EAAG;AAC1B,QAAA,OAAO,UAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,UAAA,GAAa,QAAQ,UAAU,CAAA;AAAA,EACjC;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,eAAsB,UAAA,CACpB,UAAA,EACA,GAAA,GAAc,OAAA,CAAQ,KAAI,EACC;AAC3B,EAAA,MAAM,YAAA,GAAe,UAAA,IAAc,cAAA,CAAe,GAAG,CAAA;AAErD,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,OAAO,EAAE,GAAG,aAAA,EAAc;AAAA,EAC5B;AAEA,EAAA,MAAM,MAAM,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,IAAO,WAAA,EAAY;AAEvD,EAAA,IAAI;AACF,IAAA,IAAI,GAAA,KAAQ,MAAA,IAAU,GAAA,KAAQ,KAAA,EAAO;AACnC,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,YAAA,EAAc,OAAO,CAAA;AAClD,MAAA,MAAM,MAAA,GAASA,MAAU,OAAO,CAAA;AAChC,MAAA,OAAO,EAAE,GAAG,aAAA,EAAe,GAAG,MAAA,EAAO;AAAA,IACvC;AAEA,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,MAAM,OAAA,GAAU,YAAA,CAAa,YAAA,EAAc,OAAO,CAAA;AAClD,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AACjC,MAAA,OAAO,EAAE,GAAG,aAAA,EAAe,GAAG,MAAA,EAAO;AAAA,IACvC;AAEA,IAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,IAAA,EAAM;AAEhC,MAAA,MAAM,MAAA,GAAS,MAAM,OAAO,YAAA,CAAA;AAC5B,MAAA,MAAM,MAAA,GAAS,OAAO,OAAA,IAAW,MAAA;AACjC,MAAA,OAAO,EAAE,GAAG,aAAA,EAAe,GAAG,MAAA,EAAO;AAAA,IACvC;AAEA,IAAA,OAAO,EAAE,GAAG,aAAA,EAAc;AAAA,EAC5B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,2BAAA,EAA8B,YAAY,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAClE,IAAA,OAAO,EAAE,GAAG,aAAA,EAAc;AAAA,EAC5B;AACF;AC5PO,SAAS,UAAU,OAAA,EAAuB;AAC/C,EAAA,IAAI,CAACC,UAAAA,CAAW,OAAO,CAAA,EAAG;AACxB,IAAA,SAAA,CAAU,OAAA,EAAS,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAAA,EACxC;AACF;AAEO,SAAS,SAAA,CAAU,UAAkB,OAAA,EAA8B;AACxE,EAAA,MAAM,GAAA,GAAMC,QAAQ,QAAQ,CAAA;AAC5B,EAAA,SAAA,CAAU,GAAG,CAAA;AAEb,EAAA,MAAM,OAAA,GAAUD,WAAW,QAAQ,CAAA;AACnC,EAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,eAAA,GAAkBE,YAAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AACtD,IAAA,SAAA,GAAY,eAAA,KAAoB,OAAA;AAAA,EAClC;AAEA,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,aAAA,CAAc,QAAA,EAAU,SAAS,OAAO,CAAA;AAAA,EAC1C;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,SAAS,CAAC,OAAA;AAAA,IACV,OAAA,EAAS,WAAW,CAAC,SAAA;AAAA,IACrB;AAAA,GACF;AACF;AAmBO,SAAS,gBACd,KAAA,EACkB;AAClB,EAAA,MAAM,UAAyB,EAAC;AAEhC,EAAA,KAAA,MAAW,EAAE,IAAA,EAAM,OAAA,EAAQ,IAAK,KAAA,EAAO;AACrC,IAAA,OAAA,CAAQ,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,EACvC;AAEA,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,SAAS,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,CAAA,CAAE,MAAA;AAAA,IACxC,SAAS,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,CAAA,CAAE,MAAA;AAAA,IACxC,WAAW,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,CAAA,CAAE,MAAA;AAAA,IAC5C,OAAO,OAAA,CAAQ;AAAA,GACjB;AACF;ACzCO,IAAM,cAAA,GAAiB;AAAA,EAC5B,WAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA;AAOO,IAAM,cAAA,GAAiB,EAAE,MAAA,CAAO;AAAA;AAAA,EAErC,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,cAAc,CAAA;AAAA;AAAA,EAE3B,MAAA,EAAQ,EAAE,MAAA,EAAO;AAAA;AAAA,EAEjB,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAC1B,CAAC,CAAA;AAMmC,CAAA,CAAE,KAAA,CAAM,cAAc,EAAE,QAAA;;;ACqY5D,IAAM,aAAA,uBAAoB,GAAA,EAAwB;AAM3C,SAAS,cAAc,KAAA,EAAyB;AACrD,EAAA,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,EAAA,EAAI,KAAK,CAAA;AACnC;AAcO,SAAS,YAAA,GAA6B;AAC3C,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,aAAA,CAAc,MAAA,EAAQ,CAAA;AAC1C;;;ACpcA,eAAsB,aAAa,OAAA,EAA6C;AAC9E,EAAA,OAAA,CAAQ,GAAA,CAAIC,MAAA,CAAM,IAAA,CAAK,kBAAkB,CAAC,CAAA;AAC1C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AAGxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAG9C,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,WAAA,EAAc,OAAO,SAAA,IAAa,QAAQ,GAAG,CAAC,CAAA;AACrE,EAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,cAAc,MAAA,CAAO,OAAO,GAAG,CAAC,CAAA;AACvD,EAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,cAAc,MAAA,CAAO,QAAQ,GAAG,CAAC,CAAA;AACxD,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,SAAA,CAAUC,IAAAA,CAAK,GAAA,EAAK,MAAA,CAAO,OAAO,CAAC,CAAA;AACnC,IAAA,SAAA,CAAUA,IAAAA,CAAK,GAAA,EAAK,MAAA,CAAO,QAAQ,CAAC,CAAA;AAEpC,IAAA,MAAM,QAAkD,EAAC;AACzD,IAAA,MAAM,SAAS,YAAA,EAAa;AAE5B,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA,OAAA,CAAQ,GAAA,CAAID,MAAA,CAAM,MAAA,CAAO,uDAAuD,CAAC,CAAA;AACjF,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,gBAAgB,MAAA,CAAO,MAAM,iBAAiB,CAAC,CAAA;AAGtE,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,SAAA,GAAY,MAAM,YAAA,EAAa;AAErC,MAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,QAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,UAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,OAAO,KAAA,CAAM,IAAI,wBAAwB,CAAC,CAAA;AAAA,QACnE;AACA,QAAA;AAAA,MACF;AAKA,MAAA,MAAM,QAAmB,EAAC;AAE1B,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,QAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,UAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,OAAO,KAAA,CAAM,IAAI,kBAAkB,CAAC,CAAA;AAAA,QAC7D;AACA,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,QAAA,MAAM,SAAA,GAAY,QAAA,CAAS,SAAA,GACvBC,IAAAA,CAAK,GAAA,EAAK,MAAA,CAAO,OAAA,EAAS,QAAA,CAAS,SAAS,CAAA,GAC5CA,IAAAA,CAAK,GAAA,EAAK,OAAO,OAAO,CAAA;AAE5B,QAAA,SAAA,CAAU,SAAS,CAAA;AAGnB,QAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,UAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,YAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA;AACpC,YAAA,MAAM,WAAW,KAAA,CAAM,WAAA,CAAY,MAAM,QAAA,CAAS,MAAM,KAAM,IAAA,CAAwB,EAAA;AACtF,YAAA,KAAA,CAAM,IAAA,CAAK;AAAA,cACT,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,CAAA,EAAG,QAAQ,CAAA,GAAA,CAAK,CAAA;AAAA,cACtC;AAAA,aACD,CAAA;AAAA,UACH;AAAA,QACF;AAGA,QAAA,IAAI,SAAS,KAAA,EAAO;AAClB,UAAA,MAAM,YAAA,GAAe,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AACzC,UAAA,KAAA,CAAM,IAAA,CAAK;AAAA,YACT,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AAAA,YAChC,OAAA,EAAS;AAAA,WACV,CAAA;AAAA,QACH;AAAA,MACF;AAEA,MAAA,OAAA,CAAQ,IAAID,MAAA,CAAM,KAAA,CAAM,cAAS,KAAA,CAAM,IAAI,EAAE,CAAC,CAAA;AAAA,IAChD;AAGA,IAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,aAAa,KAAA,CAAM,MAAM,WAAW,CAAC,CAAA;AAE5D,MAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,KAAK,CAAA;AAE1C,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAA,CAAM,KAAA,CAAM,CAAA,uBAAA,CAAoB,CAAC,CAAA;AAC7C,MAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,gBAAgB,MAAA,CAAO,OAAO,EAAE,CAAC,CAAA;AACxD,MAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,gBAAgB,MAAA,CAAO,OAAO,EAAE,CAAC,CAAA;AACxD,MAAA,OAAA,CAAQ,IAAIA,MAAA,CAAM,IAAA,CAAK,kBAAkB,MAAA,CAAO,SAAS,EAAE,CAAC,CAAA;AAAA,IAC9D,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAA,CAAM,MAAA,CAAO,yBAAyB,CAAC,CAAA;AAAA,IACrD;AAAA,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAA,CAAM,GAAA,CAAI,eAAe,GAAG,KAAK,CAAA;AAC/C,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AC9FO,SAAS,mBAAA,GAAqC;AACnD,EAAA,OAAO;AAAA,IACL,YAAA,sBAAkB,GAAA,EAAI;AAAA,IACtB,QAAA,sBAAc,GAAA,EAAI;AAAA,IAClB,MAAA,sBAAY,GAAA,EAAI;AAAA,IAChB,UAAA,sBAAgB,GAAA,EAAI;AAAA,IACpB,QAAA,sBAAc,GAAA,EAAI;AAAA,IAClB,SAAA,sBAAe,GAAA,EAAI;AAAA,IACnB,KAAA,sBAAW,GAAA,EAAI;AAAA,IACf,OAAA,sBAAa,GAAA,EAAI;AAAA,IACjB,WAAA,sBAAiB,GAAA,EAAI;AAAA,IACrB,KAAA,sBAAW,GAAA,EAAI;AAAA,IACf,YAAA,sBAAkB,GAAA,EAAI;AAAA,IACtB,aAAA,sBAAmB,GAAA,EAAI;AAAA,IACvB,OAAA,sBAAa,GAAA,EAAI;AAAA,IACjB,SAAA,sBAAe,GAAA,EAAI;AAAA,IACnB,QAAA,sBAAc,GAAA,EAAI;AAAA,IAClB,MAAA,sBAAY,GAAA,EAAI;AAAA,IAChB,UAAA,sBAAgB,GAAA,EAAI;AAAA,IACpB,SAAA,sBAAe,GAAA;AAAI,GACrB;AACF;AAMA,IAAI,iBAAgC,mBAAA,EAAoB;AAEjD,SAAS,iBAAA,GAAmC;AACjD,EAAA,OAAO,cAAA;AACT;AAEO,SAAS,mBAAA,GAA4B;AAC1C,EAAA,cAAA,GAAiB,mBAAA,EAAoB;AACvC;AAoBA,SAAS,gBAAgB,KAAA,EAA0F;AACjH,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AAChD,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,OACE,OAAO,IAAI,EAAA,KAAO,QAAA,IAClB,OAAO,GAAA,CAAI,IAAA,KAAS,YACpB,OAAO,GAAA,CAAI,aAAa,QAAA,IACxB,GAAA,CAAI,WAAW,MAAA,IACf,OAAO,IAAI,QAAA,KAAa,UAAA,IACxB,OAAO,GAAA,CAAI,IAAA,KAAS,UAAA;AAExB;AAKA,SAAS,uBAAuB,MAAA,EAAuC;AACrE,EAAA,KAAA,MAAW,CAAC,UAAA,EAAY,WAAW,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC9D,IAAA,IAAI,CAAC,WAAA,IAAe,OAAO,WAAA,KAAgB,QAAA,EAAU;AAGrD,IAAA,IAAI,eAAA,CAAgB,WAAW,CAAA,EAAG;AAGhC,MAAA,aAAA,CAAkB,WAAkB,CAAA;AACpC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC9B,MAAA,kBAAA,CAAmB,YAAY,WAAW,CAAA;AAC1C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,WAAA;AAGd,IAAA,IAAI,MAAM,UAAA,IAAc,KAAA,CAAM,UAAU,KAAA,CAAM,UAAA,IAAc,MAAM,SAAA,EAAW;AAC3E,MAAA,MAAM,IAAA,GAAO,KAAA;AAOb,MAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,UAAA,EAAY;AAClC,QAAA,IAAI,KAAK,EAAA,EAAI,cAAA,CAAe,WAAW,GAAA,CAAI,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,MAC1D;AACA,MAAA,KAAA,MAAW,KAAA,IAAS,KAAK,MAAA,EAAQ;AAC/B,QAAA,IAAI,MAAM,EAAA,EAAI,cAAA,CAAe,OAAO,GAAA,CAAI,KAAA,CAAM,IAAI,KAAK,CAAA;AAAA,MACzD;AACA,MAAA,KAAA,MAAW,QAAA,IAAY,KAAK,UAAA,EAAY;AACtC,QAAA,IAAI,SAAS,EAAA,EAAI,cAAA,CAAe,WAAW,GAAA,CAAI,QAAA,CAAS,IAAI,QAAQ,CAAA;AAAA,MACtE;AACA,MAAA,KAAA,MAAW,GAAA,IAAO,KAAK,SAAA,EAAW;AAChC,QAAA,IAAI,IAAI,EAAA,EAAI,cAAA,CAAe,UAAU,GAAA,CAAI,GAAA,CAAI,IAAI,GAAG,CAAA;AAAA,MACtD;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,YAAY,KAAA,CAAM,SAAA,IAAa,MAAM,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA,EAAG;AACtE,MAAA,MAAM,OAAA,GAAU,KAAA;AAKhB,MAAA,KAAA,MAAW,MAAA,IAAU,QAAQ,QAAA,EAAU;AACrC,QAAA,IAAI,OAAO,EAAA,EAAI,cAAA,CAAe,SAAS,GAAA,CAAI,MAAA,CAAO,IAAI,MAAM,CAAA;AAAA,MAC9D;AACA,MAAA,KAAA,MAAW,GAAA,IAAO,QAAQ,SAAA,EAAW;AACnC,QAAA,IAAI,IAAI,EAAA,EAAI,cAAA,CAAe,UAAU,GAAA,CAAI,GAAA,CAAI,IAAI,GAAG,CAAA;AAAA,MACtD;AACA,MAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,KAAA,IAAS,EAAC,EAAG;AACtC,QAAA,IAAI,KAAK,EAAA,EAAI,cAAA,CAAe,MAAM,GAAA,CAAI,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,MACrD;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,MAAA,EAAQ;AAClC,MAAA,MAAM,OAAA,GAAU,KAAA;AAIhB,MAAA,KAAA,MAAW,EAAA,IAAM,QAAQ,QAAA,EAAU;AACjC,QAAA,IAAI,GAAG,EAAA,EAAI,cAAA,CAAe,SAAS,GAAA,CAAI,EAAA,CAAG,IAAI,EAAE,CAAA;AAAA,MAClD;AACA,MAAA,KAAA,MAAW,KAAA,IAAS,QAAQ,MAAA,EAAQ;AAClC,QAAA,IAAI,MAAM,EAAA,EAAI,cAAA,CAAe,OAAO,GAAA,CAAI,KAAA,CAAM,IAAI,KAAK,CAAA;AAAA,MACzD;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,KAAA,IAAS,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAC7C,MAAA,MAAM,QAAA,GAAW,KAAA;AACjB,MAAA,KAAA,MAAW,IAAA,IAAQ,SAAS,KAAA,EAAO;AACjC,QAAA,IAAI,KAAK,EAAA,EAAI,cAAA,CAAe,cAAc,GAAA,CAAI,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,MAC7D;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,MAAM,KAAA,CAAM,KAAA,KAAU,MAAM,IAAA,IAAQ,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,UAAA,CAAA,EAAa;AAC7E,MAAA,cAAA,CAAe,YAAA,CAAa,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AACzD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,EAAA,IAAM,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,cAAc,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAA,EAAG;AACjF,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AACrD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,EAAA,IAAM,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA,IAAS,MAAM,QAAA,EAAU;AAC3D,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AACrD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,KAAA,CAAM,EAAA,IAAM,KAAA,CAAM,IAAA,IAAQ,MAAM,IAAA,IAAQ,CAAC,OAAA,EAAS,QAAA,EAAU,UAAU,CAAA,CAAE,QAAA,CAAS,KAAA,CAAM,IAAc,CAAA,EAAG;AAC1G,MAAA,cAAA,CAAe,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AACnD,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,MAAM,EAAA,KAAO,KAAA,CAAM,QAAQ,KAAA,CAAM,YAAA,CAAA,IAAiB,MAAM,UAAA,EAAY;AACtE,MAAA,cAAA,CAAe,aAAA,CAAc,GAAA,CAAI,KAAA,CAAM,EAAA,EAAc,KAAK,CAAA;AAC1D,MAAA;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,kBAAA,CAAmB,YAAoB,KAAA,EAAwB;AACtE,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACvC,IAAA,MAAM,GAAA,GAAM,IAAA;AACZ,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,IAAM,OAAO,GAAA,CAAI,OAAO,QAAA,EAAU;AAI3C,IAAA,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,aAAa,CAAA,IAC/C,UAAA,CAAW,WAAA,EAAY,CAAE,SAAS,aAAa,CAAA,IAC9C,GAAA,CAAI,IAAA,IAAQ,IAAI,kBAAA,EAAqB;AACxC,MAAA,cAAA,CAAe,YAAA,CAAa,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC5C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,SAAS,CAAA,IAC1C,GAAA,CAAI,KAAA,IAAS,GAAA,CAAI,QAAA,EAAW;AAC/B,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACxC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,WAAW,WAAA,EAAY,CAAE,SAAS,OAAO,CAAA,IACxC,IAAI,IAAA,IAAQ,CAAC,SAAS,QAAA,EAAU,UAAU,EAAE,QAAA,CAAS,GAAA,CAAI,IAAc,CAAA,IAAK,CAAC,IAAI,QAAA,EAAW;AAC/F,MAAA,cAAA,CAAe,MAAA,CAAO,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACtC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,WAAW,CAAA,IAC7C,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,WAAW,KAC5C,GAAA,CAAI,IAAA,IAAQ,CAAC,QAAA,EAAU,QAAA,EAAU,WAAA,EAAa,WAAW,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,IAAc,CAAA,EAAI;AAC7F,MAAA,cAAA,CAAe,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC1C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,OAAO,CAAA,IACxC,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,UAAA,IAAc,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA,EAAI;AACjE,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACxC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,MAAM,CAAA,IACxC,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,SAAS,CAAA,IAC3C,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC3C,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,UAAA,EAAa;AAChC,MAAA,cAAA,CAAe,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC7C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC3C,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,EAAA,IAAM,GAAA,CAAI,KAAA,EAAQ;AACrC,MAAA,cAAA,CAAe,SAAA,CAAU,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACzC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,WAAA,EAAY,CAAE,QAAA,CAAS,OAAO,CAAA,IACxC,GAAA,CAAI,IAAA,IAAQ,OAAO,GAAA,CAAI,KAAA,KAAU,QAAA,EAAW;AAC/C,MAAA,cAAA,CAAe,MAAA,CAAO,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACtC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,WAAW,WAAA,EAAY,CAAE,SAAS,SAAS,CAAA,IAC1C,IAAI,IAAA,IAAQ,CAAC,UAAU,SAAA,EAAW,WAAA,EAAa,YAAY,CAAA,CAAE,QAAA,CAAS,IAAI,IAAc,CAAA,IAAK,IAAI,WAAA,EAAc;AAClH,MAAA,cAAA,CAAe,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC1C,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,QAAQ,CAAA,IACzC,GAAA,CAAI,QAAQ,CAAC,MAAA,EAAQ,SAAS,QAAA,EAAU,OAAA,EAAS,QAAQ,CAAA,CAAE,QAAA,CAAS,IAAI,IAAc,CAAA,IAAK,IAAI,IAAA,EAAO;AACzG,MAAA,cAAA,CAAe,OAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACvC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,SAAS,CAAA,IAC3C,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC3C,GAAA,CAAI,UAAU,GAAA,CAAI,oBAAA,IAAwB,MAAM,OAAA,CAAQ,GAAA,CAAI,oBAAoB,CAAA,EAAI;AACvF,MAAA,cAAA,CAAe,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACxC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,UAAA,CAAW,aAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC3C,GAAA,CAAI,YAAY,GAAA,CAAI,QAAA,IAAY,IAAI,OAAA,IACpC,CAAC,QAAQ,gBAAA,EAAkB,kBAAA,EAAoB,gBAAgB,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,QAAkB,CAAA,EAAI;AACvG,MAAA,cAAA,CAAe,SAAA,CAAU,GAAA,CAAI,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AACzC,MAAA;AAAA,IACF;AAAA,EACF;AACF;AASA,eAAsB,uBAAA,CACpB,OAAA,EACA,OAAA,GAAmC,EAAC,EACjB;AACnB,EAAA,MAAM,cAAwB,EAAC;AAE/B,EAAA,IAAI,CAACH,UAAAA,CAAW,OAAO,CAAA,EAAG;AACxB,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GAAU,YAAY,OAAO,CAAA;AAEnC,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,QAAA,GAAWI,IAAAA,CAAK,OAAA,EAAS,KAAK,CAAA;AACpC,IAAA,MAAM,IAAA,GAAO,SAAS,QAAQ,CAAA;AAE9B,IAAA,IAAI,IAAA,CAAK,WAAA,EAAY,IAAK,OAAA,CAAQ,SAAA,EAAW;AAC3C,MAAA,MAAM,QAAA,GAAW,MAAM,uBAAA,CAAwB,QAAA,EAAU,OAAO,CAAA;AAChE,MAAA,WAAA,CAAY,IAAA,CAAK,GAAG,QAAQ,CAAA;AAAA,IAC9B,CAAA,MAAA,IAAW,IAAA,CAAK,MAAA,EAAO,EAAG;AACxB,MAAA,MAAM,GAAA,GAAM,QAAQ,KAAK,CAAA;AAEzB,MAAA,IAAI,CAAC,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ,MAAM,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,IAAK,CAAC,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA,EAAG;AAE5E,QAAA,IAAI,QAAA,CAAS,KAAA,EAAO,GAAG,CAAA,KAAM,OAAA,EAAS;AACpC,UAAA;AAAA,QACF;AAEA,QAAA,IAAI;AAEF,UAAA,MAAM,MAAA,GAAS,MAAM,OAAO,QAAA,CAAA;AAC5B,UAAA,WAAA,CAAY,KAAK,QAAQ,CAAA;AAGzB,UAAA,sBAAA,CAAuB,MAAM,CAAA;AAAA,QAC/B,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,0BAAA,EAA6B,QAAQ,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,WAAA;AACT;AAKA,eAAsB,aAAA,CACpB,MAAA,EACA,GAAA,GAAc,OAAA,CAAQ,KAAI,EAKzB;AAED,EAAA,mBAAA,EAAoB;AAEpB,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,MAAM,SAAkD,EAAC;AAGzD,EAAA,MAAM,SAAA,GAAYC,OAAAA,CAAQ,GAAA,EAAK,MAAA,CAAO,aAAa,QAAQ,CAAA;AAG3D,EAAA,MAAM,SAAA,GAAY;AAAA,IAChB,EAAE,IAAA,EAAMD,IAAAA,CAAK,SAAA,EAAW,cAAc,CAAA,EAAE;AAAA,IACxC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,UAAU,CAAA,EAAE;AAAA,IACpC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,cAAc,CAAA,EAAE;AAAA,IACxC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,YAAY,CAAA,EAAE;AAAA,IACtC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,SAAS,CAAA,EAAE;AAAA,IACnC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,OAAO,CAAA,EAAE;AAAA,IACjC,EAAE,IAAA,EAAMA,IAAAA,CAAK,SAAA,EAAW,UAAU,CAAA,EAAE;AAAA;AAAA,IAEpC,EAAE,MAAM,SAAA;AAAU,GACpB;AAEA,EAAA,KAAA,MAAW,EAAE,IAAA,EAAM,OAAA,EAAQ,IAAK,SAAA,EAAW;AACzC,IAAA,IAAI,CAACJ,UAAAA,CAAW,OAAO,CAAA,EAAG;AACxB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAQ,MAAM,uBAAA,CAAwB,SAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AACxE,MAAA,WAAA,CAAY,IAAA,CAAK,GAAG,KAAK,CAAA;AAAA,IAC3B,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,UAAU,iBAAA,EAAkB;AAAA,IAC5B,WAAA;AAAA,IACA;AAAA,GACF;AACF;;;ACrYA,eAAsB,YAAY,OAAA,EAA4C;AAC5E,EAAA,OAAA,CAAQ,GAAA,CAAIG,MAAAA,CAAM,IAAA,CAAK,iBAAiB,CAAC,CAAA;AACzC,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAE9C,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,UAAA,EAAa,OAAO,SAAA,IAAa,QAAQ,GAAG,CAAC,CAAA;AACpE,EAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,aAAa,OAAA,CAAQ,KAAK,EAAE,CAAC,CAAA;AAAA,EACtD;AACA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qBAAqB,CAAC,CAAA;AAC7C,IAAA,MAAM,EAAE,UAAU,WAAA,EAAa,MAAA,EAAQ,YAAW,GAAI,MAAM,aAAA,CAAc,MAAA,EAAQ,GAAG,CAAA;AAErF,IAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,YAAO,UAAA,CAAW,MAAM,yBAAyB,CAAC,CAAA;AAC3E,MAAA,KAAA,MAAW,EAAE,IAAA,EAAM,KAAA,EAAM,IAAK,UAAA,EAAY;AACxC,QAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,MAAA,CAAO,CAAA,MAAA,EAAS,QAAA,CAAS,GAAA,EAAK,IAAI,CAAC,CAAA,EAAA,EAAK,KAAK,CAAA,CAAE,CAAC,CAAA;AAAA,MACpE;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,aAAa,WAAA,CAAY,MAAM,QAAQ,CAAC,CAAA;AAC/D,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAGd,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,0BAA0B,CAAC,CAAA;AAClD,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAG7C,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,iBAAA,CAAkB,QAAQ,OAAO,CAAA;AAGjC,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAAA,CAAM,GAAA,CAAI,cAAc,GAAG,KAAK,CAAA;AAC9C,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAMA,SAAS,YAAA,CAAa,UAAyB,OAAA,EAAyC;AACtF,EAAA,MAAM,SAAsB,EAAC;AAC7B,EAAA,MAAM,SAAS,YAAA,EAAa;AAE5B,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAE1B,IAAA,MAAM,KAAA,GAAQ,oBAAA,CAAqB,QAAA,EAAU,KAAA,CAAM,EAAE,CAAA;AAErD,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAGxB,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAEvC,IAAA,KAAA,MAAW,UAAU,WAAA,EAAa;AAChC,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,MAAM,MAAA,CAAO,MAAA;AAAA,QACb,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,WAAW,KAAA,CAAM;AAAA,OAClB,CAAA;AAAA,IACH;AAAA,EACF;AAGA,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA,CAAO,OAAK,CAAA,CAAE,QAAA,KAAa,OAAO,CAAA,CAAE,MAAA;AAC1D,EAAA,MAAM,WAAW,MAAA,CAAO,MAAA,CAAO,OAAK,CAAA,CAAE,QAAA,KAAa,SAAS,CAAA,CAAE,MAAA;AAC9D,EAAA,MAAM,QAAQ,MAAA,CAAO,MAAA,CAAO,OAAK,CAAA,CAAE,QAAA,KAAa,MAAM,CAAA,CAAE,MAAA;AAGxD,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,OAAO;AAAA,MACL,QAAQ,MAAA,CAAO,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,aAAa,MAAM,CAAA;AAAA,MAChD,MAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAM;AAC3C;AAEA,SAAS,oBAAA,CAAqB,UAAyB,OAAA,EAA4B;AAEjF,EAAA,MAAM,WAAA,GAAmD;AAAA,IACvD,aAAA,EAAe,cAAA;AAAA,IACf,SAAA,EAAW,UAAA;AAAA,IACX,OAAA,EAAS,QAAA;AAAA,IACT,MAAA,EAAQ,eAAA;AAAA,IACR,QAAA,EAAU,UAAA;AAAA,IACV,QAAA,EAAU,SAAA;AAAA,IACV,cAAA,EAAgB,cAAA;AAAA,IAChB,WAAA,EAAa,YAAA;AAAA,IACb,UAAA,EAAY,YAAA;AAAA,IACZ,OAAA,EAAS,QAAA;AAAA,IACT,UAAA,EAAY;AAAA,GACd;AAEA,EAAA,MAAM,GAAA,GAAM,YAAY,OAAO,CAAA;AAC/B,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,SAAS,GAAG,CAAA,SAAU,EAAC;AAEpC,EAAA,OAAO,MAAM,IAAA,CAAM,QAAA,CAAS,GAAG,CAAA,CAA2B,QAAQ,CAAA;AACpE;AAMA,SAAS,iBAAA,CAAkB,QAAoB,OAAA,EAAmC;AAChF,EAAA,IAAI,OAAA,CAAQ,WAAW,MAAA,EAAQ;AAC7B,IAAA,OAAA,CAAQ,IAAI,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAC3C,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAW,QAAA,EAAU;AAC/B,IAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,MAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,KAAa,OAAA,GAAU,UAAU,KAAA,CAAM,QAAA,KAAa,YAAY,SAAA,GAAY,QAAA;AAChG,MAAA,OAAA,CAAQ,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,EAAK,KAAA,CAAM,OAAO,CAAA,EAAA,EAAK,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,MAAM,MAAA,GAAS,CAAA,EAAA,EAAK,MAAM,MAAM,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,CAAE,CAAA;AAAA,IACvG;AACA,IAAA;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAC9B,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,KAAA,CAAM,0BAAqB,CAAC,CAAA;AAC9C,IAAA;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,KAAa,OAAA,GAAU,WAAM,KAAA,CAAM,QAAA,KAAa,YAAY,QAAA,GAAM,QAAA;AACrF,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,KAAa,OAAA,GAAUA,MAAAA,CAAM,GAAA,GAAM,KAAA,CAAM,QAAA,KAAa,SAAA,GAAYA,MAAAA,CAAM,MAAA,GAASA,MAAAA,CAAM,IAAA;AAE3G,IAAA,MAAM,SAAS,KAAA,CAAM,MAAA,GAAS,CAAA,CAAA,EAAI,KAAA,CAAM,MAAM,CAAA,EAAA,CAAA,GAAO,EAAA;AACrD,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE,CAAC,CAAA;AACxD,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,aAAa,KAAA,CAAM,IAAI,EAAE,CAAC,CAAA;AAAA,EACnD;AAEA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,MAAA,CAAO,MAAM,CAAA,SAAA,EAAY,MAAA,CAAO,QAAQ,CAAA,WAAA,EAAc,MAAA,CAAO,KAAK,QAAQ,CAAC,CAAA;AAClH;AClKA,eAAsB,aAAa,OAAA,EAA6C;AAC9E,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,kBAAkB,CAAC,CAAA;AAC1C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAG9C,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,UAAA,EAAa,OAAO,SAAA,IAAa,QAAQ,GAAG,CAAC,CAAA;AACpE,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,aAAa,MAAA,CAAO,OAAO,GAAG,CAAC,CAAA;AACtD,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qBAAqB,CAAC,CAAA;AAC7C,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,aAAA,CAAc,QAAQ,GAAG,CAAA;AAEpD,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,MAAM,SAAS,YAAA,EAAa;AAG5B,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,KAAA,GAAQG,qBAAAA,CAAqB,QAAA,EAAU,KAAA,CAAM,EAAE,CAAA;AACrD,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAExB,MAAA,KAAA,MAAW,QAAA,IAAY,KAAA,CAAM,YAAA,EAAa,EAAG;AAC3C,QAAA,IAAI,QAAA,CAAS,WAAW,UAAA,EAAY;AAEpC,QAAA,MAAM,SAAA,GAAY,QAAA,CAAS,SAAA,GACvBF,IAAAA,CAAK,GAAA,EAAK,MAAA,CAAO,OAAA,EAAS,QAAA,CAAS,SAAS,CAAA,GAC5CA,IAAAA,CAAK,GAAA,EAAK,OAAO,OAAO,CAAA;AAG5B,QAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,UAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,YAAA,MAAM,WAAW,KAAA,CAAM,WAAA,CAAY,IAAA,EAAM,UAAU,KAAM,IAAA,CAAwB,EAAA;AACjF,YAAA,MAAM,QAAA,GAAWA,IAAAA,CAAK,SAAA,EAAW,CAAA,EAAG,QAAQ,CAAA,GAAA,CAAK,CAAA;AAEjD,YAAA,IAAI,CAACJ,UAAAA,CAAW,QAAQ,CAAA,EAAG;AACzB,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,WAAW,CAAA;AAClD,cAAA;AAAA,YACF;AAEA,YAAA,MAAM,QAAA,GAAW,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA;AACrC,YAAA,MAAM,MAAA,GAASE,YAAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAE7C,YAAA,IAAI,gBAAA,CAAiB,QAAQ,CAAA,KAAM,gBAAA,CAAiB,MAAM,CAAA,EAAG;AAC3D,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,WAAW,CAAA;AAAA,YACpD,CAAA,MAAO;AACL,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,MAAM,CAAA;AAAA,YAC/C;AAAA,UACF;AAAA,QACF;AAGA,QAAA,IAAI,SAAS,KAAA,EAAO;AAClB,UAAA,MAAM,SAAA,GAAYE,IAAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AAE5C,UAAA,IAAI,CAACJ,UAAAA,CAAW,SAAS,CAAA,EAAG;AAC1B,YAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,WAAW,CAAA;AAAA,UACrD,CAAA,MAAO;AACL,YAAA,MAAM,QAAA,GAAW,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AACrC,YAAA,MAAM,MAAA,GAASE,YAAAA,CAAa,SAAA,EAAW,OAAO,CAAA;AAE9C,YAAA,IAAI,gBAAA,CAAiB,QAAQ,CAAA,KAAM,gBAAA,CAAiB,MAAM,CAAA,EAAG;AAC3D,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,WAAW,CAAA;AAAA,YACrD,CAAA,MAAO;AACL,cAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,MAAM,CAAA;AAAA,YAChD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,kBAAA,CAAmB,SAAS,OAAO,CAAA;AAGnC,IAAA,MAAM,QAAA,GAAW,QAAQ,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,MAAA,KAAW,SAAA,IAAa,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA;AACnF,IAAA,IAAI,QAAA,IAAY,QAAQ,WAAA,EAAa;AACnC,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMC,MAAAA,CAAM,GAAA,CAAI,qBAAqB,GAAG,KAAK,CAAA;AACrD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAMA,SAASG,qBAAAA,CAAqB,UAAyB,OAAA,EAA4B;AACjF,EAAA,MAAM,WAAA,GAAmD;AAAA,IACvD,aAAA,EAAe,cAAA;AAAA,IACf,SAAA,EAAW,UAAA;AAAA,IACX,OAAA,EAAS,QAAA;AAAA,IACT,MAAA,EAAQ,eAAA;AAAA,IACR,QAAA,EAAU,UAAA;AAAA,IACV,QAAA,EAAU,SAAA;AAAA,IACV,cAAA,EAAgB,cAAA;AAAA,IAChB,WAAA,EAAa;AAAA,GACf;AAEA,EAAA,MAAM,GAAA,GAAM,YAAY,OAAO,CAAA;AAC/B,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,SAAS,GAAG,CAAA,SAAU,EAAC;AAEpC,EAAA,OAAO,MAAM,IAAA,CAAM,QAAA,CAAS,GAAG,CAAA,CAA2B,QAAQ,CAAA;AACpE;AAEA,SAAS,iBAAiB,OAAA,EAAyB;AACjD,EAAA,OAAO,OAAA,CAAQ,IAAA,EAAK,CAAE,OAAA,CAAQ,SAAS,IAAI,CAAA;AAC7C;AAEA,SAAS,kBAAA,CAAmB,SAAwB,QAAA,EAAqC;AACvF,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,KAAK,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,IAAI,CAAA;AAChD,EAAA,MAAM,UAAU,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,SAAS,CAAA;AAC1D,EAAA,MAAM,UAAU,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,SAAS,CAAA;AAE1D,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,IAAK,OAAA,CAAQ,WAAW,CAAA,EAAG;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAIH,MAAAA,CAAM,KAAA,CAAM,4BAAuB,CAAC,CAAA;AAChD,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,gBAAgB,OAAA,CAAQ,MAAM,QAAQ,CAAC,CAAA;AAC9D,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,YAAO,OAAA,CAAQ,MAAM,wBAAwB,CAAC,CAAA;AACvE,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,SAAS,MAAA,CAAO,IAAI,EAAE,CAAC,CAAA;AAAA,IAClD;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,GAAA,CAAI,YAAO,OAAA,CAAQ,MAAM,uBAAuB,CAAC,CAAA;AACnE,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,GAAA,CAAI,SAAS,MAAA,CAAO,IAAI,EAAE,CAAC,CAAA;AAAA,IAC/C;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,EAAA,CAAG,MAAM,CAAA,KAAA,EAAQ,OAAA,CAAQ,MAAM,CAAA,UAAA,EAAa,OAAA,CAAQ,MAAM,UAAU,CAAC,CAAA;AAC5G;ACvIA,eAAsB,YAAA,CACpB,MACA,OAAA,EACe;AACf,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,kBAAkB,CAAC,CAAA;AAC1C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAC9C,EAAA,MAAM,SAAA,GAAY,IAAA,IAAQ,OAAA,CAAQ,IAAA,IAAQ,KAAA;AAE1C,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,UAAA,EAAa,OAAO,SAAA,IAAa,QAAQ,GAAG,CAAC,CAAA;AACpE,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,SAAS,EAAE,CAAC,CAAA;AAChD,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qBAAqB,CAAC,CAAA;AAC7C,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,aAAA,CAAc,QAAQ,GAAG,CAAA;AAEpD,IAAA,MAAM,UAAyB,EAAC;AAChC,IAAA,MAAM,SAAS,YAAA,EAAa;AAE5B,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,qBAAA,EAAwB,OAAO,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,EAAE,CAAC,CAAA;AAAA,IACpF;AAGA,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,KAAA,GAAQG,qBAAAA,CAAqB,QAAA,EAAU,KAAA,CAAM,EAAE,CAAA;AACrD,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AAExB,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,MAAM,UAAA,GAAa,KAAA,CAAM,qBAAA,CAAsB,IAAI,CAAA;AACnD,QAAA,IAAI,CAAC,UAAA,EAAY;AAEjB,QAAA,MAAM,QAAA,GAAWF,IAAAA,CAAK,GAAA,EAAK,UAAU,CAAA;AACrC,QAAA,IAAI,CAACJ,UAAAA,CAAW,QAAQ,CAAA,EAAG;AACzB,UAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,YACX,MAAM,KAAA,CAAM,EAAA;AAAA,YACZ,OAAA,EAAS,KAAA;AAAA,YACT,QAAQ,CAAC;AAAA,cACP,QAAA,EAAU,OAAA;AAAA,cACV,OAAA,EAAS,8BAA8B,UAAU,CAAA,CAAA;AAAA,cACjD,QAAS,IAAA,CAAwB;AAAA,aAClC;AAAA,WACF,CAAA;AACD,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,YAAA,GAAe,iBAAiB,QAAQ,CAAA;AAG9C,QAAA,MAAM,WAAA,GAAc,KAAA,CAAM,KAAA,CAAM,IAAA,EAAM,YAAY,CAAA;AAElD,QAAA,IAAI,CAAC,WAAA,CAAY,OAAA,IAAW,WAAA,CAAY,MAAA,CAAO,SAAS,CAAA,IAAK,WAAA,CAAY,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC5F,UAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,YACX,MAAM,KAAA,CAAM,EAAA;AAAA,YACZ,SAAS,WAAA,CAAY,OAAA;AAAA,YACrB,MAAA,EAAQ;AAAA,cACN,GAAG,WAAA,CAAY,MAAA,CAAO,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,QAAA,EAAU,OAAA,EAAkB,OAAA,EAAS,CAAA,CAAE,SAAS,MAAA,EAAQ,CAAA,CAAE,QAAQ,KAAA,EAAO,CAAA,CAAE,OAAM,CAAE,CAAA;AAAA,cACrH,GAAG,WAAA,CAAY,QAAA,CAAS,GAAA,CAAI,CAAA,CAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAoB,OAAA,EAAS,CAAA,CAAE,SAAS,MAAA,EAAQ,CAAA,CAAE,QAAQ,KAAA,EAAO,CAAA,CAAE,OAAM,CAAE;AAAA;AAC3H,WACD,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,IAAA,kBAAA,CAAmB,OAAO,CAAA;AAG1B,IAAA,IAAI,QAAQ,QAAA,EAAU;AACpB,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,GAAA,CAAIG,MAAAA,CAAM,IAAA,CAAK,sBAAsB,CAAC,CAAA;AAC9C,MAAA,MAAM,eAAA,GAAkB,qBAAqB,QAAQ,CAAA;AAErD,MAAA,IAAI,eAAA,CAAgB,SAAS,CAAA,EAAG;AAC9B,QAAA,wBAAA,CAAyB,eAAe,CAAA;AAGxC,QAAA,KAAA,MAAW,SAAS,eAAA,EAAiB;AACnC,UAAA,IAAI,KAAA,CAAM,MAAA,CAAO,cAAA,CAAe,MAAA,GAAS,CAAA,EAAG;AAC1C,YAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,cACX,IAAA,EAAM,CAAA,SAAA,EAAY,KAAA,CAAM,OAAO,CAAA,CAAA;AAAA,cAC/B,OAAA,EAAS,KAAA,CAAM,MAAA,CAAO,eAAA,IAAmB,EAAA;AAAA;AAAA,cACzC,MAAA,EAAQ,MAAM,MAAA,CAAO,cAAA,CAAe,MAAM,CAAA,EAAG,EAAE,CAAA,CAAE,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,gBAC5D,QAAA,EAAU,SAAA;AAAA,gBACV,SAAS,CAAA,CAAA,EAAI,KAAA,CAAM,SAAS,CAAA,MAAA,EAAI,MAAM,WAAW,CAAA,GAAA,EAAM,IAAA,CAAK,EAAE,IAAI,IAAA,CAAK,QAAA,GAAW,KAAK,IAAA,CAAK,QAAQ,MAAM,EAAE,CAAA,YAAA,CAAA;AAAA,gBAC5G,QAAQ,IAAA,CAAK;AAAA,eACf,CAAE;AAAA,aACH,CAAA;AAAA,UACH;AAAA,QACF;AAGA,QAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,QAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,kOAAyC,CAAC,CAAA;AACjE,QAAA,MAAM,YAAY,eAAA,CAAgB,KAAA,CAAM,OAAK,CAAA,CAAE,MAAA,CAAO,mBAAmB,EAAE,CAAA;AAC3E,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,KAAA,CAAM,iDAAuC,CAAC,CAAA;AAAA,QAClE,CAAA,MAAO;AACL,UAAA,MAAM,SAAS,eAAA,CAAgB,MAAA,CAAO,OAAK,CAAA,CAAE,MAAA,CAAO,kBAAkB,EAAE,CAAA;AACxE,UAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,YAAO,MAAA,CAAO,MAAM,8BAA8B,CAAC,CAAA;AAAA,QAC9E;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,6BAA6B,CAAC,CAAA;AAAA,MACvD;AAAA,IACF;AAGA,IAAA,MAAM,YAAY,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAA,KAAK,CAAC,EAAE,OAAO,CAAA;AAC9C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EAEF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAAA,CAAM,GAAA,CAAI,eAAe,GAAG,KAAK,CAAA;AAC/C,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAMA,SAASG,qBAAAA,CAAqB,UAAyB,OAAA,EAA4B;AACjF,EAAA,MAAM,WAAA,GAAmD;AAAA,IACvD,aAAA,EAAe,cAAA;AAAA,IACf,SAAA,EAAW,UAAA;AAAA,IACX,OAAA,EAAS,QAAA;AAAA,IACT,MAAA,EAAQ,eAAA;AAAA,IACR,QAAA,EAAU,UAAA;AAAA,IACV,QAAA,EAAU,SAAA;AAAA,IACV,cAAA,EAAgB,cAAA;AAAA,IAChB,WAAA,EAAa,YAAA;AAAA,IACb,SAAA,EAAW,SAAA;AAAA,IACX,WAAA,EAAa,WAAA;AAAA,IACb,UAAA,EAAY,UAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACd;AAEA,EAAA,MAAM,GAAA,GAAM,YAAY,OAAO,CAAA;AAC/B,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,SAAS,GAAG,CAAA,SAAU,EAAC;AAEpC,EAAA,OAAO,MAAM,IAAA,CAAM,QAAA,CAAS,GAAG,CAAA,CAA2B,QAAQ,CAAA;AACpE;AAEA,SAAS,iBAAiB,QAAA,EAA2B;AACnD,EAAA,MAAM,OAAA,GAAUJ,YAAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAE9C,EAAA,IAAI,SAAS,QAAA,CAAS,OAAO,KAAK,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,EAAG;AAC3D,IAAA,OAAOH,MAAU,OAAO,CAAA;AAAA,EAC1B;AAEA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AAC9B,IAAA,OAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,EAC3B;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,mBAAmB,OAAA,EAA8B;AACxD,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAA,CAAQ,GAAA,CAAII,MAAAA,CAAM,KAAA,CAAM,4BAAuB,CAAC,CAAA;AAChD,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,WAAA,GAAc,CAAA;AAClB,EAAA,IAAI,aAAA,GAAgB,CAAA;AAEpB,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,QAAA,KAAa,OAAA,GAAU,QAAA,GAAM,QAAA;AAChD,MAAA,MAAM,QAAQ,KAAA,CAAM,QAAA,KAAa,OAAA,GAAUA,MAAAA,CAAM,MAAMA,MAAAA,CAAM,MAAA;AAE7D,MAAA,IAAI,KAAA,CAAM,aAAa,OAAA,EAAS,WAAA,EAAA;AAAA,WAC3B,aAAA,EAAA;AAEL,MAAA,MAAM,SAAS,KAAA,CAAM,MAAA,GAAS,CAAA,CAAA,EAAI,KAAA,CAAM,MAAM,CAAA,EAAA,CAAA,GAAO,EAAA;AACrD,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAE,CAAC,CAAA;AAAA,IAC1D;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,WAAA,EAAc,WAAW,CAAA,SAAA,EAAY,aAAa,WAAW,CAAC,CAAA;AACvF;AAoBA,SAAS,qBAAqB,QAAA,EAAgD;AAC5E,EAAA,MAAM,SAAS,YAAA,EAAa;AAC5B,EAAA,MAAM,UAAiC,EAAC;AAGxC,EAAA,MAAM,iBAAuD,EAAC;AAC9D,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACnD,IAAA,IAAI,iBAAiB,GAAA,EAAK;AACxB,MAAA,cAAA,CAAe,GAAG,CAAA,GAAI,KAAA;AAAA,IACxB;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,OAAA,GAAU,MAAM,kBAAA,EAAmB;AACzC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,MAAM,KAAA,GAAQG,qBAAAA,CAAqB,QAAA,EAAU,KAAA,CAAM,EAAE,CAAA;AACrD,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,aAAA,CAAc,KAAA,EAAO,cAAc,CAAA;AAExD,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,SAAS,KAAA,CAAM,EAAA;AAAA,UACf,WAAW,KAAA,CAAM,IAAA;AAAA,UACjB,aAAa,OAAA,CAAQ,WAAA;AAAA,UACrB,aAAa,OAAA,CAAQ,WAAA;AAAA,UACrB;AAAA,SACD,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,yBAAyB,MAAA,EAAqC;AACrE,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,OAAA,CAAQ,GAAA,CAAIH,MAAAA,CAAM,IAAA,CAAK,CAAA,YAAA,EAAe,KAAA,CAAM,SAAS,CAAA,QAAA,EAAM,KAAA,CAAM,WAAW,CAAA,CAAE,CAAC,CAAA;AAC/E,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,KAAK,KAAA,CAAM,WAAW,EAAE,CAAC,CAAA;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,gOAAA,CAAyC,CAAC,CAAA;AACjE,IAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,MAAM,MAAA,CAAO,KAAK,EAAE,CAAC,CAAA;AAC5D,IAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,KAAA,CAAM,CAAA,aAAA,EAAgB,MAAM,MAAA,CAAO,OAAO,EAAE,CAAC,CAAA;AAC/D,IAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,MAAA,CAAO,CAAA,aAAA,EAAgB,MAAM,MAAA,CAAO,SAAS,EAAE,CAAC,CAAA;AAElE,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,eAAA,IAAmB,EAAA,GAAKA,MAAAA,CAAM,KAAA,GAC3C,KAAA,CAAM,MAAA,CAAO,eAAA,IAAmB,EAAA,GAAKA,MAAAA,CAAM,SAASA,MAAAA,CAAM,GAAA;AACxE,IAAA,OAAA,CAAQ,IAAI,KAAA,CAAM,CAAA,aAAA,EAAgB,MAAM,MAAA,CAAO,eAAe,GAAG,CAAC,CAAA;AAElE,IAAA,IAAI,KAAA,CAAM,OAAO,cAAA,CAAe,MAAA,GAAS,KAAK,KAAA,CAAM,MAAA,CAAO,cAAA,CAAe,MAAA,IAAU,EAAA,EAAI;AACtF,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,MAAA,CAAO,oBAAoB,CAAC,CAAA;AAC9C,MAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,MAAA,CAAO,cAAA,EAAgB;AAC9C,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,GAAc,CAAA,EAAA,EAAK,IAAA,CAAK,YAAY,SAAA,CAAU,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA,GAAK,EAAA;AAC3E,QAAA,MAAM,SAAS,IAAA,CAAK,QAAA,GAAW,CAAA,EAAA,EAAK,IAAA,CAAK,QAAQ,CAAA,CAAA,CAAA,GAAM,EAAA;AACvD,QAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,MAAA,CAAO,CAAA,MAAA,EAAS,IAAA,CAAK,EAAE,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAE,CAAC,CAAA;AAAA,MAC9D;AAAA,IACF,CAAA,MAAA,IAAW,KAAA,CAAM,MAAA,CAAO,cAAA,CAAe,SAAS,EAAA,EAAI;AAClD,MAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,MAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,MAAA,CAAO,CAAA,GAAA,EAAM,MAAM,MAAA,CAAO,cAAA,CAAe,MAAM,CAAA,mCAAA,CAAqC,CAAC,CAAA;AACvG,MAAA,KAAA,MAAW,QAAQ,KAAA,CAAM,MAAA,CAAO,eAAe,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,EAAG;AAC1D,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,GAAc,CAAA,EAAA,EAAK,IAAA,CAAK,YAAY,SAAA,CAAU,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA,GAAK,EAAA;AAC3E,QAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,MAAA,CAAO,CAAA,MAAA,EAAS,KAAK,EAAE,CAAA,EAAG,IAAI,CAAA,CAAE,CAAC,CAAA;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AChSA,eAAsB,WAAW,OAAA,EAA2C;AAC1E,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,gBAAgB,CAAC,CAAA;AACxC,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAG9C,EAAA,IAAI,CAAC,QAAQ,IAAA,EAAM;AACjB,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,0BAA0B,CAAC,CAAA;AAClD,IAAA,MAAMI,UAAS,YAAA,EAAa;AAC5B,IAAA,KAAA,MAAWC,UAASD,OAAAA,EAAQ;AAC1B,MAAA,OAAA,CAAQ,GAAA,CAAIJ,MAAAA,CAAM,IAAA,CAAK,CAAA,MAAA,EAASK,MAAAA,CAAM,EAAE,CAAA,EAAA,EAAKA,MAAAA,CAAM,IAAI,CAAA,CAAA,CAAG,CAAC,CAAA;AAAA,IAC7D;AACA,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,OAAA,CAAQ,GAAA,CAAIL,MAAAA,CAAM,IAAA,CAAK,mDAAmD,CAAC,CAAA;AAC3E,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,SAAS,YAAA,EAAa;AAC5B,EAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,OAAK,CAAA,CAAE,EAAA,KAAO,QAAQ,IAAI,CAAA;AAEpD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAA,CAAQ,MAAMA,MAAAA,CAAM,GAAA,CAAI,gCAAgC,OAAA,CAAQ,IAAI,GAAG,CAAC,CAAA;AACxE,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,+CAA+C,CAAC,CAAA;AACvE,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAGA,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,EAAA,IAAM,CAAA,EAAG,MAAM,QAAQ,CAAA,CAAA,EAAI,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,CAAA,CAAE,KAAA,CAAM,EAAE,CAAC,CAAA,CAAA;AAG1E,EAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,KAAA,EAAO,EAAE,CAAA;AAE3C,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,uBAAuB,CAAC,CAAA;AAC/C,IAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,IAAA,OAAA,CAAQ,IAAI,QAAQ,CAAA;AACpB,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,YAAY,OAAA,CAAQ,MAAA,IAAUC,KAAK,GAAA,EAAK,MAAA,CAAO,aAAa,QAAQ,CAAA;AAC1E,EAAA,MAAM,UAAA,GAAaA,KAAK,SAAA,EAAW,CAAA,EAAG,MAAM,EAAE,CAAA,CAAA,EAAI,EAAE,CAAA,GAAA,CAAK,CAAA;AAEzD,EAAA,IAAIJ,UAAAA,CAAW,UAAU,CAAA,EAAG;AAC1B,IAAA,OAAA,CAAQ,MAAMG,MAAAA,CAAM,GAAA,CAAI,CAAA,8BAAA,EAAiC,UAAU,EAAE,CAAC,CAAA;AACtE,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAAM,aAAAA,CAAc,YAAY,QAAQ,CAAA;AAClC,EAAA,OAAA,CAAQ,IAAIN,MAAAA,CAAM,KAAA,CAAM,CAAA,kBAAA,EAAgB,UAAU,EAAE,CAAC,CAAA;AACvD;AAOA,SAAS,gBAAA,CAAiB,OAAY,EAAA,EAAoB;AACxD,EAAA,MAAM,WAAW,KAAA,CAAM,IAAA;AACvB,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,KAAA,CAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAChB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,GAAA,EAAM,QAAQ,CAAA,EAAA,EAAK,EAAE,CAAA,CAAE,CAAA;AAClC,EAAA,KAAA,CAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,CAAA,8BAAA,CAAgC,CAAA;AAC3C,EAAA,KAAA,CAAM,KAAK,CAAA,GAAA,CAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,CAAA,cAAA,EAAiB,QAAQ,CAAA,mBAAA,EAAsB,KAAA,CAAM,EAAE,CAAA,EAAA,CAAI,CAAA;AACtE,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,CAAA,aAAA,EAAgB,SAAA,CAAU,EAAE,CAAC,CAAA,EAAA,EAAK,QAAQ,CAAA,IAAA,CAAM,CAAA;AAC3D,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,OAAA,EAAU,EAAE,CAAA,EAAA,CAAI,CAAA;AAC3B,EAAA,KAAA,CAAM,KAAK,CAAA,sCAAA,CAAwC,CAAA;AACnD,EAAA,KAAA,CAAM,KAAK,CAAA,EAAA,CAAI,CAAA;AACf,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAEb,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAEA,SAAS,UAAU,GAAA,EAAqB;AACtC,EAAA,OAAO,GAAA,CACJ,WAAA,EAAY,CACZ,OAAA,CAAQ,UAAA,EAAY,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAA;AAClD;AC1EA,eAAsB,aAAA,CAAc,UAAkB,OAAA,EAA8C;AAClG,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,mBAAmB,CAAC,CAAA;AAC3C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAAA,CAAM,GAAA,CAAI,uBAAuB,CAAC,CAAA;AAChD,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,iCAAiC,CAAC,CAAA;AACzD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AACxB,EAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,MAAM,CAAA;AAC9C,EAAA,MAAM,WAAW,OAAA,CAAQ,KAAA,GAAQ,SAAS,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GAAI,CAAA;AAE/D,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,QAAQ,EAAE,CAAC,CAAA;AAC/C,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,QAAQ,EAAE,CAAC,CAAA;AAC/C,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI;AAEF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qBAAqB,CAAC,CAAA;AAC7C,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,MAAM,aAAA,CAAc,QAAQ,GAAG,CAAA;AAGpD,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,QAAA,EAAU,QAAQ,CAAA;AAC1C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAA,CAAQ,MAAMA,MAAAA,CAAM,GAAA,CAAI,CAAA,iBAAA,EAAoB,QAAQ,aAAa,CAAC,CAAA;AAClE,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAGA,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,uBAAuB,CAAC,CAAA;AAC/C,IAAA,MAAM,SAAS,aAAA,CAAc,QAAA,EAAU,QAAA,EAAU,MAAA,CAAO,MAAM,QAAQ,CAAA;AAGtE,IAAA,mBAAA,CAAoB,QAAQ,OAAO,CAAA;AAAA,EAErC,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAMA,MAAAA,CAAM,GAAA,CAAI,yBAAyB,GAAG,KAAK,CAAA;AACzD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAMA,SAAS,QAAA,CAAS,UAAyB,EAAA,EAAoD;AAC7F,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAClD,IAAA,IAAI,GAAA,YAAe,GAAA,IAAO,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG;AACrC,MAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAE;AAAA,IACnC;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,aAAA,CACP,QAAA,EACA,QAAA,EACA,UAAA,EACA,QAAA,EACc;AACd,EAAA,MAAM,gBAA8B,EAAC;AACrC,EAAA,MAAM,OAAA,mBAAU,IAAI,GAAA,CAAY,CAAC,QAAQ,CAAC,CAAA;AAG1C,EAAA,SAAS,cAAA,CAAe,IAAY,KAAA,EAAqB;AACvD,IAAA,IAAI,QAAQ,QAAA,EAAU;AAEtB,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAClD,MAAA,IAAI,EAAE,eAAe,GAAA,CAAA,EAAM;AAE3B,MAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,IAAI,CAAA,IAAK,GAAA,EAAK;AAChC,QAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAG;AAGzB,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AACnC,QAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,CAAA,CAAA,EAAI,EAAE,GAAG,CAAA,EAAG;AAC/B,UAAA,OAAA,CAAQ,IAAI,MAAM,CAAA;AAClB,UAAA,aAAA,CAAc,IAAA,CAAK;AAAA,YACjB,EAAA,EAAI,MAAA;AAAA,YACJ,IAAA;AAAA,YACA,KAAA;AAAA,YACA,UAAA,EAAY,KAAA,KAAU,CAAA,GAAI,QAAA,GAAW;AAAA,WACtC,CAAA;AAGD,UAAA,cAAA,CAAe,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,cAAA,CAAe,UAAU,CAAC,CAAA;AAE1B,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,QAAA;AAAA,IACR,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAMA,SAAS,mBAAA,CAAoB,QAAsB,OAAA,EAAqC;AACtF,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAEd,EAAA,IAAI,OAAA,CAAQ,WAAW,MAAA,EAAQ;AAC7B,IAAA,OAAA,CAAQ,IAAI,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC,CAAA;AAC3C,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAW,SAAA,EAAW;AAChC,IAAA,OAAA,CAAQ,IAAI,YAAY,CAAA;AACxB,IAAA,OAAA,CAAQ,IAAI,UAAU,CAAA;AACtB,IAAA,OAAA,CAAQ,IAAI,CAAA,IAAA,EAAO,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,MAAA,CAAO,MAAM,CAAA,CAAA,CAAG,CAAA;AACpD,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,aAAA,EAAe;AACvC,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,KAAe,QAAA,GAAW,aAAA,GAAgB,gBAAA;AAC7D,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,IAAA,EAAO,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,IAAA,CAAK,EAAE,CAAA,CAAA,EAAI,IAAA,CAAK,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,IACpE;AACA,IAAA,OAAA,CAAQ,IAAI,KAAK,CAAA;AACjB,IAAA;AAAA,EACF;AAGA,EAAA,IAAI,MAAA,CAAO,aAAA,CAAc,MAAA,KAAW,CAAA,EAAG;AACrC,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,KAAA,CAAM,8BAA8B,CAAC,CAAA;AACvD,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,SAAS,MAAA,CAAO,aAAA,CAAc,OAAO,CAAA,CAAA,KAAK,CAAA,CAAE,eAAe,QAAQ,CAAA;AACzE,EAAA,MAAM,WAAW,MAAA,CAAO,aAAA,CAAc,OAAO,CAAA,CAAA,KAAK,CAAA,CAAE,eAAe,UAAU,CAAA;AAE7E,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,oBAAoB,MAAA,CAAO,MAAM,IAAI,CAAC,CAAA;AAC/D,IAAA,KAAA,MAAW,QAAQ,MAAA,EAAQ;AACzB,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,MAAA,CAAO,CAAA,WAAA,EAAS,IAAA,CAAK,EAAE,CAAA,EAAA,EAAK,IAAA,CAAK,IAAI,CAAA,CAAA,CAAG,CAAC,CAAA;AAAA,IAC7D;AAAA,EACF;AAEA,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,IAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,sBAAsB,QAAA,CAAS,MAAM,IAAI,CAAC,CAAA;AACjE,IAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,MAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAS,IAAA,CAAK,EAAE,CAAA,EAAA,EAAK,IAAA,CAAK,IAAI,CAAA,SAAA,EAAY,IAAA,CAAK,KAAK,GAAG,CAAC,CAAA;AAAA,IACjF;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,OAAM,IAAA,CAAK,CAAA,SAAA,EAAY,OAAO,aAAA,CAAc,MAAM,oBAAoB,CAAC,CAAA;AACrF;AC/KA,IAAMO,YAAA,GAAa,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAChD,IAAMC,WAAA,GAAYV,QAAQS,YAAU,CAAA;AAEpC,eAAsB,OAAA,CAAQ,OAAA,GAAuB,EAAC,EAAkB;AACtE,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AAExB,EAAA,OAAA,CAAQ,GAAA,CAAIP,MAAAA,CAAM,IAAA,CAAK,iBAAiB,CAAC,CAAA;AACzC,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AAGd,EAAA,MAAM,SAAA,GAAYC,IAAAA,CAAK,GAAA,EAAK,QAAQ,CAAA;AACpC,EAAA,MAAM,UAAA,GAAaA,IAAAA,CAAK,GAAA,EAAK,sBAAsB,CAAA;AAEnD,EAAA,IAAI,CAAC,QAAQ,KAAA,KAAUJ,UAAAA,CAAW,SAAS,CAAA,IAAKA,UAAAA,CAAW,UAAU,CAAA,CAAA,EAAI;AACvE,IAAA,OAAA,CAAQ,GAAA,CAAIG,MAAAA,CAAM,MAAA,CAAO,gCAAgC,CAAC,CAAA;AAC1D,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,4CAA4C,CAAC,CAAA;AACpE,IAAA;AAAA,EACF;AAGA,EAAA,MAAM,cAAc,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,KAAI,IAAK,YAAA;AAG5C,EAAA,MAAM,YAAA,GAAeC,IAAAA,CAAKO,WAAA,EAAW,WAAA,EAAa,MAAM,CAAA;AAExD,EAAA,IAAI,CAACX,UAAAA,CAAW,YAAY,CAAA,EAAG;AAC7B,IAAA,OAAA,CAAQ,IAAIG,MAAAA,CAAM,GAAA,CAAI,CAAA,0CAAA,EAA6C,YAAY,EAAE,CAAC,CAAA;AAClF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,oDAAoD,CAAC,CAAA;AAC5E,IAAA;AAAA,EACF;AAGA,EAAA,IAAI,kBAAA,GAAqB,KAAA;AACzB,EAAA,eAAA,CAAgB,YAAA,EAAc,KAAK,WAAA,EAAa,OAAA,CAAQ,SAAS,KAAA,EAAO,CAAC,cAAc,OAAA,KAAY;AACjG,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,KAAA,CAAM,CAAA,WAAA,EAAc,YAAY,EAAE,CAAC,CAAA;AACrD,MAAA,IAAI,iBAAiB,cAAA,EAAgB;AACnC,QAAA,kBAAA,GAAqB,IAAA;AAAA,MACvB;AAAA,IACF,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,MAAA,CAAO,CAAA,WAAA,EAAc,YAAY,mBAAmB,CAAC,CAAA;AAAA,IACzE;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,qCAAqC,CAAC,CAAA;AAC7D,EAAA,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,EAAA,OAAA,CAAQ,IAAI,eAAe,CAAA;AAC3B,EAAA,IAAI,kBAAA,EAAoB;AACtB,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,kDAAkD,CAAC,CAAA;AAC1E,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,sDAAsD,CAAC,CAAA;AAC9E,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,sCAAsC,CAAC,CAAA;AAC9D,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,8CAA8C,CAAC,CAAA;AAAA,EACxE,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,iEAAiE,CAAC,CAAA;AACzF,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,uDAAuD,CAAC,CAAA;AAC/E,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,sDAAsD,CAAC,CAAA;AAC9E,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,sCAAsC,CAAC,CAAA;AAC9D,IAAA,OAAA,CAAQ,GAAA,CAAIA,MAAAA,CAAM,IAAA,CAAK,8CAA8C,CAAC,CAAA;AAAA,EACxE;AACF;AAKA,SAAS,gBACP,MAAA,EACA,OAAA,EACA,aACA,KAAA,EACA,MAAA,EACA,eAAuB,EAAA,EACjB;AACN,EAAA,MAAM,OAAA,GAAUS,YAAY,MAAM,CAAA;AAElC,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,OAAA,GAAUR,IAAAA,CAAK,MAAA,EAAQ,KAAK,CAAA;AAClC,IAAA,MAAM,IAAA,GAAOS,SAAS,OAAO,CAAA;AAG7B,IAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,WAAW,IAAI,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,KAAA;AACrE,IAAA,MAAM,QAAA,GAAWT,IAAAA,CAAK,OAAA,EAAS,SAAS,CAAA;AACxC,IAAA,MAAM,OAAA,GAAU,YAAA,GAAeA,IAAAA,CAAK,YAAA,EAAc,SAAS,CAAA,GAAI,SAAA;AAE/D,IAAA,IAAI,IAAA,CAAK,aAAY,EAAG;AAEtB,MAAA,IAAI,CAACJ,UAAAA,CAAW,QAAQ,CAAA,EAAG;AACzB,QAAAc,SAAAA,CAAU,QAAA,EAAU,EAAE,SAAA,EAAW,MAAM,CAAA;AACvC,QAAA,MAAA,CAAO,OAAA,GAAU,KAAK,IAAI,CAAA;AAAA,MAC5B;AAEA,MAAA,eAAA,CAAgB,OAAA,EAAS,QAAA,EAAU,WAAA,EAAa,KAAA,EAAO,QAAQ,OAAO,CAAA;AAAA,IACxE,CAAA,MAAO;AAEL,MAAA,IAAI,CAAC,KAAA,IAASd,UAAAA,CAAW,QAAQ,CAAA,EAAG;AAClC,QAAA,MAAA,CAAO,SAAS,KAAK,CAAA;AACrB,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,OAAA,GAAUE,YAAAA,CAAa,OAAA,EAAS,OAAO,CAAA;AAG3C,MAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,uBAAA,EAAyB,WAAW,CAAA;AAG9D,MAAA,MAAM,GAAA,GAAMD,QAAQ,QAAQ,CAAA;AAC5B,MAAA,IAAI,CAACD,UAAAA,CAAW,GAAG,CAAA,EAAG;AACpB,QAAAc,SAAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,MACpC;AACA,MAAAL,aAAAA,CAAc,UAAU,OAAO,CAAA;AAC/B,MAAA,MAAA,CAAO,SAAS,IAAI,CAAA;AAAA,IACtB;AAAA,EACF;AACF;;;ACrHA,IAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAE5B,OAAA,CACG,KAAK,YAAY,CAAA,CACjB,YAAY,kEAAkE,CAAA,CAC9E,QAAQ,OAAO,CAAA;AAIlB,OAAA,CACG,OAAA,CAAQ,OAAO,CAAA,CACf,WAAA,CAAY,kDAAkD,CAAA,CAC9D,MAAA,CAAO,qBAAA,EAAuB,qBAAqB,CAAA,CACnD,MAAA,CAAO,qBAAA,EAAuB,4BAAA,EAA8B,GAAG,CAAA,CAC/D,MAAA,CAAO,uBAAA,EAAyB,qCAAA,EAAuC,MAAM,CAAA,CAC7E,MAAA,CAAO,aAAA,EAAe,uCAAuC,CAAA,CAC7D,MAAA,CAAO,eAAA,EAAiB,sBAAsB,CAAA,CAC9C,OAAO,YAAY,CAAA;AAItB,OAAA,CACG,OAAA,CAAQ,MAAM,CAAA,CACd,WAAA,CAAY,4EAA4E,CAAA,CACxF,MAAA,CAAO,qBAAA,EAAuB,qBAAqB,CAAA,CACnD,MAAA,CAAO,qBAAA,EAAuB,kDAAkD,CAAA,CAChF,MAAA,CAAO,cAAA,EAAgB,0BAA0B,CAAA,CACjD,MAAA,CAAO,OAAA,EAAS,oCAAoC,CAAA,CACpD,MAAA,CAAO,uBAAA,EAAyB,mCAAA,EAAqC,MAAM,CAAA,CAC3E,MAAA,CAAO,WAAW,CAAA;AAIrB,OAAA,CACG,OAAA,CAAQ,OAAO,CAAA,CACf,WAAA,CAAY,oDAAoD,CAAA,CAChE,MAAA,CAAO,uBAAuB,qBAAqB,CAAA,CACnD,OAAO,cAAA,EAAgB,sCAAsC,EAC7D,MAAA,CAAO,uBAAA,EAAyB,mCAAmC,MAAM,CAAA,CACzE,OAAO,YAAY,CAAA;AAItB,OAAA,CACG,OAAA,CAAQ,OAAO,CAAA,CACf,WAAA,CAAY,2DAA2D,CAAA,CACvE,QAAA,CAAS,QAAA,EAAU,oEAAoE,CAAA,CACvF,MAAA,CAAO,qBAAA,EAAuB,qBAAqB,CAAA,CACnD,MAAA,CAAO,UAAA,EAAY,0BAA0B,CAAA,CAC7C,MAAA,CAAO,eAAA,EAAiB,sBAAsB,CAAA,CAC9C,MAAA,CAAO,YAAA,EAAc,mEAAmE,CAAA,CACxF,MAAA,CAAO,YAAY,CAAA;AAItB,OAAA,CACG,OAAA,CAAQ,KAAK,CAAA,CACb,WAAA,CAAY,6CAA6C,CAAA,CACzD,QAAA,CAAS,QAAA,EAAU,+EAA+E,CAAA,CAClG,MAAA,CAAO,mBAAA,EAAqB,8DAA8D,CAAA,CAC1F,MAAA,CAAO,mBAAA,EAAqB,qBAAqB,CAAA,CACjD,MAAA,CAAO,qBAAA,EAAuB,uBAAuB,CAAA,CACrD,MAAA,CAAO,uBAAA,EAAyB,uBAAuB,CAAA,CACvD,MAAA,CAAO,UAAU,CAAA;AAIpB,OAAA,CACG,OAAA,CAAQ,QAAQ,CAAA,CAChB,WAAA,CAAY,oCAAoC,CAAA,CAChD,QAAA,CAAS,MAAA,EAAQ,0CAA0C,CAAA,CAC3D,MAAA,CAAO,qBAAA,EAAuB,qBAAqB,CAAA,CACnD,MAAA,CAAO,qBAAA,EAAuB,2CAAA,EAA6C,GAAG,CAAA,CAC9E,MAAA,CAAO,yBAAA,EAA2B,gDAAA,EAAkD,MAAM,CAAA,CAC1F,MAAA,CAAO,uBAAA,EAAyB,oCAAA,EAAsC,MAAM,CAAA,CAC5E,OAAO,aAAa,CAAA;AAGvB,OAAA,CACG,OAAA,CAAQ,MAAM,CAAA,CACd,WAAA,CAAY,4DAA4D,CAAA,CACxE,MAAA,CAAO,aAAA,EAAe,0BAA0B,CAAA,CAChD,MAAA,CAAO,OAAO,CAAA;AAGjB,OAAA,CAAQ,KAAA,EAAM","file":"cli.js","sourcesContent":["import { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\n/**\n * Specification-compliant output path definitions\n * \n * Human-readable artifacts (docs/):\n * requirements/ - Requirements Markdown\n * usecases/ - Use cases\n * architecture/ - Architecture (C4 diagrams)\n * data-model/ - Conceptual model (ER diagrams)\n * screens/ - Screen specifications\n * flows/ - Process flows\n * glossary/ - Glossary\n * \n * Machine-readable artifacts (specs/):\n * schemas/entities/ - Entity JSON Schema\n * index.json - Aggregated data\n */\nexport interface OutputPaths {\n // docs/ subdirectories\n requirements: string;\n usecases: string;\n architecture: string;\n dataModel: string;\n screens: string;\n flows: string;\n glossary: string;\n component: string;\n \n // specs/ subdirectories\n schemasEntities: string;\n}\n\nexport interface SpeckeeperConfig {\n // Project info\n projectName?: string;\n version?: string;\n \n // Source paths\n srcDir: string;\n requirementsDir?: string;\n designDir?: string;\n usecasesDir?: string;\n \n // Output paths\n docsDir: string;\n specsDir: string;\n \n // External SSOT paths\n externalSsot?: {\n openapi?: {\n enabled: boolean;\n paths: string[];\n microContracts?: {\n enabled: boolean;\n requiredExtensions?: string[];\n strictMode?: boolean;\n };\n };\n ddl?: {\n enabled: boolean;\n paths: string[];\n type: 'ddl' | 'prisma' | 'typeorm' | 'drizzle';\n };\n iac?: {\n enabled: boolean;\n paths: string[];\n type: 'cloudformation' | 'terraform' | 'cdk';\n };\n };\n \n // Lint configuration\n lint?: {\n architecture?: {\n allowCrossBoundaryDependencies?: boolean;\n allowCrossLayerViolations?: boolean;\n maxComponentsPerDiagram?: number;\n };\n conceptModel?: {\n requireEntityDescription?: boolean;\n requireAggregateRoot?: boolean;\n warnOnOrphanEntities?: boolean;\n namingConvention?: 'PascalCase' | 'camelCase' | 'snake_case' | 'none';\n };\n screen?: {\n warnOnOrphanScreens?: boolean;\n warnOnDeadEnds?: boolean;\n checkAuthPaths?: boolean;\n };\n phaseGate?: {\n currentPhase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strictMode?: boolean;\n };\n };\n \n // Build configuration\n build?: {\n generateMermaidImages?: boolean;\n mermaidCliPath?: string;\n };\n \n // Custom model definitions\n models?: unknown[];\n}\n\n// Default configuration\nconst defaultConfig: SpeckeeperConfig = {\n srcDir: 'src',\n designDir: 'design', // Directory for requirements/design TS models\n docsDir: 'docs',\n specsDir: 'specs',\n};\n\n// ============================================================================\n// Output Paths (spec-compliant)\n// ============================================================================\n\n/**\n * Get output paths compliant with specification\n */\nexport function getOutputPaths(config: SpeckeeperConfig, cwd: string = process.cwd()): OutputPaths {\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n return {\n // docs/ subdirectories (compliant with spec section 7.1)\n requirements: join(docsDir, 'requirements'),\n usecases: join(docsDir, 'usecases'),\n architecture: join(docsDir, 'architecture'),\n dataModel: join(docsDir, 'data-model'),\n screens: join(docsDir, 'screens'),\n flows: join(docsDir, 'flows'),\n glossary: join(docsDir, 'glossary'),\n component: join(docsDir, 'component'),\n \n // specs/ subdirectories (compliant with spec section 7.1)\n schemasEntities: join(specsDir, 'schemas', 'entities'),\n };\n}\n\n/**\n * List of expected output paths (for drift check)\n */\nexport function getExpectedOutputDirs(config: SpeckeeperConfig, cwd: string = process.cwd()): string[] {\n const paths = getOutputPaths(config, cwd);\n return [\n paths.requirements,\n paths.usecases,\n paths.architecture,\n paths.dataModel,\n paths.screens,\n paths.flows,\n paths.glossary,\n paths.component,\n paths.schemasEntities,\n ];\n}\n\n/**\n * Validate if output path complies with specification\n */\nexport function validateOutputPaths(actualPath: string, config: SpeckeeperConfig, cwd: string = process.cwd()): {\n valid: boolean;\n expectedPaths: string[];\n message?: string;\n} {\n const expectedDirs = getExpectedOutputDirs(config, cwd);\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n // Check if actualPath is under docs/ or specs/\n const isUnderDocs = actualPath.startsWith(docsDir);\n const isUnderSpecs = actualPath.startsWith(specsDir);\n \n if (!isUnderDocs && !isUnderSpecs) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" is not under docs/ or specs/`,\n };\n }\n \n // Check if under any of the expected paths\n const isValidPath = expectedDirs.some(dir => actualPath.startsWith(dir));\n \n if (!isValidPath) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" does not match spec-compliant paths. Expected one of: ${expectedDirs.map(d => d.replace(cwd + '/', '')).join(', ')}`,\n };\n }\n \n return { valid: true, expectedPaths: expectedDirs };\n}\n\n// ============================================================================\n// Configuration Loading\n// ============================================================================\n\nconst CONFIG_FILES = [\n 'speckeeper.config.yaml',\n 'speckeeper.config.yml',\n 'speckeeper.config.json',\n 'speckeeper.config.ts',\n 'speckeeper.config.js',\n];\n\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n \n while (currentDir !== dirname(currentDir)) {\n for (const configFile of CONFIG_FILES) {\n const configPath = resolve(currentDir, configFile);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n currentDir = dirname(currentDir);\n }\n \n return null;\n}\n\nexport async function loadConfig(\n configPath?: string,\n cwd: string = process.cwd()\n): Promise<SpeckeeperConfig> {\n const resolvedPath = configPath ?? findConfigFile(cwd);\n \n if (!resolvedPath) {\n return { ...defaultConfig };\n }\n \n const ext = resolvedPath.split('.').pop()?.toLowerCase();\n \n try {\n if (ext === 'yaml' || ext === 'yml') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = parseYaml(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'json') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'ts' || ext === 'js') {\n // Dynamic import for TS/JS config\n const module = await import(resolvedPath);\n const parsed = module.default ?? module;\n return { ...defaultConfig, ...parsed };\n }\n \n return { ...defaultConfig };\n } catch (error) {\n console.error(`Failed to load config from ${resolvedPath}:`, error);\n return { ...defaultConfig };\n }\n}\n\n// ============================================================================\n// Configuration Validation\n// ============================================================================\n\nexport function validateConfig(config: SpeckeeperConfig): string[] {\n const errors: string[] = [];\n \n if (!config.srcDir) {\n errors.push('srcDir is required');\n }\n \n if (!config.docsDir) {\n errors.push('docsDir is required');\n }\n \n if (!config.specsDir) {\n errors.push('specsDir is required');\n }\n \n return errors;\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { createHash } from 'node:crypto';\n\n// ============================================================================\n// File Writing\n// ============================================================================\n\nexport interface WriteResult {\n path: string;\n created: boolean;\n updated: boolean;\n unchanged: boolean;\n}\n\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\nexport function writeFile(filePath: string, content: string): WriteResult {\n const dir = dirname(filePath);\n ensureDir(dir);\n \n const existed = existsSync(filePath);\n let unchanged = false;\n \n if (existed) {\n const existingContent = readFileSync(filePath, 'utf-8');\n unchanged = existingContent === content;\n }\n \n if (!unchanged) {\n writeFileSync(filePath, content, 'utf-8');\n }\n \n return {\n path: filePath,\n created: !existed,\n updated: existed && !unchanged,\n unchanged,\n };\n}\n\nexport function writeJsonFile(filePath: string, data: unknown, indent: number = 2): WriteResult {\n const content = JSON.stringify(data, null, indent) + '\\n';\n return writeFile(filePath, content);\n}\n\n// ============================================================================\n// Batch Writing\n// ============================================================================\n\nexport interface BatchWriteResult {\n results: WriteResult[];\n created: number;\n updated: number;\n unchanged: number;\n total: number;\n}\n\nexport function batchWriteFiles(\n files: Array<{ path: string; content: string }>\n): BatchWriteResult {\n const results: WriteResult[] = [];\n \n for (const { path, content } of files) {\n results.push(writeFile(path, content));\n }\n \n return {\n results,\n created: results.filter(r => r.created).length,\n updated: results.filter(r => r.updated).length,\n unchanged: results.filter(r => r.unchanged).length,\n total: results.length,\n };\n}\n\n// ============================================================================\n// Drift Detection\n// ============================================================================\n\nexport interface DriftResult {\n file: string;\n hasDrift: boolean;\n expectedHash?: string;\n actualHash?: string;\n missing?: boolean;\n}\n\nexport function computeHash(content: string): string {\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\nexport function checkFileDrift(\n filePath: string,\n expectedContent: string\n): DriftResult {\n const expectedHash = computeHash(expectedContent);\n \n if (!existsSync(filePath)) {\n return {\n file: filePath,\n hasDrift: true,\n expectedHash,\n missing: true,\n };\n }\n \n const actualContent = readFileSync(filePath, 'utf-8');\n const actualHash = computeHash(actualContent);\n \n return {\n file: filePath,\n hasDrift: expectedHash !== actualHash,\n expectedHash,\n actualHash,\n };\n}\n\nexport function checkBatchDrift(\n files: Array<{ path: string; content: string }>\n): DriftResult[] {\n return files.map(({ path, content }) => checkFileDrift(path, content));\n}\n\n// ============================================================================\n// File Discovery\n// ============================================================================\n\nimport { glob } from 'glob';\n\nexport async function findFiles(\n pattern: string,\n cwd: string = process.cwd()\n): Promise<string[]> {\n return glob(pattern, { cwd, absolute: true });\n}\n\nexport async function findTypeScriptFiles(\n srcDir: string\n): Promise<string[]> {\n return findFiles('**/*.ts', srcDir);\n}\n\nexport async function findDefinitionFiles(\n srcDir: string,\n subDir: string\n): Promise<string[]> {\n const pattern = join(srcDir, subDir, '**/*.ts');\n return glob(pattern, { absolute: true, ignore: ['**/*.d.ts', '**/index.ts'] });\n}\n\n// ============================================================================\n// Output Helpers\n// ============================================================================\n\nexport function generateDocsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n\nexport function generateSpecsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n","/**\n * Definition and validation of model relations\n */\nimport { z } from 'zod';\n\n// ============================================================================\n// Model Levels\n// ============================================================================\n\n/**\n * Model abstraction level\n * \n * - L0: Business + Domain Analysis (Why / Problem space)\n * Desired outcomes/value, business flows, actors, terminology, business rules\n * - L1: Requirements (What)\n * Functional/non-functional requirements, constraints, acceptance criteria\n * - L2: Design (How / Direction)\n * Architecture, component breakdown, domain model, key sequences\n * - L3: Detailed Design/Implementation (How to build / Concrete artifacts)\n * Screen/API/DB definitions, external SSOT references\n */\nexport type ModelLevel = 'L0' | 'L1' | 'L2' | 'L3';\n\n/**\n * Get numeric index of level\n */\nexport function getLevelIndex(level: ModelLevel): number {\n return ['L0', 'L1', 'L2', 'L3'].indexOf(level);\n}\n\n// ============================================================================\n// Relation Types\n// ============================================================================\n\n/**\n * Relation types\n */\nexport const RELATION_TYPES = [\n 'dependsOn',\n 'uses',\n 'includes',\n 'implements',\n 'refines',\n 'verifies',\n 'satisfies',\n 'traces',\n 'relatedTo',\n] as const;\n\nexport type RelationType = typeof RELATION_TYPES[number];\n\n/**\n * Relation schema\n */\nexport const RelationSchema = z.object({\n /** Relation type */\n type: z.enum(RELATION_TYPES),\n /** Target ID */\n target: z.string(),\n /** Description (optional) */\n description: z.string().optional(),\n});\n\n/**\n * Relation field to add to model schemas\n * Usage: schema.extend({ relations: RelationsFieldSchema })\n */\nexport const RelationsFieldSchema = z.array(RelationSchema).optional();\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\n// ============================================================================\n// Relation Constraints\n// ============================================================================\n\n/**\n * Definition of relation constraints\n */\nexport interface RelationConstraint {\n /** Allowed target levels (all levels allowed if not specified) */\n allowedTargetLevels?: ModelLevel[];\n /** Level constraint rule */\n levelRule: 'source>target' | 'source>=target' | 'same' | 'any';\n /** Direction of impact propagation */\n propagation: 'forward' | 'backward' | 'both';\n}\n\n/**\n * Constraint definitions per relation type\n * \n * Level hierarchy:\n * L0 (Business) → L1 (Requirements) → L2 (Design) → L3 (Implementation)\n * Abstract ───────────────────────────→ Concrete\n */\nexport const RELATION_CONSTRAINTS: Record<RelationType, RelationConstraint> = {\n // Concrete→Abstract (implementation/design fulfills requirements)\n 'implements': {\n allowedTargetLevels: ['L1'], // Implements requirements\n levelRule: 'source>target',\n propagation: 'forward', // A changes → B needs review\n },\n // Concrete→Abstract (design/implementation satisfies business/requirements)\n 'satisfies': {\n allowedTargetLevels: ['L0', 'L1'], // Satisfies business/requirements\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A needs update\n },\n // Concrete→Abstract (refinement: requirements refine business, design refines requirements)\n 'refines': {\n allowedTargetLevels: ['L0', 'L1'], // Refines business/requirements\n levelRule: 'source>target',\n propagation: 'backward', // B changes → A needs update\n },\n // Test→Requirements/Business (verification relationship)\n 'verifies': {\n allowedTargetLevels: ['L0', 'L1'], // Verifies business/requirements\n levelRule: 'any',\n propagation: 'backward', // B changes → A needs update\n },\n // Dependencies (same level or concrete→abstract)\n 'dependsOn': {\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A affected\n },\n // Usage relationship (no level constraint)\n 'uses': {\n levelRule: 'any',\n propagation: 'backward', // B changes → A affected\n },\n // Inclusion relationship (same level only)\n 'includes': {\n levelRule: 'same',\n propagation: 'backward', // B changes → A affected\n },\n // Bidirectional tracing\n 'traces': {\n levelRule: 'any',\n propagation: 'both',\n },\n // General relation\n 'relatedTo': {\n levelRule: 'any',\n propagation: 'both',\n },\n};\n\n// ============================================================================\n// Relation Validation\n// ============================================================================\n\n/**\n * Relation validation result\n */\nexport interface RelationValidationResult {\n valid: boolean;\n errors: RelationValidationError[];\n}\n\n/**\n * Relation validation error\n */\nexport interface RelationValidationError {\n type: 'level_violation' | 'target_level_violation' | 'self_reference' | 'cycle_detected';\n message: string;\n relation: Relation;\n sourceId: string;\n}\n\n/**\n * Validate level constraint for single relation\n * \n * @param sourceLevel - Source model level (set in _models/)\n * @param sourceSpecId - Source spec ID\n * @param relation - Relation\n * @param targetLevel - Target model level\n */\nexport function validateRelationLevel(\n sourceLevel: ModelLevel | undefined,\n sourceSpecId: string,\n relation: Relation,\n targetLevel: ModelLevel | undefined,\n): RelationValidationError | null {\n // Self-reference check\n if (sourceSpecId === relation.target) {\n return {\n type: 'self_reference',\n message: `Self-reference is not allowed: ${sourceSpecId} → ${relation.target}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n\n // Skip if level is undefined\n if (!sourceLevel || !targetLevel) {\n return null;\n }\n \n const constraint = RELATION_CONSTRAINTS[relation.type];\n \n // Target level constraint check\n if (constraint.allowedTargetLevels && \n !constraint.allowedTargetLevels.includes(targetLevel)) {\n return {\n type: 'target_level_violation',\n message: `'${relation.type}' relation target must be ${constraint.allowedTargetLevels.join(' or ')}, but target is ${targetLevel}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n \n // Level direction constraint check\n const srcIdx = getLevelIndex(sourceLevel);\n const tgtIdx = getLevelIndex(targetLevel);\n \n switch (constraint.levelRule) {\n case 'source>target':\n if (srcIdx <= tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'source>=target':\n if (srcIdx < tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be same or more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'same':\n if (srcIdx !== tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) and target (${targetLevel}) to be same level`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n }\n \n return null;\n}\n\n/**\n * Detect circular references\n */\nexport function detectCycles(\n relations: Array<{ sourceId: string; targetId: string; type: RelationType }>,\n): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const graph = new Map<string, Set<string>>();\n const relationMap = new Map<string, Relation>();\n \n // Build graph\n for (const rel of relations) {\n if (!graph.has(rel.sourceId)) {\n graph.set(rel.sourceId, new Set());\n }\n graph.get(rel.sourceId)!.add(rel.targetId);\n relationMap.set(`${rel.sourceId}→${rel.targetId}`, { type: rel.type, target: rel.targetId });\n }\n \n // Detect cycles using DFS\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cyclePath: string[] = [];\n \n function dfs(node: string): boolean {\n visited.add(node);\n recursionStack.add(node);\n cyclePath.push(node);\n \n const neighbors = graph.get(node);\n if (neighbors) {\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) {\n return true;\n }\n } else if (recursionStack.has(neighbor)) {\n // Cycle detected\n const cycleStart = cyclePath.indexOf(neighbor);\n const cycle = cyclePath.slice(cycleStart);\n cycle.push(neighbor); // Close the cycle\n \n errors.push({\n type: 'cycle_detected',\n message: `Circular reference detected: ${cycle.join(' → ')}`,\n relation: relationMap.get(`${node}→${neighbor}`)!,\n sourceId: node,\n });\n return true;\n }\n }\n }\n \n cyclePath.pop();\n recursionStack.delete(node);\n return false;\n }\n \n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n \n return errors;\n}\n\n/**\n * Infer model ID from spec ID (prefix-based)\n */\nexport function inferModelIdFromSpecId(specId: string): string | undefined {\n const prefixMap: Record<string, string> = {\n 'REQ': 'requirement',\n 'CR': 'constraint',\n 'UC': 'usecase',\n 'ACTOR': 'actor',\n 'TERM': 'term',\n 'COMP': 'component',\n 'ENT': 'entity',\n 'FLOW': 'process-flow',\n 'LAYER': 'layer',\n 'BND': 'boundary',\n 'SCR': 'screen',\n 'API': 'api-ref',\n 'TBL': 'table-ref',\n 'IAC': 'iac-ref',\n 'BATCH': 'batch-ref',\n };\n \n for (const [prefix, modelId] of Object.entries(prefixMap)) {\n if (specId.startsWith(prefix + '-')) {\n return modelId;\n }\n }\n \n return undefined;\n}\n","/**\n * Model base class\n * \n * All model definitions inherit from this class\n */\nimport { z, ZodType } from 'zod';\nimport {\n type ModelLevel,\n type Relation,\n type RelationValidationError,\n validateRelationLevel,\n detectCycles,\n inferModelIdFromSpecId,\n} from './relation.js';\n\n// Re-export relation types\nexport type { ModelLevel, Relation, RelationValidationError };\nexport { RELATION_TYPES, RELATION_CONSTRAINTS, RelationSchema, RelationsFieldSchema } from './relation.js';\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Lint rule definition\n */\nexport interface LintRule<T> {\n id: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n check: (spec: T) => boolean; // true if there is an issue\n}\n\n/**\n * Lint result\n */\nexport interface LintResult {\n ruleId: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n specId?: string;\n}\n\n/**\n * Exporter definition\n */\nexport interface Exporter<T> {\n format: 'markdown' | 'json' | 'mermaid';\n single?: (spec: T) => string;\n index?: (specs: T[]) => string;\n outputDir?: string;\n filename?: (spec: T) => string;\n}\n\n/**\n * External checker definition\n */\nexport interface ExternalChecker<T> {\n targetType: string; // 'openapi' | 'ddl' | 'cli' etc.\n sourcePath: (spec: T) => string;\n check: (spec: T, externalData: unknown) => CheckResult;\n}\n\n/**\n * Check result\n */\nexport interface CheckResult {\n success: boolean;\n errors: { message: string; field?: string; specId?: string }[];\n warnings: { message: string; field?: string; specId?: string }[];\n}\n\n/**\n * Coverage result\n */\nexport interface CoverageResult {\n /** Total target count */\n total: number;\n /** Covered count */\n covered: number;\n /** Uncovered count */\n uncovered: number;\n /** Coverage rate (%) */\n coveragePercent: number;\n /** Details of covered items */\n coveredItems: { id: string; description?: string }[];\n /** Details of uncovered items */\n uncoveredItems: { id: string; description?: string; sourceId?: string }[];\n}\n\n/**\n * Coverage checker definition\n * \n * Verify cross-model consistency (coverage).\n * Example: Whether TestRef covers acceptanceCriteria of Requirement\n */\nexport interface CoverageChecker<T> {\n /** Target model ID for coverage (e.g. 'requirement') */\n targetModel: string;\n /** Description of coverage check */\n description: string;\n /** Execute coverage check */\n check: (\n specs: T[],\n registry: Record<string, Map<string, unknown>>\n ) => CoverageResult;\n}\n\n// ============================================================================\n// Renderer (for embeds)\n// ============================================================================\n\n/**\n * Render context\n * Simplified version compatible with embedoc's EmbedContext\n */\nexport interface RenderContext {\n /** Parameters (filter conditions other than format, etc.) */\n params: Record<string, string | undefined>;\n /** Markdown helpers */\n markdown: {\n /** Generate table */\n table: (headers: string[], rows: (string | unknown)[][]) => string;\n };\n}\n\n/**\n * Renderer definition\n * \n * Model-specific rendering called from embeds\n */\nexport interface Renderer<T> {\n /** Format ID ('table', 'list', 'detail', 'spec-chapter', etc.) */\n format: string;\n /** Rendering process */\n render: (specs: T[], ctx: RenderContext) => string;\n}\n\n// ============================================================================\n// Model Base Class\n// ============================================================================\n\n/**\n * Model base class\n * \n * @template TSchema - Zod schema type\n */\nexport abstract class Model<TSchema extends ZodType> {\n /** Singleton instance storage (per subclass) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private static _instances: WeakMap<new () => any, Model<ZodType>> = new WeakMap();\n\n /**\n * Get singleton instance of the model\n * Usage: RequirementModel.instance\n */\n static get instance(): Model<ZodType> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctor = this as unknown as new () => any;\n if (!this._instances.has(ctor)) {\n this._instances.set(ctor, new ctor());\n }\n return this._instances.get(ctor)!;\n }\n\n /** Model ID ('requirement', 'usecase', etc.) */\n abstract readonly id: string;\n \n /** Model name ('Requirement', 'UseCase', etc.) */\n abstract readonly name: string;\n \n /** ID prefix ('REQ', 'UC', etc.) */\n abstract readonly idPrefix: string;\n \n /** Zod schema */\n abstract readonly schema: TSchema;\n \n /** Model description (optional) */\n readonly description?: string;\n \n /** External SSOT type (optional, e.g. 'OpenAPI', 'DDL/Prisma') */\n readonly externalSsotType?: string;\n \n /** Spec instance type */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected get specType(): z.infer<TSchema> { return undefined as any; }\n \n /** Lint rules (override in subclass) */\n protected lintRules: LintRule<z.infer<TSchema>>[] = [];\n \n /** Exporters (override in subclass) */\n protected exporters: Exporter<z.infer<TSchema>>[] = [];\n \n /** External checker (optional) */\n protected externalChecker?: ExternalChecker<z.infer<TSchema>>;\n \n /** Coverage checker (optional) */\n protected coverageChecker?: CoverageChecker<z.infer<TSchema>>;\n \n /** Model level (set in _models/) */\n protected modelLevel?: ModelLevel;\n \n /** Renderers (for embeds, override in subclass) */\n protected renderers: Renderer<z.infer<TSchema>>[] = [];\n \n /**\n * Get model level\n * Returns modelLevel set in _models/\n */\n get level(): ModelLevel | undefined {\n return this.modelLevel;\n }\n \n /**\n * Execute schema validation\n */\n validate(spec: unknown): z.infer<TSchema> {\n return this.schema.parse(spec);\n }\n \n /**\n * Schema validation (safe version, returns error object on failure)\n */\n safeParse(spec: unknown): { success: true; data: z.infer<TSchema> } | { success: false; error: z.ZodError } {\n return this.schema.safeParse(spec);\n }\n \n /**\n * Execute lint\n */\n lint(spec: z.infer<TSchema>): LintResult[] {\n const specId = (spec as { id?: string }).id;\n return this.lintRules\n .filter(rule => rule.check(spec))\n .map(rule => ({\n ruleId: rule.id,\n severity: rule.severity,\n message: rule.message,\n specId,\n }));\n }\n \n /**\n * Execute lint for multiple specs\n */\n lintAll(specs: z.infer<TSchema>[]): LintResult[] {\n return specs.flatMap(spec => this.lint(spec));\n }\n \n /**\n * Validate level constraints of relations\n * @param spec - Spec instance (if it has relations property)\n * @returns Array of validation errors\n */\n validateRelations(spec: z.infer<TSchema>): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n \n if (!specWithRelations.relations || !specWithRelations.id) {\n return errors;\n }\n \n // Get all models to retrieve target model levels\n const allModels = getAllModels();\n const modelLevelMap = new Map<string, ModelLevel | undefined>();\n for (const model of allModels) {\n modelLevelMap.set(model.id, model.level);\n }\n \n for (const relation of specWithRelations.relations) {\n // Infer target model ID\n const targetModelId = inferModelIdFromSpecId(relation.target);\n if (!targetModelId) {\n continue; // Skip if model ID cannot be inferred\n }\n \n const targetLevel = modelLevelMap.get(targetModelId);\n \n const error = validateRelationLevel(\n this.level,\n specWithRelations.id,\n relation,\n targetLevel,\n );\n \n if (error) {\n errors.push(error);\n }\n }\n \n return errors;\n }\n \n /**\n * Validate relations of multiple specs (including circular reference check)\n */\n validateAllRelations(specs: z.infer<TSchema>[]): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const allRelations: Array<{ sourceId: string; targetId: string; type: string }> = [];\n \n for (const spec of specs) {\n // Individual level constraint check\n errors.push(...this.validateRelations(spec));\n \n // Collect relations for circular reference check\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n if (specWithRelations.relations && specWithRelations.id) {\n for (const rel of specWithRelations.relations) {\n allRelations.push({\n sourceId: specWithRelations.id,\n targetId: rel.target,\n type: rel.type,\n });\n }\n }\n }\n \n // Circular reference check\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errors.push(...detectCycles(allRelations as any));\n \n return errors;\n }\n \n /**\n * Export in specified format (single spec)\n */\n exportSingle(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.single) return null;\n return exporter.single(spec);\n }\n \n /**\n * Export in specified format (index)\n */\n exportIndex(specs: z.infer<TSchema>[], format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.index) return null;\n return exporter.index(specs);\n }\n \n /**\n * Get exporter output directory\n */\n getOutputDir(format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n return exporter?.outputDir ?? null;\n }\n \n /**\n * Get filename\n */\n getFilename(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.filename) return null;\n return exporter.filename(spec);\n }\n \n /**\n * Check consistency with external SSOT\n */\n check(spec: z.infer<TSchema>, externalData: unknown): CheckResult {\n if (!this.externalChecker) {\n return { success: true, errors: [], warnings: [] };\n }\n return this.externalChecker.check(spec, externalData);\n }\n \n /**\n * Get external SSOT path\n */\n getExternalSourcePath(spec: z.infer<TSchema>): string | null {\n if (!this.externalChecker) return null;\n return this.externalChecker.sourcePath(spec);\n }\n \n /**\n * Execute coverage check\n * @param specs - Array of spec instances for this model\n * @param registry - Registry of all models\n */\n checkCoverage(\n specs: z.infer<TSchema>[],\n registry: Record<string, Map<string, unknown>>\n ): CoverageResult | null {\n if (!this.coverageChecker) return null;\n return this.coverageChecker.check(specs, registry);\n }\n \n /**\n * Get coverage checker\n */\n getCoverageChecker(): CoverageChecker<z.infer<TSchema>> | undefined {\n return this.coverageChecker;\n }\n \n /**\n * Get lint rules\n */\n getLintRules(): LintRule<z.infer<TSchema>>[] {\n return this.lintRules;\n }\n \n /**\n * Get exporters\n */\n getExporters(): Exporter<z.infer<TSchema>>[] {\n return this.exporters;\n }\n \n // ============================================================================\n // Renderer (for embeds)\n // ============================================================================\n \n /**\n * Render in specified format\n * @param format - Format ID ('table', 'list', 'detail', etc.)\n * @param specs - Array of specs to render\n * @param ctx - Render context\n * @returns Rendered result (Markdown string), null if no matching renderer\n */\n render(format: string, specs: z.infer<TSchema>[], ctx: RenderContext): string | null {\n const renderer = this.renderers.find(r => r.format === format);\n if (!renderer) return null;\n return renderer.render(specs, ctx);\n }\n \n /**\n * Get list of available formats\n */\n getAvailableFormats(): string[] {\n return this.renderers.map(r => r.format);\n }\n \n /**\n * Get renderers\n */\n getRenderers(): Renderer<z.infer<TSchema>>[] {\n return this.renderers;\n }\n \n /**\n * Check if renderer exists for specific format\n */\n hasRenderer(format: string): boolean {\n return this.renderers.some(r => r.format === format);\n }\n}\n\n// ============================================================================\n// Model Registry\n// ============================================================================\n\n/** Map of registered models */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst modelRegistry = new Map<string, Model<any>>();\n\n/**\n * Register model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function registerModel(model: Model<any>): void {\n modelRegistry.set(model.id, model);\n}\n\n/**\n * Get model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getModel(id: string): Model<any> | undefined {\n return modelRegistry.get(id);\n}\n\n/**\n * Get all registered models\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getAllModels(): Model<any>[] {\n return Array.from(modelRegistry.values());\n}\n\n/**\n * Clear registry\n */\nexport function clearModelRegistry(): void {\n modelRegistry.clear();\n}\n","/**\n * Build Command\n * \n * Generate documents and schemas using model class exporters\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { batchWriteFiles, ensureDir } from '../utils/file-writer.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Build Command Options\n// ============================================================================\n\nexport interface BuildCommandOptions {\n config?: string;\n output?: string;\n format?: 'markdown' | 'json' | 'both';\n verbose?: boolean;\n clean?: boolean;\n}\n\n// ============================================================================\n// Build Command\n// ============================================================================\n\nexport async function buildCommand(options: BuildCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper build'));\n console.log('');\n \n const cwd = process.cwd();\n \n // Load config\n const config = await loadConfig(options.config);\n // Output paths available via getOutputPaths(config, cwd) if needed\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log(chalk.gray(` Specs: ${config.specsDir}/`));\n console.log('');\n \n try {\n // Ensure base output directories exist\n ensureDir(join(cwd, config.docsDir));\n ensureDir(join(cwd, config.specsDir));\n \n const files: Array<{ path: string; content: string }> = [];\n const models = getAllModels();\n \n if (models.length === 0) {\n console.log(chalk.yellow(' No models registered. Run model registration first.'));\n return;\n }\n \n console.log(chalk.blue(` Processing ${models.length} model types...`));\n \n // Process each model type\n for (const model of models) {\n const exporters = model.getExporters();\n \n if (exporters.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no exporters defined`));\n }\n continue;\n }\n \n // TODO: Load specs for this model from design/ directory\n // For now, this is a placeholder - actual implementation needs\n // to load specs from the appropriate design/*.ts files\n const specs: unknown[] = [];\n \n if (specs.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no specs found`));\n }\n continue;\n }\n \n for (const exporter of exporters) {\n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n ensureDir(outputDir);\n \n // Generate individual files\n if (exporter.single) {\n for (const spec of specs) {\n const content = exporter.single(spec);\n const filename = model.getFilename(spec, exporter.format) || (spec as { id: string }).id;\n files.push({\n path: join(outputDir, `${filename}.md`),\n content,\n });\n }\n }\n \n // Generate index file\n if (exporter.index) {\n const indexContent = exporter.index(specs);\n files.push({\n path: join(outputDir, 'index.md'),\n content: indexContent,\n });\n }\n }\n \n console.log(chalk.green(` ✓ ${model.name}`));\n }\n \n // Write all files\n if (files.length > 0) {\n console.log('');\n console.log(chalk.blue(` Writing ${files.length} files...`));\n \n const result = await batchWriteFiles(files);\n \n console.log('');\n console.log(chalk.green(` ✓ Build complete`));\n console.log(chalk.gray(` Created: ${result.created}`));\n console.log(chalk.gray(` Updated: ${result.updated}`));\n console.log(chalk.gray(` Unchanged: ${result.unchanged}`));\n } else {\n console.log(chalk.yellow(' No files to generate.'));\n }\n \n } catch (error) {\n console.error(chalk.red('Build failed:'), error);\n process.exit(1);\n }\n}\n","/**\n * Model Loader\n * \n * Load models defined in TypeScript and convert to usable format for build command\n */\n\nimport { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve, extname, basename } from 'node:path';\nimport type { SpeckeeperConfig } from './config-loader.js';\nimport { registerModel as coreRegisterModel } from '../core/model.js';\n\n// ============================================================================\n// Registry Types\n// ============================================================================\n\n/**\n * Model registry - stores all loaded models\n */\nexport interface ModelRegistry {\n requirements: Map<string, unknown>;\n useCases: Map<string, unknown>;\n actors: Map<string, unknown>;\n components: Map<string, unknown>;\n entities: Map<string, unknown>;\n relations: Map<string, unknown>;\n rules: Map<string, unknown>;\n screens: Map<string, unknown>;\n transitions: Map<string, unknown>;\n forms: Map<string, unknown>;\n processFlows: Map<string, unknown>;\n glossaryTerms: Map<string, unknown>;\n apiRefs: Map<string, unknown>;\n tableRefs: Map<string, unknown>;\n testRefs: Map<string, unknown>;\n layers: Map<string, unknown>;\n boundaries: Map<string, unknown>;\n artifacts: Map<string, unknown>;\n}\n\nexport function createEmptyRegistry(): ModelRegistry {\n return {\n requirements: new Map(),\n useCases: new Map(),\n actors: new Map(),\n components: new Map(),\n entities: new Map(),\n relations: new Map(),\n rules: new Map(),\n screens: new Map(),\n transitions: new Map(),\n forms: new Map(),\n processFlows: new Map(),\n glossaryTerms: new Map(),\n apiRefs: new Map(),\n tableRefs: new Map(),\n testRefs: new Map(),\n layers: new Map(),\n boundaries: new Map(),\n artifacts: new Map(),\n };\n}\n\n// ============================================================================\n// Global Registry (shared registry for DSL functions to register to)\n// ============================================================================\n\nlet globalRegistry: ModelRegistry = createEmptyRegistry();\n\nexport function getGlobalRegistry(): ModelRegistry {\n return globalRegistry;\n}\n\nexport function resetGlobalRegistry(): void {\n globalRegistry = createEmptyRegistry();\n}\n\n/**\n * Function for DSL functions to register models\n */\nexport function registerModel(\n type: keyof ModelRegistry,\n id: string,\n model: unknown\n): void {\n globalRegistry[type].set(id, model);\n}\n\n// ============================================================================\n// Model Registration from Exports\n// ============================================================================\n\n/**\n * Determine if value is a Model class instance\n */\nfunction isModelInstance(value: unknown): value is { id: string; name: string; idPrefix: string; schema: unknown } {\n if (!value || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === 'string' &&\n typeof obj.name === 'string' &&\n typeof obj.idPrefix === 'string' &&\n obj.schema !== undefined &&\n typeof obj.validate === 'function' &&\n typeof obj.lint === 'function'\n );\n}\n\n/**\n * Detect models from imported module exports and register to globalRegistry\n */\nfunction registerExportedModels(module: Record<string, unknown>): void {\n for (const [exportName, exportValue] of Object.entries(module)) {\n if (!exportValue || typeof exportValue !== 'object') continue;\n \n // Detect and register Model class instances\n if (isModelInstance(exportValue)) {\n // Register to core model registry\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n coreRegisterModel(exportValue as any);\n continue;\n }\n \n // Process arrays\n if (Array.isArray(exportValue)) {\n registerArrayItems(exportName, exportValue);\n continue;\n }\n \n const value = exportValue as Record<string, unknown>;\n \n // Detect ArchitectureModel (has components, layers, boundaries, relations)\n if (value.components && value.layers && value.boundaries && value.relations) {\n const arch = value as { \n name?: string;\n components: { id?: string }[]; \n layers: { id?: string }[]; \n boundaries: { id?: string }[];\n relations: { id?: string }[];\n };\n for (const comp of arch.components) {\n if (comp.id) globalRegistry.components.set(comp.id, comp);\n }\n for (const layer of arch.layers) {\n if (layer.id) globalRegistry.layers.set(layer.id, layer);\n }\n for (const boundary of arch.boundaries) {\n if (boundary.id) globalRegistry.boundaries.set(boundary.id, boundary);\n }\n for (const rel of arch.relations) {\n if (rel.id) globalRegistry.relations.set(rel.id, rel);\n }\n continue;\n }\n \n // Detect ConceptModel (has entities, relations, rules)\n if (value.entities && value.relations && Array.isArray(value.entities)) {\n const concept = value as { \n entities: { id?: string }[]; \n relations: { id?: string }[];\n rules?: { id?: string }[];\n };\n for (const entity of concept.entities) {\n if (entity.id) globalRegistry.entities.set(entity.id, entity);\n }\n for (const rel of concept.relations) {\n if (rel.id) globalRegistry.relations.set(rel.id, rel);\n }\n for (const rule of concept.rules || []) {\n if (rule.id) globalRegistry.rules.set(rule.id, rule);\n }\n continue;\n }\n \n // Detect UseCaseModel (has useCases, actors)\n if (value.useCases && value.actors) {\n const ucModel = value as { \n useCases: { id?: string }[]; \n actors: { id?: string }[];\n };\n for (const uc of ucModel.useCases) {\n if (uc.id) globalRegistry.useCases.set(uc.id, uc);\n }\n for (const actor of ucModel.actors) {\n if (actor.id) globalRegistry.actors.set(actor.id, actor);\n }\n continue;\n }\n \n // Detect Glossary (array with terms or {terms: []} format)\n if (value.terms && Array.isArray(value.terms)) {\n const glossary = value as { terms: { id?: string }[] };\n for (const term of glossary.terms) {\n if (term.id) globalRegistry.glossaryTerms.set(term.id, term);\n }\n continue;\n }\n \n // Detect single Requirement\n if (value.id && value.title && (value.kind || value.type || value.acceptance)) {\n globalRegistry.requirements.set(value.id as string, value);\n continue;\n }\n \n // Detect single Entity\n if (value.id && value.name && value.attributes && Array.isArray(value.attributes)) {\n globalRegistry.entities.set(value.id as string, value);\n continue;\n }\n \n // Detect single UseCase\n if (value.id && value.name && value.actor && value.mainFlow) {\n globalRegistry.useCases.set(value.id as string, value);\n continue;\n }\n \n // Detect single Actor\n if (value.id && value.name && value.type && ['human', 'system', 'external'].includes(value.type as string)) {\n globalRegistry.actors.set(value.id as string, value);\n continue;\n }\n \n // Detect single Term\n if (value.id && (value.term || value.abbreviation) && value.definition) {\n globalRegistry.glossaryTerms.set(value.id as string, value);\n continue;\n }\n }\n}\n\n/**\n * Detect items from array and register to registry\n */\nfunction registerArrayItems(exportName: string, items: unknown[]): void {\n for (const item of items) {\n if (!item || typeof item !== 'object') continue;\n const obj = item as Record<string, unknown>;\n if (!obj.id || typeof obj.id !== 'string') continue;\n \n // Infer type from export name or object structure\n // requirements / allRequirements / functionalRequirements etc.\n if (exportName.toLowerCase().includes('requirement') || \n exportName.toLowerCase().includes('constraints') ||\n (obj.type && obj.acceptanceCriteria)) {\n globalRegistry.requirements.set(obj.id, item);\n continue;\n }\n \n // useCases / usecases\n if (exportName.toLowerCase().includes('usecase') || \n (obj.actor && obj.mainFlow)) {\n globalRegistry.useCases.set(obj.id, item);\n continue;\n }\n \n // actors\n if (exportName.toLowerCase().includes('actor') ||\n (obj.type && ['human', 'system', 'external'].includes(obj.type as string) && !obj.mainFlow)) {\n globalRegistry.actors.set(obj.id, item);\n continue;\n }\n \n // components / containers\n if (exportName.toLowerCase().includes('component') ||\n exportName.toLowerCase().includes('container') ||\n (obj.type && ['person', 'system', 'container', 'component'].includes(obj.type as string))) {\n globalRegistry.components.set(obj.id, item);\n continue;\n }\n \n // entities\n if (exportName.toLowerCase().includes('entit') ||\n (obj.name && obj.attributes && Array.isArray(obj.attributes))) {\n globalRegistry.entities.set(obj.id, item);\n continue;\n }\n \n // terms / acronyms / glossary\n if (exportName.toLowerCase().includes('term') ||\n exportName.toLowerCase().includes('acronym') ||\n exportName.toLowerCase().includes('glossary') ||\n (obj.term && obj.definition)) {\n globalRegistry.glossaryTerms.set(obj.id, item);\n continue;\n }\n \n // relations\n if (exportName.toLowerCase().includes('relation') ||\n (obj.from && obj.to && obj.label)) {\n globalRegistry.relations.set(obj.id, item);\n continue;\n }\n \n // layers\n if (exportName.toLowerCase().includes('layer') ||\n (obj.name && typeof obj.order === 'number')) {\n globalRegistry.layers.set(obj.id, item);\n continue;\n }\n \n // boundaries\n if (exportName.toLowerCase().includes('boundar') ||\n (obj.type && ['system', 'context', 'container', 'deployment'].includes(obj.type as string) && obj.description)) {\n globalRegistry.boundaries.set(obj.id, item);\n continue;\n }\n \n // screens\n if (exportName.toLowerCase().includes('screen') ||\n (obj.type && ['page', 'modal', 'drawer', 'panel', 'wizard'].includes(obj.type as string) && obj.auth)) {\n globalRegistry.screens.set(obj.id, item);\n continue;\n }\n \n // testRefs\n if (exportName.toLowerCase().includes('testref') ||\n exportName.toLowerCase().includes('test-ref') ||\n (obj.source && obj.verifiesRequirements && Array.isArray(obj.verifiesRequirements))) {\n globalRegistry.testRefs.set(obj.id, item);\n continue;\n }\n \n // artifacts\n if (exportName.toLowerCase().includes('artifact') ||\n (obj.category && obj.location && obj.purpose &&\n ['ssot', 'human-readable', 'machine-readable', 'implementation'].includes(obj.category as string))) {\n globalRegistry.artifacts.set(obj.id, item);\n continue;\n }\n }\n}\n\n// ============================================================================\n// Model Loading\n// ============================================================================\n\n/**\n * Dynamically import TS files from specified directory and collect models\n */\nexport async function loadModelsFromDirectory(\n dirPath: string,\n options: { recursive?: boolean } = {}\n): Promise<string[]> {\n const loadedFiles: string[] = [];\n \n if (!existsSync(dirPath)) {\n return loadedFiles;\n }\n \n const entries = readdirSync(dirPath);\n \n for (const entry of entries) {\n const fullPath = join(dirPath, entry);\n const stat = statSync(fullPath);\n \n if (stat.isDirectory() && options.recursive) {\n const subFiles = await loadModelsFromDirectory(fullPath, options);\n loadedFiles.push(...subFiles);\n } else if (stat.isFile()) {\n const ext = extname(entry);\n // Target .ts, .js, .mts, .mjs files\n if (['.ts', '.js', '.mts', '.mjs'].includes(ext) && !entry.endsWith('.d.ts')) {\n // Exclude index.ts (possibly a re-export file)\n if (basename(entry, ext) === 'index') {\n continue;\n }\n \n try {\n // Dynamic import\n const module = await import(fullPath);\n loadedFiles.push(fullPath);\n \n // Register exported models to globalRegistry\n registerExportedModels(module);\n } catch (error) {\n console.error(`Failed to load model from ${fullPath}:`, error);\n }\n }\n }\n }\n \n return loadedFiles;\n}\n\n/**\n * Load all models based on configuration\n */\nexport async function loadAllModels(\n config: SpeckeeperConfig,\n cwd: string = process.cwd()\n): Promise<{\n registry: ModelRegistry;\n loadedFiles: string[];\n errors: Array<{ file: string; error: unknown }>;\n}> {\n // Reset registry\n resetGlobalRegistry();\n \n const loadedFiles: string[] = [];\n const errors: Array<{ file: string; error: unknown }> = [];\n \n // Load from design/ directory (compliant with spec section 7.1)\n const designDir = resolve(cwd, config.designDir || 'design');\n \n // Standard directory structure (compliant with spec section 7.1)\n const modelDirs = [\n { path: join(designDir, 'requirements') },\n { path: join(designDir, 'usecases') },\n { path: join(designDir, 'architecture') },\n { path: join(designDir, 'data-model') },\n { path: join(designDir, 'screens') },\n { path: join(designDir, 'flows') },\n { path: join(designDir, 'glossary') },\n // Also load files directly under design/ by default (index.ts, etc.)\n { path: designDir },\n ];\n \n for (const { path: dirPath } of modelDirs) {\n if (!existsSync(dirPath)) {\n continue;\n }\n \n try {\n const files = await loadModelsFromDirectory(dirPath, { recursive: true });\n loadedFiles.push(...files);\n } catch (error) {\n errors.push({ file: dirPath, error });\n }\n }\n \n return {\n registry: getGlobalRegistry(),\n loadedFiles,\n errors,\n };\n}\n\n// ============================================================================\n// Registry Helpers\n// ============================================================================\n\n/**\n * Get registry statistics\n */\nexport function getRegistryStats(registry: ModelRegistry): Record<string, number> {\n const stats: Record<string, number> = {};\n \n for (const [key, map] of Object.entries(registry)) {\n stats[key] = (map as Map<string, unknown>).size;\n }\n \n return stats;\n}\n\n/**\n * Get all IDs in registry\n */\nexport function getAllIds(registry: ModelRegistry): Set<string> {\n const allIds = new Set<string>();\n \n for (const map of Object.values(registry)) {\n for (const id of (map as Map<string, unknown>).keys()) {\n allIds.add(id);\n }\n }\n \n return allIds;\n}\n\n/**\n * Identify model type from ID\n */\nexport function findModelType(\n registry: ModelRegistry,\n id: string\n): keyof ModelRegistry | null {\n for (const [type, map] of Object.entries(registry)) {\n if ((map as Map<string, unknown>).has(id)) {\n return type as keyof ModelRegistry;\n }\n }\n return null;\n}\n\n/**\n * Get model by ID\n */\nexport function getModelById(\n registry: ModelRegistry,\n id: string\n): { type: keyof ModelRegistry; model: unknown } | null {\n const type = findModelType(registry, id);\n if (!type) return null;\n \n return {\n type,\n model: registry[type].get(id),\n };\n}\n","/**\n * Lint Command\n * \n * Execute design consistency checks using model class lintRules\n */\n\nimport chalk from 'chalk';\nimport { relative } from 'node:path';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface LintCommandOptions {\n config?: string;\n phase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strict?: boolean;\n fix?: boolean;\n format?: 'text' | 'json' | 'github';\n}\n\nexport type LintSeverity = 'error' | 'warning' | 'info';\n\nexport interface LintIssue {\n rule: string;\n severity: LintSeverity;\n message: string;\n specId?: string;\n modelType?: string;\n}\n\nexport interface LintResult {\n issues: LintIssue[];\n errors: number;\n warnings: number;\n infos: number;\n}\n\n// ============================================================================\n// Lint Command\n// ============================================================================\n\nexport async function lintCommand(options: LintCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper lint'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n if (options.phase) {\n console.log(chalk.gray(` Phase: ${options.phase}`));\n }\n console.log('');\n \n try {\n // Load all models from design/\n console.log(chalk.blue(' Loading models...'));\n const { registry, loadedFiles, errors: loadErrors } = await loadAllModels(config, cwd);\n \n if (loadErrors.length > 0) {\n console.log(chalk.yellow(` ⚠ ${loadErrors.length} file(s) failed to load`));\n for (const { file, error } of loadErrors) {\n console.log(chalk.yellow(` - ${relative(cwd, file)}: ${error}`));\n }\n }\n \n console.log(chalk.gray(` Loaded: ${loadedFiles.length} files`));\n console.log('');\n \n // Run lint using model classes\n console.log(chalk.blue(' Running lint checks...'));\n const result = runModelLint(registry, options);\n \n // Output results\n console.log('');\n outputLintResults(result, options);\n \n // Exit with error code if there are errors\n if (result.errors > 0) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Lint failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Lint Runner\n// ============================================================================\n\nfunction runModelLint(registry: ModelRegistry, options: LintCommandOptions): LintResult {\n const issues: LintIssue[] = [];\n const models = getAllModels();\n \n for (const model of models) {\n // Get specs from registry for this model type\n const specs = getSpecsFromRegistry(registry, model.id);\n \n if (specs.length === 0) continue;\n \n // Run lint rules\n const lintResults = model.lintAll(specs);\n \n for (const result of lintResults) {\n issues.push({\n rule: result.ruleId,\n severity: result.severity,\n message: result.message,\n specId: result.specId,\n modelType: model.name,\n });\n }\n }\n \n // Count by severity\n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n const infos = issues.filter(i => i.severity === 'info').length;\n \n // Filter by strict mode\n if (!options.strict) {\n return {\n issues: issues.filter(i => i.severity !== 'info'),\n errors,\n warnings,\n infos,\n };\n }\n \n return { issues, errors, warnings, infos };\n}\n\nfunction getSpecsFromRegistry(registry: ModelRegistry, modelId: string): unknown[] {\n // Map model IDs to registry keys\n const registryMap: Record<string, keyof ModelRegistry> = {\n 'requirement': 'requirements',\n 'usecase': 'useCases',\n 'actor': 'actors',\n 'term': 'glossaryTerms',\n 'entity': 'entities',\n 'screen': 'screens',\n 'process-flow': 'processFlows',\n 'component': 'components',\n 'boundary': 'boundaries',\n 'layer': 'layers',\n 'relation': 'relations',\n };\n \n const key = registryMap[modelId];\n if (!key || !registry[key]) return [];\n \n return Array.from((registry[key] as Map<string, unknown>).values());\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputLintResults(result: LintResult, options: LintCommandOptions): void {\n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'github') {\n for (const issue of result.issues) {\n const level = issue.severity === 'error' ? 'error' : issue.severity === 'warning' ? 'warning' : 'notice';\n console.log(`::${level}::${issue.message} [${issue.rule}]${issue.specId ? ` (${issue.specId})` : ''}`);\n }\n return;\n }\n \n // Default text format\n if (result.issues.length === 0) {\n console.log(chalk.green(' ✓ No issues found'));\n return;\n }\n \n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : issue.severity === 'warning' ? '⚠' : 'ℹ';\n const color = issue.severity === 'error' ? chalk.red : issue.severity === 'warning' ? chalk.yellow : chalk.blue;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n console.log(chalk.gray(` Rule: ${issue.rule}`));\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${result.errors} errors, ${result.warnings} warnings, ${result.infos} infos`));\n}\n","/**\n * Drift Command\n * \n * Detect drift between generated artifacts and SSOT\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DriftCommandOptions {\n config?: string;\n verbose?: boolean;\n failOnDrift?: boolean;\n}\n\nexport interface DriftResult {\n file: string;\n status: 'ok' | 'drifted' | 'missing';\n details?: string;\n}\n\n// ============================================================================\n// Drift Command\n// ============================================================================\n\nexport async function driftCommand(options: DriftCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper drift'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n // Output paths available via getOutputPaths if needed\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n const results: DriftResult[] = [];\n const models = getAllModels();\n \n // Check each model's generated files\n for (const model of models) {\n const specs = getSpecsFromRegistry(registry, model.id);\n if (specs.length === 0) continue;\n \n for (const exporter of model.getExporters()) {\n if (exporter.format !== 'markdown') continue;\n \n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n // Check individual files\n if (exporter.single) {\n for (const spec of specs) {\n const filename = model.getFilename(spec, 'markdown') || (spec as { id: string }).id;\n const filePath = join(outputDir, `${filename}.md`);\n \n if (!existsSync(filePath)) {\n results.push({ file: filePath, status: 'missing' });\n continue;\n }\n \n const expected = exporter.single(spec);\n const actual = readFileSync(filePath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: filePath, status: 'drifted' });\n } else {\n results.push({ file: filePath, status: 'ok' });\n }\n }\n }\n \n // Check index file\n if (exporter.index) {\n const indexPath = join(outputDir, 'index.md');\n \n if (!existsSync(indexPath)) {\n results.push({ file: indexPath, status: 'missing' });\n } else {\n const expected = exporter.index(specs);\n const actual = readFileSync(indexPath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: indexPath, status: 'drifted' });\n } else {\n results.push({ file: indexPath, status: 'ok' });\n }\n }\n }\n }\n }\n \n // Output results\n outputDriftResults(results, options);\n \n // Exit with error code if drift detected and failOnDrift is set\n const hasDrift = results.some(r => r.status === 'drifted' || r.status === 'missing');\n if (hasDrift && options.failOnDrift) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Drift check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction getSpecsFromRegistry(registry: ModelRegistry, modelId: string): unknown[] {\n const registryMap: Record<string, keyof ModelRegistry> = {\n 'requirement': 'requirements',\n 'usecase': 'useCases',\n 'actor': 'actors',\n 'term': 'glossaryTerms',\n 'entity': 'entities',\n 'screen': 'screens',\n 'process-flow': 'processFlows',\n 'component': 'components',\n };\n \n const key = registryMap[modelId];\n if (!key || !registry[key]) return [];\n \n return Array.from((registry[key] as Map<string, unknown>).values());\n}\n\nfunction normalizeContent(content: string): string {\n return content.trim().replace(/\\r\\n/g, '\\n');\n}\n\nfunction outputDriftResults(results: DriftResult[], _options: DriftCommandOptions): void {\n console.log('');\n \n const ok = results.filter(r => r.status === 'ok');\n const drifted = results.filter(r => r.status === 'drifted');\n const missing = results.filter(r => r.status === 'missing');\n \n if (drifted.length === 0 && missing.length === 0) {\n console.log(chalk.green(' ✓ No drift detected'));\n console.log(chalk.gray(` Checked: ${results.length} files`));\n return;\n }\n \n if (drifted.length > 0) {\n console.log(chalk.yellow(` ⚠ ${drifted.length} file(s) have drifted:`));\n for (const result of drifted) {\n console.log(chalk.yellow(` - ${result.file}`));\n }\n }\n \n if (missing.length > 0) {\n console.log(chalk.red(` ✗ ${missing.length} file(s) are missing:`));\n for (const result of missing) {\n console.log(chalk.red(` - ${result.file}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${ok.length} ok, ${drifted.length} drifted, ${missing.length} missing`));\n}\n","/**\n * Check Command\n * \n * Check consistency with external SSOT using model class externalChecker\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\nimport { getAllModels, type CoverageResult } from '../core/model.js';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CheckCommandOptions {\n config?: string;\n type?: 'openapi' | 'ddl' | 'iac' | 'all';\n verbose?: boolean;\n coverage?: boolean;\n}\n\nexport interface CheckIssue {\n severity: 'error' | 'warning';\n message: string;\n specId?: string;\n field?: string;\n}\n\nexport interface CheckResult {\n type: string;\n success: boolean;\n issues: CheckIssue[];\n}\n\n// ============================================================================\n// Check Command\n// ============================================================================\n\nexport async function checkCommand(\n type: string | undefined,\n options: CheckCommandOptions\n): Promise<void> {\n console.log(chalk.blue('speckeeper check'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n const checkType = type || options.type || 'all';\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Type: ${checkType}`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n const results: CheckResult[] = [];\n const models = getAllModels();\n \n if (options.verbose) {\n console.log(chalk.gray(` Registered models: ${models.map(m => m.id).join(', ')}`));\n }\n \n // Run checks for each model that has an external checker\n for (const model of models) {\n const specs = getSpecsFromRegistry(registry, model.id);\n if (specs.length === 0) continue;\n \n for (const spec of specs) {\n const sourcePath = model.getExternalSourcePath(spec);\n if (!sourcePath) continue;\n \n const fullPath = join(cwd, sourcePath);\n if (!existsSync(fullPath)) {\n results.push({\n type: model.id,\n success: false,\n issues: [{\n severity: 'error',\n message: `External source not found: ${sourcePath}`,\n specId: (spec as { id: string }).id,\n }],\n });\n continue;\n }\n \n // Load external data\n const externalData = loadExternalData(fullPath);\n \n // Run check\n const checkResult = model.check(spec, externalData);\n \n if (!checkResult.success || checkResult.errors.length > 0 || checkResult.warnings.length > 0) {\n results.push({\n type: model.id,\n success: checkResult.success,\n issues: [\n ...checkResult.errors.map(e => ({ severity: 'error' as const, message: e.message, specId: e.specId, field: e.field })),\n ...checkResult.warnings.map(w => ({ severity: 'warning' as const, message: w.message, specId: w.specId, field: w.field })),\n ],\n });\n }\n }\n }\n \n // Output results\n outputCheckResults(results);\n \n // Coverage check (if --coverage flag is set)\n if (options.coverage) {\n console.log('');\n console.log(chalk.blue(' Coverage checks...'));\n const coverageResults = runAllCoverageChecks(registry);\n \n if (coverageResults.length > 0) {\n outputAllCoverageResults(coverageResults);\n \n // Add uncovered items as warnings\n for (const check of coverageResults) {\n if (check.result.uncoveredItems.length > 0) {\n results.push({\n type: `coverage-${check.modelId}`,\n success: check.result.coveragePercent >= 80, // fail if below 80%\n issues: check.result.uncoveredItems.slice(0, 10).map(item => ({\n severity: 'warning' as const,\n message: `[${check.modelName}→${check.targetModel}] '${item.id}'${item.sourceId ? ` (${item.sourceId})` : ''} not covered`,\n specId: item.id,\n })),\n });\n }\n }\n \n // Summary\n console.log('');\n console.log(chalk.gray(' ─────────────────────────────────────'));\n const allPassed = coverageResults.every(c => c.result.coveragePercent >= 80);\n if (allPassed) {\n console.log(chalk.green(' ✓ All coverage checks passed (≥80%)'));\n } else {\n const failed = coverageResults.filter(c => c.result.coveragePercent < 80);\n console.log(chalk.yellow(` ⚠ ${failed.length} coverage check(s) below 80%`));\n }\n } else {\n console.log(chalk.gray(' No coverage checker found'));\n }\n }\n \n // Exit with error code if there are errors\n const hasErrors = results.some(r => !r.success);\n if (hasErrors) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction getSpecsFromRegistry(registry: ModelRegistry, modelId: string): unknown[] {\n const registryMap: Record<string, keyof ModelRegistry> = {\n 'requirement': 'requirements',\n 'usecase': 'useCases',\n 'actor': 'actors',\n 'term': 'glossaryTerms',\n 'entity': 'entities',\n 'screen': 'screens',\n 'process-flow': 'processFlows',\n 'component': 'components',\n 'api-ref': 'apiRefs',\n 'table-ref': 'tableRefs',\n 'test-ref': 'testRefs',\n 'artifact': 'artifacts',\n };\n \n const key = registryMap[modelId];\n if (!key || !registry[key]) return [];\n \n return Array.from((registry[key] as Map<string, unknown>).values());\n}\n\nfunction loadExternalData(filePath: string): unknown {\n const content = readFileSync(filePath, 'utf-8');\n \n if (filePath.endsWith('.yaml') || filePath.endsWith('.yml')) {\n return parseYaml(content);\n }\n \n if (filePath.endsWith('.json')) {\n return JSON.parse(content);\n }\n \n return content;\n}\n\nfunction outputCheckResults(results: CheckResult[]): void {\n console.log('');\n \n if (results.length === 0) {\n console.log(chalk.green(' ✓ All checks passed'));\n return;\n }\n \n let totalErrors = 0;\n let totalWarnings = 0;\n \n for (const result of results) {\n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : '⚠';\n const color = issue.severity === 'error' ? chalk.red : chalk.yellow;\n \n if (issue.severity === 'error') totalErrors++;\n else totalWarnings++;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${totalErrors} errors, ${totalWarnings} warnings`));\n}\n\n// ============================================================================\n// Coverage Check\n// ============================================================================\n\ninterface CoverageCheckResult {\n modelId: string;\n modelName: string;\n description: string;\n targetModel: string;\n result: CoverageResult;\n}\n\n/**\n * Execute all coverage checks\n * \n * Detect all models with coverageChecker and run coverage checks.\n * Logic is defined in each model (design/_models/).\n */\nfunction runAllCoverageChecks(registry: ModelRegistry): CoverageCheckResult[] {\n const models = getAllModels();\n const results: CoverageCheckResult[] = [];\n \n // Convert registry to Record format\n const registryRecord: Record<string, Map<string, unknown>> = {};\n for (const [key, value] of Object.entries(registry)) {\n if (value instanceof Map) {\n registryRecord[key] = value;\n }\n }\n \n // Search for models with coverageChecker and execute\n for (const model of models) {\n const checker = model.getCoverageChecker();\n if (checker) {\n const specs = getSpecsFromRegistry(registry, model.id);\n const result = model.checkCoverage(specs, registryRecord);\n \n if (result) {\n results.push({\n modelId: model.id,\n modelName: model.name,\n description: checker.description,\n targetModel: checker.targetModel,\n result,\n });\n }\n }\n }\n \n return results;\n}\n\nfunction outputAllCoverageResults(checks: CoverageCheckResult[]): void {\n for (const check of checks) {\n console.log('');\n console.log(chalk.blue(` Coverage: ${check.modelName} → ${check.targetModel}`));\n console.log(chalk.gray(` ${check.description}`));\n console.log(chalk.gray(` ─────────────────────────────────────`));\n console.log(chalk.gray(` Total: ${check.result.total}`));\n console.log(chalk.green(` Covered: ${check.result.covered}`));\n console.log(chalk.yellow(` Uncovered: ${check.result.uncovered}`));\n \n const color = check.result.coveragePercent >= 80 ? chalk.green : \n check.result.coveragePercent >= 50 ? chalk.yellow : chalk.red;\n console.log(color(` Coverage: ${check.result.coveragePercent}%`));\n \n if (check.result.uncoveredItems.length > 0 && check.result.uncoveredItems.length <= 10) {\n console.log('');\n console.log(chalk.yellow(' Uncovered items:'));\n for (const item of check.result.uncoveredItems) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n const source = item.sourceId ? ` (${item.sourceId})` : '';\n console.log(chalk.yellow(` - ${item.id}${source}${desc}`));\n }\n } else if (check.result.uncoveredItems.length > 10) {\n console.log('');\n console.log(chalk.yellow(` (${check.result.uncoveredItems.length} uncovered items - showing first 5)`));\n for (const item of check.result.uncoveredItems.slice(0, 5)) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n console.log(chalk.yellow(` - ${item.id}${desc}`));\n }\n }\n }\n}\n","/**\n * New Command\n * \n * Generate templates for new model instances\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { writeFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface NewCommandOptions {\n config?: string;\n type?: string;\n id?: string;\n output?: string;\n dryRun?: boolean;\n}\n\n// ============================================================================\n// New Command\n// ============================================================================\n\nexport async function newCommand(options: NewCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper new'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n // List available types if no type specified\n if (!options.type) {\n console.log(chalk.gray(' Available model types:'));\n const models = getAllModels();\n for (const model of models) {\n console.log(chalk.gray(` - ${model.id} (${model.name})`));\n }\n console.log('');\n console.log(chalk.gray(' Usage: speckeeper new --type <type> [--id <id>]'));\n return;\n }\n \n // Find model\n const models = getAllModels();\n const model = models.find(m => m.id === options.type);\n \n if (!model) {\n console.error(chalk.red(` Error: Unknown model type '${options.type}'`));\n console.log(chalk.gray(' Run `speckeeper new` to see available types'));\n process.exit(1);\n }\n \n // Generate ID if not provided\n const id = options.id || `${model.idPrefix}-${String(Date.now()).slice(-6)}`;\n \n // Generate template\n const template = generateTemplate(model, id);\n \n if (options.dryRun) {\n console.log(chalk.gray(' Template (dry run):'));\n console.log('');\n console.log(template);\n return;\n }\n \n // Write template to file\n const outputDir = options.output || join(cwd, config.designDir || 'design');\n const outputFile = join(outputDir, `${model.id}-${id}.ts`);\n \n if (existsSync(outputFile)) {\n console.error(chalk.red(` Error: File already exists: ${outputFile}`));\n process.exit(1);\n }\n \n writeFileSync(outputFile, template);\n console.log(chalk.green(` ✓ Created: ${outputFile}`));\n}\n\n// ============================================================================\n// Template Generation\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction generateTemplate(model: any, id: string): string {\n const typeName = model.name;\n const lines: string[] = [];\n \n lines.push(`/**`);\n lines.push(` * ${typeName}: ${id}`);\n lines.push(` * `);\n lines.push(` * Generated by speckeeper new`);\n lines.push(` */`);\n lines.push(`import type { ${typeName} } from './_models/${model.id}';`);\n lines.push('');\n lines.push(`export const ${camelCase(id)}: ${typeName} = {`);\n lines.push(` id: '${id}',`);\n lines.push(` // TODO: Fill in the required fields`);\n lines.push(`};`);\n lines.push('');\n \n return lines.join('\\n');\n}\n\nfunction camelCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[-_](.)/g, (_, c) => c.toUpperCase());\n}\n","/**\n * Impact Command\n * \n * Analyze the impact scope of changes\n */\n\nimport chalk from 'chalk';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImpactCommandOptions {\n config?: string;\n depth?: string;\n direction?: 'upstream' | 'downstream' | 'both';\n format?: 'text' | 'json' | 'mermaid';\n}\n\nexport interface ImpactNode {\n id: string;\n type: string;\n depth: number;\n impactType: 'direct' | 'indirect';\n}\n\nexport interface ImpactResult {\n target: string;\n targetType: string;\n impactedNodes: ImpactNode[];\n}\n\n// ============================================================================\n// Impact Command\n// ============================================================================\n\nexport async function impactCommand(targetId: string, options: ImpactCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper impact'));\n console.log('');\n \n if (!targetId) {\n console.error(chalk.red('Error: ID is required'));\n console.log(chalk.gray(' Usage: speckeeper impact <id>'));\n process.exit(1);\n }\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n const maxDepth = options.depth ? parseInt(options.depth, 10) : 3;\n \n console.log(chalk.gray(` Target: ${targetId}`));\n console.log(chalk.gray(` Depth: ${maxDepth}`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n // Find target\n const target = findById(registry, targetId);\n if (!target) {\n console.error(chalk.red(` Error: Target '${targetId}' not found`));\n process.exit(1);\n }\n \n // Analyze impact\n console.log(chalk.blue(' Analyzing impact...'));\n const result = analyzeImpact(registry, targetId, target.type, maxDepth);\n \n // Output results\n outputImpactResults(result, options);\n \n } catch (error) {\n console.error(chalk.red('Impact analysis failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Impact Analysis\n// ============================================================================\n\nfunction findById(registry: ModelRegistry, id: string): { type: string; data: unknown } | null {\n for (const [type, map] of Object.entries(registry)) {\n if (map instanceof Map && map.has(id)) {\n return { type, data: map.get(id) };\n }\n }\n return null;\n}\n\nfunction analyzeImpact(\n registry: ModelRegistry,\n targetId: string,\n targetType: string,\n maxDepth: number\n): ImpactResult {\n const impactedNodes: ImpactNode[] = [];\n const visited = new Set<string>([targetId]);\n \n // Find references to the target\n function findReferences(id: string, depth: number): void {\n if (depth > maxDepth) return;\n \n for (const [type, map] of Object.entries(registry)) {\n if (!(map instanceof Map)) continue;\n \n for (const [itemId, item] of map) {\n if (visited.has(itemId)) continue;\n \n // Check if this item references the target\n const itemStr = JSON.stringify(item);\n if (itemStr.includes(`\"${id}\"`)) {\n visited.add(itemId);\n impactedNodes.push({\n id: itemId,\n type,\n depth,\n impactType: depth === 1 ? 'direct' : 'indirect',\n });\n \n // Recursively find references to this item\n findReferences(itemId, depth + 1);\n }\n }\n }\n }\n \n findReferences(targetId, 1);\n \n return {\n target: targetId,\n targetType,\n impactedNodes,\n };\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputImpactResults(result: ImpactResult, options: ImpactCommandOptions): void {\n console.log('');\n \n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'mermaid') {\n console.log('```mermaid');\n console.log('graph TD');\n console.log(` ${result.target}[${result.target}]`);\n for (const node of result.impactedNodes) {\n const style = node.impactType === 'direct' ? '-->|direct|' : '-.->|indirect|';\n console.log(` ${result.target} ${style} ${node.id}[${node.id}]`);\n }\n console.log('```');\n return;\n }\n \n // Default text format\n if (result.impactedNodes.length === 0) {\n console.log(chalk.green(' No impacted elements found'));\n return;\n }\n \n const direct = result.impactedNodes.filter(n => n.impactType === 'direct');\n const indirect = result.impactedNodes.filter(n => n.impactType === 'indirect');\n \n if (direct.length > 0) {\n console.log(chalk.yellow(` Direct impact (${direct.length}):`));\n for (const node of direct) {\n console.log(chalk.yellow(` → ${node.id} (${node.type})`));\n }\n }\n \n if (indirect.length > 0) {\n console.log(chalk.gray(` Indirect impact (${indirect.length}):`));\n for (const node of indirect) {\n console.log(chalk.gray(` ⤳ ${node.id} (${node.type}, depth: ${node.depth})`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Total: ${result.impactedNodes.length} impacted elements`));\n}\n","/**\n * speckeeper init command\n * \n * Generate starter templates for a new speckeeper project\n */\nimport chalk from 'chalk';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface InitOptions {\n force?: boolean;\n}\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport async function runInit(options: InitOptions = {}): Promise<void> {\n const cwd = process.cwd();\n \n console.log(chalk.cyan('speckeeper init'));\n console.log('');\n \n // Check if already initialized\n const designDir = join(cwd, 'design');\n const configFile = join(cwd, 'speckeeper.config.ts');\n \n if (!options.force && (existsSync(designDir) || existsSync(configFile))) {\n console.log(chalk.yellow(' Project already initialized.'));\n console.log(chalk.gray(' Use --force to overwrite existing files.'));\n return;\n }\n \n // Get project name from directory\n const projectName = cwd.split('/').pop() || 'my-project';\n \n // Find templates directory\n const templatesDir = join(__dirname, 'templates', 'init');\n \n if (!existsSync(templatesDir)) {\n console.log(chalk.red(` Error: Templates directory not found at ${templatesDir}`));\n console.log(chalk.gray(' Please ensure the package is properly installed.'));\n return;\n }\n \n // Copy template files\n let packageJsonCreated = false;\n copyTemplateDir(templatesDir, cwd, projectName, options.force || false, (relativePath, created) => {\n if (created) {\n console.log(chalk.green(` Created: ${relativePath}`));\n if (relativePath === 'package.json') {\n packageJsonCreated = true;\n }\n } else {\n console.log(chalk.yellow(` Skipped: ${relativePath} (already exists)`));\n }\n });\n \n console.log('');\n console.log(chalk.cyan(' Project initialized successfully!'));\n console.log('');\n console.log(' Next steps:');\n if (packageJsonCreated) {\n console.log(chalk.gray(' 1. Run `npm install` to install dependencies'));\n console.log(chalk.gray(' 2. Edit design/_models/ to customize your models'));\n console.log(chalk.gray(' 3. Add specifications in design/'));\n console.log(chalk.gray(' 4. Run `npx speckeeper lint` to validate'));\n } else {\n console.log(chalk.gray(' 1. Add speckeeper and zod to your package.json dependencies'));\n console.log(chalk.gray(' 2. Ensure \"type\": \"module\" is set in package.json'));\n console.log(chalk.gray(' 3. Edit design/_models/ to customize your models'));\n console.log(chalk.gray(' 4. Add specifications in design/'));\n console.log(chalk.gray(' 5. Run `npx speckeeper lint` to validate'));\n }\n}\n\n/**\n * Recursively copy template directory\n */\nfunction copyTemplateDir(\n srcDir: string,\n destDir: string,\n projectName: string,\n force: boolean,\n onFile: (relativePath: string, created: boolean) => void,\n relativePath: string = ''\n): void {\n const entries = readdirSync(srcDir);\n \n for (const entry of entries) {\n const srcPath = join(srcDir, entry);\n const stat = statSync(srcPath);\n \n // Handle .template extension\n const destEntry = entry.endsWith('.template') ? entry.slice(0, -9) : entry;\n const destPath = join(destDir, destEntry);\n const relPath = relativePath ? join(relativePath, destEntry) : destEntry;\n \n if (stat.isDirectory()) {\n // Create directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true });\n onFile(relPath + '/', true);\n }\n // Recurse into directory\n copyTemplateDir(srcPath, destPath, projectName, force, onFile, relPath);\n } else {\n // Skip if file exists and not force\n if (!force && existsSync(destPath)) {\n onFile(relPath, false);\n continue;\n }\n \n // Read and process template\n let content = readFileSync(srcPath, 'utf-8');\n \n // Replace template variables\n content = content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, projectName);\n \n // Write file\n const dir = dirname(destPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(destPath, content);\n onFile(relPath, true);\n }\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { buildCommand } from './build.js';\nimport { lintCommand } from './lint.js';\nimport { driftCommand } from './drift.js';\nimport { checkCommand } from './check.js';\nimport { newCommand } from './new.js';\nimport { impactCommand } from './impact.js';\nimport { runInit } from './init.js';\n\nconst program = new Command();\n\nprogram\n .name('speckeeper')\n .description('Requirements and design management framework with TypeScript DSL')\n .version('0.1.0');\n\n// Build command\n// Spec: design/cli-commands.ts CMD-BUILD\nprogram\n .command('build')\n .description('Generate docs/ and specs/ from TypeScript models')\n .option('-c, --config <path>', 'Path to config file')\n .option('-o, --output <path>', 'Base output directory path', '.')\n .option('-f, --format <format>', 'Output format: markdown, json, both', 'both')\n .option('-w, --watch', 'Watch for changes and auto-regenerate')\n .option('-v, --verbose', 'Show detailed output')\n .action(buildCommand);\n\n// Lint command\n// Spec: design/cli-commands.ts CMD-LINT\nprogram\n .command('lint')\n .description('Check design integrity (ID duplicates, references, layer violations, etc.)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-p, --phase <phase>', 'Phase gate to check against (REQ, HLD, LLD, OPS)')\n .option('-s, --strict', 'Treat warnings as errors')\n .option('--fix', 'Attempt to fix auto-fixable issues')\n .option('-f, --format <format>', 'Output format: text, json, github', 'text')\n .action(lintCommand);\n\n// Drift command\n// Spec: design/cli-commands.ts CMD-DRIFT\nprogram\n .command('drift')\n .description('Check if generated files have been manually edited')\n .option('-c, --config <path>', 'Path to config file')\n .option('-u, --update', 'Auto-update if differences are found')\n .option('-f, --format <format>', 'Output format: text, json, diff', 'text')\n .action(driftCommand);\n\n// Check command\n// Spec: design/cli-commands.ts CMD-CHECK\nprogram\n .command('check')\n .description('Check external SSOT conformance (including custom models)')\n .argument('[type]', 'Type of check: external-ssot, openapi, ddl, iac, custom, all, test')\n .option('-c, --config <path>', 'Path to config file')\n .option('--strict', 'Treat warnings as errors')\n .option('-v, --verbose', 'Show detailed output')\n .option('--coverage', 'Check if all testable acceptance criteria are covered by TestRefs')\n .action(checkCommand);\n\n// New command\n// Spec: design/cli-commands.ts CMD-NEW\nprogram\n .command('new')\n .description('Create a new element with auto-generated ID')\n .argument('<type>', 'Type: requirement, usecase, entity, component, screen, flow, error-case, term')\n .option('-k, --kind <kind>', 'Sub-kind (e.g., functional, non-functional for requirements)')\n .option('-n, --name <name>', 'Name of the element')\n .option('-o, --output <path>', 'Output directory path')\n .option('-t, --template <path>', 'Path to template file')\n .action(newCommand);\n\n// Impact command\n// Spec: design/cli-commands.ts CMD-IMPACT\nprogram\n .command('impact')\n .description('Analyze impact of changes to an ID')\n .argument('<id>', 'ID to analyze (e.g., REQ-001, ENT-ORDER)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-d, --depth <depth>', 'Analysis depth (reference tracking level)', '3')\n .option('--direction <direction>', 'Analysis direction: upstream, downstream, both', 'both')\n .option('-f, --format <format>', 'Output format: text, json, mermaid', 'text')\n .action(impactCommand);\n\n// Init command\nprogram\n .command('init')\n .description('Initialize a new speckeeper project with starter templates')\n .option('-f, --force', 'Overwrite existing files')\n .action(runInit);\n\n// Parse arguments\nprogram.parse();\n"]}
1
+ {"version":3,"sources":["../src/utils/config-loader.ts","../src/utils/file-writer.ts","../src/core/relation.ts","../src/core/model.ts","../src/utils/model-loader.ts","../src/cli/build.ts","../src/cli/lint.ts","../src/cli/drift.ts","../src/cli/check.ts","../src/cli/new.ts","../src/cli/impact.ts","../src/cli/init.ts","../src/scaffold/mermaid-parser.ts","../src/scaffold/edge-vocabulary.ts","../src/scaffold/template-registry.ts","../src/scaffold/templates/requirement.ts","../src/scaffold/templates/usecase.ts","../src/scaffold/templates/term.ts","../src/scaffold/templates/entity.ts","../src/scaffold/templates/logical-entity.ts","../src/scaffold/templates/acceptance-test.ts","../src/scaffold/templates/data-test.ts","../src/scaffold/templates/validation-constraint.ts","../src/scaffold/templates/base.ts","../src/scaffold/templates/checkers/ddl-checker.ts","../src/scaffold/templates/checkers/openapi-checker.ts","../src/scaffold/templates/checkers/test-checker.ts","../src/scaffold/templates/checkers/base-checker.ts","../src/scaffold/templates/index.ts","../src/scaffold/model-generator.ts","../src/scaffold/checker-generator.ts","../src/scaffold/index-generator.ts","../src/cli/scaffold.ts","../src/cli/index.ts"],"names":["parseYaml","existsSync","dirname","readFileSync","join","resolve","chalk","relative","models","model","writeFileSync","__filename","__dirname","readdirSync","statSync","mkdirSync","toCamelCase"],"mappings":"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","file":"cli.js","sourcesContent":["import { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\n/**\n * Specification-compliant output path definitions\n * \n * Human-readable artifacts (docs/):\n * requirements/ - Requirements Markdown\n * usecases/ - Use cases\n * architecture/ - Architecture (C4 diagrams)\n * data-model/ - Conceptual model (ER diagrams)\n * screens/ - Screen specifications\n * flows/ - Process flows\n * glossary/ - Glossary\n * \n * Machine-readable artifacts (specs/):\n * schemas/entities/ - Entity JSON Schema\n * index.json - Aggregated data\n */\nexport interface OutputPaths {\n // docs/ subdirectories\n requirements: string;\n usecases: string;\n architecture: string;\n dataModel: string;\n screens: string;\n flows: string;\n glossary: string;\n component: string;\n \n // specs/ subdirectories\n schemasEntities: string;\n}\n\nexport interface SpeckeeperConfig {\n // Project info\n projectName?: string;\n version?: string;\n \n // Source paths\n srcDir: string;\n requirementsDir?: string;\n designDir?: string;\n usecasesDir?: string;\n \n // Output paths\n docsDir: string;\n specsDir: string;\n \n // External SSOT paths\n externalSsot?: {\n openapi?: {\n enabled: boolean;\n paths: string[];\n microContracts?: {\n enabled: boolean;\n requiredExtensions?: string[];\n strictMode?: boolean;\n };\n };\n ddl?: {\n enabled: boolean;\n paths: string[];\n type: 'ddl' | 'prisma' | 'typeorm' | 'drizzle';\n };\n iac?: {\n enabled: boolean;\n paths: string[];\n type: 'cloudformation' | 'terraform' | 'cdk';\n };\n };\n \n // Lint configuration\n lint?: {\n architecture?: {\n allowCrossBoundaryDependencies?: boolean;\n allowCrossLayerViolations?: boolean;\n maxComponentsPerDiagram?: number;\n };\n conceptModel?: {\n requireEntityDescription?: boolean;\n requireAggregateRoot?: boolean;\n warnOnOrphanEntities?: boolean;\n namingConvention?: 'PascalCase' | 'camelCase' | 'snake_case' | 'none';\n };\n screen?: {\n warnOnOrphanScreens?: boolean;\n warnOnDeadEnds?: boolean;\n checkAuthPaths?: boolean;\n };\n phaseGate?: {\n currentPhase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strictMode?: boolean;\n };\n };\n \n // Build configuration\n build?: {\n generateMermaidImages?: boolean;\n mermaidCliPath?: string;\n };\n \n // Custom model definitions\n models?: unknown[];\n}\n\n// Default configuration\nconst defaultConfig: SpeckeeperConfig = {\n srcDir: 'src',\n designDir: 'design', // Directory for requirements/design TS models\n docsDir: 'docs',\n specsDir: 'specs',\n};\n\n// ============================================================================\n// Output Paths (spec-compliant)\n// ============================================================================\n\n/**\n * Get output paths compliant with specification\n */\nexport function getOutputPaths(config: SpeckeeperConfig, cwd: string = process.cwd()): OutputPaths {\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n return {\n // docs/ subdirectories (compliant with spec section 7.1)\n requirements: join(docsDir, 'requirements'),\n usecases: join(docsDir, 'usecases'),\n architecture: join(docsDir, 'architecture'),\n dataModel: join(docsDir, 'data-model'),\n screens: join(docsDir, 'screens'),\n flows: join(docsDir, 'flows'),\n glossary: join(docsDir, 'glossary'),\n component: join(docsDir, 'component'),\n \n // specs/ subdirectories (compliant with spec section 7.1)\n schemasEntities: join(specsDir, 'schemas', 'entities'),\n };\n}\n\n/**\n * List of expected output paths (for drift check)\n */\nexport function getExpectedOutputDirs(config: SpeckeeperConfig, cwd: string = process.cwd()): string[] {\n const paths = getOutputPaths(config, cwd);\n return [\n paths.requirements,\n paths.usecases,\n paths.architecture,\n paths.dataModel,\n paths.screens,\n paths.flows,\n paths.glossary,\n paths.component,\n paths.schemasEntities,\n ];\n}\n\n/**\n * Validate if output path complies with specification\n */\nexport function validateOutputPaths(actualPath: string, config: SpeckeeperConfig, cwd: string = process.cwd()): {\n valid: boolean;\n expectedPaths: string[];\n message?: string;\n} {\n const expectedDirs = getExpectedOutputDirs(config, cwd);\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n // Check if actualPath is under docs/ or specs/\n const isUnderDocs = actualPath.startsWith(docsDir);\n const isUnderSpecs = actualPath.startsWith(specsDir);\n \n if (!isUnderDocs && !isUnderSpecs) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" is not under docs/ or specs/`,\n };\n }\n \n // Check if under any of the expected paths\n const isValidPath = expectedDirs.some(dir => actualPath.startsWith(dir));\n \n if (!isValidPath) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" does not match spec-compliant paths. Expected one of: ${expectedDirs.map(d => d.replace(cwd + '/', '')).join(', ')}`,\n };\n }\n \n return { valid: true, expectedPaths: expectedDirs };\n}\n\n// ============================================================================\n// Configuration Loading\n// ============================================================================\n\nconst CONFIG_FILES = [\n 'speckeeper.config.yaml',\n 'speckeeper.config.yml',\n 'speckeeper.config.json',\n 'speckeeper.config.ts',\n 'speckeeper.config.js',\n];\n\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n \n while (currentDir !== dirname(currentDir)) {\n for (const configFile of CONFIG_FILES) {\n const configPath = resolve(currentDir, configFile);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n currentDir = dirname(currentDir);\n }\n \n return null;\n}\n\nexport async function loadConfig(\n configPath?: string,\n cwd: string = process.cwd()\n): Promise<SpeckeeperConfig> {\n const resolvedPath = configPath ?? findConfigFile(cwd);\n \n if (!resolvedPath) {\n return { ...defaultConfig };\n }\n \n const ext = resolvedPath.split('.').pop()?.toLowerCase();\n \n try {\n if (ext === 'yaml' || ext === 'yml') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = parseYaml(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'json') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'ts' || ext === 'js') {\n // Dynamic import for TS/JS config\n const module = await import(resolvedPath);\n const parsed = module.default ?? module;\n return { ...defaultConfig, ...parsed };\n }\n \n return { ...defaultConfig };\n } catch (error) {\n console.error(`Failed to load config from ${resolvedPath}:`, error);\n return { ...defaultConfig };\n }\n}\n\n// ============================================================================\n// Configuration Validation\n// ============================================================================\n\nexport function validateConfig(config: SpeckeeperConfig): string[] {\n const errors: string[] = [];\n \n if (!config.srcDir) {\n errors.push('srcDir is required');\n }\n \n if (!config.docsDir) {\n errors.push('docsDir is required');\n }\n \n if (!config.specsDir) {\n errors.push('specsDir is required');\n }\n \n return errors;\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { createHash } from 'node:crypto';\n\n// ============================================================================\n// File Writing\n// ============================================================================\n\nexport interface WriteResult {\n path: string;\n created: boolean;\n updated: boolean;\n unchanged: boolean;\n}\n\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\nexport function writeFile(filePath: string, content: string): WriteResult {\n const dir = dirname(filePath);\n ensureDir(dir);\n \n const existed = existsSync(filePath);\n let unchanged = false;\n \n if (existed) {\n const existingContent = readFileSync(filePath, 'utf-8');\n unchanged = existingContent === content;\n }\n \n if (!unchanged) {\n writeFileSync(filePath, content, 'utf-8');\n }\n \n return {\n path: filePath,\n created: !existed,\n updated: existed && !unchanged,\n unchanged,\n };\n}\n\nexport function writeJsonFile(filePath: string, data: unknown, indent: number = 2): WriteResult {\n const content = JSON.stringify(data, null, indent) + '\\n';\n return writeFile(filePath, content);\n}\n\n// ============================================================================\n// Batch Writing\n// ============================================================================\n\nexport interface BatchWriteResult {\n results: WriteResult[];\n created: number;\n updated: number;\n unchanged: number;\n total: number;\n}\n\nexport function batchWriteFiles(\n files: Array<{ path: string; content: string }>\n): BatchWriteResult {\n const results: WriteResult[] = [];\n \n for (const { path, content } of files) {\n results.push(writeFile(path, content));\n }\n \n return {\n results,\n created: results.filter(r => r.created).length,\n updated: results.filter(r => r.updated).length,\n unchanged: results.filter(r => r.unchanged).length,\n total: results.length,\n };\n}\n\n// ============================================================================\n// Drift Detection\n// ============================================================================\n\nexport interface DriftResult {\n file: string;\n hasDrift: boolean;\n expectedHash?: string;\n actualHash?: string;\n missing?: boolean;\n}\n\nexport function computeHash(content: string): string {\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\nexport function checkFileDrift(\n filePath: string,\n expectedContent: string\n): DriftResult {\n const expectedHash = computeHash(expectedContent);\n \n if (!existsSync(filePath)) {\n return {\n file: filePath,\n hasDrift: true,\n expectedHash,\n missing: true,\n };\n }\n \n const actualContent = readFileSync(filePath, 'utf-8');\n const actualHash = computeHash(actualContent);\n \n return {\n file: filePath,\n hasDrift: expectedHash !== actualHash,\n expectedHash,\n actualHash,\n };\n}\n\nexport function checkBatchDrift(\n files: Array<{ path: string; content: string }>\n): DriftResult[] {\n return files.map(({ path, content }) => checkFileDrift(path, content));\n}\n\n// ============================================================================\n// File Discovery\n// ============================================================================\n\nimport { glob } from 'glob';\n\nexport async function findFiles(\n pattern: string,\n cwd: string = process.cwd()\n): Promise<string[]> {\n return glob(pattern, { cwd, absolute: true });\n}\n\nexport async function findTypeScriptFiles(\n srcDir: string\n): Promise<string[]> {\n return findFiles('**/*.ts', srcDir);\n}\n\nexport async function findDefinitionFiles(\n srcDir: string,\n subDir: string\n): Promise<string[]> {\n const pattern = join(srcDir, subDir, '**/*.ts');\n return glob(pattern, { absolute: true, ignore: ['**/*.d.ts', '**/index.ts'] });\n}\n\n// ============================================================================\n// Output Helpers\n// ============================================================================\n\nexport function generateDocsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n\nexport function generateSpecsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n","/**\n * Definition and validation of model relations\n */\nimport { z } from 'zod';\n\n// ============================================================================\n// Model Levels\n// ============================================================================\n\n/**\n * Model abstraction level\n * \n * - L0: Business + Domain Analysis (Why / Problem space)\n * Desired outcomes/value, business flows, actors, terminology, business rules\n * - L1: Requirements (What)\n * Functional/non-functional requirements, constraints, acceptance criteria\n * - L2: Design (How / Direction)\n * Architecture, component breakdown, domain model, key sequences\n * - L3: Detailed Design/Implementation (How to build / Concrete artifacts)\n * Screen/API/DB definitions, external SSOT references\n */\nexport type ModelLevel = 'L0' | 'L1' | 'L2' | 'L3';\n\n/**\n * Get numeric index of level\n */\nexport function getLevelIndex(level: ModelLevel): number {\n return ['L0', 'L1', 'L2', 'L3'].indexOf(level);\n}\n\n// ============================================================================\n// Relation Types\n// ============================================================================\n\n/**\n * Relation types\n */\nexport const RELATION_TYPES = [\n 'dependsOn',\n 'uses',\n 'includes',\n 'implements',\n 'refines',\n 'verifies',\n 'satisfies',\n 'traces',\n 'relatedTo',\n] as const;\n\nexport type RelationType = typeof RELATION_TYPES[number];\n\n/**\n * Relation schema\n */\nexport const RelationSchema = z.object({\n /** Relation type */\n type: z.enum(RELATION_TYPES),\n /** Target ID */\n target: z.string(),\n /** Description (optional) */\n description: z.string().optional(),\n});\n\n/**\n * Relation field to add to model schemas\n * Usage: schema.extend({ relations: RelationsFieldSchema })\n */\nexport const RelationsFieldSchema = z.array(RelationSchema).optional();\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\n// ============================================================================\n// Relation Constraints\n// ============================================================================\n\n/**\n * Definition of relation constraints\n */\nexport interface RelationConstraint {\n /** Allowed target levels (all levels allowed if not specified) */\n allowedTargetLevels?: ModelLevel[];\n /** Level constraint rule */\n levelRule: 'source>target' | 'source>=target' | 'same' | 'any';\n /** Direction of impact propagation */\n propagation: 'forward' | 'backward' | 'both';\n}\n\n/**\n * Constraint definitions per relation type\n * \n * Level hierarchy:\n * L0 (Business) → L1 (Requirements) → L2 (Design) → L3 (Implementation)\n * Abstract ───────────────────────────→ Concrete\n */\nexport const RELATION_CONSTRAINTS: Record<RelationType, RelationConstraint> = {\n // Concrete→Abstract (implementation/design fulfills requirements)\n 'implements': {\n allowedTargetLevels: ['L1'], // Implements requirements\n levelRule: 'source>target',\n propagation: 'forward', // A changes → B needs review\n },\n // Concrete→Abstract (design/implementation satisfies business/requirements)\n 'satisfies': {\n allowedTargetLevels: ['L0', 'L1'], // Satisfies business/requirements\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A needs update\n },\n // Concrete→Abstract (refinement: requirements refine business, design refines requirements)\n 'refines': {\n allowedTargetLevels: ['L0', 'L1'], // Refines business/requirements\n levelRule: 'source>target',\n propagation: 'backward', // B changes → A needs update\n },\n // Test→Requirements/Business (verification relationship)\n 'verifies': {\n allowedTargetLevels: ['L0', 'L1'], // Verifies business/requirements\n levelRule: 'any',\n propagation: 'backward', // B changes → A needs update\n },\n // Dependencies (same level or concrete→abstract)\n 'dependsOn': {\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A affected\n },\n // Usage relationship (no level constraint)\n 'uses': {\n levelRule: 'any',\n propagation: 'backward', // B changes → A affected\n },\n // Inclusion relationship (same level only)\n 'includes': {\n levelRule: 'same',\n propagation: 'backward', // B changes → A affected\n },\n // Bidirectional tracing\n 'traces': {\n levelRule: 'any',\n propagation: 'both',\n },\n // General relation\n 'relatedTo': {\n levelRule: 'any',\n propagation: 'both',\n },\n};\n\n// ============================================================================\n// Relation Validation\n// ============================================================================\n\n/**\n * Relation validation result\n */\nexport interface RelationValidationResult {\n valid: boolean;\n errors: RelationValidationError[];\n}\n\n/**\n * Relation validation error\n */\nexport interface RelationValidationError {\n type: 'level_violation' | 'target_level_violation' | 'self_reference' | 'cycle_detected';\n message: string;\n relation: Relation;\n sourceId: string;\n}\n\n/**\n * Validate level constraint for single relation\n * \n * @param sourceLevel - Source model level (set in _models/)\n * @param sourceSpecId - Source spec ID\n * @param relation - Relation\n * @param targetLevel - Target model level\n */\nexport function validateRelationLevel(\n sourceLevel: ModelLevel | undefined,\n sourceSpecId: string,\n relation: Relation,\n targetLevel: ModelLevel | undefined,\n): RelationValidationError | null {\n // Self-reference check\n if (sourceSpecId === relation.target) {\n return {\n type: 'self_reference',\n message: `Self-reference is not allowed: ${sourceSpecId} → ${relation.target}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n\n // Skip if level is undefined\n if (!sourceLevel || !targetLevel) {\n return null;\n }\n \n const constraint = RELATION_CONSTRAINTS[relation.type];\n \n // Target level constraint check\n if (constraint.allowedTargetLevels && \n !constraint.allowedTargetLevels.includes(targetLevel)) {\n return {\n type: 'target_level_violation',\n message: `'${relation.type}' relation target must be ${constraint.allowedTargetLevels.join(' or ')}, but target is ${targetLevel}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n \n // Level direction constraint check\n const srcIdx = getLevelIndex(sourceLevel);\n const tgtIdx = getLevelIndex(targetLevel);\n \n switch (constraint.levelRule) {\n case 'source>target':\n if (srcIdx <= tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'source>=target':\n if (srcIdx < tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be same or more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'same':\n if (srcIdx !== tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) and target (${targetLevel}) to be same level`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n }\n \n return null;\n}\n\n/**\n * Detect circular references\n */\nexport function detectCycles(\n relations: Array<{ sourceId: string; targetId: string; type: RelationType }>,\n): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const graph = new Map<string, Set<string>>();\n const relationMap = new Map<string, Relation>();\n \n // Build graph\n for (const rel of relations) {\n if (!graph.has(rel.sourceId)) {\n graph.set(rel.sourceId, new Set());\n }\n graph.get(rel.sourceId)!.add(rel.targetId);\n relationMap.set(`${rel.sourceId}→${rel.targetId}`, { type: rel.type, target: rel.targetId });\n }\n \n // Detect cycles using DFS\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cyclePath: string[] = [];\n \n function dfs(node: string): boolean {\n visited.add(node);\n recursionStack.add(node);\n cyclePath.push(node);\n \n const neighbors = graph.get(node);\n if (neighbors) {\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) {\n return true;\n }\n } else if (recursionStack.has(neighbor)) {\n // Cycle detected\n const cycleStart = cyclePath.indexOf(neighbor);\n const cycle = cyclePath.slice(cycleStart);\n cycle.push(neighbor); // Close the cycle\n \n errors.push({\n type: 'cycle_detected',\n message: `Circular reference detected: ${cycle.join(' → ')}`,\n relation: relationMap.get(`${node}→${neighbor}`)!,\n sourceId: node,\n });\n return true;\n }\n }\n }\n \n cyclePath.pop();\n recursionStack.delete(node);\n return false;\n }\n \n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n \n return errors;\n}\n\n/**\n * Infer model ID from spec ID (prefix-based)\n */\nexport function inferModelIdFromSpecId(specId: string): string | undefined {\n const prefixMap: Record<string, string> = {\n 'REQ': 'requirement',\n 'CR': 'constraint',\n 'UC': 'usecase',\n 'ACTOR': 'actor',\n 'TERM': 'term',\n 'COMP': 'component',\n 'ENT': 'entity',\n 'FLOW': 'process-flow',\n 'LAYER': 'layer',\n 'BND': 'boundary',\n 'SCR': 'screen',\n 'API': 'api-ref',\n 'TBL': 'table-ref',\n 'IAC': 'iac-ref',\n 'BATCH': 'batch-ref',\n };\n \n for (const [prefix, modelId] of Object.entries(prefixMap)) {\n if (specId.startsWith(prefix + '-')) {\n return modelId;\n }\n }\n \n return undefined;\n}\n","/**\n * Model base class\n * \n * All model definitions inherit from this class\n */\nimport { z, ZodType } from 'zod';\nimport {\n type ModelLevel,\n type Relation,\n type RelationValidationError,\n validateRelationLevel,\n detectCycles,\n inferModelIdFromSpecId,\n} from './relation.js';\n\n// Re-export relation types\nexport type { ModelLevel, Relation, RelationValidationError };\nexport { RELATION_TYPES, RELATION_CONSTRAINTS, RelationSchema, RelationsFieldSchema } from './relation.js';\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Lint rule definition\n */\nexport interface LintRule<T> {\n id: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n check: (spec: T) => boolean; // true if there is an issue\n}\n\n/**\n * Lint result\n */\nexport interface LintResult {\n ruleId: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n specId?: string;\n}\n\n/**\n * Exporter definition\n */\nexport interface Exporter<T> {\n format: 'markdown' | 'json' | 'mermaid';\n single?: (spec: T) => string;\n index?: (specs: T[]) => string;\n outputDir?: string;\n filename?: (spec: T) => string;\n}\n\n/**\n * External checker definition\n */\nexport interface ExternalChecker<T> {\n targetType: string; // 'openapi' | 'ddl' | 'cli' etc.\n sourcePath: (spec: T) => string;\n check: (spec: T, externalData: unknown) => CheckResult;\n}\n\n/**\n * Check result\n */\nexport interface CheckResult {\n success: boolean;\n errors: { message: string; field?: string; specId?: string }[];\n warnings: { message: string; field?: string; specId?: string }[];\n}\n\n/**\n * Coverage result\n */\nexport interface CoverageResult {\n /** Total target count */\n total: number;\n /** Covered count */\n covered: number;\n /** Uncovered count */\n uncovered: number;\n /** Coverage rate (%) */\n coveragePercent: number;\n /** Details of covered items */\n coveredItems: { id: string; description?: string }[];\n /** Details of uncovered items */\n uncoveredItems: { id: string; description?: string; sourceId?: string }[];\n}\n\n/**\n * Coverage checker definition\n * \n * Verify cross-model consistency (coverage).\n * Example: Whether TestRef covers acceptanceCriteria of Requirement\n */\nexport interface CoverageChecker<T> {\n /** Target model ID for coverage (e.g. 'requirement') */\n targetModel: string;\n /** Description of coverage check */\n description: string;\n /** Execute coverage check */\n check: (\n specs: T[],\n registry: Record<string, Map<string, unknown>>\n ) => CoverageResult;\n}\n\n// ============================================================================\n// Renderer (for embeds)\n// ============================================================================\n\n/**\n * Render context\n * Simplified version compatible with embedoc's EmbedContext\n */\nexport interface RenderContext {\n /** Parameters (filter conditions other than format, etc.) */\n params: Record<string, string | undefined>;\n /** Markdown helpers */\n markdown: {\n /** Generate table */\n table: (headers: string[], rows: (string | unknown)[][]) => string;\n };\n}\n\n/**\n * Renderer definition\n * \n * Model-specific rendering called from embeds\n */\nexport interface Renderer<T> {\n /** Format ID ('table', 'list', 'detail', 'spec-chapter', etc.) */\n format: string;\n /** Rendering process */\n render: (specs: T[], ctx: RenderContext) => string;\n}\n\n// ============================================================================\n// Model Base Class\n// ============================================================================\n\n/**\n * Model base class\n * \n * @template TSchema - Zod schema type\n */\nexport abstract class Model<TSchema extends ZodType> {\n /** Singleton instance storage (per subclass) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private static _instances: WeakMap<new () => any, Model<ZodType>> = new WeakMap();\n\n /**\n * Get singleton instance of the model\n * Usage: RequirementModel.instance\n */\n static get instance(): Model<ZodType> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctor = this as unknown as new () => any;\n if (!this._instances.has(ctor)) {\n this._instances.set(ctor, new ctor());\n }\n return this._instances.get(ctor)!;\n }\n\n /** Model ID ('requirement', 'usecase', etc.) */\n abstract readonly id: string;\n \n /** Model name ('Requirement', 'UseCase', etc.) */\n abstract readonly name: string;\n \n /** ID prefix ('REQ', 'UC', etc.) */\n abstract readonly idPrefix: string;\n \n /** Zod schema */\n abstract readonly schema: TSchema;\n \n /** Model description (optional) */\n readonly description?: string;\n \n /** External SSOT type (optional, e.g. 'OpenAPI', 'DDL/Prisma') */\n readonly externalSsotType?: string;\n \n /** Spec instance type */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected get specType(): z.infer<TSchema> { return undefined as any; }\n \n /** Lint rules (override in subclass) */\n protected lintRules: LintRule<z.infer<TSchema>>[] = [];\n \n /** Exporters (override in subclass) */\n protected exporters: Exporter<z.infer<TSchema>>[] = [];\n \n /** External checker (optional) */\n protected externalChecker?: ExternalChecker<z.infer<TSchema>>;\n \n /** Coverage checker (optional) */\n protected coverageChecker?: CoverageChecker<z.infer<TSchema>>;\n \n /** Model level (set in _models/) */\n protected modelLevel?: ModelLevel;\n \n /** Renderers (for embeds, override in subclass) */\n protected renderers: Renderer<z.infer<TSchema>>[] = [];\n \n /**\n * Get model level\n * Returns modelLevel set in _models/\n */\n get level(): ModelLevel | undefined {\n return this.modelLevel;\n }\n \n /**\n * Execute schema validation\n */\n validate(spec: unknown): z.infer<TSchema> {\n return this.schema.parse(spec);\n }\n \n /**\n * Schema validation (safe version, returns error object on failure)\n */\n safeParse(spec: unknown): { success: true; data: z.infer<TSchema> } | { success: false; error: z.ZodError } {\n return this.schema.safeParse(spec);\n }\n \n /**\n * Execute lint\n */\n lint(spec: z.infer<TSchema>): LintResult[] {\n const specId = (spec as { id?: string }).id;\n return this.lintRules\n .filter(rule => rule.check(spec))\n .map(rule => ({\n ruleId: rule.id,\n severity: rule.severity,\n message: rule.message,\n specId,\n }));\n }\n \n /**\n * Execute lint for multiple specs\n */\n lintAll(specs: z.infer<TSchema>[]): LintResult[] {\n return specs.flatMap(spec => this.lint(spec));\n }\n \n /**\n * Validate level constraints of relations\n * @param spec - Spec instance (if it has relations property)\n * @returns Array of validation errors\n */\n validateRelations(spec: z.infer<TSchema>): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n \n if (!specWithRelations.relations || !specWithRelations.id) {\n return errors;\n }\n \n // Get all models to retrieve target model levels\n const allModels = getAllModels();\n const modelLevelMap = new Map<string, ModelLevel | undefined>();\n for (const model of allModels) {\n modelLevelMap.set(model.id, model.level);\n }\n \n for (const relation of specWithRelations.relations) {\n // Infer target model ID\n const targetModelId = inferModelIdFromSpecId(relation.target);\n if (!targetModelId) {\n continue; // Skip if model ID cannot be inferred\n }\n \n const targetLevel = modelLevelMap.get(targetModelId);\n \n const error = validateRelationLevel(\n this.level,\n specWithRelations.id,\n relation,\n targetLevel,\n );\n \n if (error) {\n errors.push(error);\n }\n }\n \n return errors;\n }\n \n /**\n * Validate relations of multiple specs (including circular reference check)\n */\n validateAllRelations(specs: z.infer<TSchema>[]): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const allRelations: Array<{ sourceId: string; targetId: string; type: string }> = [];\n \n for (const spec of specs) {\n // Individual level constraint check\n errors.push(...this.validateRelations(spec));\n \n // Collect relations for circular reference check\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n if (specWithRelations.relations && specWithRelations.id) {\n for (const rel of specWithRelations.relations) {\n allRelations.push({\n sourceId: specWithRelations.id,\n targetId: rel.target,\n type: rel.type,\n });\n }\n }\n }\n \n // Circular reference check\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errors.push(...detectCycles(allRelations as any));\n \n return errors;\n }\n \n /**\n * Export in specified format (single spec)\n */\n exportSingle(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.single) return null;\n return exporter.single(spec);\n }\n \n /**\n * Export in specified format (index)\n */\n exportIndex(specs: z.infer<TSchema>[], format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.index) return null;\n return exporter.index(specs);\n }\n \n /**\n * Get exporter output directory\n */\n getOutputDir(format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n return exporter?.outputDir ?? null;\n }\n \n /**\n * Get filename\n */\n getFilename(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.filename) return null;\n return exporter.filename(spec);\n }\n \n /**\n * Check consistency with external SSOT\n */\n check(spec: z.infer<TSchema>, externalData: unknown): CheckResult {\n if (!this.externalChecker) {\n return { success: true, errors: [], warnings: [] };\n }\n return this.externalChecker.check(spec, externalData);\n }\n \n /**\n * Get external SSOT path\n */\n getExternalSourcePath(spec: z.infer<TSchema>): string | null {\n if (!this.externalChecker) return null;\n return this.externalChecker.sourcePath(spec);\n }\n \n /**\n * Execute coverage check\n * @param specs - Array of spec instances for this model\n * @param registry - Registry of all models\n */\n checkCoverage(\n specs: z.infer<TSchema>[],\n registry: Record<string, Map<string, unknown>>\n ): CoverageResult | null {\n if (!this.coverageChecker) return null;\n return this.coverageChecker.check(specs, registry);\n }\n \n /**\n * Get coverage checker\n */\n getCoverageChecker(): CoverageChecker<z.infer<TSchema>> | undefined {\n return this.coverageChecker;\n }\n \n /**\n * Get lint rules\n */\n getLintRules(): LintRule<z.infer<TSchema>>[] {\n return this.lintRules;\n }\n \n /**\n * Get exporters\n */\n getExporters(): Exporter<z.infer<TSchema>>[] {\n return this.exporters;\n }\n \n // ============================================================================\n // Renderer (for embeds)\n // ============================================================================\n \n /**\n * Render in specified format\n * @param format - Format ID ('table', 'list', 'detail', etc.)\n * @param specs - Array of specs to render\n * @param ctx - Render context\n * @returns Rendered result (Markdown string), null if no matching renderer\n */\n render(format: string, specs: z.infer<TSchema>[], ctx: RenderContext): string | null {\n const renderer = this.renderers.find(r => r.format === format);\n if (!renderer) return null;\n return renderer.render(specs, ctx);\n }\n \n /**\n * Get list of available formats\n */\n getAvailableFormats(): string[] {\n return this.renderers.map(r => r.format);\n }\n \n /**\n * Get renderers\n */\n getRenderers(): Renderer<z.infer<TSchema>>[] {\n return this.renderers;\n }\n \n /**\n * Check if renderer exists for specific format\n */\n hasRenderer(format: string): boolean {\n return this.renderers.some(r => r.format === format);\n }\n \n /**\n * Register spec instances for this model.\n * Stores specs in the global specStore keyed by this model's id.\n */\n register(specs: z.infer<TSchema>[]): void {\n if (!specStore.has(this.id)) {\n specStore.set(this.id, new Map());\n }\n const map = specStore.get(this.id)!;\n for (const spec of specs) {\n map.set((spec as { id: string }).id, spec);\n }\n }\n}\n\n// ============================================================================\n// Spec Store\n// ============================================================================\n\nconst specStore = new Map<string, Map<string, unknown>>();\n\n/**\n * Get the global spec store (model ID → spec ID → spec data)\n */\nexport function getSpecStore(): Map<string, Map<string, unknown>> {\n return specStore;\n}\n\n/**\n * Reset the spec store (clears all registered specs)\n */\nexport function resetSpecStore(): void {\n specStore.clear();\n}\n\n// ============================================================================\n// Model Registry\n// ============================================================================\n\n/** Map of registered models */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst modelRegistry = new Map<string, Model<any>>();\n\n/**\n * Register model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function registerModel(model: Model<any>): void {\n modelRegistry.set(model.id, model);\n}\n\n/**\n * Get model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getModel(id: string): Model<any> | undefined {\n return modelRegistry.get(id);\n}\n\n/**\n * Get all registered models\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getAllModels(): Model<any>[] {\n return Array.from(modelRegistry.values());\n}\n\n/**\n * Clear registry\n */\nexport function clearModelRegistry(): void {\n modelRegistry.clear();\n}\n","/**\n * Model Loader\n * \n * Load models and specs from design/ directory.\n * Spec registration is done explicitly via Model.register() in each spec file.\n */\n\nimport { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join, resolve, extname, basename } from 'node:path';\nimport type { SpeckeeperConfig } from './config-loader.js';\nimport {\n registerModel as coreRegisterModel,\n clearModelRegistry,\n getSpecStore,\n resetSpecStore,\n} from '../core/model.js';\n\n// ============================================================================\n// Registry Types\n// ============================================================================\n\n/**\n * Model registry - stores all loaded spec data.\n * Keys are model IDs (e.g. 'functional-requirement', 'usecase').\n * Values are Maps of spec ID -> spec data.\n */\nexport type ModelRegistry = Record<string, Map<string, unknown>>;\n\n// ============================================================================\n// Model Instance Detection\n// ============================================================================\n\n/**\n * Determine if value is a Model class instance\n */\nfunction isModelInstance(value: unknown): value is { id: string; name: string; idPrefix: string; schema: unknown } {\n if (!value || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === 'string' &&\n typeof obj.name === 'string' &&\n typeof obj.idPrefix === 'string' &&\n obj.schema !== undefined &&\n typeof obj.validate === 'function' &&\n typeof obj.lint === 'function'\n );\n}\n\n/**\n * Detect and register Model class instances from module exports.\n * Only registers Model instances to the core model registry.\n * Spec data registration is handled by Model.register() calls in spec files.\n */\nfunction registerExportedModelInstances(module: Record<string, unknown>): void {\n for (const [, exportValue] of Object.entries(module)) {\n if (!exportValue || typeof exportValue !== 'object') continue;\n if (isModelInstance(exportValue)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n coreRegisterModel(exportValue as any);\n }\n }\n}\n\n// ============================================================================\n// File Loading\n// ============================================================================\n\n/**\n * Dynamically import TS files from specified directory.\n * Model class instances found in exports are registered to core registry.\n * Spec data is registered via Model.register() side effects during import.\n */\nexport async function loadModelsFromDirectory(\n dirPath: string,\n options: { recursive?: boolean } = {}\n): Promise<string[]> {\n const loadedFiles: string[] = [];\n\n if (!existsSync(dirPath)) {\n return loadedFiles;\n }\n\n const entries = readdirSync(dirPath);\n\n for (const entry of entries) {\n const fullPath = join(dirPath, entry);\n const stat = statSync(fullPath);\n\n if (stat.isDirectory() && options.recursive) {\n const subFiles = await loadModelsFromDirectory(fullPath, options);\n loadedFiles.push(...subFiles);\n } else if (stat.isFile()) {\n const ext = extname(entry);\n if (['.ts', '.js', '.mts', '.mjs'].includes(ext) && !entry.endsWith('.d.ts')) {\n if (basename(entry, ext) === 'index') {\n continue;\n }\n\n try {\n const module = await import(fullPath);\n loadedFiles.push(fullPath);\n registerExportedModelInstances(module);\n } catch (error) {\n console.error(`Failed to load from ${fullPath}:`, error);\n }\n }\n }\n }\n\n return loadedFiles;\n}\n\n/**\n * Load all models and specs based on configuration.\n * \n * 1. Reset spec store and model registry\n * 2. Register Model class instances from config.models\n * 3. Scan design/ files (triggers Model.register() calls as side effects)\n * 4. Build registry from specStore\n */\nexport async function loadAllModels(\n config: SpeckeeperConfig,\n cwd: string = process.cwd()\n): Promise<{\n registry: ModelRegistry;\n loadedFiles: string[];\n errors: Array<{ file: string; error: unknown }>;\n}> {\n resetSpecStore();\n clearModelRegistry();\n\n const loadedFiles: string[] = [];\n const errors: Array<{ file: string; error: unknown }> = [];\n\n // Register Model class instances from config.models first\n if (config.models && Array.isArray(config.models)) {\n for (const model of config.models) {\n if (isModelInstance(model)) {\n coreRegisterModel(model as Parameters<typeof coreRegisterModel>[0]);\n }\n }\n }\n\n const designDir = resolve(cwd, config.designDir || 'design');\n\n const modelDirs = [\n { path: join(designDir, '_models') },\n { path: join(designDir, 'requirements') },\n { path: join(designDir, 'usecases') },\n { path: join(designDir, 'architecture') },\n { path: join(designDir, 'data-model') },\n { path: join(designDir, 'screens') },\n { path: join(designDir, 'flows') },\n { path: join(designDir, 'glossary') },\n { path: designDir },\n ];\n\n for (const { path: dirPath } of modelDirs) {\n if (!existsSync(dirPath)) {\n continue;\n }\n\n try {\n const files = await loadModelsFromDirectory(dirPath, { recursive: true });\n loadedFiles.push(...files);\n } catch (error) {\n errors.push({ file: dirPath, error });\n }\n }\n\n // Build registry from specStore (populated by Model.register() calls)\n const store = getSpecStore();\n const registry: ModelRegistry = {};\n for (const [modelId, specMap] of store) {\n registry[modelId] = specMap;\n }\n\n return {\n registry,\n loadedFiles,\n errors,\n };\n}\n\n// ============================================================================\n// Registry Helpers\n// ============================================================================\n\n/**\n * Get specs from registry for a given model ID\n */\nexport function getSpecsFromRegistry(registry: ModelRegistry, modelId: string): unknown[] {\n const map = registry[modelId];\n if (!map) return [];\n return Array.from(map.values());\n}\n\n/**\n * Get registry statistics\n */\nexport function getRegistryStats(registry: ModelRegistry): Record<string, number> {\n const stats: Record<string, number> = {};\n\n for (const [key, map] of Object.entries(registry)) {\n stats[key] = map.size;\n }\n\n return stats;\n}\n\n/**\n * Get all IDs in registry\n */\nexport function getAllIds(registry: ModelRegistry): Set<string> {\n const allIds = new Set<string>();\n\n for (const map of Object.values(registry)) {\n for (const id of map.keys()) {\n allIds.add(id);\n }\n }\n\n return allIds;\n}\n\n/**\n * Identify model type from ID\n */\nexport function findModelType(\n registry: ModelRegistry,\n id: string\n): string | null {\n for (const [type, map] of Object.entries(registry)) {\n if (map.has(id)) {\n return type;\n }\n }\n return null;\n}\n\n/**\n * Get model by ID\n */\nexport function getModelById(\n registry: ModelRegistry,\n id: string\n): { type: string; model: unknown } | null {\n const type = findModelType(registry, id);\n if (!type) return null;\n\n return {\n type,\n model: registry[type].get(id),\n };\n}\n","/**\n * Build Command\n * \n * Generate documents and schemas using model class exporters\n */\n\nimport chalk from 'chalk';\nimport { join, relative } from 'node:path';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { batchWriteFiles, ensureDir } from '../utils/file-writer.js';\nimport { getAllModels } from '../core/model.js';\nimport { loadAllModels, getSpecsFromRegistry } from '../utils/model-loader.js';\n\n// ============================================================================\n// Build Command Options\n// ============================================================================\n\nexport interface BuildCommandOptions {\n config?: string;\n output?: string;\n format?: 'markdown' | 'json' | 'both';\n verbose?: boolean;\n clean?: boolean;\n}\n\n// ============================================================================\n// Build Command\n// ============================================================================\n\nexport async function buildCommand(options: BuildCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper build'));\n console.log('');\n \n const cwd = process.cwd();\n \n // Load config\n const config = await loadConfig(options.config);\n // Output paths available via getOutputPaths(config, cwd) if needed\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log(chalk.gray(` Specs: ${config.specsDir}/`));\n console.log('');\n \n try {\n // Load all models from design/ and config\n console.log(chalk.blue(' Loading models...'));\n const { registry, loadedFiles, errors: loadErrors } = await loadAllModels(config, cwd);\n \n if (loadErrors.length > 0) {\n console.log(chalk.yellow(` ⚠ ${loadErrors.length} file(s) failed to load`));\n for (const { file, error } of loadErrors) {\n console.log(chalk.yellow(` - ${relative(cwd, file)}: ${error}`));\n }\n }\n \n console.log(chalk.gray(` Loaded: ${loadedFiles.length} files`));\n console.log('');\n \n // Ensure base output directories exist\n ensureDir(join(cwd, config.docsDir));\n ensureDir(join(cwd, config.specsDir));\n \n const files: Array<{ path: string; content: string }> = [];\n const models = getAllModels();\n \n if (models.length === 0) {\n console.log(chalk.yellow(' No models registered. Add models to speckeeper.config.ts.'));\n return;\n }\n \n console.log(chalk.blue(` Processing ${models.length} model types...`));\n \n // Process each model type\n for (const model of models) {\n const exporters = model.getExporters();\n \n if (exporters.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no exporters defined`));\n }\n continue;\n }\n \n const specs = getSpecsFromRegistry(registry, model.id);\n \n if (specs.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no specs found`));\n }\n continue;\n }\n \n for (const exporter of exporters) {\n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n ensureDir(outputDir);\n \n // Generate individual files\n if (exporter.single) {\n for (const spec of specs) {\n const content = exporter.single(spec);\n const filename = model.getFilename(spec, exporter.format) || (spec as { id: string }).id;\n files.push({\n path: join(outputDir, `${filename}.md`),\n content,\n });\n }\n }\n \n // Generate index file\n if (exporter.index) {\n const indexContent = exporter.index(specs);\n files.push({\n path: join(outputDir, 'index.md'),\n content: indexContent,\n });\n }\n }\n \n console.log(chalk.green(` ✓ ${model.name}`));\n }\n \n // Write all files\n if (files.length > 0) {\n console.log('');\n console.log(chalk.blue(` Writing ${files.length} files...`));\n \n const result = await batchWriteFiles(files);\n \n console.log('');\n console.log(chalk.green(` ✓ Build complete`));\n console.log(chalk.gray(` Created: ${result.created}`));\n console.log(chalk.gray(` Updated: ${result.updated}`));\n console.log(chalk.gray(` Unchanged: ${result.unchanged}`));\n } else {\n console.log(chalk.yellow(' No files to generate.'));\n }\n \n } catch (error) {\n console.error(chalk.red('Build failed:'), error);\n process.exit(1);\n }\n}\n","/**\n * Lint Command\n * \n * Execute design consistency checks using model class lintRules\n */\n\nimport chalk from 'chalk';\nimport { relative } from 'node:path';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, getSpecsFromRegistry, type ModelRegistry } from '../utils/model-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface LintCommandOptions {\n config?: string;\n phase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strict?: boolean;\n fix?: boolean;\n format?: 'text' | 'json' | 'github';\n}\n\nexport type LintSeverity = 'error' | 'warning' | 'info';\n\nexport interface LintIssue {\n rule: string;\n severity: LintSeverity;\n message: string;\n specId?: string;\n modelType?: string;\n}\n\nexport interface LintResult {\n issues: LintIssue[];\n errors: number;\n warnings: number;\n infos: number;\n}\n\n// ============================================================================\n// Lint Command\n// ============================================================================\n\nexport async function lintCommand(options: LintCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper lint'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n if (options.phase) {\n console.log(chalk.gray(` Phase: ${options.phase}`));\n }\n console.log('');\n \n try {\n // Load all models from design/\n console.log(chalk.blue(' Loading models...'));\n const { registry, loadedFiles, errors: loadErrors } = await loadAllModels(config, cwd);\n \n if (loadErrors.length > 0) {\n console.log(chalk.yellow(` ⚠ ${loadErrors.length} file(s) failed to load`));\n for (const { file, error } of loadErrors) {\n console.log(chalk.yellow(` - ${relative(cwd, file)}: ${error}`));\n }\n }\n \n console.log(chalk.gray(` Loaded: ${loadedFiles.length} files`));\n console.log('');\n \n // Run lint using model classes\n console.log(chalk.blue(' Running lint checks...'));\n const result = runModelLint(registry, options);\n \n // Output results\n console.log('');\n outputLintResults(result, options);\n \n // Exit with error code if there are errors\n if (result.errors > 0) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Lint failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Lint Runner\n// ============================================================================\n\nfunction runModelLint(registry: ModelRegistry, options: LintCommandOptions): LintResult {\n const issues: LintIssue[] = [];\n const models = getAllModels();\n \n for (const model of models) {\n // Get specs from registry for this model type\n const specs = getSpecsFromRegistry(registry, model.id);\n \n if (specs.length === 0) continue;\n \n // Run lint rules\n const lintResults = model.lintAll(specs);\n \n for (const result of lintResults) {\n issues.push({\n rule: result.ruleId,\n severity: result.severity,\n message: result.message,\n specId: result.specId,\n modelType: model.name,\n });\n }\n }\n \n // Count by severity\n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n const infos = issues.filter(i => i.severity === 'info').length;\n \n // Filter by strict mode\n if (!options.strict) {\n return {\n issues: issues.filter(i => i.severity !== 'info'),\n errors,\n warnings,\n infos,\n };\n }\n \n return { issues, errors, warnings, infos };\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputLintResults(result: LintResult, options: LintCommandOptions): void {\n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'github') {\n for (const issue of result.issues) {\n const level = issue.severity === 'error' ? 'error' : issue.severity === 'warning' ? 'warning' : 'notice';\n console.log(`::${level}::${issue.message} [${issue.rule}]${issue.specId ? ` (${issue.specId})` : ''}`);\n }\n return;\n }\n \n // Default text format\n if (result.issues.length === 0) {\n console.log(chalk.green(' ✓ No issues found'));\n return;\n }\n \n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : issue.severity === 'warning' ? '⚠' : 'ℹ';\n const color = issue.severity === 'error' ? chalk.red : issue.severity === 'warning' ? chalk.yellow : chalk.blue;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n console.log(chalk.gray(` Rule: ${issue.rule}`));\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${result.errors} errors, ${result.warnings} warnings, ${result.infos} infos`));\n}\n","/**\n * Drift Command\n * \n * Detect drift between generated artifacts and SSOT\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, getSpecsFromRegistry } from '../utils/model-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DriftCommandOptions {\n config?: string;\n verbose?: boolean;\n failOnDrift?: boolean;\n}\n\nexport interface DriftResult {\n file: string;\n status: 'ok' | 'drifted' | 'missing';\n details?: string;\n}\n\n// ============================================================================\n// Drift Command\n// ============================================================================\n\nexport async function driftCommand(options: DriftCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper drift'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n // Output paths available via getOutputPaths if needed\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n const results: DriftResult[] = [];\n const models = getAllModels();\n \n // Check each model's generated files\n for (const model of models) {\n const specs = getSpecsFromRegistry(registry, model.id);\n if (specs.length === 0) continue;\n \n for (const exporter of model.getExporters()) {\n if (exporter.format !== 'markdown') continue;\n \n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n // Check individual files\n if (exporter.single) {\n for (const spec of specs) {\n const filename = model.getFilename(spec, 'markdown') || (spec as { id: string }).id;\n const filePath = join(outputDir, `${filename}.md`);\n \n if (!existsSync(filePath)) {\n results.push({ file: filePath, status: 'missing' });\n continue;\n }\n \n const expected = exporter.single(spec);\n const actual = readFileSync(filePath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: filePath, status: 'drifted' });\n } else {\n results.push({ file: filePath, status: 'ok' });\n }\n }\n }\n \n // Check index file\n if (exporter.index) {\n const indexPath = join(outputDir, 'index.md');\n \n if (!existsSync(indexPath)) {\n results.push({ file: indexPath, status: 'missing' });\n } else {\n const expected = exporter.index(specs);\n const actual = readFileSync(indexPath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: indexPath, status: 'drifted' });\n } else {\n results.push({ file: indexPath, status: 'ok' });\n }\n }\n }\n }\n }\n \n // Output results\n outputDriftResults(results, options);\n \n // Exit with error code if drift detected and failOnDrift is set\n const hasDrift = results.some(r => r.status === 'drifted' || r.status === 'missing');\n if (hasDrift && options.failOnDrift) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Drift check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction normalizeContent(content: string): string {\n return content.trim().replace(/\\r\\n/g, '\\n');\n}\n\nfunction outputDriftResults(results: DriftResult[], _options: DriftCommandOptions): void {\n console.log('');\n \n const ok = results.filter(r => r.status === 'ok');\n const drifted = results.filter(r => r.status === 'drifted');\n const missing = results.filter(r => r.status === 'missing');\n \n if (drifted.length === 0 && missing.length === 0) {\n console.log(chalk.green(' ✓ No drift detected'));\n console.log(chalk.gray(` Checked: ${results.length} files`));\n return;\n }\n \n if (drifted.length > 0) {\n console.log(chalk.yellow(` ⚠ ${drifted.length} file(s) have drifted:`));\n for (const result of drifted) {\n console.log(chalk.yellow(` - ${result.file}`));\n }\n }\n \n if (missing.length > 0) {\n console.log(chalk.red(` ✗ ${missing.length} file(s) are missing:`));\n for (const result of missing) {\n console.log(chalk.red(` - ${result.file}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${ok.length} ok, ${drifted.length} drifted, ${missing.length} missing`));\n}\n","/**\n * Check Command\n * \n * Check consistency with external SSOT using model class externalChecker\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, getSpecsFromRegistry, type ModelRegistry } from '../utils/model-loader.js';\nimport { getAllModels, type CoverageResult } from '../core/model.js';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CheckCommandOptions {\n config?: string;\n type?: 'openapi' | 'ddl' | 'iac' | 'all';\n verbose?: boolean;\n coverage?: boolean;\n}\n\nexport interface CheckIssue {\n severity: 'error' | 'warning';\n message: string;\n specId?: string;\n field?: string;\n}\n\nexport interface CheckResult {\n type: string;\n success: boolean;\n issues: CheckIssue[];\n}\n\n// ============================================================================\n// Check Command\n// ============================================================================\n\nexport async function checkCommand(\n type: string | undefined,\n options: CheckCommandOptions\n): Promise<void> {\n console.log(chalk.blue('speckeeper check'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n const checkType = type || options.type || 'all';\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Type: ${checkType}`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n const results: CheckResult[] = [];\n const models = getAllModels();\n \n if (options.verbose) {\n console.log(chalk.gray(` Registered models: ${models.map(m => m.id).join(', ')}`));\n }\n \n // Run checks for each model that has an external checker\n for (const model of models) {\n const specs = getSpecsFromRegistry(registry, model.id);\n if (specs.length === 0) continue;\n \n for (const spec of specs) {\n const sourcePath = model.getExternalSourcePath(spec);\n if (!sourcePath) continue;\n \n const fullPath = join(cwd, sourcePath);\n if (!existsSync(fullPath)) {\n results.push({\n type: model.id,\n success: false,\n issues: [{\n severity: 'error',\n message: `External source not found: ${sourcePath}`,\n specId: (spec as { id: string }).id,\n }],\n });\n continue;\n }\n \n // Load external data\n const externalData = loadExternalData(fullPath);\n \n // Run check\n const checkResult = model.check(spec, externalData);\n \n if (!checkResult.success || checkResult.errors.length > 0 || checkResult.warnings.length > 0) {\n results.push({\n type: model.id,\n success: checkResult.success,\n issues: [\n ...checkResult.errors.map(e => ({ severity: 'error' as const, message: e.message, specId: e.specId, field: e.field })),\n ...checkResult.warnings.map(w => ({ severity: 'warning' as const, message: w.message, specId: w.specId, field: w.field })),\n ],\n });\n }\n }\n }\n \n // Output results\n outputCheckResults(results);\n \n // Coverage check (if --coverage flag is set)\n if (options.coverage) {\n console.log('');\n console.log(chalk.blue(' Coverage checks...'));\n const coverageResults = runAllCoverageChecks(registry);\n \n if (coverageResults.length > 0) {\n outputAllCoverageResults(coverageResults);\n \n // Add uncovered items as warnings\n for (const check of coverageResults) {\n if (check.result.uncoveredItems.length > 0) {\n results.push({\n type: `coverage-${check.modelId}`,\n success: check.result.coveragePercent >= 80, // fail if below 80%\n issues: check.result.uncoveredItems.slice(0, 10).map(item => ({\n severity: 'warning' as const,\n message: `[${check.modelName}→${check.targetModel}] '${item.id}'${item.sourceId ? ` (${item.sourceId})` : ''} not covered`,\n specId: item.id,\n })),\n });\n }\n }\n \n // Summary\n console.log('');\n console.log(chalk.gray(' ─────────────────────────────────────'));\n const allPassed = coverageResults.every(c => c.result.coveragePercent >= 80);\n if (allPassed) {\n console.log(chalk.green(' ✓ All coverage checks passed (≥80%)'));\n } else {\n const failed = coverageResults.filter(c => c.result.coveragePercent < 80);\n console.log(chalk.yellow(` ⚠ ${failed.length} coverage check(s) below 80%`));\n }\n } else {\n console.log(chalk.gray(' No coverage checker found'));\n }\n }\n \n // Exit with error code if there are errors\n const hasErrors = results.some(r => !r.success);\n if (hasErrors) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction loadExternalData(filePath: string): unknown {\n const content = readFileSync(filePath, 'utf-8');\n \n if (filePath.endsWith('.yaml') || filePath.endsWith('.yml')) {\n return parseYaml(content);\n }\n \n if (filePath.endsWith('.json')) {\n return JSON.parse(content);\n }\n \n return content;\n}\n\nfunction outputCheckResults(results: CheckResult[]): void {\n console.log('');\n \n if (results.length === 0) {\n console.log(chalk.green(' ✓ All checks passed'));\n return;\n }\n \n let totalErrors = 0;\n let totalWarnings = 0;\n \n for (const result of results) {\n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : '⚠';\n const color = issue.severity === 'error' ? chalk.red : chalk.yellow;\n \n if (issue.severity === 'error') totalErrors++;\n else totalWarnings++;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${totalErrors} errors, ${totalWarnings} warnings`));\n}\n\n// ============================================================================\n// Coverage Check\n// ============================================================================\n\ninterface CoverageCheckResult {\n modelId: string;\n modelName: string;\n description: string;\n targetModel: string;\n result: CoverageResult;\n}\n\n/**\n * Execute all coverage checks\n * \n * Detect all models with coverageChecker and run coverage checks.\n * Logic is defined in each model (design/_models/).\n */\nfunction runAllCoverageChecks(registry: ModelRegistry): CoverageCheckResult[] {\n const models = getAllModels();\n const results: CoverageCheckResult[] = [];\n \n // Search for models with coverageChecker and execute\n for (const model of models) {\n const checker = model.getCoverageChecker();\n if (checker) {\n const specs = getSpecsFromRegistry(registry, model.id);\n const result = model.checkCoverage(specs, registry);\n \n if (result) {\n results.push({\n modelId: model.id,\n modelName: model.name,\n description: checker.description,\n targetModel: checker.targetModel,\n result,\n });\n }\n }\n }\n \n return results;\n}\n\nfunction outputAllCoverageResults(checks: CoverageCheckResult[]): void {\n for (const check of checks) {\n console.log('');\n console.log(chalk.blue(` Coverage: ${check.modelName} → ${check.targetModel}`));\n console.log(chalk.gray(` ${check.description}`));\n console.log(chalk.gray(` ─────────────────────────────────────`));\n console.log(chalk.gray(` Total: ${check.result.total}`));\n console.log(chalk.green(` Covered: ${check.result.covered}`));\n console.log(chalk.yellow(` Uncovered: ${check.result.uncovered}`));\n \n const color = check.result.coveragePercent >= 80 ? chalk.green : \n check.result.coveragePercent >= 50 ? chalk.yellow : chalk.red;\n console.log(color(` Coverage: ${check.result.coveragePercent}%`));\n \n if (check.result.uncoveredItems.length > 0 && check.result.uncoveredItems.length <= 10) {\n console.log('');\n console.log(chalk.yellow(' Uncovered items:'));\n for (const item of check.result.uncoveredItems) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n const source = item.sourceId ? ` (${item.sourceId})` : '';\n console.log(chalk.yellow(` - ${item.id}${source}${desc}`));\n }\n } else if (check.result.uncoveredItems.length > 10) {\n console.log('');\n console.log(chalk.yellow(` (${check.result.uncoveredItems.length} uncovered items - showing first 5)`));\n for (const item of check.result.uncoveredItems.slice(0, 5)) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n console.log(chalk.yellow(` - ${item.id}${desc}`));\n }\n }\n }\n}\n","/**\n * New Command\n * \n * Generate templates for new model instances\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { writeFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface NewCommandOptions {\n config?: string;\n type?: string;\n id?: string;\n output?: string;\n dryRun?: boolean;\n}\n\n// ============================================================================\n// New Command\n// ============================================================================\n\nexport async function newCommand(options: NewCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper new'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n // List available types if no type specified\n if (!options.type) {\n console.log(chalk.gray(' Available model types:'));\n const models = getAllModels();\n for (const model of models) {\n console.log(chalk.gray(` - ${model.id} (${model.name})`));\n }\n console.log('');\n console.log(chalk.gray(' Usage: speckeeper new --type <type> [--id <id>]'));\n return;\n }\n \n // Find model\n const models = getAllModels();\n const model = models.find(m => m.id === options.type);\n \n if (!model) {\n console.error(chalk.red(` Error: Unknown model type '${options.type}'`));\n console.log(chalk.gray(' Run `speckeeper new` to see available types'));\n process.exit(1);\n }\n \n // Generate ID if not provided\n const id = options.id || `${model.idPrefix}-${String(Date.now()).slice(-6)}`;\n \n // Generate template\n const template = generateTemplate(model, id);\n \n if (options.dryRun) {\n console.log(chalk.gray(' Template (dry run):'));\n console.log('');\n console.log(template);\n return;\n }\n \n // Write template to file\n const outputDir = options.output || join(cwd, config.designDir || 'design');\n const outputFile = join(outputDir, `${model.id}-${id}.ts`);\n \n if (existsSync(outputFile)) {\n console.error(chalk.red(` Error: File already exists: ${outputFile}`));\n process.exit(1);\n }\n \n writeFileSync(outputFile, template);\n console.log(chalk.green(` ✓ Created: ${outputFile}`));\n}\n\n// ============================================================================\n// Template Generation\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction generateTemplate(model: any, id: string): string {\n const typeName = model.name;\n const lines: string[] = [];\n \n lines.push(`/**`);\n lines.push(` * ${typeName}: ${id}`);\n lines.push(` * `);\n lines.push(` * Generated by speckeeper new`);\n lines.push(` */`);\n lines.push(`import type { ${typeName} } from './_models/${model.id}';`);\n lines.push('');\n lines.push(`export const ${camelCase(id)}: ${typeName} = {`);\n lines.push(` id: '${id}',`);\n lines.push(` // TODO: Fill in the required fields`);\n lines.push(`};`);\n lines.push('');\n \n return lines.join('\\n');\n}\n\nfunction camelCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[-_](.)/g, (_, c) => c.toUpperCase());\n}\n","/**\n * Impact Command\n * \n * Analyze the impact scope of changes\n */\n\nimport chalk from 'chalk';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { loadAllModels, type ModelRegistry } from '../utils/model-loader.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImpactCommandOptions {\n config?: string;\n depth?: string;\n direction?: 'upstream' | 'downstream' | 'both';\n format?: 'text' | 'json' | 'mermaid';\n}\n\nexport interface ImpactNode {\n id: string;\n type: string;\n depth: number;\n impactType: 'direct' | 'indirect';\n}\n\nexport interface ImpactResult {\n target: string;\n targetType: string;\n impactedNodes: ImpactNode[];\n}\n\n// ============================================================================\n// Impact Command\n// ============================================================================\n\nexport async function impactCommand(targetId: string, options: ImpactCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper impact'));\n console.log('');\n \n if (!targetId) {\n console.error(chalk.red('Error: ID is required'));\n console.log(chalk.gray(' Usage: speckeeper impact <id>'));\n process.exit(1);\n }\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n const maxDepth = options.depth ? parseInt(options.depth, 10) : 3;\n \n console.log(chalk.gray(` Target: ${targetId}`));\n console.log(chalk.gray(` Depth: ${maxDepth}`));\n console.log('');\n \n try {\n // Load all models\n console.log(chalk.blue(' Loading models...'));\n const { registry } = await loadAllModels(config, cwd);\n \n // Find target\n const target = findById(registry, targetId);\n if (!target) {\n console.error(chalk.red(` Error: Target '${targetId}' not found`));\n process.exit(1);\n }\n \n // Analyze impact\n console.log(chalk.blue(' Analyzing impact...'));\n const result = analyzeImpact(registry, targetId, target.type, maxDepth);\n \n // Output results\n outputImpactResults(result, options);\n \n } catch (error) {\n console.error(chalk.red('Impact analysis failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Impact Analysis\n// ============================================================================\n\nfunction findById(registry: ModelRegistry, id: string): { type: string; data: unknown } | null {\n for (const [type, map] of Object.entries(registry)) {\n if (map instanceof Map && map.has(id)) {\n return { type, data: map.get(id) };\n }\n }\n return null;\n}\n\nfunction analyzeImpact(\n registry: ModelRegistry,\n targetId: string,\n targetType: string,\n maxDepth: number\n): ImpactResult {\n const impactedNodes: ImpactNode[] = [];\n const visited = new Set<string>([targetId]);\n \n // Find references to the target\n function findReferences(id: string, depth: number): void {\n if (depth > maxDepth) return;\n \n for (const [type, map] of Object.entries(registry)) {\n if (!(map instanceof Map)) continue;\n \n for (const [itemId, item] of map) {\n if (visited.has(itemId)) continue;\n \n // Check if this item references the target\n const itemStr = JSON.stringify(item);\n if (itemStr.includes(`\"${id}\"`)) {\n visited.add(itemId);\n impactedNodes.push({\n id: itemId,\n type,\n depth,\n impactType: depth === 1 ? 'direct' : 'indirect',\n });\n \n // Recursively find references to this item\n findReferences(itemId, depth + 1);\n }\n }\n }\n }\n \n findReferences(targetId, 1);\n \n return {\n target: targetId,\n targetType,\n impactedNodes,\n };\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputImpactResults(result: ImpactResult, options: ImpactCommandOptions): void {\n console.log('');\n \n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'mermaid') {\n console.log('```mermaid');\n console.log('graph TD');\n console.log(` ${result.target}[${result.target}]`);\n for (const node of result.impactedNodes) {\n const style = node.impactType === 'direct' ? '-->|direct|' : '-.->|indirect|';\n console.log(` ${result.target} ${style} ${node.id}[${node.id}]`);\n }\n console.log('```');\n return;\n }\n \n // Default text format\n if (result.impactedNodes.length === 0) {\n console.log(chalk.green(' No impacted elements found'));\n return;\n }\n \n const direct = result.impactedNodes.filter(n => n.impactType === 'direct');\n const indirect = result.impactedNodes.filter(n => n.impactType === 'indirect');\n \n if (direct.length > 0) {\n console.log(chalk.yellow(` Direct impact (${direct.length}):`));\n for (const node of direct) {\n console.log(chalk.yellow(` → ${node.id} (${node.type})`));\n }\n }\n \n if (indirect.length > 0) {\n console.log(chalk.gray(` Indirect impact (${indirect.length}):`));\n for (const node of indirect) {\n console.log(chalk.gray(` ⤳ ${node.id} (${node.type}, depth: ${node.depth})`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Total: ${result.impactedNodes.length} impacted elements`));\n}\n","/**\n * speckeeper init command\n * \n * Generate starter templates for a new speckeeper project\n */\nimport chalk from 'chalk';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface InitOptions {\n force?: boolean;\n}\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport async function runInit(options: InitOptions = {}): Promise<void> {\n const cwd = process.cwd();\n \n console.log(chalk.cyan('speckeeper init'));\n console.log('');\n \n // Check if already initialized\n const designDir = join(cwd, 'design');\n const configFile = join(cwd, 'speckeeper.config.ts');\n \n if (!options.force && (existsSync(designDir) || existsSync(configFile))) {\n console.log(chalk.yellow(' Project already initialized.'));\n console.log(chalk.gray(' Use --force to overwrite existing files.'));\n return;\n }\n \n // Get project name from directory\n const projectName = cwd.split('/').pop() || 'my-project';\n \n // Find templates directory\n const templatesDir = join(__dirname, 'templates', 'init');\n \n if (!existsSync(templatesDir)) {\n console.log(chalk.red(` Error: Templates directory not found at ${templatesDir}`));\n console.log(chalk.gray(' Please ensure the package is properly installed.'));\n return;\n }\n \n // Copy template files\n let packageJsonCreated = false;\n copyTemplateDir(templatesDir, cwd, projectName, options.force || false, (relativePath, created) => {\n if (created) {\n console.log(chalk.green(` Created: ${relativePath}`));\n if (relativePath === 'package.json') {\n packageJsonCreated = true;\n }\n } else {\n console.log(chalk.yellow(` Skipped: ${relativePath} (already exists)`));\n }\n });\n \n console.log('');\n console.log(chalk.cyan(' Project initialized successfully!'));\n console.log('');\n console.log(' Next steps:');\n if (packageJsonCreated) {\n console.log(chalk.gray(' 1. Run `npm install` to install dependencies'));\n console.log(chalk.gray(' 2. Edit design/_models/ to customize your models'));\n console.log(chalk.gray(' 3. Add specifications in design/'));\n console.log(chalk.gray(' 4. Run `npx speckeeper lint` to validate'));\n } else {\n console.log(chalk.gray(' 1. Add speckeeper and zod to your package.json dependencies'));\n console.log(chalk.gray(' 2. Ensure \"type\": \"module\" is set in package.json'));\n console.log(chalk.gray(' 3. Edit design/_models/ to customize your models'));\n console.log(chalk.gray(' 4. Add specifications in design/'));\n console.log(chalk.gray(' 5. Run `npx speckeeper lint` to validate'));\n }\n}\n\n/**\n * Recursively copy template directory\n */\nfunction copyTemplateDir(\n srcDir: string,\n destDir: string,\n projectName: string,\n force: boolean,\n onFile: (relativePath: string, created: boolean) => void,\n relativePath: string = ''\n): void {\n const entries = readdirSync(srcDir);\n \n for (const entry of entries) {\n const srcPath = join(srcDir, entry);\n const stat = statSync(srcPath);\n \n // Handle .template extension\n const destEntry = entry.endsWith('.template') ? entry.slice(0, -9) : entry;\n const destPath = join(destDir, destEntry);\n const relPath = relativePath ? join(relativePath, destEntry) : destEntry;\n \n if (stat.isDirectory()) {\n // Create directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true });\n onFile(relPath + '/', true);\n }\n // Recurse into directory\n copyTemplateDir(srcPath, destPath, projectName, force, onFile, relPath);\n } else {\n // Skip if file exists and not force\n if (!force && existsSync(destPath)) {\n onFile(relPath, false);\n continue;\n }\n \n // Read and process template\n let content = readFileSync(srcPath, 'utf-8');\n \n // Replace template variables\n content = content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, projectName);\n \n // Write file\n const dir = dirname(destPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(destPath, content);\n onFile(relPath, true);\n }\n }\n}\n","/**\n * Mermaid flowchart parser\n *\n * Extracts nodes, edges, classDefs, and class assignments\n * from a mermaid flowchart block embedded in Markdown.\n */\nimport type {\n ArrowDirection,\n MermaidNode,\n MermaidEdge,\n MermaidClassDef,\n MermaidClassAssignment,\n ParsedFlowchart,\n} from './types.js';\n\n/**\n * Extract mermaid code blocks from Markdown content\n */\nexport function extractMermaidBlocks(markdown: string): string[] {\n const blocks: string[] = [];\n const regex = /```mermaid\\s*\\n([\\s\\S]*?)```/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(markdown)) !== null) {\n blocks.push(match[1]);\n }\n return blocks;\n}\n\n/**\n * Parse a mermaid flowchart block into structured data\n */\nexport function parseFlowchart(mermaidSource: string): ParsedFlowchart {\n const lines = mermaidSource.split('\\n');\n const nodes = new Map<string, MermaidNode>();\n const edges: MermaidEdge[] = [];\n const classDefs: MermaidClassDef[] = [];\n const classAssignments: MermaidClassAssignment[] = [];\n let direction = 'TB';\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n\n if (!line || line.startsWith('%%')) continue;\n\n const flowchartMatch = line.match(/^flowchart\\s+(\\w+)/);\n if (flowchartMatch) {\n direction = flowchartMatch[1];\n continue;\n }\n\n if (line.startsWith('graph ')) {\n const gMatch = line.match(/^graph\\s+(\\w+)/);\n if (gMatch) direction = gMatch[1];\n continue;\n }\n\n const classDefMatch = line.match(/^classDef\\s+(\\S+)\\s+(.*)/);\n if (classDefMatch) {\n classDefs.push({ name: classDefMatch[1], styles: classDefMatch[2] });\n continue;\n }\n\n const classAssignMatch = line.match(/^class\\s+(\\S+)\\s+(\\S+)/);\n if (classAssignMatch) {\n const nodeIds = classAssignMatch[1].split(',').map(s => s.trim());\n classAssignments.push({ nodeIds, className: classAssignMatch[2] });\n for (const id of nodeIds) {\n ensureNode(nodes, id);\n const node = nodes.get(id)!;\n if (!node.classes.includes(classAssignMatch[2])) {\n node.classes.push(classAssignMatch[2]);\n }\n }\n continue;\n }\n\n const edgeParsed = tryParseEdgeLine(line);\n if (edgeParsed) {\n for (const { sourceId, sourceLabel, targetId, targetLabel, label, direction: dir } of edgeParsed) {\n ensureNode(nodes, sourceId, sourceLabel);\n ensureNode(nodes, targetId, targetLabel);\n edges.push({\n sourceId,\n targetId,\n rawLabel: label,\n direction: dir,\n });\n }\n continue;\n }\n\n const standaloneNode = tryParseStandaloneNode(line);\n if (standaloneNode) {\n ensureNode(nodes, standaloneNode.id, standaloneNode.label);\n }\n }\n\n return { direction, nodes, edges, classDefs, classAssignments };\n}\n\n/**\n * Parse Markdown and return the first flowchart found\n */\nexport function parseMarkdownFlowchart(markdown: string): ParsedFlowchart | null {\n const blocks = extractMermaidBlocks(markdown);\n for (const block of blocks) {\n const trimmed = block.trim();\n if (trimmed.startsWith('flowchart') || trimmed.startsWith('graph')) {\n return parseFlowchart(trimmed);\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction ensureNode(nodes: Map<string, MermaidNode>, id: string, label?: string): void {\n const existing = nodes.get(id);\n if (existing) {\n if (label && !existing.label) {\n existing.label = label;\n }\n } else {\n nodes.set(id, { id, label, classes: [] });\n }\n}\n\n/** Node with optional label: ID[Label text] or ID */\nconst NODE_PATTERN = /([A-Za-z_]\\w*)(?:\\[([^\\]]*)\\])?/;\n\ninterface ParsedEdgeResult {\n sourceId: string;\n sourceLabel: string | undefined;\n targetId: string;\n targetLabel: string | undefined;\n label: string | undefined;\n direction: ArrowDirection;\n}\n\n/**\n * Try to parse an edge line. Returns array of edges (a line can have chained edges).\n *\n * Supported arrow patterns:\n * --> ---> ----> forward\n * <--> <---> <----> bidirectional\n * -.-> forward (dotted)\n * ==> forward (thick)\n * -->|label| forward with label\n * <-->|label| bidirectional with label\n */\nfunction tryParseEdgeLine(line: string): ParsedEdgeResult[] | null {\n // Arrow patterns, ordered longest-first to avoid partial matches\n const arrowPatterns = [\n { regex: /<-{2,}>/, direction: 'bidirectional' as ArrowDirection },\n { regex: /<={2,}>/, direction: 'bidirectional' as ArrowDirection },\n { regex: /-{2,}>/, direction: 'forward' as ArrowDirection },\n { regex: /={2,}>/, direction: 'forward' as ArrowDirection },\n { regex: /-\\.->/, direction: 'forward' as ArrowDirection },\n ];\n\n // Try to find any arrow in the line\n let bestMatch: {\n index: number;\n length: number;\n direction: ArrowDirection;\n } | null = null;\n\n for (const ap of arrowPatterns) {\n const m = line.match(ap.regex);\n if (m && m.index !== undefined) {\n if (!bestMatch || m.index < bestMatch.index) {\n bestMatch = { index: m.index, length: m[0].length, direction: ap.direction };\n }\n }\n }\n\n if (!bestMatch) return null;\n\n // Split line at the arrow\n const leftPart = line.substring(0, bestMatch.index).trim();\n const rightPart = line.substring(bestMatch.index + bestMatch.length).trim();\n\n // Extract source node from left part\n const sourceMatch = leftPart.match(NODE_PATTERN);\n if (!sourceMatch) return null;\n const sourceId = sourceMatch[1];\n const sourceLabel = sourceMatch[2] || undefined;\n\n // Right part may be: |label| TargetNode or just TargetNode\n let label: string | undefined;\n let targetStr = rightPart;\n\n const labelMatch = rightPart.match(/^\\|([^|]*)\\|\\s*(.*)/);\n if (labelMatch) {\n label = labelMatch[1].trim();\n targetStr = labelMatch[2];\n }\n\n // Extract target node\n const targetMatch = targetStr.match(NODE_PATTERN);\n if (!targetMatch) return null;\n const targetId = targetMatch[1];\n const targetLabel = targetMatch[2] || undefined;\n\n return [{\n sourceId,\n sourceLabel,\n targetId,\n targetLabel,\n label,\n direction: bestMatch.direction,\n }];\n}\n\nfunction tryParseStandaloneNode(line: string): { id: string; label: string | undefined } | null {\n const m = line.match(/^([A-Za-z_]\\w*)\\[([^\\]]*)\\]\\s*$/);\n if (m) {\n return { id: m[1], label: m[2] };\n }\n return null;\n}\n","/**\n * Edge label controlled vocabulary\n *\n * Edge labels for speckeeper-managed nodes must match speckeeper's\n * RELATION_TYPES. Labels between non-speckeeper nodes are free text.\n */\nimport type {\n EdgeVocabularyEntry,\n MermaidEdge,\n MermaidNode,\n ResolvedEdge,\n ScaffoldDiagnostic,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Vocabulary definitions\n// ---------------------------------------------------------------------------\n\n/**\n * Speckeeper-managed vocabulary — labels match RELATION_TYPES exactly.\n * Used for edges involving at least one speckeeper-managed node.\n */\nexport const EDGE_VOCABULARY: EdgeVocabularyEntry[] = [\n // A. lint targets (speckeeper ↔ speckeeper reference integrity)\n {\n label: 'refines',\n expectedDirection: 'forward',\n relationType: 'refines',\n category: 'lint',\n description: 'Decompose higher-level item into lower-level detail',\n },\n {\n label: 'relatedTo',\n expectedDirection: 'bidirectional',\n relationType: 'relatedTo',\n category: 'lint',\n description: 'Bidirectional association or consistency constraint',\n },\n {\n label: 'uses',\n expectedDirection: 'forward',\n relationType: 'uses',\n category: 'lint',\n description: 'Reference / dependency',\n },\n\n // B. check targets (speckeeper → external SSOT)\n {\n label: 'implements',\n expectedDirection: 'forward',\n relationType: 'implements',\n category: 'check',\n description: 'Realize speckeeper spec as external artifact, interface, or test',\n },\n\n // C. coverage targets\n {\n label: 'includes',\n expectedDirection: 'forward',\n relationType: 'includes',\n category: 'coverage',\n description: 'Parent contains child items',\n },\n {\n label: 'traces',\n expectedDirection: 'forward',\n relationType: 'traces',\n category: 'coverage',\n description: 'Derive target from source',\n },\n {\n label: 'verifies',\n expectedDirection: 'forward',\n relationType: 'verifies',\n category: 'coverage',\n description: 'Test verifies target',\n },\n\n // Additional RELATION_TYPES (usable but no special scaffold behaviour)\n {\n label: 'dependsOn',\n expectedDirection: 'forward',\n relationType: 'dependsOn',\n category: 'lint',\n description: 'Dependency relationship',\n },\n {\n label: 'satisfies',\n expectedDirection: 'forward',\n relationType: 'satisfies',\n category: 'lint',\n description: 'Satisfies business/requirements',\n },\n];\n\n/**\n * Well-known labels for edges between non-speckeeper nodes.\n * These are not validated — any label is accepted for external-only edges.\n * Listed here so scaffold can recognise and categorise them.\n */\nexport const EXTERNAL_LABELS: EdgeVocabularyEntry[] = [\n {\n label: 'generate',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'drift',\n description: 'Automated generation (external tool)',\n },\n {\n label: 'apply',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'external',\n description: 'Apply to external system',\n },\n {\n label: 'deploy',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'external',\n description: 'Deploy artifact',\n },\n];\n\nconst ALL_VOCABULARY = [...EDGE_VOCABULARY, ...EXTERNAL_LABELS];\n\nconst SORTED_VOCABULARY = [...ALL_VOCABULARY].sort(\n (a, b) => b.label.length - a.label.length,\n);\n\nconst SORTED_SPECKEEPER_VOCABULARY = [...EDGE_VOCABULARY].sort(\n (a, b) => b.label.length - a.label.length,\n);\n\n// ---------------------------------------------------------------------------\n// Label normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Normalise a raw edge label to its canonical vocabulary entry.\n *\n * 1. Exact match (case-insensitive)\n * 2. Label ends with a vocabulary entry (longest match wins)\n * 3. Label contains a vocabulary entry (longest match wins)\n * 4. null if no match\n */\nexport function normalizeLabel(\n rawLabel: string | undefined,\n vocabulary: EdgeVocabularyEntry[] = SORTED_VOCABULARY,\n): { entry: EdgeVocabularyEntry; modifier: string | undefined } | null {\n if (!rawLabel) return null;\n\n const lower = rawLabel.toLowerCase().trim();\n\n for (const entry of vocabulary) {\n if (lower === entry.label.toLowerCase()) {\n return { entry, modifier: undefined };\n }\n }\n\n for (const entry of vocabulary) {\n const entryLower = entry.label.toLowerCase();\n if (lower.endsWith(entryLower)) {\n const mod = rawLabel.slice(0, rawLabel.length - entry.label.length).trim();\n return { entry, modifier: mod || undefined };\n }\n }\n\n for (const entry of vocabulary) {\n const entryLower = entry.label.toLowerCase();\n if (lower.includes(entryLower)) {\n const idx = lower.indexOf(entryLower);\n const before = rawLabel.slice(0, idx).trim();\n const after = rawLabel.slice(idx + entry.label.length).trim();\n const mod = [before, after].filter(Boolean).join(' ');\n return { entry, modifier: mod || undefined };\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Edge resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve raw edges to vocabulary-backed ResolvedEdges,\n * collecting diagnostics along the way.\n */\nexport function resolveEdges(\n edges: MermaidEdge[],\n nodes: Map<string, MermaidNode>,\n speckeeperClassName: string,\n): { resolved: ResolvedEdge[]; diagnostics: ScaffoldDiagnostic[] } {\n const diagnostics: ScaffoldDiagnostic[] = [];\n const resolved: ResolvedEdge[] = [];\n\n const isSpk = (id: string): boolean =>\n nodes.get(id)?.classes.includes(speckeeperClassName) ?? false;\n\n const fallback = EDGE_VOCABULARY.find(v => v.label === 'relatedTo')!;\n\n for (const edge of edges) {\n const involvesSpeckeeper = isSpk(edge.sourceId) || isSpk(edge.targetId);\n\n // Try to normalise against the full vocabulary\n const norm = normalizeLabel(edge.rawLabel);\n\n if (!norm) {\n if (involvesSpeckeeper) {\n // Edge involves speckeeper node but label doesn't match any RelationType\n diagnostics.push({\n severity: 'warning',\n message: `Edge label \"${edge.rawLabel}\" is not a valid speckeeper RelationType — falling back to \"relatedTo\"`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n resolved.push({\n ...edge,\n normalizedLabel: 'relatedTo',\n vocabulary: fallback,\n modifier: undefined,\n });\n } else {\n // Both nodes are external — free text label, skip validation\n resolved.push({\n ...edge,\n normalizedLabel: edge.rawLabel ?? '',\n vocabulary: { label: edge.rawLabel ?? '', expectedDirection: 'forward', relationType: undefined, category: 'external', description: '' },\n modifier: undefined,\n });\n }\n continue;\n }\n\n // If the edge involves a speckeeper node, the label must be a RelationType\n if (involvesSpeckeeper && !norm.entry.relationType) {\n const spkNorm = normalizeLabel(edge.rawLabel, SORTED_SPECKEEPER_VOCABULARY);\n if (!spkNorm) {\n diagnostics.push({\n severity: 'warning',\n message: `Edge label \"${edge.rawLabel}\" is not a valid speckeeper RelationType — falling back to \"relatedTo\"`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n resolved.push({\n ...edge,\n normalizedLabel: 'relatedTo',\n vocabulary: fallback,\n modifier: undefined,\n });\n continue;\n }\n }\n\n resolved.push({\n ...edge,\n normalizedLabel: norm.entry.label,\n vocabulary: norm.entry,\n modifier: norm.modifier,\n });\n\n // Validate arrow direction (only for speckeeper-involved edges)\n if (involvesSpeckeeper && edge.direction !== norm.entry.expectedDirection) {\n const expected = norm.entry.expectedDirection === 'bidirectional' ? '<-->' : '-->';\n diagnostics.push({\n severity: 'warning',\n message: `\"${norm.entry.label}\" expects ${expected} arrow but got ${edge.direction === 'bidirectional' ? '<-->' : '-->'}`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n\n // Validate: \"implements\" should not be speckeeper → speckeeper\n if (norm.entry.label === 'implements') {\n if (isSpk(edge.sourceId) && isSpk(edge.targetId)) {\n diagnostics.push({\n severity: 'warning',\n message: '\"implements\" should be speckeeper → external; consider using \"refines\" for speckeeper → speckeeper edges',\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n }\n\n // Validate: \"includes\" and \"traces\" should be speckeeper → speckeeper\n if (norm.entry.label === 'includes' || norm.entry.label === 'traces') {\n if (!isSpk(edge.sourceId) || !isSpk(edge.targetId)) {\n diagnostics.push({\n severity: 'warning',\n message: `\"${norm.entry.label}\" should connect two speckeeper-managed nodes`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n }\n }\n\n return { resolved, diagnostics };\n}\n\n// ---------------------------------------------------------------------------\n// Category helpers\n// ---------------------------------------------------------------------------\n\nexport function isLintEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'lint';\n}\n\nexport function isCheckEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'check';\n}\n\nexport function isCoverageEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'coverage';\n}\n\nexport function isDriftEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'drift';\n}\n\n/**\n * Determine whether an \"implements\" edge should generate a coverage checker\n * (target is a test-like node) rather than an external checker.\n */\nexport function isTestLikeNode(node: MermaidNode | undefined): boolean {\n if (!node) return false;\n const id = node.id.toUpperCase();\n const testIds = ['UT', 'IT', 'DUT', 'E2ET'];\n if (testIds.includes(id)) return true;\n if (id.includes('TEST')) return true;\n const label = (node.label ?? '').toLowerCase();\n if (label.includes('テスト') || label.includes('test')) return true;\n return false;\n}\n","/**\n * Template registry\n *\n * Maps mermaid node IDs to model template names and\n * external target node IDs to checker template names.\n *\n * Rule: Node ID = ID Prefix. Multiple node IDs can map to the same\n * template file (e.g. SR/FR/NFR → requirement.ts with 3 Model classes).\n */\n\nimport type { ModelLevel } from '../core/relation.js';\n\n// ---------------------------------------------------------------------------\n// Model template metadata\n// ---------------------------------------------------------------------------\n\nexport interface ModelTemplateInfo {\n /** Template identifier */\n templateName: string;\n /** Default model level */\n defaultLevel: ModelLevel;\n /** ID prefix for spec instances (= node ID) */\n defaultIdPrefix: string;\n /** Human-readable model name (PascalCase) */\n modelName: string;\n /** kebab-case file name (without .ts) */\n fileName: string;\n}\n\n// ---------------------------------------------------------------------------\n// Node ID → template alias mapping\n// ---------------------------------------------------------------------------\n\nconst NODE_ALIAS: Record<string, string> = {\n // L0\n TERM: 'term',\n CDM: 'entity',\n // L1\n SR: 'requirement',\n FR: 'requirement',\n NFR: 'requirement',\n UC: 'usecase',\n // L2\n LDM: 'logical-entity',\n AT: 'acceptance-test',\n DT: 'data-test',\n VC: 'validation-constraint',\n};\n\n/** Metadata per template (used for the file-level info, not per-node) */\nconst TEMPLATE_META: Record<string, { level: ModelLevel; fileName: string; primaryTypeName: string }> = {\n term: { level: 'L0', fileName: 'term', primaryTypeName: 'Term' },\n entity: { level: 'L0', fileName: 'entity', primaryTypeName: 'Entity' },\n requirement: { level: 'L1', fileName: 'requirement', primaryTypeName: 'Requirement' },\n usecase: { level: 'L1', fileName: 'usecase', primaryTypeName: 'UseCase' },\n 'logical-entity': { level: 'L2', fileName: 'logical-entity', primaryTypeName: 'LogicalEntity' },\n 'acceptance-test': { level: 'L2', fileName: 'acceptance-test', primaryTypeName: 'AcceptanceTest' },\n 'data-test': { level: 'L2', fileName: 'data-test', primaryTypeName: 'DataTest' },\n 'validation-constraint': { level: 'L2', fileName: 'validation-constraint', primaryTypeName: 'ValidationConstraint' },\n};\n\n/**\n * Resolve a mermaid node ID to a model template.\n * Node ID = ID Prefix.\n * Unknown node IDs fall back to 'base' template.\n */\nexport function resolveModelTemplate(nodeId: string): ModelTemplateInfo {\n const templateName = NODE_ALIAS[nodeId];\n if (templateName) {\n const meta = TEMPLATE_META[templateName];\n return {\n templateName,\n defaultLevel: meta.level,\n defaultIdPrefix: nodeId,\n modelName: meta.primaryTypeName,\n fileName: meta.fileName,\n };\n }\n\n return {\n templateName: 'base',\n defaultLevel: 'L1',\n defaultIdPrefix: nodeId,\n modelName: toPascalCase(nodeId),\n fileName: toKebabCase(nodeId),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Checker template alias mapping\n// ---------------------------------------------------------------------------\n\nexport interface CheckerTemplateInfo {\n templateName: string;\n targetType: string;\n fileName: string;\n}\n\nconst CHECKER_ALIAS: Record<string, CheckerTemplateInfo> = {\n DDL: {\n templateName: 'ddl-checker',\n targetType: 'ddl',\n fileName: 'ddl-checker',\n },\n API: {\n templateName: 'openapi-checker',\n targetType: 'openapi',\n fileName: 'openapi-checker',\n },\n E2ET: {\n templateName: 'test-checker',\n targetType: 'test',\n fileName: 'e2e-test-checker',\n },\n UT: {\n templateName: 'test-checker',\n targetType: 'test',\n fileName: 'unit-test-checker',\n },\n DUT: {\n templateName: 'test-checker',\n targetType: 'test',\n fileName: 'data-unit-test-checker',\n },\n IT: {\n templateName: 'test-checker',\n targetType: 'test',\n fileName: 'integration-test-checker',\n },\n};\n\n/**\n * Resolve an external target node ID to a checker template.\n * Returns undefined for unknown targets (will use base-checker).\n */\nexport function resolveCheckerTemplate(targetNodeId: string): CheckerTemplateInfo | undefined {\n return CHECKER_ALIAS[targetNodeId];\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction toPascalCase(s: string): string {\n return s\n .split(/[-_]/)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join('');\n}\n\nfunction toKebabCase(s: string): string {\n return s\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[_\\s]+/g, '-')\n .toLowerCase();\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateRequirementModel(_params: ModelTemplateParams): string {\n return `/**\n * Requirement Model Definitions\n *\n * Contains SystemRequirement (SR), FunctionalRequirement (FR),\n * and NonFunctionalRequirement (NFR) models sharing the same schema.\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const AcceptanceCriteriaSchema = z.object({\n id: z.string(),\n description: z.string(),\n verificationMethod: z.enum(['test', 'review', 'demo', 'inspection']).optional(),\n});\n\nexport const RequirementSchema = z.object({\n id: z.string(),\n name: z.string().min(1),\n description: z.string(),\n type: z.enum(['functional', 'non-functional', 'constraint']),\n priority: z.enum(['must', 'should', 'could']),\n rationale: z.string().optional(),\n acceptanceCriteria: z.array(AcceptanceCriteriaSchema).min(1),\n category: z.string().optional(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type AcceptanceCriteria = z.infer<typeof AcceptanceCriteriaSchema>;\nexport type Requirement = z.input<typeof RequirementSchema>;\n\n// =============================================================================\n// Shared lint rules and exporters\n// =============================================================================\n\nconst requirementLintRules: LintRule<Requirement>[] = [\n {\n id: 'req-acceptance-not-empty',\n severity: 'error',\n message: 'Requirement must have at least one acceptance criteria',\n check: (spec) => !spec.acceptanceCriteria || spec.acceptanceCriteria.length === 0,\n },\n {\n id: 'req-acceptance-id-format',\n severity: 'warning',\n message: 'Acceptance criteria ID should follow parent requirement ID (e.g., FR-001-01)',\n check: (spec) => {\n if (!spec.acceptanceCriteria) return false;\n return spec.acceptanceCriteria.some(ac => !ac.id.startsWith(spec.id + '-'));\n },\n },\n];\n\nconst requirementExporters: Exporter<Requirement>[] = [\n {\n format: 'markdown',\n single: (spec) => {\n const lines: string[] = [];\n lines.push(\\`# \\${spec.name}\\`);\n lines.push('');\n lines.push(\\`**ID**: \\${spec.id}\\`);\n lines.push(\\`**Type**: \\${spec.type}\\`);\n lines.push(\\`**Priority**: \\${spec.priority}\\`);\n lines.push('');\n lines.push('## Description');\n lines.push('');\n lines.push(spec.description);\n lines.push('');\n lines.push('## Acceptance Criteria');\n lines.push('');\n for (const ac of spec.acceptanceCriteria) {\n lines.push(\\`- **\\${ac.id}**: \\${ac.description}\\`);\n }\n return lines.join('\\\\n');\n },\n outputDir: 'requirements',\n filename: (spec) => spec.id,\n },\n];\n\n// =============================================================================\n// Model Classes\n// =============================================================================\n\nclass SystemRequirementModel extends Model<typeof RequirementSchema> {\n readonly id = 'system-requirement';\n readonly name = 'SystemRequirement';\n readonly idPrefix = 'SR';\n readonly schema = RequirementSchema;\n readonly description = 'Defines system-level requirements';\n protected modelLevel: ModelLevel = 'L1';\n protected lintRules = requirementLintRules;\n protected exporters = requirementExporters;\n}\n\nclass FunctionalRequirementModel extends Model<typeof RequirementSchema> {\n readonly id = 'functional-requirement';\n readonly name = 'FunctionalRequirement';\n readonly idPrefix = 'FR';\n readonly schema = RequirementSchema;\n readonly description = 'Defines functional requirements';\n protected modelLevel: ModelLevel = 'L1';\n protected lintRules = requirementLintRules;\n protected exporters = requirementExporters;\n}\n\nclass NonFunctionalRequirementModel extends Model<typeof RequirementSchema> {\n readonly id = 'non-functional-requirement';\n readonly name = 'NonFunctionalRequirement';\n readonly idPrefix = 'NFR';\n readonly schema = RequirementSchema;\n readonly description = 'Defines non-functional requirements and constraints';\n protected modelLevel: ModelLevel = 'L1';\n protected lintRules = requirementLintRules;\n protected exporters = requirementExporters;\n}\n\nexport { SystemRequirementModel, FunctionalRequirementModel, NonFunctionalRequirementModel };\n`;\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateUseCaseModel(_params: ModelTemplateParams): string {\n return `/**\n * UseCase Model Definition\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const ActorSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().optional(),\n type: z.enum(['human', 'system', 'external']),\n relations: z.array(RelationSchema).optional(),\n});\n\nexport const UseCaseStepSchema = z.object({\n stepNumber: z.number(),\n type: z.enum(['user_action', 'system_response', 'alternative']),\n description: z.string(),\n});\n\nexport const UseCaseSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string(),\n actor: z.string(),\n preconditions: z.array(z.string()).optional().default([]),\n postconditions: z.array(z.string()).optional().default([]),\n mainFlow: z.array(UseCaseStepSchema),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type Actor = z.input<typeof ActorSchema>;\nexport type UseCaseStep = z.infer<typeof UseCaseStepSchema>;\nexport type UseCase = z.input<typeof UseCaseSchema>;\n\n// =============================================================================\n// Actor Model Class\n// =============================================================================\n\nclass ActorModel extends Model<typeof ActorSchema> {\n readonly id = 'actor';\n readonly name = 'Actor';\n readonly idPrefix = 'ACT';\n readonly schema = ActorSchema;\n readonly description = 'Defines actors';\n protected modelLevel: ModelLevel = 'L0';\n\n protected lintRules: LintRule<Actor>[] = [\n {\n id: 'actor-has-description',\n severity: 'warning',\n message: 'Actor should have a description',\n check: (spec) => !spec.description || spec.description.trim() === '',\n },\n ];\n\n protected exporters: Exporter<Actor>[] = [];\n}\n\n// =============================================================================\n// UseCase Model Class\n// =============================================================================\n\nclass UseCaseModel extends Model<typeof UseCaseSchema> {\n readonly id = 'usecase';\n readonly name = 'UseCase';\n readonly idPrefix = 'UC';\n readonly schema = UseCaseSchema;\n readonly description = 'Defines use cases (business flows)';\n protected modelLevel: ModelLevel = 'L1';\n\n protected lintRules: LintRule<UseCase>[] = [\n {\n id: 'usecase-has-main-flow',\n severity: 'error',\n message: 'UseCase must have a main flow',\n check: (spec) => !spec.mainFlow || spec.mainFlow.length === 0,\n },\n {\n id: 'usecase-has-actor',\n severity: 'error',\n message: 'UseCase must have an actor',\n check: (spec) => !spec.actor || spec.actor.trim() === '',\n },\n ];\n\n protected exporters: Exporter<UseCase>[] = [];\n}\n\nexport { ActorModel, UseCaseModel };\n`;\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateTermModel(_params: ModelTemplateParams): string {\n return `/**\n * Term Model Definition\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const TermSchema = z.object({\n id: z.string(),\n term: z.string(),\n definition: z.string(),\n category: z.enum(['business', 'technical', 'acronym', 'process', 'role']),\n abbreviation: z.string().optional(),\n expandedForm: z.string().optional(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type Term = z.input<typeof TermSchema>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass TermModel extends Model<typeof TermSchema> {\n readonly id = 'term';\n readonly name = 'Term';\n readonly idPrefix = 'TERM';\n readonly schema = TermSchema;\n readonly description = 'Defines terms (glossary)';\n protected modelLevel: ModelLevel = 'L0';\n\n protected lintRules: LintRule<Term>[] = [\n {\n id: 'term-has-definition',\n severity: 'error',\n message: 'Term must have a definition',\n check: (spec) => !spec.definition || spec.definition.trim() === '',\n },\n {\n id: 'term-acronym-has-expanded-form',\n severity: 'warning',\n message: 'Acronym terms should have an expanded form',\n check: (spec) => spec.category === 'acronym' && !spec.expandedForm,\n },\n ];\n\n protected exporters: Exporter<Term>[] = [];\n}\n\nexport { TermModel };\n`;\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateEntityModel(_params: ModelTemplateParams): string {\n return `/**\n * Entity Model Definition (Conceptual Data Model)\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const AttributeSchema = z.object({\n name: z.string(),\n type: z.enum(['string', 'number', 'boolean', 'date', 'datetime', 'uuid', 'enum', 'reference']),\n required: z.boolean().optional().default(true),\n description: z.string().optional(),\n});\n\nexport const EntitySchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string(),\n attributes: z.array(AttributeSchema),\n isAggregateRoot: z.boolean().optional().default(false),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type Attribute = z.infer<typeof AttributeSchema>;\nexport type Entity = z.input<typeof EntitySchema>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass ConceptualDataModel extends Model<typeof EntitySchema> {\n readonly id = 'conceptual-data-model';\n readonly name = 'ConceptualDataModel';\n readonly idPrefix = 'CDM';\n readonly schema = EntitySchema;\n readonly description = 'Defines conceptual entities (domain model)';\n protected modelLevel: ModelLevel = 'L0';\n\n protected lintRules: LintRule<Entity>[] = [\n {\n id: 'entity-has-attributes',\n severity: 'warning',\n message: 'Entity should have at least one attribute',\n check: (spec) => !spec.attributes || spec.attributes.length === 0,\n },\n ];\n\n protected exporters: Exporter<Entity>[] = [\n {\n format: 'markdown',\n single: (spec) => {\n const lines: string[] = [];\n lines.push(\\`# \\${spec.name}\\`);\n lines.push('');\n lines.push(\\`**ID**: \\${spec.id}\\`);\n lines.push('');\n lines.push(spec.description);\n lines.push('');\n lines.push('## Attributes');\n lines.push('');\n lines.push('| Name | Type | Required | Description |');\n lines.push('|------|------|----------|-------------|');\n for (const attr of spec.attributes) {\n lines.push(\\`| \\${attr.name} | \\${attr.type} | \\${attr.required ? 'Yes' : 'No'} | \\${attr.description || ''} |\\`);\n }\n return lines.join('\\\\n');\n },\n outputDir: 'data-model',\n filename: (spec) => spec.id,\n },\n ];\n}\n\nexport { ConceptualDataModel };\n`;\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateLogicalEntityModel(_params: ModelTemplateParams): string {\n return `/**\n * LogicalEntity Model Definition (Logical Data Model)\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const ColumnSchema = z.object({\n name: z.string(),\n dataType: z.string(),\n nullable: z.boolean().optional().default(false),\n primaryKey: z.boolean().optional().default(false),\n foreignKey: z.object({\n table: z.string(),\n column: z.string(),\n }).optional(),\n description: z.string().optional(),\n});\n\nexport const ConstraintSchema = z.object({\n name: z.string(),\n type: z.enum(['unique', 'check', 'foreign_key', 'index']),\n columns: z.array(z.string()),\n expression: z.string().optional(),\n});\n\nexport const LogicalEntitySchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string(),\n tableName: z.string(),\n columns: z.array(ColumnSchema).min(1),\n constraints: z.array(ConstraintSchema).optional(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type Column = z.infer<typeof ColumnSchema>;\nexport type Constraint = z.infer<typeof ConstraintSchema>;\nexport type LogicalEntity = z.input<typeof LogicalEntitySchema>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass LogicalDataModel extends Model<typeof LogicalEntitySchema> {\n readonly id = 'logical-data-model';\n readonly name = 'LogicalDataModel';\n readonly idPrefix = 'LDM';\n readonly schema = LogicalEntitySchema;\n readonly description = 'Defines logical data model entities (tables, columns, constraints)';\n protected modelLevel: ModelLevel = 'L2';\n\n protected lintRules: LintRule<LogicalEntity>[] = [\n {\n id: 'lent-has-columns',\n severity: 'error',\n message: 'LogicalEntity must have at least one column',\n check: (spec) => !spec.columns || spec.columns.length === 0,\n },\n {\n id: 'lent-has-primary-key',\n severity: 'warning',\n message: 'LogicalEntity should have at least one primary key column',\n check: (spec) => {\n if (!spec.columns) return true;\n return !spec.columns.some(c => c.primaryKey);\n },\n },\n ];\n\n protected exporters: Exporter<LogicalEntity>[] = [\n {\n format: 'markdown',\n single: (spec) => {\n const lines: string[] = [];\n lines.push(\\`# \\${spec.name}\\`);\n lines.push('');\n lines.push(\\`**ID**: \\${spec.id} \\`);\n lines.push(\\`**Table**: \\${spec.tableName}\\`);\n lines.push('');\n lines.push(spec.description);\n lines.push('');\n lines.push('## Columns');\n lines.push('');\n lines.push('| Name | Type | Nullable | PK | Description |');\n lines.push('|------|------|----------|----|-------------|');\n for (const col of spec.columns) {\n lines.push(\\`| \\${col.name} | \\${col.dataType} | \\${col.nullable ? 'Yes' : 'No'} | \\${col.primaryKey ? 'Yes' : ''} | \\${col.description || ''} |\\`);\n }\n return lines.join('\\\\n');\n },\n outputDir: 'data-model',\n filename: (spec) => spec.id,\n },\n ];\n}\n\nexport { LogicalDataModel };\n`;\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateAcceptanceTestModel(_params: ModelTemplateParams): string {\n return `/**\n * AcceptanceTest Model Definition\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const TestStepSchema = z.object({\n stepNumber: z.number(),\n action: z.string(),\n expectedResult: z.string(),\n});\n\nexport const AcceptanceTestSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string(),\n targetId: z.string(),\n testType: z.enum(['e2e', 'manual', 'review']),\n steps: z.array(TestStepSchema).optional(),\n expectedResult: z.string(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type TestStep = z.infer<typeof TestStepSchema>;\nexport type AcceptanceTest = z.input<typeof AcceptanceTestSchema>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass AcceptanceTestModel extends Model<typeof AcceptanceTestSchema> {\n readonly id = 'acceptance-test';\n readonly name = 'AcceptanceTest';\n readonly idPrefix = 'AT';\n readonly schema = AcceptanceTestSchema;\n readonly description = 'Defines acceptance test specifications';\n protected modelLevel: ModelLevel = 'L2';\n\n protected lintRules: LintRule<AcceptanceTest>[] = [\n {\n id: 'at-has-target',\n severity: 'error',\n message: 'AcceptanceTest must reference a target requirement or use case',\n check: (spec) => !spec.targetId || spec.targetId.trim() === '',\n },\n ];\n\n protected exporters: Exporter<AcceptanceTest>[] = [];\n}\n\nexport { AcceptanceTestModel };\n`;\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateDataTestModel(_params: ModelTemplateParams): string {\n return `/**\n * DataTest Model Definition\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const DataTestSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string(),\n targetEntityId: z.string(),\n ruleType: z.enum(['fk', 'unique', 'type', 'not-null']),\n condition: z.string(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type DataTest = z.input<typeof DataTestSchema>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass DataTestModel extends Model<typeof DataTestSchema> {\n readonly id = 'data-test';\n readonly name = 'DataTest';\n readonly idPrefix = 'DT';\n readonly schema = DataTestSchema;\n readonly description = 'Defines data integrity test specifications';\n protected modelLevel: ModelLevel = 'L2';\n\n protected lintRules: LintRule<DataTest>[] = [\n {\n id: 'dt-has-target-entity',\n severity: 'error',\n message: 'DataTest must reference a target entity',\n check: (spec) => !spec.targetEntityId || spec.targetEntityId.trim() === '',\n },\n ];\n\n protected exporters: Exporter<DataTest>[] = [];\n}\n\nexport { DataTestModel };\n`;\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateValidationConstraintModel(_params: ModelTemplateParams): string {\n return `/**\n * ValidationConstraint Model Definition\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const ValidationConstraintSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string(),\n targetField: z.string(),\n constraintType: z.enum(['range', 'format', 'required', 'enum', 'custom']),\n rule: z.string(),\n errorMessage: z.string().optional(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type ValidationConstraint = z.input<typeof ValidationConstraintSchema>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass ValidationConstraintModel extends Model<typeof ValidationConstraintSchema> {\n readonly id = 'validation-constraint';\n readonly name = 'ValidationConstraint';\n readonly idPrefix = 'VC';\n readonly schema = ValidationConstraintSchema;\n readonly description = 'Defines validation constraints (input rules, boundary values, formats)';\n protected modelLevel: ModelLevel = 'L2';\n\n protected lintRules: LintRule<ValidationConstraint>[] = [\n {\n id: 'vc-has-rule',\n severity: 'error',\n message: 'ValidationConstraint must have a rule definition',\n check: (spec) => !spec.rule || spec.rule.trim() === '',\n },\n ];\n\n protected exporters: Exporter<ValidationConstraint>[] = [];\n}\n\nexport { ValidationConstraintModel };\n`;\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateBaseModel(params: ModelTemplateParams): string {\n const schemaName = `${params.modelName}Schema`;\n const className = `${params.modelName}Model`;\n\n return `/**\n * ${params.modelName} Model Definition\n *\n * Generated by speckeeper scaffold — customise as needed.\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const ${schemaName} = z.object({\n id: z.string(),\n name: z.string().min(1),\n description: z.string(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type ${params.modelName} = z.input<typeof ${schemaName}>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass ${className} extends Model<typeof ${schemaName}> {\n readonly id = '${params.modelId}';\n readonly name = '${params.modelName}';\n readonly idPrefix = '${params.idPrefix}';\n readonly schema = ${schemaName};\n readonly description = '${params.description}';\n // TODO: adjust modelLevel\n protected modelLevel: ModelLevel = '${params.level}';\n\n protected lintRules: LintRule<${params.modelName}>[] = [\n {\n id: '${params.modelId}-has-description',\n severity: 'warning',\n message: '${params.modelName} should have a description',\n check: (spec) => !spec.description || spec.description.trim() === '',\n },\n ];\n\n protected exporters: Exporter<${params.modelName}>[] = [];\n}\n\nexport { ${className} };\n`;\n}\n","import type { CheckerTemplateParams } from '../types.js';\n\nexport function generateDdlChecker(_params: CheckerTemplateParams): string {\n return `import { readFileSync, existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { ExternalChecker, CheckResult } from 'speckeeper';\nimport type { LogicalEntity } from '../_models/logical-entity.ts';\n\n/**\n * DDL Checker: verifies that logical entity definitions\n * have corresponding tables/columns in schema.sql.\n */\nexport const ddlChecker: ExternalChecker<LogicalEntity> = {\n targetType: 'ddl',\n\n sourcePath: () => resolve('..', 'db', 'schema.sql'),\n\n check: (spec, _externalData): CheckResult => {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n\n const schemaPath = resolve('..', 'db', 'schema.sql');\n if (!existsSync(schemaPath)) {\n warnings.push({\n message: \\`schema.sql not found: \\${schemaPath}\\`,\n specId: spec.id,\n });\n return { success: true, errors, warnings };\n }\n\n const _schemaSql = readFileSync(schemaPath, 'utf-8');\n\n // TODO: implement table/column existence check\n warnings.push({\n message: \\`DDL checker not fully implemented for \\${spec.id} — add table/column verification logic\\`,\n specId: spec.id,\n });\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n };\n },\n};\n`;\n}\n","import type { CheckerTemplateParams } from '../types.js';\n\nexport function generateOpenapiChecker(_params: CheckerTemplateParams): string {\n return `import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { ExternalChecker, CheckResult } from 'speckeeper';\nimport type { UseCase } from '../_models/usecase.ts';\n\n/**\n * OpenAPI Checker: verifies that use cases have corresponding\n * endpoint definitions in the OpenAPI spec.\n */\nexport const openapiChecker: ExternalChecker<UseCase> = {\n targetType: 'openapi',\n\n sourcePath: () => resolve('..', 'api', 'spec'),\n\n check: (spec, _externalData): CheckResult => {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n\n const specDir = resolve('..', 'api', 'spec');\n if (!existsSync(specDir)) {\n warnings.push({\n message: \\`OpenAPI spec directory not found: \\${specDir}\\`,\n specId: spec.id,\n });\n return { success: true, errors, warnings };\n }\n\n // TODO: implement endpoint existence check\n warnings.push({\n message: \\`OpenAPI checker not fully implemented for \\${spec.id} — add endpoint verification logic\\`,\n specId: spec.id,\n });\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n };\n },\n};\n`;\n}\n","import type { CheckerTemplateParams } from '../types.js';\n\nexport function generateTestChecker(params: CheckerTemplateParams): string {\n return `import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { glob } from 'glob';\nimport type { ExternalChecker, CheckResult } from 'speckeeper';\nimport type { ${params.sourceModelName} } from '../_models/${params.sourceModelFile}.ts';\n\n/**\n * Test Checker: verifies that ${params.sourceModelName} items have\n * corresponding test code that exists and references the spec ID.\n *\n * Checks:\n * 1. Test file(s) exist at the expected path\n * 2. Test file content references the spec ID (in describe/it/test blocks or embedoc markers)\n */\nexport const ${toCamelCase(params.checkerName)}: ExternalChecker<${params.sourceModelName}> = {\n targetType: '${params.targetType}',\n\n sourcePath: () => '.',\n\n check: (spec, _externalData): CheckResult => {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n const basePath = process.cwd();\n\n // TODO: configure test file path pattern per spec\n // For now, search common test directories\n const testPatterns = [\n 'test/**/*.test.ts',\n 'test/**/*.spec.ts',\n 'tests/**/*.test.ts',\n 'tests/**/*.spec.ts',\n ];\n\n let testFiles: string[] = [];\n for (const pattern of testPatterns) {\n testFiles = testFiles.concat(glob.sync(pattern, { cwd: basePath }));\n }\n\n if (testFiles.length === 0) {\n warnings.push({\n message: \\`No test files found for \\${spec.id}\\`,\n specId: spec.id,\n });\n return { success: true, errors, warnings };\n }\n\n // Check if spec ID is referenced in any test file\n let specIdFound = false;\n for (const testFile of testFiles) {\n const fullPath = join(basePath, testFile);\n try {\n const content = readFileSync(fullPath, 'utf-8');\n const patterns = [\n new RegExp(\\`describe\\\\\\\\s*\\\\\\\\(\\\\\\\\s*['\\\\\\`\"].*\\${spec.id}\\`, 'm'),\n new RegExp(\\`it\\\\\\\\s*\\\\\\\\(\\\\\\\\s*['\\\\\\`\"].*\\${spec.id}\\`, 'm'),\n new RegExp(\\`test\\\\\\\\s*\\\\\\\\(\\\\\\\\s*['\\\\\\`\"].*\\${spec.id}\\`, 'm'),\n new RegExp(\\`@embedoc.*\\${spec.id}\\`, 'm'),\n ];\n if (patterns.some(p => p.test(content))) {\n specIdFound = true;\n break;\n }\n } catch {\n // skip unreadable files\n }\n }\n\n if (!specIdFound) {\n warnings.push({\n message: \\`Spec ID \"\\${spec.id}\" not found in any test file — test should reference the spec ID in describe/it/test or embedoc marker\\`,\n specId: spec.id,\n });\n }\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n };\n },\n};\n`;\n}\n\nfunction toCamelCase(s: string): string {\n return s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n}\n","import type { CheckerTemplateParams } from '../types.js';\n\nexport function generateBaseChecker(params: CheckerTemplateParams): string {\n return `import type { ExternalChecker, CheckResult } from 'speckeeper';\nimport type { ${params.sourceModelName} } from '../_models/${params.sourceModelFile}.ts';\n\n/**\n * ${params.checkerName}: verifies ${params.sourceModelName} against external ${params.targetType} artifacts.\n *\n * Generated by speckeeper scaffold — implement check logic.\n */\nexport const ${toCamelCase(params.checkerName)}: ExternalChecker<${params.sourceModelName}> = {\n targetType: '${params.targetType}',\n\n sourcePath: () => '.',\n\n check: (spec, _externalData): CheckResult => {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n\n // TODO: implement check logic for ${params.targetType}\n warnings.push({\n message: \\`${params.checkerName} not implemented for \\${spec.id}\\`,\n specId: spec.id,\n });\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n };\n },\n};\n`;\n}\n\nfunction toCamelCase(s: string): string {\n return s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n}\n","/**\n * Template registry — maps template names to generator functions\n */\nimport type { ModelTemplateParams, CheckerTemplateParams } from './types.js';\n\nimport { generateRequirementModel } from './requirement.js';\nimport { generateUseCaseModel } from './usecase.js';\nimport { generateTermModel } from './term.js';\nimport { generateEntityModel } from './entity.js';\nimport { generateLogicalEntityModel } from './logical-entity.js';\nimport { generateAcceptanceTestModel } from './acceptance-test.js';\nimport { generateDataTestModel } from './data-test.js';\nimport { generateValidationConstraintModel } from './validation-constraint.js';\nimport { generateBaseModel } from './base.js';\n\nimport { generateDdlChecker } from './checkers/ddl-checker.js';\nimport { generateOpenapiChecker } from './checkers/openapi-checker.js';\nimport { generateTestChecker } from './checkers/test-checker.js';\nimport { generateBaseChecker } from './checkers/base-checker.js';\n\nexport type ModelTemplateFunction = (params: ModelTemplateParams) => string;\nexport type CheckerTemplateFunction = (params: CheckerTemplateParams) => string;\n\nexport const MODEL_TEMPLATE_FUNCTIONS: Record<string, ModelTemplateFunction> = {\n requirement: generateRequirementModel,\n usecase: generateUseCaseModel,\n term: generateTermModel,\n entity: generateEntityModel,\n 'logical-entity': generateLogicalEntityModel,\n 'acceptance-test': generateAcceptanceTestModel,\n 'data-test': generateDataTestModel,\n 'validation-constraint': generateValidationConstraintModel,\n base: generateBaseModel,\n};\n\nexport const CHECKER_TEMPLATE_FUNCTIONS: Record<string, CheckerTemplateFunction> = {\n 'ddl-checker': generateDdlChecker,\n 'openapi-checker': generateOpenapiChecker,\n 'test-checker': generateTestChecker,\n 'base-checker': generateBaseChecker,\n};\n","/**\n * Model file generator\n *\n * Generates _models/*.ts files for speckeeper-managed nodes\n * by looking up the appropriate template.\n */\nimport type {\n MermaidNode,\n ResolvedEdge,\n GeneratedFile,\n} from './types.js';\nimport { resolveModelTemplate } from './template-registry.js';\nimport { MODEL_TEMPLATE_FUNCTIONS } from './templates/index.js';\n\n/**\n * Generate _models/*.ts file for a single speckeeper-managed node.\n *\n * @param node - The mermaid node\n * @param incomingEdges - Edges pointing to this node\n * @param outgoingEdges - Edges from this node\n * @returns GeneratedFile or null if no template matches\n */\nexport function generateModelFile(\n node: MermaidNode,\n _incomingEdges: ResolvedEdge[],\n _outgoingEdges: ResolvedEdge[],\n): GeneratedFile {\n const templateInfo = resolveModelTemplate(node.id);\n const templateFn = MODEL_TEMPLATE_FUNCTIONS[templateInfo.templateName];\n\n if (!templateFn) {\n const baseFn = MODEL_TEMPLATE_FUNCTIONS['base'];\n return {\n relativePath: `_models/${templateInfo.fileName}.ts`,\n content: baseFn({\n modelId: templateInfo.fileName,\n modelName: templateInfo.modelName,\n idPrefix: templateInfo.defaultIdPrefix,\n level: templateInfo.defaultLevel,\n description: node.label ?? node.id,\n }),\n };\n }\n\n const content = templateFn({\n modelId: templateInfo.fileName,\n modelName: templateInfo.modelName,\n idPrefix: templateInfo.defaultIdPrefix,\n level: templateInfo.defaultLevel,\n description: node.label ?? node.id,\n });\n\n return {\n relativePath: `_models/${templateInfo.fileName}.ts`,\n content,\n };\n}\n\n/**\n * Generate an empty spec data file with register() call pre-wired.\n */\nexport function generateSpecDataFile(\n node: MermaidNode,\n): GeneratedFile {\n const templateInfo = resolveModelTemplate(node.id);\n const className = `${templateInfo.modelName}Model`;\n const typeName = templateInfo.modelName;\n const varName = toCamelCase(templateInfo.modelName) + 's';\n const fileName = templateInfo.fileName;\n\n const content = `/**\n * ${templateInfo.modelName} Specifications\n *\n * Generated by speckeeper scaffold — add your specs below.\n */\nimport type { ${typeName} } from './_models/${fileName}';\nimport { ${className} } from './_models/${fileName}';\n\nexport const ${varName}: ${typeName}[] = [\n // { id: '${templateInfo.defaultIdPrefix}-001', name: '...', description: '...' },\n];\n\n${className}.instance.register(${varName});\n`;\n\n return {\n relativePath: `${fileName}.ts`,\n content,\n };\n}\n\nfunction toCamelCase(pascalCase: string): string {\n return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);\n}\n\n/**\n * Generate all model files for speckeeper-managed nodes.\n *\n * Multiple nodes may map to the same template (e.g. SR, FR, NFR → requirement).\n * In that case, only one file is generated (de-duplicated by template name).\n * Also generates a corresponding empty spec data file for each model.\n */\nexport function generateAllModelFiles(\n speckeeperNodes: MermaidNode[],\n resolvedEdges: ResolvedEdge[],\n): GeneratedFile[] {\n const files: GeneratedFile[] = [];\n const generated = new Set<string>();\n\n for (const node of speckeeperNodes) {\n const templateInfo = resolveModelTemplate(node.id);\n const key = templateInfo.templateName === 'base'\n ? `base:${node.id}`\n : templateInfo.templateName;\n\n if (generated.has(key)) continue;\n generated.add(key);\n\n const incoming = resolvedEdges.filter(e => e.targetId === node.id);\n const outgoing = resolvedEdges.filter(e => e.sourceId === node.id);\n files.push(generateModelFile(node, incoming, outgoing));\n files.push(generateSpecDataFile(node));\n }\n\n return files;\n}\n","/**\n * Checker file generator\n *\n * Generates _checkers/*.ts files for edges from speckeeper-managed nodes\n * to external (non-speckeeper) nodes that require ExternalChecker.\n */\nimport type {\n MermaidNode,\n ResolvedEdge,\n GeneratedFile,\n} from './types.js';\nimport { isCheckEdge } from './edge-vocabulary.js';\nimport { resolveModelTemplate, resolveCheckerTemplate } from './template-registry.js';\nimport { CHECKER_TEMPLATE_FUNCTIONS } from './templates/index.js';\n\n/**\n * Determine which edges need checker generation.\n *\n * An edge qualifies if:\n * 1. Its vocabulary category is 'check' (implements)\n * 2. The source is speckeeper-managed and target is external\n *\n * For test-like targets, a test-checker is generated (verifies test file\n * existence and spec ID references). For artifact targets, an ExternalChecker\n * is generated.\n */\nexport function findCheckerEdges(\n resolvedEdges: ResolvedEdge[],\n nodes: Map<string, MermaidNode>,\n speckeeperClassName: string,\n): ResolvedEdge[] {\n const isSpk = (id: string): boolean =>\n nodes.get(id)?.classes.includes(speckeeperClassName) ?? false;\n\n return resolvedEdges.filter(edge => {\n if (!isCheckEdge(edge.vocabulary)) return false;\n if (!isSpk(edge.sourceId)) return false;\n if (isSpk(edge.targetId)) return false;\n return true;\n });\n}\n\n/**\n * Generate _checkers/*.ts for a single checker edge.\n */\nexport function generateCheckerFile(\n edge: ResolvedEdge,\n _nodes: Map<string, MermaidNode>,\n): GeneratedFile {\n const checkerInfo = resolveCheckerTemplate(edge.targetId);\n const sourceTemplateInfo = resolveModelTemplate(edge.sourceId);\n\n if (checkerInfo) {\n const templateFn = CHECKER_TEMPLATE_FUNCTIONS[checkerInfo.templateName];\n if (templateFn) {\n return {\n relativePath: `_checkers/${checkerInfo.fileName}.ts`,\n content: templateFn({\n checkerName: checkerInfo.fileName,\n targetType: checkerInfo.targetType,\n sourceModelName: sourceTemplateInfo.modelName,\n sourceModelFile: sourceTemplateInfo.fileName,\n description: `Checks ${sourceTemplateInfo.modelName} against ${edge.targetId}`,\n }),\n };\n }\n }\n\n const baseFn = CHECKER_TEMPLATE_FUNCTIONS['base-checker'];\n const targetId = edge.targetId.toLowerCase();\n const fileName = `${targetId}-checker`;\n\n return {\n relativePath: `_checkers/${fileName}.ts`,\n content: baseFn({\n checkerName: fileName,\n targetType: targetId,\n sourceModelName: sourceTemplateInfo.modelName,\n sourceModelFile: sourceTemplateInfo.fileName,\n description: `Checks ${sourceTemplateInfo.modelName} against ${edge.targetId}`,\n }),\n };\n}\n\n/**\n * Generate all checker files.\n * De-duplicates by target node ID (multiple edges to the same target → one checker).\n */\nexport function generateAllCheckerFiles(\n resolvedEdges: ResolvedEdge[],\n nodes: Map<string, MermaidNode>,\n speckeeperClassName: string,\n): GeneratedFile[] {\n const checkerEdges = findCheckerEdges(resolvedEdges, nodes, speckeeperClassName);\n const files: GeneratedFile[] = [];\n const generated = new Set<string>();\n\n for (const edge of checkerEdges) {\n if (generated.has(edge.targetId)) continue;\n generated.add(edge.targetId);\n files.push(generateCheckerFile(edge, nodes));\n }\n\n return files;\n}\n","/**\n * Index file generator\n *\n * Generates _models/index.ts that re-exports all model classes\n * and provides an allModels array.\n */\nimport type { GeneratedFile } from './types.js';\n\ninterface ModelExportEntry {\n /** File name without .ts (e.g. 'requirement') */\n fileName: string;\n /** Class names to export (e.g. ['RequirementModel']) */\n classNames: string[];\n}\n\n/**\n * Derive model class names from generated model file content.\n *\n * Looks for `export { ClassName }` or `export { A, B }` at end of file.\n */\nfunction extractExportedClassNames(content: string): string[] {\n const match = content.match(/export\\s*\\{([^}]+)\\}\\s*;?\\s*$/m);\n if (!match) return [];\n return match[1].split(',').map(s => s.trim()).filter(Boolean);\n}\n\n/**\n * Generate _models/index.ts from a list of generated model files.\n */\nexport function generateModelsIndex(modelFiles: GeneratedFile[]): GeneratedFile {\n const entries: ModelExportEntry[] = [];\n\n for (const file of modelFiles) {\n const fileName = file.relativePath\n .replace(/^_models\\//, '')\n .replace(/\\.ts$/, '');\n const classNames = extractExportedClassNames(file.content);\n if (classNames.length > 0) {\n entries.push({ fileName, classNames });\n }\n }\n\n entries.sort((a, b) => a.fileName.localeCompare(b.fileName));\n\n const lines: string[] = [];\n lines.push('/**');\n lines.push(' * Model index — generated by speckeeper scaffold');\n lines.push(' */');\n lines.push('');\n\n for (const entry of entries) {\n lines.push(`export { ${entry.classNames.join(', ')} } from './${entry.fileName}.js';`);\n }\n\n lines.push('');\n\n const modelInstanceNames = entries.flatMap(e =>\n e.classNames.filter(n => n.endsWith('Model')),\n );\n\n if (modelInstanceNames.length > 0) {\n lines.push('import { Model } from \\'speckeeper\\';');\n lines.push('import type { ZodType } from \\'zod\\';');\n lines.push('');\n\n for (const entry of entries) {\n const models = entry.classNames.filter(n => n.endsWith('Model'));\n if (models.length > 0) {\n lines.push(`import { ${models.join(', ')} } from './${entry.fileName}.js';`);\n }\n }\n\n lines.push('');\n lines.push('// eslint-disable-next-line @typescript-eslint/no-explicit-any');\n lines.push('export const allModels: Model<ZodType>[] = [');\n\n for (const name of modelInstanceNames) {\n lines.push(` ${name}.instance as Model<ZodType>,`);\n }\n\n lines.push('];');\n }\n\n lines.push('');\n\n return {\n relativePath: '_models/index.ts',\n content: lines.join('\\n'),\n };\n}\n","/**\n * Scaffold Command\n *\n * Generate _models/ and _checkers/ from a mermaid flowchart definition.\n */\nimport chalk from 'chalk';\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, dirname, resolve } from 'node:path';\nimport { parseMarkdownFlowchart } from '../scaffold/mermaid-parser.js';\nimport { resolveEdges } from '../scaffold/edge-vocabulary.js';\nimport { generateAllModelFiles } from '../scaffold/model-generator.js';\nimport { generateAllCheckerFiles } from '../scaffold/checker-generator.js';\nimport { generateModelsIndex } from '../scaffold/index-generator.js';\nimport type { GeneratedFile, MermaidNode, ScaffoldDiagnostic } from '../scaffold/types.js';\n\nconst SPECKEEPER_CLASS = 'speckeeper';\n\nexport interface ScaffoldCommandOptions {\n source: string;\n output?: string;\n force?: boolean;\n dryRun?: boolean;\n}\n\nexport async function scaffoldCommand(options: ScaffoldCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper scaffold'));\n console.log('');\n\n // 1. Read source file\n const sourcePath = resolve(options.source);\n if (!existsSync(sourcePath)) {\n console.error(chalk.red(` Error: Source file not found: ${sourcePath}`));\n process.exit(1);\n }\n\n const markdown = readFileSync(sourcePath, 'utf-8');\n\n // 2. Parse mermaid flowchart\n const flowchart = parseMarkdownFlowchart(markdown);\n if (!flowchart) {\n console.error(chalk.red(' Error: No mermaid flowchart found in the source file'));\n process.exit(1);\n }\n\n console.log(chalk.gray(` Parsed: ${flowchart.nodes.size} nodes, ${flowchart.edges.length} edges`));\n\n // 3. Identify speckeeper-managed nodes\n const speckeeperNodes: MermaidNode[] = [];\n for (const node of flowchart.nodes.values()) {\n if (node.classes.includes(SPECKEEPER_CLASS)) {\n speckeeperNodes.push(node);\n }\n }\n\n if (speckeeperNodes.length === 0) {\n console.error(chalk.red(` Error: No nodes with class \"${SPECKEEPER_CLASS}\" found`));\n console.log(chalk.gray(' Add `classDef speckeeper ...` and `class NODE1,NODE2 speckeeper` to your flowchart'));\n process.exit(1);\n }\n\n console.log(chalk.gray(` speckeeper-managed nodes: ${speckeeperNodes.map(n => n.id).join(', ')}`));\n\n // 4. Resolve edges with vocabulary\n const { resolved, diagnostics } = resolveEdges(\n flowchart.edges,\n flowchart.nodes,\n SPECKEEPER_CLASS,\n );\n\n // 5. Report diagnostics\n printDiagnostics(diagnostics);\n\n // 6. Generate files\n const outputDir = options.output\n ? resolve(options.output)\n : join(process.cwd(), 'design');\n\n const modelFiles = generateAllModelFiles(speckeeperNodes, resolved);\n const checkerFiles = generateAllCheckerFiles(resolved, flowchart.nodes, SPECKEEPER_CLASS);\n const indexFile = generateModelsIndex(modelFiles);\n\n const allFiles: GeneratedFile[] = [...modelFiles, indexFile, ...checkerFiles];\n\n console.log('');\n console.log(chalk.cyan(` Files to generate (${allFiles.length}):`));\n for (const file of allFiles) {\n console.log(chalk.gray(` ${file.relativePath}`));\n }\n\n // 7. Write or dry-run\n if (options.dryRun) {\n console.log('');\n console.log(chalk.yellow(' Dry run — no files written'));\n console.log('');\n for (const file of allFiles) {\n console.log(chalk.cyan(` === ${file.relativePath} ===`));\n console.log(file.content);\n }\n return;\n }\n\n console.log('');\n let created = 0;\n let skipped = 0;\n\n for (const file of allFiles) {\n const fullPath = join(outputDir, file.relativePath);\n const dir = dirname(fullPath);\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n if (existsSync(fullPath) && !options.force) {\n console.log(chalk.yellow(` Skipped: ${file.relativePath} (already exists, use --force to overwrite)`));\n skipped++;\n continue;\n }\n\n writeFileSync(fullPath, file.content);\n console.log(chalk.green(` Created: ${file.relativePath}`));\n created++;\n }\n\n console.log('');\n console.log(chalk.cyan(` Done: ${created} created, ${skipped} skipped`));\n}\n\nfunction printDiagnostics(diagnostics: ScaffoldDiagnostic[]): void {\n if (diagnostics.length === 0) return;\n\n console.log('');\n console.log(chalk.cyan(' Diagnostics:'));\n\n for (const diag of diagnostics) {\n const prefix = diag.severity === 'error'\n ? chalk.red(' ERROR')\n : diag.severity === 'warning'\n ? chalk.yellow(' WARN ')\n : chalk.gray(' INFO ');\n const ctx = diag.context ? chalk.gray(` [${diag.context}]`) : '';\n console.log(`${prefix} ${diag.message}${ctx}`);\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { buildCommand } from './build.js';\nimport { lintCommand } from './lint.js';\nimport { driftCommand } from './drift.js';\nimport { checkCommand } from './check.js';\nimport { newCommand } from './new.js';\nimport { impactCommand } from './impact.js';\nimport { runInit } from './init.js';\nimport { scaffoldCommand } from './scaffold.js';\n\nconst program = new Command();\n\nprogram\n .name('speckeeper')\n .description('Requirements and design management framework with TypeScript DSL')\n .version('0.1.0');\n\n// Build command\n// Spec: design/cli-commands.ts CMD-BUILD\nprogram\n .command('build')\n .description('Generate docs/ and specs/ from TypeScript models')\n .option('-c, --config <path>', 'Path to config file')\n .option('-o, --output <path>', 'Base output directory path', '.')\n .option('-f, --format <format>', 'Output format: markdown, json, both', 'both')\n .option('-w, --watch', 'Watch for changes and auto-regenerate')\n .option('-v, --verbose', 'Show detailed output')\n .action(buildCommand);\n\n// Lint command\n// Spec: design/cli-commands.ts CMD-LINT\nprogram\n .command('lint')\n .description('Check design integrity (ID duplicates, references, layer violations, etc.)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-p, --phase <phase>', 'Phase gate to check against (REQ, HLD, LLD, OPS)')\n .option('-s, --strict', 'Treat warnings as errors')\n .option('--fix', 'Attempt to fix auto-fixable issues')\n .option('-f, --format <format>', 'Output format: text, json, github', 'text')\n .action(lintCommand);\n\n// Drift command\n// Spec: design/cli-commands.ts CMD-DRIFT\nprogram\n .command('drift')\n .description('Check if generated files have been manually edited')\n .option('-c, --config <path>', 'Path to config file')\n .option('-u, --update', 'Auto-update if differences are found')\n .option('-f, --format <format>', 'Output format: text, json, diff', 'text')\n .action(driftCommand);\n\n// Check command\n// Spec: design/cli-commands.ts CMD-CHECK\nprogram\n .command('check')\n .description('Check external SSOT conformance (including custom models)')\n .argument('[type]', 'Type of check: external-ssot, openapi, ddl, iac, custom, all, test')\n .option('-c, --config <path>', 'Path to config file')\n .option('--strict', 'Treat warnings as errors')\n .option('-v, --verbose', 'Show detailed output')\n .option('--coverage', 'Check if all testable acceptance criteria are covered by TestRefs')\n .action(checkCommand);\n\n// New command\n// Spec: design/cli-commands.ts CMD-NEW\nprogram\n .command('new')\n .description('Create a new element with auto-generated ID')\n .argument('<type>', 'Type: requirement, usecase, entity, component, screen, flow, error-case, term')\n .option('-k, --kind <kind>', 'Sub-kind (e.g., functional, non-functional for requirements)')\n .option('-n, --name <name>', 'Name of the element')\n .option('-o, --output <path>', 'Output directory path')\n .option('-t, --template <path>', 'Path to template file')\n .action(newCommand);\n\n// Impact command\n// Spec: design/cli-commands.ts CMD-IMPACT\nprogram\n .command('impact')\n .description('Analyze impact of changes to an ID')\n .argument('<id>', 'ID to analyze (e.g., REQ-001, ENT-ORDER)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-d, --depth <depth>', 'Analysis depth (reference tracking level)', '3')\n .option('--direction <direction>', 'Analysis direction: upstream, downstream, both', 'both')\n .option('-f, --format <format>', 'Output format: text, json, mermaid', 'text')\n .action(impactCommand);\n\n// Init command\nprogram\n .command('init')\n .description('Initialize a new speckeeper project with starter templates')\n .option('-f, --force', 'Overwrite existing files')\n .action(runInit);\n\n// Scaffold command\nprogram\n .command('scaffold')\n .description('Generate _models/ and _checkers/ from a mermaid flowchart definition')\n .requiredOption('-s, --source <path>', 'Path to Markdown file containing mermaid flowchart')\n .option('-o, --output <path>', 'Output directory (default: design/)')\n .option('-f, --force', 'Overwrite existing files')\n .option('--dry-run', 'Preview generated files without writing')\n .action(scaffoldCommand);\n\n// Parse arguments\nprogram.parse();\n"]}