@lssm/bundle.contractspec-workspace 0.0.0-canary-20251217060834 → 0.0.0-canary-20251217072406

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.
Files changed (269) hide show
  1. package/dist/_virtual/rolldown_runtime.js +22 -1
  2. package/dist/adapters/ai.js +82 -1
  3. package/dist/adapters/factory.js +36 -1
  4. package/dist/adapters/fs.js +118 -1
  5. package/dist/adapters/git.js +54 -1
  6. package/dist/adapters/index.js +7 -1
  7. package/dist/adapters/logger.js +80 -1
  8. package/dist/adapters/watcher.js +69 -1
  9. package/dist/adapters/workspace.js +190 -2
  10. package/dist/ai/agents/claude-code-agent.js +146 -9
  11. package/dist/ai/agents/cursor-agent.js +286 -17
  12. package/dist/ai/agents/index.js +5 -1
  13. package/dist/ai/agents/openai-codex-agent.js +140 -8
  14. package/dist/ai/agents/orchestrator.js +142 -1
  15. package/dist/ai/agents/simple-agent.js +80 -4
  16. package/dist/ai/client.js +162 -1
  17. package/dist/ai/index.js +27 -1
  18. package/dist/ai/prompts/code-generation.js +55 -13
  19. package/dist/ai/prompts/index.js +12 -1
  20. package/dist/ai/prompts/spec-creation.js +61 -20
  21. package/dist/ai/providers.js +40 -1
  22. package/dist/formatters/index.js +18 -1
  23. package/dist/formatters/json.js +71 -1
  24. package/dist/formatters/sarif.js +163 -1
  25. package/dist/formatters/text.js +208 -2
  26. package/dist/index.d.ts +0 -3
  27. package/dist/index.js +81 -1
  28. package/dist/libs/ai-providers/dist/factory.js +154 -0
  29. package/dist/libs/ai-providers/dist/index.js +4 -0
  30. package/dist/libs/ai-providers/dist/legacy.js +72 -0
  31. package/dist/libs/ai-providers/dist/models.js +287 -0
  32. package/dist/libs/ai-providers/dist/validation.js +1 -0
  33. package/dist/libs/contracts/dist/capabilities/openbanking.js +88 -0
  34. package/dist/libs/contracts/dist/client/index.js +5 -0
  35. package/dist/libs/contracts/dist/client/react/feature-render.js +2 -0
  36. package/dist/libs/contracts/dist/client/react/form-render.js +4 -0
  37. package/dist/libs/contracts/dist/client/react/index.js +4 -0
  38. package/dist/libs/contracts/dist/contract-registry/index.js +1 -0
  39. package/dist/libs/contracts/dist/contract-registry/schemas.js +60 -0
  40. package/dist/libs/contracts/dist/docs/PUBLISHING.docblock.js +16 -0
  41. package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js +16 -0
  42. package/dist/libs/contracts/dist/docs/index.js +29 -0
  43. package/dist/libs/contracts/dist/docs/presentations.js +71 -0
  44. package/dist/libs/contracts/dist/docs/registry.js +44 -0
  45. package/dist/libs/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +16 -0
  46. package/dist/libs/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +16 -0
  47. package/dist/libs/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +16 -0
  48. package/dist/libs/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +16 -0
  49. package/dist/libs/contracts/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +16 -0
  50. package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js +80 -0
  51. package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js +57 -0
  52. package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js +16 -0
  53. package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js +357 -0
  54. package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js +37 -0
  55. package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js +16 -0
  56. package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js +20 -0
  57. package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js +48 -0
  58. package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js +79 -0
  59. package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js +84 -0
  60. package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js +45 -0
  61. package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js +67 -0
  62. package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js +40 -0
  63. package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js +69 -0
  64. package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js +47 -0
  65. package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js +62 -0
  66. package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js +155 -0
  67. package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js +20 -0
  68. package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js +101 -0
  69. package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js +20 -0
  70. package/dist/libs/contracts/dist/events.js +8 -0
  71. package/dist/libs/contracts/dist/experiments/evaluator.js +1 -0
  72. package/dist/libs/contracts/dist/index.js +72 -0
  73. package/dist/libs/contracts/dist/install.js +2 -0
  74. package/dist/libs/contracts/dist/integrations/contracts.js +377 -0
  75. package/dist/libs/contracts/dist/integrations/index.js +18 -0
  76. package/dist/libs/contracts/dist/integrations/openbanking/contracts/accounts.js +228 -0
  77. package/dist/libs/contracts/dist/integrations/openbanking/contracts/balances.js +159 -0
  78. package/dist/libs/contracts/dist/integrations/openbanking/contracts/index.js +3 -0
  79. package/dist/libs/contracts/dist/integrations/openbanking/contracts/transactions.js +210 -0
  80. package/dist/libs/contracts/dist/integrations/openbanking/models.js +242 -0
  81. package/dist/libs/contracts/dist/integrations/openbanking/telemetry.js +13 -0
  82. package/dist/libs/contracts/dist/integrations/providers/elevenlabs.js +52 -0
  83. package/dist/libs/contracts/dist/integrations/providers/gcs-storage.js +75 -0
  84. package/dist/libs/contracts/dist/integrations/providers/gmail.js +87 -0
  85. package/dist/libs/contracts/dist/integrations/providers/google-calendar.js +66 -0
  86. package/dist/libs/contracts/dist/integrations/providers/index.js +11 -0
  87. package/dist/libs/contracts/dist/integrations/providers/mistral.js +68 -0
  88. package/dist/libs/contracts/dist/integrations/providers/postmark.js +68 -0
  89. package/dist/libs/contracts/dist/integrations/providers/powens.js +116 -0
  90. package/dist/libs/contracts/dist/integrations/providers/qdrant.js +73 -0
  91. package/dist/libs/contracts/dist/integrations/providers/registry.js +10 -0
  92. package/dist/libs/contracts/dist/integrations/providers/stripe.js +83 -0
  93. package/dist/libs/contracts/dist/integrations/providers/twilio-sms.js +61 -0
  94. package/dist/libs/contracts/dist/jsonschema.js +24 -0
  95. package/dist/libs/contracts/dist/knowledge/contracts.js +306 -0
  96. package/dist/libs/contracts/dist/knowledge/index.js +7 -0
  97. package/dist/libs/contracts/dist/knowledge/spaces/email-threads.js +34 -0
  98. package/dist/libs/contracts/dist/knowledge/spaces/financial-docs.js +34 -0
  99. package/dist/libs/contracts/dist/knowledge/spaces/financial-overview.js +38 -0
  100. package/dist/libs/contracts/dist/knowledge/spaces/index.js +6 -0
  101. package/dist/libs/contracts/dist/knowledge/spaces/product-canon.js +34 -0
  102. package/dist/libs/contracts/dist/knowledge/spaces/support-faq.js +37 -0
  103. package/dist/libs/contracts/dist/knowledge/spaces/uploaded-docs.js +34 -0
  104. package/dist/libs/contracts/dist/llm/exporters.js +352 -0
  105. package/dist/libs/contracts/dist/llm/index.js +2 -0
  106. package/dist/libs/contracts/dist/llm/prompts.js +211 -0
  107. package/dist/libs/contracts/dist/onboarding-base.js +196 -0
  108. package/dist/libs/contracts/dist/openapi.js +75 -0
  109. package/dist/libs/contracts/dist/ownership.js +21 -0
  110. package/dist/libs/contracts/dist/presentations.js +1 -0
  111. package/dist/libs/contracts/dist/presentations.v2.js +11 -0
  112. package/dist/libs/contracts/dist/prompt.js +1 -0
  113. package/dist/libs/contracts/dist/promptRegistry.js +1 -0
  114. package/dist/libs/contracts/dist/regenerator/index.js +2 -0
  115. package/dist/libs/contracts/dist/regenerator/service.js +92 -0
  116. package/dist/libs/contracts/dist/regenerator/utils.js +51 -0
  117. package/dist/libs/contracts/dist/registry.js +208 -0
  118. package/dist/libs/contracts/dist/resources.js +1 -0
  119. package/dist/libs/contracts/dist/schema/dist/EnumType.js +2 -0
  120. package/dist/libs/contracts/dist/schema/dist/FieldType.js +49 -0
  121. package/dist/libs/contracts/dist/schema/dist/ScalarTypeEnum.js +236 -0
  122. package/dist/libs/contracts/dist/schema/dist/SchemaModel.js +34 -0
  123. package/dist/libs/contracts/dist/schema/dist/entity/defineEntity.js +1 -0
  124. package/dist/libs/contracts/dist/schema/dist/entity/index.js +2 -0
  125. package/dist/libs/contracts/dist/schema/dist/entity/types.js +1 -0
  126. package/dist/libs/contracts/dist/schema/dist/index.js +6 -0
  127. package/dist/libs/contracts/dist/server/graphql-pothos.js +6 -0
  128. package/dist/libs/contracts/dist/server/index.js +8 -0
  129. package/dist/libs/contracts/dist/server/mcp/createMcpServer.js +4 -0
  130. package/dist/libs/contracts/dist/server/mcp/registerPresentations.js +2 -0
  131. package/dist/libs/contracts/dist/server/mcp/registerPrompts.js +1 -0
  132. package/dist/libs/contracts/dist/server/mcp/registerResources.js +2 -0
  133. package/dist/libs/contracts/dist/server/mcp/registerTools.js +1 -0
  134. package/dist/libs/contracts/dist/server/provider-mcp.js +1 -0
  135. package/dist/libs/contracts/dist/server/rest-elysia.js +1 -0
  136. package/dist/libs/contracts/dist/server/rest-express.js +1 -0
  137. package/dist/libs/contracts/dist/server/rest-generic.js +1 -0
  138. package/dist/libs/contracts/dist/server/rest-next-app.js +1 -0
  139. package/dist/libs/contracts/dist/server/rest-next-pages.js +1 -0
  140. package/dist/libs/contracts/dist/spec.js +35 -0
  141. package/dist/libs/contracts/dist/telemetry/index.js +1 -0
  142. package/dist/libs/contracts/dist/telemetry/tracker.js +1 -0
  143. package/dist/libs/contracts/dist/tests/index.js +1 -0
  144. package/dist/libs/contracts/dist/tests/runner.js +150 -0
  145. package/dist/libs/contracts/dist/workflow/index.js +1 -0
  146. package/dist/libs/contracts/dist/workflow/runner.js +1 -0
  147. package/dist/libs/contracts-transformers/dist/common/utils.js +47 -0
  148. package/dist/libs/contracts-transformers/dist/openapi/exporter.js +1 -0
  149. package/dist/libs/contracts-transformers/dist/openapi/importer.js +255 -0
  150. package/dist/libs/contracts-transformers/dist/openapi/index.js +4 -0
  151. package/dist/libs/contracts-transformers/dist/openapi/parser.js +231 -0
  152. package/dist/libs/contracts-transformers/dist/openapi/schema-converter.js +201 -0
  153. package/dist/modules/contractspec-workspace/dist/ai/code-generation.js +137 -0
  154. package/dist/modules/contractspec-workspace/dist/ai/spec-creation.js +101 -0
  155. package/dist/modules/contractspec-workspace/dist/analysis/deps/graph.js +84 -0
  156. package/dist/modules/contractspec-workspace/dist/analysis/deps/parse-imports.js +30 -0
  157. package/dist/modules/contractspec-workspace/dist/analysis/diff/semantic.js +96 -0
  158. package/dist/modules/contractspec-workspace/dist/analysis/feature-scan.js +151 -0
  159. package/dist/modules/contractspec-workspace/dist/analysis/spec-scan.js +344 -0
  160. package/dist/modules/contractspec-workspace/dist/analysis/validate/spec-structure.js +122 -0
  161. package/dist/modules/contractspec-workspace/dist/templates/app-config.js +105 -0
  162. package/dist/modules/contractspec-workspace/dist/templates/data-view.js +68 -0
  163. package/dist/modules/contractspec-workspace/dist/templates/event.js +38 -0
  164. package/dist/modules/contractspec-workspace/dist/templates/experiment.js +87 -0
  165. package/dist/modules/contractspec-workspace/dist/templates/handler.js +95 -0
  166. package/dist/modules/contractspec-workspace/dist/templates/integration-utils.js +104 -0
  167. package/dist/modules/contractspec-workspace/dist/templates/integration.js +62 -0
  168. package/dist/modules/contractspec-workspace/dist/templates/knowledge.js +68 -0
  169. package/dist/modules/contractspec-workspace/dist/templates/migration.js +60 -0
  170. package/dist/modules/contractspec-workspace/dist/templates/operation.js +100 -0
  171. package/dist/modules/contractspec-workspace/dist/templates/presentation.js +78 -0
  172. package/dist/modules/contractspec-workspace/dist/templates/telemetry.js +89 -0
  173. package/dist/modules/contractspec-workspace/dist/templates/utils.js +38 -0
  174. package/dist/modules/contractspec-workspace/dist/templates/workflow-runner.js +48 -0
  175. package/dist/modules/contractspec-workspace/dist/templates/workflow.js +67 -0
  176. package/dist/modules/contractspec-workspace/dist/types/generation-types.js +20 -0
  177. package/dist/services/agent-guide/adapters/claude-code.js +144 -3
  178. package/dist/services/agent-guide/adapters/cursor-cli.js +135 -3
  179. package/dist/services/agent-guide/adapters/generic-mcp.js +159 -3
  180. package/dist/services/agent-guide/adapters/index.js +30 -1
  181. package/dist/services/agent-guide/agent-guide-service.js +148 -1
  182. package/dist/services/agent-guide/index.js +5 -1
  183. package/dist/services/build.js +140 -1
  184. package/dist/services/ci-check/ci-check-service.js +393 -1
  185. package/dist/services/ci-check/index.js +2 -1
  186. package/dist/services/ci-check/types.js +28 -1
  187. package/dist/services/clean.js +71 -1
  188. package/dist/services/config.js +76 -1
  189. package/dist/services/deps.js +62 -1
  190. package/dist/services/diff.js +33 -1
  191. package/dist/services/doctor/checks/ai.js +118 -2
  192. package/dist/services/doctor/checks/cli.js +146 -1
  193. package/dist/services/doctor/checks/config.js +170 -1
  194. package/dist/services/doctor/checks/deps.js +180 -1
  195. package/dist/services/doctor/checks/index.js +6 -1
  196. package/dist/services/doctor/checks/mcp.js +144 -1
  197. package/dist/services/doctor/checks/workspace.js +243 -1
  198. package/dist/services/doctor/doctor-service.js +115 -2
  199. package/dist/services/doctor/index.js +2 -1
  200. package/dist/services/doctor/types.js +26 -1
  201. package/dist/services/implementation/discovery.js +143 -2
  202. package/dist/services/implementation/index.js +2 -1
  203. package/dist/services/implementation/resolver.js +223 -1
  204. package/dist/services/index.js +53 -1
  205. package/dist/services/integrity-diagram.js +274 -6
  206. package/dist/services/integrity.js +272 -1
  207. package/dist/services/list.js +35 -1
  208. package/dist/services/openapi/export-service.js +51 -2
  209. package/dist/services/openapi/import-service.js +75 -1
  210. package/dist/services/openapi/index.js +4 -1
  211. package/dist/services/openapi/sync-service.js +121 -1
  212. package/dist/services/openapi/validate-service.js +130 -1
  213. package/dist/services/regenerator.js +23 -1
  214. package/dist/services/registry.js +73 -1
  215. package/dist/services/setup/config-generators.js +113 -26
  216. package/dist/services/setup/file-merger.js +60 -2
  217. package/dist/services/setup/index.js +4 -1
  218. package/dist/services/setup/setup-service.js +95 -1
  219. package/dist/services/setup/targets/agents-md.js +46 -1
  220. package/dist/services/setup/targets/cli-config.js +59 -1
  221. package/dist/services/setup/targets/cursor-rules.js +47 -1
  222. package/dist/services/setup/targets/mcp-claude.js +59 -1
  223. package/dist/services/setup/targets/mcp-cursor.js +58 -1
  224. package/dist/services/setup/targets/vscode-settings.js +62 -1
  225. package/dist/services/setup/types.js +26 -1
  226. package/dist/services/sync.js +62 -1
  227. package/dist/services/test.js +30 -1
  228. package/dist/services/validate-implementation.js +69 -1
  229. package/dist/services/validate.js +47 -1
  230. package/dist/services/verification-cache/adapters/filesystem.js +121 -1
  231. package/dist/services/verification-cache/adapters/in-memory.js +45 -1
  232. package/dist/services/verification-cache/adapters/index.js +3 -1
  233. package/dist/services/verification-cache/adapters/workspace-state.js +90 -1
  234. package/dist/services/verification-cache/cache-service.js +255 -1
  235. package/dist/services/verification-cache/index.js +6 -1
  236. package/dist/services/verification-cache/types.js +15 -1
  237. package/dist/services/verify/ai-verifier.js +336 -9
  238. package/dist/services/verify/behavior-verifier.js +185 -1
  239. package/dist/services/verify/index.js +4 -1
  240. package/dist/services/verify/structure-verifier.js +195 -2
  241. package/dist/services/verify/verify-service.js +203 -3
  242. package/dist/services/watch.js +31 -1
  243. package/dist/services/workspace-info.js +102 -2
  244. package/dist/templates/app-config.template.js +101 -28
  245. package/dist/templates/data-view.template.js +42 -27
  246. package/dist/templates/event.template.js +29 -14
  247. package/dist/templates/experiment.template.js +77 -51
  248. package/dist/templates/handler.template.js +53 -17
  249. package/dist/templates/index.js +36 -1
  250. package/dist/templates/integration.template.js +134 -50
  251. package/dist/templates/knowledge.template.js +62 -21
  252. package/dist/templates/migration.template.js +50 -26
  253. package/dist/templates/operation.template.js +44 -28
  254. package/dist/templates/presentation.template.js +46 -20
  255. package/dist/templates/telemetry.template.js +74 -53
  256. package/dist/templates/workflow-runner.template.js +12 -6
  257. package/dist/templates/workflow.template.js +51 -24
  258. package/package.json +13 -9
  259. package/dist/adapters/index.d.ts +0 -7
  260. package/dist/ports/index.d.ts +0 -5
  261. package/dist/services/agent-guide/index.d.ts +0 -6
  262. package/dist/services/ci-check/index.d.ts +0 -2
  263. package/dist/services/doctor/index.d.ts +0 -2
  264. package/dist/services/implementation/index.d.ts +0 -3
  265. package/dist/services/index.d.ts +0 -56
  266. package/dist/services/openapi/index.d.ts +0 -5
  267. package/dist/services/verification-cache/adapters/index.d.ts +0 -3
  268. package/dist/services/verification-cache/index.d.ts +0 -6
  269. package/dist/services/verify/index.d.ts +0 -5
@@ -1 +1,75 @@
1
- import{importFromOpenApi as e,parseOpenApi as t}from"@lssm/lib.contracts-transformers/openapi";import{dirname as n,join as r}from"path";async function i(i,a){let{fs:o,logger:s}=a,{source:c,outputDir:l,prefix:u,tags:d,exclude:f,defaultStability:p,defaultOwners:m,defaultAuth:h,dryRun:g=!1}=i;s.info(`Importing from OpenAPI: ${c}`);let _=await t(c,{fetch:globalThis.fetch,readFile:e=>o.readFile(e)});if(_.warnings.length>0)for(let e of _.warnings)s.warn(`Parse warning: ${e}`);s.info(`Parsed ${_.operations.length} operations from ${_.info.title} v${_.info.version}`);let v=e(_,{prefix:u,tags:d,exclude:f,defaultStability:p,defaultOwners:m,defaultAuth:h});s.info(`Import result: ${v.summary.imported} imported, ${v.summary.skipped} skipped, ${v.summary.errors} errors`);let y=[],b=[],x=[];for(let e of v.specs){let t=r(l,e.fileName);if(g)s.info(`[DRY RUN] Would create: ${t}`);else{let r=n(t);await o.mkdir(r),await o.writeFile(t,e.code),s.info(`Created: ${t}`)}y.push({path:t,operationId:e.source.sourceId,specName:e.fileName.replace(`.ts`,``)})}for(let e of v.skipped)b.push({operationId:e.sourceId,reason:e.reason}),s.debug(`Skipped: ${e.sourceId} - ${e.reason}`);for(let e of v.errors)x.push({operationId:e.sourceId,error:e.error}),s.error(`Error: ${e.sourceId} - ${e.error}`);return{imported:v.summary.imported,skipped:v.summary.skipped,errors:v.summary.errors,files:y,skippedOperations:b,errorMessages:x}}export{i as importFromOpenApiService};
1
+ import { parseOpenApi } from "../../libs/contracts-transformers/dist/openapi/parser.js";
2
+ import { importFromOpenApi } from "../../libs/contracts-transformers/dist/openapi/importer.js";
3
+ import "../../libs/contracts-transformers/dist/openapi/index.js";
4
+ import { dirname, join } from "path";
5
+
6
+ //#region src/services/openapi/import-service.ts
7
+ /**
8
+ * OpenAPI import service - imports specs from OpenAPI documents.
9
+ */
10
+ /**
11
+ * Import ContractSpec specs from an OpenAPI document.
12
+ */
13
+ async function importFromOpenApiService(options, adapters) {
14
+ const { fs, logger } = adapters;
15
+ const { source, outputDir, prefix, tags, exclude, defaultStability, defaultOwners, defaultAuth, dryRun = false } = options;
16
+ logger.info(`Importing from OpenAPI: ${source}`);
17
+ const parseResult = await parseOpenApi(source, {
18
+ fetch: globalThis.fetch,
19
+ readFile: (path) => fs.readFile(path)
20
+ });
21
+ if (parseResult.warnings.length > 0) for (const warning of parseResult.warnings) logger.warn(`Parse warning: ${warning}`);
22
+ logger.info(`Parsed ${parseResult.operations.length} operations from ${parseResult.info.title} v${parseResult.info.version}`);
23
+ const importResult = importFromOpenApi(parseResult, {
24
+ prefix,
25
+ tags,
26
+ exclude,
27
+ defaultStability,
28
+ defaultOwners,
29
+ defaultAuth
30
+ });
31
+ logger.info(`Import result: ${importResult.summary.imported} imported, ${importResult.summary.skipped} skipped, ${importResult.summary.errors} errors`);
32
+ const files = [];
33
+ const skippedOperations = [];
34
+ const errorMessages = [];
35
+ for (const spec of importResult.specs) {
36
+ const filePath = join(outputDir, spec.fileName);
37
+ if (dryRun) logger.info(`[DRY RUN] Would create: ${filePath}`);
38
+ else {
39
+ const dir = dirname(filePath);
40
+ await fs.mkdir(dir);
41
+ await fs.writeFile(filePath, spec.code);
42
+ logger.info(`Created: ${filePath}`);
43
+ }
44
+ files.push({
45
+ path: filePath,
46
+ operationId: spec.source.sourceId,
47
+ specName: spec.fileName.replace(".ts", "")
48
+ });
49
+ }
50
+ for (const skipped of importResult.skipped) {
51
+ skippedOperations.push({
52
+ operationId: skipped.sourceId,
53
+ reason: skipped.reason
54
+ });
55
+ logger.debug(`Skipped: ${skipped.sourceId} - ${skipped.reason}`);
56
+ }
57
+ for (const error of importResult.errors) {
58
+ errorMessages.push({
59
+ operationId: error.sourceId,
60
+ error: error.error
61
+ });
62
+ logger.error(`Error: ${error.sourceId} - ${error.error}`);
63
+ }
64
+ return {
65
+ imported: importResult.summary.imported,
66
+ skipped: importResult.summary.skipped,
67
+ errors: importResult.summary.errors,
68
+ files,
69
+ skippedOperations,
70
+ errorMessages
71
+ };
72
+ }
73
+
74
+ //#endregion
75
+ export { importFromOpenApiService };
@@ -1 +1,4 @@
1
- import{importFromOpenApiService as e}from"./import-service.js";import{syncWithOpenApiService as t}from"./sync-service.js";import{validateAgainstOpenApiService as n}from"./validate-service.js";import{exportOpenApi as r}from"./export-service.js";
1
+ import { importFromOpenApiService } from "./import-service.js";
2
+ import { syncWithOpenApiService } from "./sync-service.js";
3
+ import { validateAgainstOpenApiService } from "./validate-service.js";
4
+ import { exportOpenApi } from "./export-service.js";
@@ -1 +1,121 @@
1
- import{importFromOpenApi as e,parseOpenApi as t}from"@lssm/lib.contracts-transformers/openapi";import{dirname as n,join as r}from"path";async function i(i,a,o){let{fs:s,logger:c}=o,{sources:l,sourceName:u,interactive:d,force:f,dryRun:p}=i,{sources:m,outputDir:h}=a,g=l??m??[];if(u&&(g=g.filter(e=>e.name===u),g.length===0))throw Error(`Source not found: ${u}`);if(g.length===0)return c.warn(`No OpenAPI sources configured. Add sources to .contractsrc.json`),{added:0,updated:0,unchanged:0,conflicts:0,changes:[]};let _={added:0,updated:0,unchanged:0,conflicts:0,changes:[]};for(let i of g){c.info(`Syncing with source: ${i.name}`);let a=i.url??i.file;if(!a){c.warn(`Source ${i.name} has no url or file configured`);continue}let o=await t(a,{fetch:globalThis.fetch,readFile:e=>s.readFile(e)});c.info(`Parsed ${o.operations.length} operations from ${i.name}`);let l=e(o,{prefix:i.prefix,tags:i.tags,exclude:i.exclude,defaultStability:i.defaultStability,defaultAuth:i.defaultAuth});for(let e of l.specs){let t=r(h,e.fileName);if(await s.exists(t))await s.readFile(t)===e.code?(_.unchanged++,_.changes.push({operationId:e.source.sourceId,action:`unchanged`,path:t})):f===`openapi`?(p||await s.writeFile(t,e.code),_.updated++,_.changes.push({operationId:e.source.sourceId,action:`updated`,path:t}),c.info(`Updated: ${e.source.sourceId}`)):f===`contractspec`?(_.unchanged++,_.changes.push({operationId:e.source.sourceId,action:`unchanged`,path:t}),c.info(`Kept: ${e.source.sourceId}`)):d?(_.conflicts++,_.changes.push({operationId:e.source.sourceId,action:`conflict`,path:t}),c.warn(`Conflict: ${e.source.sourceId} - needs resolution`)):(_.conflicts++,_.changes.push({operationId:e.source.sourceId,action:`conflict`,path:t}),c.warn(`Conflict: ${e.source.sourceId}`));else{if(!p){let r=n(t);await s.mkdir(r),await s.writeFile(t,e.code)}_.added++,_.changes.push({operationId:e.source.sourceId,action:`added`,path:t}),c.info(`Added: ${e.source.sourceId}`)}}}return c.info(`Sync complete: ${_.added} added, ${_.updated} updated, ${_.unchanged} unchanged, ${_.conflicts} conflicts`),_}export{i as syncWithOpenApiService};
1
+ import { parseOpenApi } from "../../libs/contracts-transformers/dist/openapi/parser.js";
2
+ import { importFromOpenApi } from "../../libs/contracts-transformers/dist/openapi/importer.js";
3
+ import "../../libs/contracts-transformers/dist/openapi/index.js";
4
+ import { dirname, join } from "path";
5
+
6
+ //#region src/services/openapi/sync-service.ts
7
+ /**
8
+ * OpenAPI sync service - syncs specs with OpenAPI sources.
9
+ */
10
+ /**
11
+ * Sync ContractSpec specs with OpenAPI sources.
12
+ */
13
+ async function syncWithOpenApiService(options, config, adapters) {
14
+ const { fs, logger } = adapters;
15
+ const { sources: optSources, sourceName, interactive, force, dryRun } = options;
16
+ const { sources: configSources, outputDir } = config;
17
+ let sourcesToSync = optSources ?? configSources ?? [];
18
+ if (sourceName) {
19
+ sourcesToSync = sourcesToSync.filter((s) => s.name === sourceName);
20
+ if (sourcesToSync.length === 0) throw new Error(`Source not found: ${sourceName}`);
21
+ }
22
+ if (sourcesToSync.length === 0) {
23
+ logger.warn("No OpenAPI sources configured. Add sources to .contractsrc.json");
24
+ return {
25
+ added: 0,
26
+ updated: 0,
27
+ unchanged: 0,
28
+ conflicts: 0,
29
+ changes: []
30
+ };
31
+ }
32
+ const result = {
33
+ added: 0,
34
+ updated: 0,
35
+ unchanged: 0,
36
+ conflicts: 0,
37
+ changes: []
38
+ };
39
+ for (const source of sourcesToSync) {
40
+ logger.info(`Syncing with source: ${source.name}`);
41
+ const sourceLocation = source.url ?? source.file;
42
+ if (!sourceLocation) {
43
+ logger.warn(`Source ${source.name} has no url or file configured`);
44
+ continue;
45
+ }
46
+ const parseResult = await parseOpenApi(sourceLocation, {
47
+ fetch: globalThis.fetch,
48
+ readFile: (path) => fs.readFile(path)
49
+ });
50
+ logger.info(`Parsed ${parseResult.operations.length} operations from ${source.name}`);
51
+ const importResult = importFromOpenApi(parseResult, {
52
+ prefix: source.prefix,
53
+ tags: source.tags,
54
+ exclude: source.exclude,
55
+ defaultStability: source.defaultStability,
56
+ defaultAuth: source.defaultAuth
57
+ });
58
+ for (const imported of importResult.specs) {
59
+ const filePath = join(outputDir, imported.fileName);
60
+ if (!await fs.exists(filePath)) {
61
+ if (!dryRun) {
62
+ const dir = dirname(filePath);
63
+ await fs.mkdir(dir);
64
+ await fs.writeFile(filePath, imported.code);
65
+ }
66
+ result.added++;
67
+ result.changes.push({
68
+ operationId: imported.source.sourceId,
69
+ action: "added",
70
+ path: filePath
71
+ });
72
+ logger.info(`Added: ${imported.source.sourceId}`);
73
+ } else if (await fs.readFile(filePath) === imported.code) {
74
+ result.unchanged++;
75
+ result.changes.push({
76
+ operationId: imported.source.sourceId,
77
+ action: "unchanged",
78
+ path: filePath
79
+ });
80
+ } else if (force === "openapi") {
81
+ if (!dryRun) await fs.writeFile(filePath, imported.code);
82
+ result.updated++;
83
+ result.changes.push({
84
+ operationId: imported.source.sourceId,
85
+ action: "updated",
86
+ path: filePath
87
+ });
88
+ logger.info(`Updated: ${imported.source.sourceId}`);
89
+ } else if (force === "contractspec") {
90
+ result.unchanged++;
91
+ result.changes.push({
92
+ operationId: imported.source.sourceId,
93
+ action: "unchanged",
94
+ path: filePath
95
+ });
96
+ logger.info(`Kept: ${imported.source.sourceId}`);
97
+ } else if (interactive) {
98
+ result.conflicts++;
99
+ result.changes.push({
100
+ operationId: imported.source.sourceId,
101
+ action: "conflict",
102
+ path: filePath
103
+ });
104
+ logger.warn(`Conflict: ${imported.source.sourceId} - needs resolution`);
105
+ } else {
106
+ result.conflicts++;
107
+ result.changes.push({
108
+ operationId: imported.source.sourceId,
109
+ action: "conflict",
110
+ path: filePath
111
+ });
112
+ logger.warn(`Conflict: ${imported.source.sourceId}`);
113
+ }
114
+ }
115
+ }
116
+ logger.info(`Sync complete: ${result.added} added, ${result.updated} updated, ${result.unchanged} unchanged, ${result.conflicts} conflicts`);
117
+ return result;
118
+ }
119
+
120
+ //#endregion
121
+ export { syncWithOpenApiService };
@@ -1 +1,130 @@
1
- import{parseOpenApi as e}from"@lssm/lib.contracts-transformers/openapi";async function t(t,n){let{fs:r,logger:i}=n,{specPath:a,openApiSource:o,ignoreDescriptions:s,ignoreTags:c,ignoreTransport:l}=t;i.info(`Validating specs against OpenAPI: ${o}`);let u=await e(o,{fetch:globalThis.fetch,readFile:e=>r.readFile(e)});i.info(`Parsed ${u.operations.length} operations from ${u.info.title}`);let d=new Map;for(let e of u.operations)d.set(e.operationId,e);let f=[],p=0,m=0,h=await r.stat(a),g=[];if(h.isDirectory){let e=await r.glob({pattern:`**/*.ts`,cwd:a,ignore:[`node_modules/**`,`dist/**`,`*.test.ts`,`*.spec.ts`],absolute:!0});g.push(...e)}else g.push(a);i.info(`Found ${g.length} spec files to validate`);for(let e of g)try{let t=await r.readFile(e),n=t.match(/operationId:\s*['"]([^'"]+)['"]/)||t.match(/name:\s*['"]([^'"]+)['"]/)||t.match(/export\s+const\s+(\w+)Spec\s*=/);if(!n||!n[1]){i.debug(`Could not extract operationId from ${e}`);continue}let a=n[1];p++;let o;if(o=d.get(a),!o){let e=a.replace(/([A-Z])/g,`_$1`).toLowerCase();o=d.get(e)}if(!o){for(let[e,t]of d)if(e.toLowerCase().includes(a.toLowerCase())||a.toLowerCase().includes(e.toLowerCase())){o=t;break}}if(!o){f.push({specPath:e,valid:!1,diffs:[{path:``,type:`removed`,description:`No matching operation found in OpenAPI for spec: ${a}`}]}),m++;continue}let s=[];if(o.deprecated&&!t.includes(`deprecated`)&&s.push({path:`meta.stability`,type:`modified`,description:`OpenAPI operation is deprecated but spec does not indicate deprecation`}),!l){let e=t.match(/path:\s*['"]([^'"]+)['"]/);e&&e[1]!==o.path&&s.push({path:`transport.rest.path`,type:`modified`,description:`Path mismatch: spec has "${e[1]}", OpenAPI has "${o.path}"`})}if(!l){let e=t.match(/method:\s*['"]([^'"]+)['"]/);e?.[1]&&e[1].toLowerCase()!==o.method.toLowerCase()&&s.push({path:`transport.rest.method`,type:`modified`,description:`Method mismatch: spec has "${e[1]}", OpenAPI has "${o.method.toUpperCase()}"`})}let c=s.length===0;c||m++,f.push({specPath:e,operationId:o.operationId,valid:c,diffs:s})}catch(t){i.error(`Error validating ${e}: ${t}`),f.push({specPath:e,valid:!1,diffs:[{path:``,type:`modified`,description:`Error: ${t instanceof Error?t.message:String(t)}`}]}),m++}let _=m===0;return i.info(`Validation ${_?`passed`:`failed`}: ${p} specs checked, ${m} with differences`),{valid:_,specsValidated:p,specsWithDiffs:m,results:f}}export{t as validateAgainstOpenApiService};
1
+ import { parseOpenApi } from "../../libs/contracts-transformers/dist/openapi/parser.js";
2
+ import "../../libs/contracts-transformers/dist/openapi/index.js";
3
+
4
+ //#region src/services/openapi/validate-service.ts
5
+ /**
6
+ * OpenAPI validation service - validates specs against OpenAPI sources.
7
+ */
8
+ /**
9
+ * Validate ContractSpec specs against an OpenAPI source.
10
+ */
11
+ async function validateAgainstOpenApiService(options, adapters) {
12
+ const { fs, logger } = adapters;
13
+ const { specPath, openApiSource, ignoreDescriptions, ignoreTags, ignoreTransport } = options;
14
+ logger.info(`Validating specs against OpenAPI: ${openApiSource}`);
15
+ const parseResult = await parseOpenApi(openApiSource, {
16
+ fetch: globalThis.fetch,
17
+ readFile: (path) => fs.readFile(path)
18
+ });
19
+ logger.info(`Parsed ${parseResult.operations.length} operations from ${parseResult.info.title}`);
20
+ const operationsMap = /* @__PURE__ */ new Map();
21
+ for (const op of parseResult.operations) operationsMap.set(op.operationId, op);
22
+ const results = [];
23
+ let specsValidated = 0;
24
+ let specsWithDiffs = 0;
25
+ const stat = await fs.stat(specPath);
26
+ const specFiles = [];
27
+ if (stat.isDirectory) {
28
+ const files = await fs.glob({
29
+ pattern: "**/*.ts",
30
+ cwd: specPath,
31
+ ignore: [
32
+ "node_modules/**",
33
+ "dist/**",
34
+ "*.test.ts",
35
+ "*.spec.ts"
36
+ ],
37
+ absolute: true
38
+ });
39
+ specFiles.push(...files);
40
+ } else specFiles.push(specPath);
41
+ logger.info(`Found ${specFiles.length} spec files to validate`);
42
+ for (const file of specFiles) try {
43
+ const content = await fs.readFile(file);
44
+ const operationIdMatch = content.match(/operationId:\s*['"]([^'"]+)['"]/) || content.match(/name:\s*['"]([^'"]+)['"]/) || content.match(/export\s+const\s+(\w+)Spec\s*=/);
45
+ if (!operationIdMatch || !operationIdMatch[1]) {
46
+ logger.debug(`Could not extract operationId from ${file}`);
47
+ continue;
48
+ }
49
+ const specName = operationIdMatch[1];
50
+ specsValidated++;
51
+ let matchingOp;
52
+ matchingOp = operationsMap.get(specName);
53
+ if (!matchingOp) {
54
+ const snakeName = specName.replace(/([A-Z])/g, "_$1").toLowerCase();
55
+ matchingOp = operationsMap.get(snakeName);
56
+ }
57
+ if (!matchingOp) {
58
+ for (const [opId, op] of operationsMap) if (opId.toLowerCase().includes(specName.toLowerCase()) || specName.toLowerCase().includes(opId.toLowerCase())) {
59
+ matchingOp = op;
60
+ break;
61
+ }
62
+ }
63
+ if (!matchingOp) {
64
+ results.push({
65
+ specPath: file,
66
+ valid: false,
67
+ diffs: [{
68
+ path: "",
69
+ type: "removed",
70
+ description: `No matching operation found in OpenAPI for spec: ${specName}`
71
+ }]
72
+ });
73
+ specsWithDiffs++;
74
+ continue;
75
+ }
76
+ const diffs = [];
77
+ if (matchingOp.deprecated && !content.includes("deprecated")) diffs.push({
78
+ path: "meta.stability",
79
+ type: "modified",
80
+ description: "OpenAPI operation is deprecated but spec does not indicate deprecation"
81
+ });
82
+ if (!ignoreTransport) {
83
+ const pathMatch = content.match(/path:\s*['"]([^'"]+)['"]/);
84
+ if (pathMatch && pathMatch[1] !== matchingOp.path) diffs.push({
85
+ path: "transport.rest.path",
86
+ type: "modified",
87
+ description: `Path mismatch: spec has "${pathMatch[1]}", OpenAPI has "${matchingOp.path}"`
88
+ });
89
+ }
90
+ if (!ignoreTransport) {
91
+ const methodMatch = content.match(/method:\s*['"]([^'"]+)['"]/);
92
+ if (methodMatch?.[1] && methodMatch[1].toLowerCase() !== matchingOp.method.toLowerCase()) diffs.push({
93
+ path: "transport.rest.method",
94
+ type: "modified",
95
+ description: `Method mismatch: spec has "${methodMatch[1]}", OpenAPI has "${matchingOp.method.toUpperCase()}"`
96
+ });
97
+ }
98
+ const valid$1 = diffs.length === 0;
99
+ if (!valid$1) specsWithDiffs++;
100
+ results.push({
101
+ specPath: file,
102
+ operationId: matchingOp.operationId,
103
+ valid: valid$1,
104
+ diffs
105
+ });
106
+ } catch (error) {
107
+ logger.error(`Error validating ${file}: ${error}`);
108
+ results.push({
109
+ specPath: file,
110
+ valid: false,
111
+ diffs: [{
112
+ path: "",
113
+ type: "modified",
114
+ description: `Error: ${error instanceof Error ? error.message : String(error)}`
115
+ }]
116
+ });
117
+ specsWithDiffs++;
118
+ }
119
+ const valid = specsWithDiffs === 0;
120
+ logger.info(`Validation ${valid ? "passed" : "failed"}: ${specsValidated} specs checked, ${specsWithDiffs} with differences`);
121
+ return {
122
+ valid,
123
+ specsValidated,
124
+ specsWithDiffs,
125
+ results
126
+ };
127
+ }
128
+
129
+ //#endregion
130
+ export { validateAgainstOpenApiService };
@@ -1 +1,23 @@
1
- import{RegeneratorService as e}from"@lssm/lib.contracts/regenerator";function t(t){return new e({contexts:t.contexts,adapters:t.adapters??{},rules:t.rules,sink:t.sink,pollIntervalMs:t.pollIntervalMs,batchDurationMs:t.batchDurationMs})}export{t as createRegeneratorService};
1
+ import { RegeneratorService } from "../libs/contracts/dist/regenerator/service.js";
2
+ import "../libs/contracts/dist/regenerator/index.js";
3
+
4
+ //#region src/services/regenerator.ts
5
+ /**
6
+ * Regenerator service.
7
+ *
8
+ * Thin wrapper around `@lssm/lib.contracts/regenerator` for reuse across CLI/VSCode/web.
9
+ * This service does not perform module loading; callers provide resolved contexts/rules/sink.
10
+ */
11
+ function createRegeneratorService(options) {
12
+ return new RegeneratorService({
13
+ contexts: options.contexts,
14
+ adapters: options.adapters ?? {},
15
+ rules: options.rules,
16
+ sink: options.sink,
17
+ pollIntervalMs: options.pollIntervalMs,
18
+ batchDurationMs: options.batchDurationMs
19
+ });
20
+ }
21
+
22
+ //#endregion
23
+ export { createRegeneratorService };
@@ -1 +1,73 @@
1
- var e=class{registryUrl;constructor(e){this.registryUrl=e.registryUrl.replace(/\/+$/,``)}async getJson(e){let t=`${this.registryUrl}${e.startsWith(`/`)?``:`/`}${e}`,n;try{n=await fetch(t,{method:`GET`,headers:{Accept:`application/json`}})}catch(e){throw Error(`Registry request failed: ${t} (${e instanceof Error?e.message:String(e)})`)}if(!n.ok){let e=await n.text().catch(()=>``);throw Error(`Registry request failed: ${n.status} ${n.statusText} ${e}`)}return await n.json()}};function t(e){return e||process.env.CONTRACTSPEC_REGISTRY_URL||`http://localhost:8090`}async function n(n,r,i){let{logger:a}=i,o=t(r.registryUrl);a.info(`Adding spec to registry: ${n}`,{registryUrl:o}),await new e({registryUrl:o}).getJson(`/specs/add?path=${encodeURIComponent(n)}`),a.info(`Spec added to registry successfully`)}async function r(n,r){let{logger:i}=r,a=t(n.registryUrl);i.info(`Listing specs from registry`,{registryUrl:a});let o=new e({registryUrl:a}),s=n.filter?`?filter=${encodeURIComponent(n.filter)}`:``,c=await o.getJson(`/specs${s}`);return i.info(`Found ${c.length} specs`),c}async function i(n,r,i){let{logger:a}=i,o=t(r.registryUrl);a.info(`Searching registry: ${n}`,{registryUrl:o});let s=await new e({registryUrl:o}).getJson(`/specs/search?q=${encodeURIComponent(n)}`);return a.info(`Found ${s.length} results`),s}export{e as RegistryClient,n as addToRegistry,r as listFromRegistry,t as resolveRegistryUrl,i as searchRegistry};
1
+ //#region src/services/registry.ts
2
+ /**
3
+ * Registry client for interacting with ContractSpec registry.
4
+ */
5
+ var RegistryClient = class {
6
+ registryUrl;
7
+ constructor(opts) {
8
+ this.registryUrl = opts.registryUrl.replace(/\/+$/, "");
9
+ }
10
+ /**
11
+ * Make GET request to registry.
12
+ */
13
+ async getJson(path) {
14
+ const url = `${this.registryUrl}${path.startsWith("/") ? "" : "/"}${path}`;
15
+ let res;
16
+ try {
17
+ res = await fetch(url, {
18
+ method: "GET",
19
+ headers: { Accept: "application/json" }
20
+ });
21
+ } catch (error) {
22
+ throw new Error(`Registry request failed: ${url} (${error instanceof Error ? error.message : String(error)})`);
23
+ }
24
+ if (!res.ok) {
25
+ const text = await res.text().catch(() => "");
26
+ throw new Error(`Registry request failed: ${res.status} ${res.statusText} ${text}`);
27
+ }
28
+ return await res.json();
29
+ }
30
+ };
31
+ /**
32
+ * Resolve registry URL from options or environment.
33
+ */
34
+ function resolveRegistryUrl(cliRegistryUrl) {
35
+ return cliRegistryUrl || process.env.CONTRACTSPEC_REGISTRY_URL || "http://localhost:8090";
36
+ }
37
+ /**
38
+ * Add spec to registry.
39
+ */
40
+ async function addToRegistry(specPath, options, adapters) {
41
+ const { logger } = adapters;
42
+ const registryUrl = resolveRegistryUrl(options.registryUrl);
43
+ logger.info(`Adding spec to registry: ${specPath}`, { registryUrl });
44
+ await new RegistryClient({ registryUrl }).getJson(`/specs/add?path=${encodeURIComponent(specPath)}`);
45
+ logger.info("Spec added to registry successfully");
46
+ }
47
+ /**
48
+ * List specs from registry.
49
+ */
50
+ async function listFromRegistry(options, adapters) {
51
+ const { logger } = adapters;
52
+ const registryUrl = resolveRegistryUrl(options.registryUrl);
53
+ logger.info("Listing specs from registry", { registryUrl });
54
+ const client = new RegistryClient({ registryUrl });
55
+ const filter = options.filter ? `?filter=${encodeURIComponent(options.filter)}` : "";
56
+ const specs = await client.getJson(`/specs${filter}`);
57
+ logger.info(`Found ${specs.length} specs`);
58
+ return specs;
59
+ }
60
+ /**
61
+ * Search registry for specs.
62
+ */
63
+ async function searchRegistry(query, options, adapters) {
64
+ const { logger } = adapters;
65
+ const registryUrl = resolveRegistryUrl(options.registryUrl);
66
+ logger.info(`Searching registry: ${query}`, { registryUrl });
67
+ const results = await new RegistryClient({ registryUrl }).getJson(`/specs/search?q=${encodeURIComponent(query)}`);
68
+ logger.info(`Found ${results.length} results`);
69
+ return results;
70
+ }
71
+
72
+ //#endregion
73
+ export { RegistryClient, addToRegistry, listFromRegistry, resolveRegistryUrl, searchRegistry };
@@ -1,4 +1,72 @@
1
- function e(e){let t=e.isMonorepo&&e.scope===`package`;return{$schema:`https://contractspec.dev/schemas/contractsrc.json`,aiProvider:`claude`,aiModel:`claude-sonnet-4-20250514`,agentMode:`claude-code`,outputDir:`./src`,conventions:{operations:`contracts/operations`,events:`contracts/events`,presentations:`contracts/presentations`,forms:`contracts/forms`,features:`contracts/features`},defaultOwners:e.defaultOwners??[`@team`],defaultTags:[],...t&&e.packageName?{package:e.packageName}:{}}}function t(){return{"contractspec.validation.enabled":!0,"contractspec.validation.validateOnSave":!0,"contractspec.validation.validateOnOpen":!0,"contractspec.codeLens.enabled":!0,"contractspec.diagnostics.showWarnings":!0,"contractspec.diagnostics.showHints":!0,"contractspec.integrity.enabled":!0,"contractspec.integrity.checkOnSave":!0}}function n(){return{mcpServers:{"contractspec-local":{command:`bunx`,args:[`contractspec-mcp`]}}}}function r(){return{mcpServers:{"contractspec-local":{command:`bunx`,args:[`contractspec-mcp`]}}}}function i(e){let t=e.projectName??`this project`,n=e.isMonorepo&&e.scope===`package`&&e.packageRoot?`${e.packageRoot.split(`/`).slice(-2).join(`/`)}/src/contracts`:`src/contracts`;return`# ContractSpec Development Rules
1
+ //#region src/services/setup/config-generators.ts
2
+ /**
3
+ * Generate .contractsrc.json content.
4
+ *
5
+ * Adapts defaults based on monorepo scope.
6
+ */
7
+ function generateContractsrcConfig(options) {
8
+ const isPackageLevel = options.isMonorepo && options.scope === "package";
9
+ return {
10
+ $schema: "https://contractspec.dev/schemas/contractsrc.json",
11
+ aiProvider: "claude",
12
+ aiModel: "claude-sonnet-4-20250514",
13
+ agentMode: "claude-code",
14
+ outputDir: "./src",
15
+ conventions: {
16
+ operations: "contracts/operations",
17
+ events: "contracts/events",
18
+ presentations: "contracts/presentations",
19
+ forms: "contracts/forms",
20
+ features: "contracts/features"
21
+ },
22
+ defaultOwners: options.defaultOwners ?? ["@team"],
23
+ defaultTags: [],
24
+ ...isPackageLevel && options.packageName ? { package: options.packageName } : {}
25
+ };
26
+ }
27
+ /**
28
+ * Generate .vscode/settings.json ContractSpec settings.
29
+ */
30
+ function generateVscodeSettings() {
31
+ return {
32
+ "contractspec.validation.enabled": true,
33
+ "contractspec.validation.validateOnSave": true,
34
+ "contractspec.validation.validateOnOpen": true,
35
+ "contractspec.codeLens.enabled": true,
36
+ "contractspec.diagnostics.showWarnings": true,
37
+ "contractspec.diagnostics.showHints": true,
38
+ "contractspec.integrity.enabled": true,
39
+ "contractspec.integrity.checkOnSave": true
40
+ };
41
+ }
42
+ /**
43
+ * Generate .cursor/mcp.json content.
44
+ */
45
+ function generateCursorMcpConfig() {
46
+ return { mcpServers: { "contractspec-local": {
47
+ command: "bunx",
48
+ args: ["contractspec-mcp"]
49
+ } } };
50
+ }
51
+ /**
52
+ * Generate Claude Desktop MCP config.
53
+ * Returns the mcpServers section to merge into claude_desktop_config.json.
54
+ */
55
+ function generateClaudeMcpConfig() {
56
+ return { mcpServers: { "contractspec-local": {
57
+ command: "bunx",
58
+ args: ["contractspec-mcp"]
59
+ } } };
60
+ }
61
+ /**
62
+ * Generate .cursor/rules/contractspec.mdc content.
63
+ *
64
+ * Adapts paths based on monorepo scope.
65
+ */
66
+ function generateCursorRules(options) {
67
+ const projectName = options.projectName ?? "this project";
68
+ const basePath = options.isMonorepo && options.scope === "package" && options.packageRoot ? `${options.packageRoot.split("/").slice(-2).join("/")}/src/contracts` : "src/contracts";
69
+ return `# ContractSpec Development Rules
2
70
 
3
71
  This project uses ContractSpec for spec-first development. Follow these guidelines when working with AI agents.
4
72
 
@@ -7,22 +75,14 @@ This project uses ContractSpec for spec-first development. Follow these guidelin
7
75
  - **Always update contracts first** before changing implementation code.
8
76
  - Contracts are the source of truth for operations, events, and presentations.
9
77
  - Implementation code should be generated or derived from contracts.
10
- ${e.isMonorepo?`
11
- ## Monorepo Structure
12
-
13
- This is a monorepo. Contracts may exist at:
14
- - Package level: \`packages/*/src/contracts/\`
15
- - Workspace level: \`src/contracts/\`
16
-
17
- Check the appropriate level based on the feature scope.
18
- `:``}
78
+ ${options.isMonorepo ? `\n## Monorepo Structure\n\nThis is a monorepo. Contracts may exist at:\n- Package level: \`packages/*/src/contracts/\`\n- Workspace level: \`src/contracts/\`\n\nCheck the appropriate level based on the feature scope.\n` : ""}
19
79
  ## Contract Locations
20
80
 
21
81
  Contracts are located in:
22
- - \`${n}/operations/\` - Command and query specs
23
- - \`${n}/events/\` - Event specs
24
- - \`${n}/presentations/\` - UI presentation specs
25
- - \`${n}/features/\` - Feature module specs
82
+ - \`${basePath}/operations/\` - Command and query specs
83
+ - \`${basePath}/events/\` - Event specs
84
+ - \`${basePath}/presentations/\` - UI presentation specs
85
+ - \`${basePath}/features/\` - Feature module specs
26
86
 
27
87
  ## When Making Changes
28
88
 
@@ -50,17 +110,28 @@ defineCommand({
50
110
  });
51
111
  \`\`\`
52
112
 
53
- ## Rules for ${t}
113
+ ## Rules for ${projectName}
54
114
 
55
115
  - All API endpoints must have a corresponding operation contract.
56
116
  - Events must be declared in contracts before being emitted.
57
117
  - UI components should reference presentation contracts.
58
118
  - Feature flags should be defined in feature modules.
59
- `}function a(e){let t=e.projectName??`This Project`,n=e.isMonorepo&&e.scope===`package`,r=`src/contracts/`;return`# AI Agent Guide
119
+ `;
120
+ }
121
+ /**
122
+ * Generate AGENTS.md content.
123
+ *
124
+ * Adapts paths and instructions based on monorepo scope.
125
+ */
126
+ function generateAgentsMd(options) {
127
+ const projectName = options.projectName ?? "This Project";
128
+ const isPackageLevel = options.isMonorepo && options.scope === "package";
129
+ const contractPath = "src/contracts/";
130
+ return `# AI Agent Guide
60
131
 
61
132
  This repository uses **ContractSpec** for spec-first development. AI agents should follow these guidelines.
62
133
 
63
- ## Project: ${t}
134
+ ## Project: ${projectName}
64
135
 
65
136
  ## ContractSpec Overview
66
137
 
@@ -71,7 +142,7 @@ ContractSpec is a deterministic, spec-first compiler that keeps AI-written softw
71
142
  1. **Contracts are the source of truth** - Always check/update contracts before modifying implementation.
72
143
  2. **Safe regeneration** - Code can be regenerated from specs without breaking invariants.
73
144
  3. **Multi-surface consistency** - API, events, and UI stay in sync via shared contracts.
74
- ${e.isMonorepo?`
145
+ ${options.isMonorepo ? `
75
146
  ## Monorepo Structure
76
147
 
77
148
  This is a monorepo. Contracts can exist at multiple levels:
@@ -87,13 +158,13 @@ When adding a contract, consider:
87
158
 
88
159
  ### Current Scope
89
160
 
90
- ${n?`You are working at the **package level**: \`${e.packageName??e.packageRoot}\``:`You are working at the **workspace level**.`}
91
- `:``}
161
+ ${isPackageLevel ? `You are working at the **package level**: \`${options.packageName ?? options.packageRoot}\`` : "You are working at the **workspace level**."}
162
+ ` : ""}
92
163
  ## Working in This Repository
93
164
 
94
165
  ### Before Making Changes
95
166
 
96
- 1. Check for existing contracts in \`${r}\`
167
+ 1. Check for existing contracts in \`${contractPath}\`
97
168
  2. If a contract exists, update it first
98
169
  3. Regenerate implementation with \`contractspec build\`
99
170
  4. Validate with \`contractspec validate\`
@@ -109,10 +180,10 @@ ${n?`You are working at the **package level**: \`${e.packageName??e.packageRoot}
109
180
 
110
181
  | Type | Location |
111
182
  |------|----------|
112
- | Operations | \`${r}operations/\` |
113
- | Events | \`${r}events/\` |
114
- | Presentations | \`${r}presentations/\` |
115
- | Features | \`${r}features/\` |
183
+ | Operations | \`${contractPath}operations/\` |
184
+ | Events | \`${contractPath}events/\` |
185
+ | Presentations | \`${contractPath}presentations/\` |
186
+ | Features | \`${contractPath}features/\` |
116
187
 
117
188
  ## MCP Tools Available
118
189
 
@@ -147,4 +218,20 @@ contractspec integrity
147
218
  ## Nested AGENTS.md
148
219
 
149
220
  More specific instructions may exist in subdirectories. Check for \`AGENTS.md\` files in the relevant package or module.
150
- `}function o(){let e=process.platform,t=process.env.HOME??process.env.USERPROFILE??``;switch(e){case`darwin`:return`${t}/Library/Application Support/Claude/claude_desktop_config.json`;case`win32`:return`${process.env.APPDATA??t}/Claude/claude_desktop_config.json`;default:return`${t}/.config/claude/claude_desktop_config.json`}}export{a as generateAgentsMd,r as generateClaudeMcpConfig,e as generateContractsrcConfig,n as generateCursorMcpConfig,i as generateCursorRules,t as generateVscodeSettings,o as getClaudeDesktopConfigPath};
221
+ `;
222
+ }
223
+ /**
224
+ * Get the file path for Claude Desktop config based on platform.
225
+ */
226
+ function getClaudeDesktopConfigPath() {
227
+ const platform = process.platform;
228
+ const homeDir = process.env["HOME"] ?? process.env["USERPROFILE"] ?? "";
229
+ switch (platform) {
230
+ case "darwin": return `${homeDir}/Library/Application Support/Claude/claude_desktop_config.json`;
231
+ case "win32": return `${process.env["APPDATA"] ?? homeDir}/Claude/claude_desktop_config.json`;
232
+ default: return `${homeDir}/.config/claude/claude_desktop_config.json`;
233
+ }
234
+ }
235
+
236
+ //#endregion
237
+ export { generateAgentsMd, generateClaudeMcpConfig, generateContractsrcConfig, generateCursorMcpConfig, generateCursorRules, generateVscodeSettings, getClaudeDesktopConfigPath };