@lssm/bundle.contractspec-workspace 0.0.0-canary-20251217063201 → 0.0.0-canary-20251217073102

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 (257) 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.js +81 -1
  27. package/dist/libs/ai-providers/dist/factory.js +154 -1
  28. package/dist/libs/ai-providers/dist/index.js +4 -1
  29. package/dist/libs/ai-providers/dist/legacy.js +72 -1
  30. package/dist/libs/ai-providers/dist/models.js +287 -1
  31. package/dist/libs/ai-providers/dist/validation.js +1 -1
  32. package/dist/libs/contracts/dist/capabilities/openbanking.js +88 -1
  33. package/dist/libs/contracts/dist/client/index.js +5 -1
  34. package/dist/libs/contracts/dist/client/react/feature-render.js +2 -1
  35. package/dist/libs/contracts/dist/client/react/form-render.js +4 -1
  36. package/dist/libs/contracts/dist/client/react/index.js +4 -1
  37. package/dist/libs/contracts/dist/contract-registry/index.js +1 -1
  38. package/dist/libs/contracts/dist/contract-registry/schemas.js +60 -1
  39. package/dist/libs/contracts/dist/docs/PUBLISHING.docblock.js +16 -76
  40. package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js +16 -350
  41. package/dist/libs/contracts/dist/docs/index.js +29 -1
  42. package/dist/libs/contracts/dist/docs/presentations.js +71 -1
  43. package/dist/libs/contracts/dist/docs/registry.js +44 -1
  44. package/dist/libs/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +16 -383
  45. package/dist/libs/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +16 -68
  46. package/dist/libs/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +16 -140
  47. package/dist/libs/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +16 -86
  48. package/dist/libs/contracts/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +16 -1
  49. package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js +24 -2
  50. package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js +21 -2
  51. package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js +16 -213
  52. package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js +73 -5
  53. package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js +37 -1
  54. package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js +16 -1
  55. package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js +20 -262
  56. package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js +48 -1
  57. package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js +24 -2
  58. package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js +23 -2
  59. package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js +25 -16
  60. package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js +67 -1
  61. package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js +22 -2
  62. package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js +40 -36
  63. package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js +47 -1
  64. package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js +23 -2
  65. package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js +36 -3
  66. package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js +20 -1
  67. package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js +36 -3
  68. package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js +20 -1
  69. package/dist/libs/contracts/dist/events.js +8 -1
  70. package/dist/libs/contracts/dist/experiments/evaluator.js +1 -1
  71. package/dist/libs/contracts/dist/index.js +72 -1
  72. package/dist/libs/contracts/dist/install.js +2 -1
  73. package/dist/libs/contracts/dist/integrations/contracts.js +377 -1
  74. package/dist/libs/contracts/dist/integrations/index.js +18 -1
  75. package/dist/libs/contracts/dist/integrations/openbanking/contracts/accounts.js +228 -1
  76. package/dist/libs/contracts/dist/integrations/openbanking/contracts/balances.js +159 -1
  77. package/dist/libs/contracts/dist/integrations/openbanking/contracts/index.js +3 -1
  78. package/dist/libs/contracts/dist/integrations/openbanking/contracts/transactions.js +210 -1
  79. package/dist/libs/contracts/dist/integrations/openbanking/models.js +242 -1
  80. package/dist/libs/contracts/dist/integrations/openbanking/telemetry.js +13 -1
  81. package/dist/libs/contracts/dist/integrations/providers/elevenlabs.js +52 -1
  82. package/dist/libs/contracts/dist/integrations/providers/gcs-storage.js +75 -1
  83. package/dist/libs/contracts/dist/integrations/providers/gmail.js +87 -1
  84. package/dist/libs/contracts/dist/integrations/providers/google-calendar.js +66 -1
  85. package/dist/libs/contracts/dist/integrations/providers/index.js +11 -1
  86. package/dist/libs/contracts/dist/integrations/providers/mistral.js +68 -1
  87. package/dist/libs/contracts/dist/integrations/providers/postmark.js +68 -1
  88. package/dist/libs/contracts/dist/integrations/providers/powens.js +116 -1
  89. package/dist/libs/contracts/dist/integrations/providers/qdrant.js +73 -1
  90. package/dist/libs/contracts/dist/integrations/providers/registry.js +10 -1
  91. package/dist/libs/contracts/dist/integrations/providers/stripe.js +83 -1
  92. package/dist/libs/contracts/dist/integrations/providers/twilio-sms.js +61 -1
  93. package/dist/libs/contracts/dist/jsonschema.js +24 -1
  94. package/dist/libs/contracts/dist/knowledge/contracts.js +306 -1
  95. package/dist/libs/contracts/dist/knowledge/index.js +7 -1
  96. package/dist/libs/contracts/dist/knowledge/spaces/email-threads.js +34 -1
  97. package/dist/libs/contracts/dist/knowledge/spaces/financial-docs.js +34 -1
  98. package/dist/libs/contracts/dist/knowledge/spaces/financial-overview.js +38 -1
  99. package/dist/libs/contracts/dist/knowledge/spaces/index.js +6 -1
  100. package/dist/libs/contracts/dist/knowledge/spaces/product-canon.js +34 -1
  101. package/dist/libs/contracts/dist/knowledge/spaces/support-faq.js +37 -1
  102. package/dist/libs/contracts/dist/knowledge/spaces/uploaded-docs.js +34 -1
  103. package/dist/libs/contracts/dist/llm/exporters.js +352 -4
  104. package/dist/libs/contracts/dist/llm/index.js +2 -1
  105. package/dist/libs/contracts/dist/llm/prompts.js +143 -7
  106. package/dist/libs/contracts/dist/onboarding-base.js +196 -1
  107. package/dist/libs/contracts/dist/openapi.js +75 -1
  108. package/dist/libs/contracts/dist/ownership.js +21 -1
  109. package/dist/libs/contracts/dist/presentations.js +1 -1
  110. package/dist/libs/contracts/dist/presentations.v2.js +11 -1
  111. package/dist/libs/contracts/dist/prompt.js +1 -1
  112. package/dist/libs/contracts/dist/promptRegistry.js +1 -1
  113. package/dist/libs/contracts/dist/regenerator/index.js +2 -1
  114. package/dist/libs/contracts/dist/regenerator/service.js +92 -1
  115. package/dist/libs/contracts/dist/regenerator/utils.js +51 -1
  116. package/dist/libs/contracts/dist/registry.js +208 -1
  117. package/dist/libs/contracts/dist/resources.js +1 -1
  118. package/dist/libs/contracts/dist/schema/dist/EnumType.js +2 -1
  119. package/dist/libs/contracts/dist/schema/dist/FieldType.js +49 -1
  120. package/dist/libs/contracts/dist/schema/dist/ScalarTypeEnum.js +236 -1
  121. package/dist/libs/contracts/dist/schema/dist/SchemaModel.js +34 -1
  122. package/dist/libs/contracts/dist/schema/dist/entity/defineEntity.js +1 -1
  123. package/dist/libs/contracts/dist/schema/dist/entity/index.js +2 -1
  124. package/dist/libs/contracts/dist/schema/dist/entity/types.js +1 -1
  125. package/dist/libs/contracts/dist/schema/dist/index.js +6 -1
  126. package/dist/libs/contracts/dist/server/graphql-pothos.js +6 -1
  127. package/dist/libs/contracts/dist/server/index.js +8 -1
  128. package/dist/libs/contracts/dist/server/mcp/createMcpServer.js +4 -1
  129. package/dist/libs/contracts/dist/server/mcp/registerPresentations.js +2 -1
  130. package/dist/libs/contracts/dist/server/mcp/registerPrompts.js +1 -1
  131. package/dist/libs/contracts/dist/server/mcp/registerResources.js +2 -1
  132. package/dist/libs/contracts/dist/server/mcp/registerTools.js +1 -1
  133. package/dist/libs/contracts/dist/server/provider-mcp.js +1 -1
  134. package/dist/libs/contracts/dist/server/rest-elysia.js +1 -1
  135. package/dist/libs/contracts/dist/server/rest-express.js +1 -1
  136. package/dist/libs/contracts/dist/server/rest-generic.js +1 -1
  137. package/dist/libs/contracts/dist/server/rest-next-app.js +1 -1
  138. package/dist/libs/contracts/dist/server/rest-next-pages.js +1 -1
  139. package/dist/libs/contracts/dist/spec.js +35 -1
  140. package/dist/libs/contracts/dist/telemetry/index.js +1 -1
  141. package/dist/libs/contracts/dist/telemetry/tracker.js +1 -1
  142. package/dist/libs/contracts/dist/tests/index.js +1 -1
  143. package/dist/libs/contracts/dist/tests/runner.js +150 -1
  144. package/dist/libs/contracts/dist/workflow/index.js +1 -1
  145. package/dist/libs/contracts/dist/workflow/runner.js +1 -1
  146. package/dist/libs/contracts-transformers/dist/common/utils.js +47 -1
  147. package/dist/libs/contracts-transformers/dist/openapi/exporter.js +1 -1
  148. package/dist/libs/contracts-transformers/dist/openapi/importer.js +255 -2
  149. package/dist/libs/contracts-transformers/dist/openapi/index.js +4 -1
  150. package/dist/libs/contracts-transformers/dist/openapi/parser.js +231 -1
  151. package/dist/libs/contracts-transformers/dist/openapi/schema-converter.js +201 -4
  152. package/dist/modules/contractspec-workspace/dist/ai/code-generation.js +50 -13
  153. package/dist/modules/contractspec-workspace/dist/ai/spec-creation.js +50 -18
  154. package/dist/modules/contractspec-workspace/dist/analysis/deps/graph.js +84 -2
  155. package/dist/modules/contractspec-workspace/dist/analysis/deps/parse-imports.js +30 -1
  156. package/dist/modules/contractspec-workspace/dist/analysis/diff/semantic.js +96 -1
  157. package/dist/modules/contractspec-workspace/dist/analysis/feature-scan.js +151 -1
  158. package/dist/modules/contractspec-workspace/dist/analysis/spec-scan.js +344 -1
  159. package/dist/modules/contractspec-workspace/dist/analysis/validate/spec-structure.js +122 -1
  160. package/dist/modules/contractspec-workspace/dist/templates/app-config.js +100 -28
  161. package/dist/modules/contractspec-workspace/dist/templates/data-view.js +41 -27
  162. package/dist/modules/contractspec-workspace/dist/templates/event.js +28 -14
  163. package/dist/modules/contractspec-workspace/dist/templates/experiment.js +76 -51
  164. package/dist/modules/contractspec-workspace/dist/templates/handler.js +49 -17
  165. package/dist/modules/contractspec-workspace/dist/templates/integration-utils.js +97 -26
  166. package/dist/modules/contractspec-workspace/dist/templates/integration.js +46 -23
  167. package/dist/modules/contractspec-workspace/dist/templates/knowledge.js +59 -19
  168. package/dist/modules/contractspec-workspace/dist/templates/migration.js +49 -26
  169. package/dist/modules/contractspec-workspace/dist/templates/operation.js +40 -28
  170. package/dist/modules/contractspec-workspace/dist/templates/presentation.js +45 -20
  171. package/dist/modules/contractspec-workspace/dist/templates/telemetry.js +73 -53
  172. package/dist/modules/contractspec-workspace/dist/templates/utils.js +38 -1
  173. package/dist/modules/contractspec-workspace/dist/templates/workflow-runner.js +12 -6
  174. package/dist/modules/contractspec-workspace/dist/templates/workflow.js +50 -24
  175. package/dist/modules/contractspec-workspace/dist/types/generation-types.js +20 -1
  176. package/dist/services/agent-guide/adapters/claude-code.js +144 -3
  177. package/dist/services/agent-guide/adapters/cursor-cli.js +135 -3
  178. package/dist/services/agent-guide/adapters/generic-mcp.js +159 -3
  179. package/dist/services/agent-guide/adapters/index.js +30 -1
  180. package/dist/services/agent-guide/agent-guide-service.js +148 -1
  181. package/dist/services/agent-guide/index.js +5 -1
  182. package/dist/services/build.js +140 -1
  183. package/dist/services/ci-check/ci-check-service.js +393 -1
  184. package/dist/services/ci-check/index.js +2 -1
  185. package/dist/services/ci-check/types.js +28 -1
  186. package/dist/services/clean.js +71 -1
  187. package/dist/services/config.js +76 -1
  188. package/dist/services/deps.js +62 -1
  189. package/dist/services/diff.js +33 -1
  190. package/dist/services/doctor/checks/ai.js +118 -2
  191. package/dist/services/doctor/checks/cli.js +146 -1
  192. package/dist/services/doctor/checks/config.js +170 -1
  193. package/dist/services/doctor/checks/deps.js +180 -1
  194. package/dist/services/doctor/checks/index.js +6 -1
  195. package/dist/services/doctor/checks/mcp.js +144 -1
  196. package/dist/services/doctor/checks/workspace.js +243 -1
  197. package/dist/services/doctor/doctor-service.js +115 -2
  198. package/dist/services/doctor/index.js +2 -1
  199. package/dist/services/doctor/types.js +26 -1
  200. package/dist/services/implementation/discovery.js +143 -2
  201. package/dist/services/implementation/index.js +2 -1
  202. package/dist/services/implementation/resolver.js +223 -1
  203. package/dist/services/index.js +53 -1
  204. package/dist/services/integrity-diagram.js +274 -6
  205. package/dist/services/integrity.js +272 -1
  206. package/dist/services/list.js +35 -1
  207. package/dist/services/openapi/export-service.js +51 -2
  208. package/dist/services/openapi/import-service.js +75 -1
  209. package/dist/services/openapi/index.js +4 -1
  210. package/dist/services/openapi/sync-service.js +121 -1
  211. package/dist/services/openapi/validate-service.js +130 -1
  212. package/dist/services/regenerator.js +23 -1
  213. package/dist/services/registry.js +73 -1
  214. package/dist/services/setup/config-generators.js +113 -26
  215. package/dist/services/setup/file-merger.js +60 -2
  216. package/dist/services/setup/index.js +4 -1
  217. package/dist/services/setup/setup-service.js +95 -1
  218. package/dist/services/setup/targets/agents-md.js +46 -1
  219. package/dist/services/setup/targets/cli-config.js +59 -1
  220. package/dist/services/setup/targets/cursor-rules.js +47 -1
  221. package/dist/services/setup/targets/mcp-claude.js +59 -1
  222. package/dist/services/setup/targets/mcp-cursor.js +58 -1
  223. package/dist/services/setup/targets/vscode-settings.js +62 -1
  224. package/dist/services/setup/types.js +26 -1
  225. package/dist/services/sync.js +62 -1
  226. package/dist/services/test.js +30 -1
  227. package/dist/services/validate-implementation.js +69 -1
  228. package/dist/services/validate.js +47 -1
  229. package/dist/services/verification-cache/adapters/filesystem.js +121 -1
  230. package/dist/services/verification-cache/adapters/in-memory.js +45 -1
  231. package/dist/services/verification-cache/adapters/index.js +3 -1
  232. package/dist/services/verification-cache/adapters/workspace-state.js +90 -1
  233. package/dist/services/verification-cache/cache-service.js +255 -1
  234. package/dist/services/verification-cache/index.js +6 -1
  235. package/dist/services/verification-cache/types.js +15 -1
  236. package/dist/services/verify/ai-verifier.js +336 -9
  237. package/dist/services/verify/behavior-verifier.js +185 -1
  238. package/dist/services/verify/index.js +4 -1
  239. package/dist/services/verify/structure-verifier.js +195 -2
  240. package/dist/services/verify/verify-service.js +203 -3
  241. package/dist/services/watch.js +31 -1
  242. package/dist/services/workspace-info.js +102 -2
  243. package/dist/templates/app-config.template.js +101 -28
  244. package/dist/templates/data-view.template.js +42 -27
  245. package/dist/templates/event.template.js +29 -14
  246. package/dist/templates/experiment.template.js +77 -51
  247. package/dist/templates/handler.template.js +53 -17
  248. package/dist/templates/index.js +36 -1
  249. package/dist/templates/integration.template.js +134 -50
  250. package/dist/templates/knowledge.template.js +62 -21
  251. package/dist/templates/migration.template.js +50 -26
  252. package/dist/templates/operation.template.js +44 -28
  253. package/dist/templates/presentation.template.js +46 -20
  254. package/dist/templates/telemetry.template.js +74 -53
  255. package/dist/templates/workflow-runner.template.js +12 -6
  256. package/dist/templates/workflow.template.js +51 -24
  257. package/package.json +13 -9
@@ -1,2 +1,60 @@
1
- function e(t,r){let i={...t};for(let a of Object.keys(r)){let o=t[a],s=r[a];o===void 0?i[a]=s:n(o)&&n(s)&&(i[a]=e(o,s))}return i}function t(e,r){let i={...e};for(let a of Object.keys(r)){let o=e[a],s=r[a];s!==void 0&&(n(o)&&n(s)?i[a]=t(o,s):i[a]=s)}return i}function n(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function r(e){try{return JSON.parse(e)}catch{return null}}function i(e){return JSON.stringify(e,null,2)+`
2
- `}export{t as deepMergeOverwrite,e as deepMergePreserve,i as formatJson,r as safeParseJson};
1
+ //#region src/services/setup/file-merger.ts
2
+ /**
3
+ * File merger utilities.
4
+ *
5
+ * Deep-merges JSON files without losing user settings.
6
+ */
7
+ /**
8
+ * Deep merge two objects, preserving existing user values.
9
+ * New keys are added, but existing keys are NOT overwritten.
10
+ */
11
+ function deepMergePreserve(existing, defaults) {
12
+ const result = { ...existing };
13
+ for (const key of Object.keys(defaults)) {
14
+ const existingValue = existing[key];
15
+ const defaultValue = defaults[key];
16
+ if (existingValue === void 0) result[key] = defaultValue;
17
+ else if (isPlainObject(existingValue) && isPlainObject(defaultValue)) result[key] = deepMergePreserve(existingValue, defaultValue);
18
+ }
19
+ return result;
20
+ }
21
+ /**
22
+ * Deep merge two objects, with new values taking precedence.
23
+ * Used when we want to update existing configs.
24
+ */
25
+ function deepMergeOverwrite(existing, updates) {
26
+ const result = { ...existing };
27
+ for (const key of Object.keys(updates)) {
28
+ const existingValue = existing[key];
29
+ const updateValue = updates[key];
30
+ if (updateValue === void 0) continue;
31
+ if (isPlainObject(existingValue) && isPlainObject(updateValue)) result[key] = deepMergeOverwrite(existingValue, updateValue);
32
+ else result[key] = updateValue;
33
+ }
34
+ return result;
35
+ }
36
+ /**
37
+ * Check if a value is a plain object (not array, null, or other).
38
+ */
39
+ function isPlainObject(value) {
40
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
41
+ }
42
+ /**
43
+ * Parse JSON safely, returning null on failure.
44
+ */
45
+ function safeParseJson(content) {
46
+ try {
47
+ return JSON.parse(content);
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+ /**
53
+ * Format JSON with consistent indentation.
54
+ */
55
+ function formatJson(obj) {
56
+ return JSON.stringify(obj, null, 2) + "\n";
57
+ }
58
+
59
+ //#endregion
60
+ export { deepMergeOverwrite, deepMergePreserve, formatJson, safeParseJson };
@@ -1 +1,4 @@
1
- import{ALL_SETUP_TARGETS as e,SETUP_TARGET_LABELS as t}from"./types.js";import{generateAgentsMd as n,generateClaudeMcpConfig as r,generateContractsrcConfig as i,generateCursorMcpConfig as a,generateCursorRules as o,generateVscodeSettings as s,getClaudeDesktopConfigPath as c}from"./config-generators.js";import{deepMergeOverwrite as l,deepMergePreserve as u,formatJson as d,safeParseJson as f}from"./file-merger.js";import{runSetup as p}from"./setup-service.js";
1
+ import { ALL_SETUP_TARGETS, SETUP_TARGET_LABELS } from "./types.js";
2
+ import { generateAgentsMd, generateClaudeMcpConfig, generateContractsrcConfig, generateCursorMcpConfig, generateCursorRules, generateVscodeSettings, getClaudeDesktopConfigPath } from "./config-generators.js";
3
+ import { deepMergeOverwrite, deepMergePreserve, formatJson, safeParseJson } from "./file-merger.js";
4
+ import { runSetup } from "./setup-service.js";
@@ -1 +1,95 @@
1
- import{findPackageRoot as e,findWorkspaceRoot as t,getPackageName as n,isMonorepo as r}from"../../adapters/workspace.js";import{ALL_SETUP_TARGETS as i,SETUP_TARGET_LABELS as a}from"./types.js";import{setupCliConfig as o}from"./targets/cli-config.js";import{setupVscodeSettings as s}from"./targets/vscode-settings.js";import{setupMcpCursor as c}from"./targets/mcp-cursor.js";import{setupMcpClaude as l}from"./targets/mcp-claude.js";import{setupCursorRules as u}from"./targets/cursor-rules.js";import{setupAgentsMd as d}from"./targets/agents-md.js";const f={confirm:async()=>!0,multiSelect:async(e,t)=>t.filter(e=>e.selected!==!1).map(e=>e.value),input:async(e,t)=>t??``};async function p(o,s,c=f){let l=[],u=s.targets.length>0?s.targets:i,d=s.workspaceRoot,p=t(d),h=s.packageRoot??e(d),g=s.isMonorepo??r(p),_=s.packageName??(g?n(h):void 0),v=s.scope??`workspace`,y=h!==p;g&&s.interactive&&y&&(v=(await c.multiSelect(`Monorepo detected. Configure at which level?`,[{value:`package`,label:`Package level (${_??h})`,selected:!0},{value:`workspace`,label:`Workspace level (${p})`}]))[0]??`package`);let b=u;s.interactive&&(b=await c.multiSelect(`Select components to configure:`,i.map(e=>({value:e,label:a[e],selected:u.includes(e)}))));let x=s.projectName;if(s.interactive&&!x){let e=v===`package`&&_?_:d.split(`/`).pop()??`my-project`;x=await c.input(`Project name:`,e)}let S={...s,workspaceRoot:p,packageRoot:h,isMonorepo:g,scope:v,packageName:_,projectName:x,targets:b};for(let e of b){let t=await m(o,e,S,c);l.push(t)}let C=l.filter(e=>e.action!==`error`).length,w=l.filter(e=>e.action===`error`).length,T=g?` (${v} level)`:``;return{success:w===0,files:l,summary:`Setup complete${T}: ${C} configured, ${w} failed.`}}async function m(e,t,n,r){switch(t){case`cli-config`:return o(e,n,r);case`vscode-settings`:return s(e,n,r);case`mcp-cursor`:return c(e,n,r);case`mcp-claude`:return l(e,n,r);case`cursor-rules`:return u(e,n,r);case`agents-md`:return d(e,n,r);default:return{target:t,filePath:``,action:`error`,message:`Unknown target: ${t}`}}}export{p as runSetup};
1
+ import { findPackageRoot, findWorkspaceRoot, getPackageName, isMonorepo } from "../../adapters/workspace.js";
2
+ import { ALL_SETUP_TARGETS, SETUP_TARGET_LABELS } from "./types.js";
3
+ import { setupCliConfig } from "./targets/cli-config.js";
4
+ import { setupVscodeSettings } from "./targets/vscode-settings.js";
5
+ import { setupMcpCursor } from "./targets/mcp-cursor.js";
6
+ import { setupMcpClaude } from "./targets/mcp-claude.js";
7
+ import { setupCursorRules } from "./targets/cursor-rules.js";
8
+ import { setupAgentsMd } from "./targets/agents-md.js";
9
+
10
+ //#region src/services/setup/setup-service.ts
11
+ /**
12
+ * Default prompt callbacks that always accept defaults.
13
+ */
14
+ const defaultPrompts = {
15
+ confirm: async () => true,
16
+ multiSelect: async (_msg, options) => options.filter((o) => o.selected !== false).map((o) => o.value),
17
+ input: async (_msg, defaultValue) => defaultValue ?? ""
18
+ };
19
+ /**
20
+ * Run the ContractSpec setup.
21
+ */
22
+ async function runSetup(fs, options, prompts = defaultPrompts) {
23
+ const results = [];
24
+ const targets = options.targets.length > 0 ? options.targets : ALL_SETUP_TARGETS;
25
+ const workspaceRoot = options.workspaceRoot;
26
+ const detectedWorkspaceRoot = findWorkspaceRoot(workspaceRoot);
27
+ const packageRoot = options.packageRoot ?? findPackageRoot(workspaceRoot);
28
+ const monorepo = options.isMonorepo ?? isMonorepo(detectedWorkspaceRoot);
29
+ const packageName = options.packageName ?? (monorepo ? getPackageName(packageRoot) : void 0);
30
+ let scope = options.scope ?? "workspace";
31
+ const isDifferentRoots = packageRoot !== detectedWorkspaceRoot;
32
+ if (monorepo && options.interactive && isDifferentRoots) scope = (await prompts.multiSelect(`Monorepo detected. Configure at which level?`, [{
33
+ value: "package",
34
+ label: `Package level (${packageName ?? packageRoot})`,
35
+ selected: true
36
+ }, {
37
+ value: "workspace",
38
+ label: `Workspace level (${detectedWorkspaceRoot})`
39
+ }]))[0] ?? "package";
40
+ let selectedTargets = targets;
41
+ if (options.interactive) selectedTargets = await prompts.multiSelect("Select components to configure:", ALL_SETUP_TARGETS.map((t) => ({
42
+ value: t,
43
+ label: SETUP_TARGET_LABELS[t],
44
+ selected: targets.includes(t)
45
+ })));
46
+ let projectName = options.projectName;
47
+ if (options.interactive && !projectName) {
48
+ const defaultName = scope === "package" && packageName ? packageName : workspaceRoot.split("/").pop() ?? "my-project";
49
+ projectName = await prompts.input("Project name:", defaultName);
50
+ }
51
+ const setupOptions = {
52
+ ...options,
53
+ workspaceRoot: detectedWorkspaceRoot,
54
+ packageRoot,
55
+ isMonorepo: monorepo,
56
+ scope,
57
+ packageName,
58
+ projectName,
59
+ targets: selectedTargets
60
+ };
61
+ for (const target of selectedTargets) {
62
+ const result = await setupTarget(fs, target, setupOptions, prompts);
63
+ results.push(result);
64
+ }
65
+ const succeeded = results.filter((r) => r.action !== "error").length;
66
+ const failed = results.filter((r) => r.action === "error").length;
67
+ const scopeInfo = monorepo ? ` (${scope} level)` : "";
68
+ return {
69
+ success: failed === 0,
70
+ files: results,
71
+ summary: `Setup complete${scopeInfo}: ${succeeded} configured, ${failed} failed.`
72
+ };
73
+ }
74
+ /**
75
+ * Setup a single target.
76
+ */
77
+ async function setupTarget(fs, target, options, prompts) {
78
+ switch (target) {
79
+ case "cli-config": return setupCliConfig(fs, options, prompts);
80
+ case "vscode-settings": return setupVscodeSettings(fs, options, prompts);
81
+ case "mcp-cursor": return setupMcpCursor(fs, options, prompts);
82
+ case "mcp-claude": return setupMcpClaude(fs, options, prompts);
83
+ case "cursor-rules": return setupCursorRules(fs, options, prompts);
84
+ case "agents-md": return setupAgentsMd(fs, options, prompts);
85
+ default: return {
86
+ target,
87
+ filePath: "",
88
+ action: "error",
89
+ message: `Unknown target: ${target}`
90
+ };
91
+ }
92
+ }
93
+
94
+ //#endregion
95
+ export { runSetup };
@@ -1 +1,46 @@
1
- import{generateAgentsMd as e}from"../config-generators.js";async function t(t,n,r){let i=n.isMonorepo&&n.scope===`package`?n.packageRoot??n.workspaceRoot:n.workspaceRoot,a=t.join(i,`AGENTS.md`);try{let i=await t.exists(a),o=e(n);if(i)if(n.interactive){if(!await r.confirm(`${a} exists. Overwrite?`))return{target:`agents-md`,filePath:a,action:`skipped`,message:`User kept existing AGENTS.md`}}else return{target:`agents-md`,filePath:a,action:`skipped`,message:`File already exists`};return await t.writeFile(a,o),{target:`agents-md`,filePath:a,action:i?`merged`:`created`,message:i?`Updated AGENTS.md`:`Created AGENTS.md`}}catch(e){return{target:`agents-md`,filePath:a,action:`error`,message:e instanceof Error?e.message:`Unknown error`}}}export{t as setupAgentsMd};
1
+ import { generateAgentsMd } from "../config-generators.js";
2
+
3
+ //#region src/services/setup/targets/agents-md.ts
4
+ /**
5
+ * Setup AGENTS.md
6
+ *
7
+ * In monorepo with package scope, creates AGENTS.md at package root.
8
+ */
9
+ async function setupAgentsMd(fs, options, prompts) {
10
+ const targetRoot = options.isMonorepo && options.scope === "package" ? options.packageRoot ?? options.workspaceRoot : options.workspaceRoot;
11
+ const filePath = fs.join(targetRoot, "AGENTS.md");
12
+ try {
13
+ const exists = await fs.exists(filePath);
14
+ const content = generateAgentsMd(options);
15
+ if (exists) if (options.interactive) {
16
+ if (!await prompts.confirm(`${filePath} exists. Overwrite?`)) return {
17
+ target: "agents-md",
18
+ filePath,
19
+ action: "skipped",
20
+ message: "User kept existing AGENTS.md"
21
+ };
22
+ } else return {
23
+ target: "agents-md",
24
+ filePath,
25
+ action: "skipped",
26
+ message: "File already exists"
27
+ };
28
+ await fs.writeFile(filePath, content);
29
+ return {
30
+ target: "agents-md",
31
+ filePath,
32
+ action: exists ? "merged" : "created",
33
+ message: exists ? "Updated AGENTS.md" : "Created AGENTS.md"
34
+ };
35
+ } catch (error) {
36
+ return {
37
+ target: "agents-md",
38
+ filePath,
39
+ action: "error",
40
+ message: error instanceof Error ? error.message : "Unknown error"
41
+ };
42
+ }
43
+ }
44
+
45
+ //#endregion
46
+ export { setupAgentsMd };
@@ -1 +1,59 @@
1
- import{generateContractsrcConfig as e}from"../config-generators.js";import{deepMergePreserve as t,formatJson as n,safeParseJson as r}from"../file-merger.js";async function i(i,a,o){let s=a.isMonorepo&&a.scope===`package`?a.packageRoot??a.workspaceRoot:a.workspaceRoot,c=i.join(s,`.contractsrc.json`);try{let s=await i.exists(c),l=e(a);if(s){let e=r(await i.readFile(c));if(!e)return{target:`cli-config`,filePath:c,action:`error`,message:`Existing file is not valid JSON`};if(a.interactive&&!await o.confirm(`${c} exists. Merge ContractSpec defaults?`))return{target:`cli-config`,filePath:c,action:`skipped`,message:`User skipped merge`};let s=t(e,l);return await i.writeFile(c,n(s)),{target:`cli-config`,filePath:c,action:`merged`,message:`Merged with existing configuration`}}return await i.writeFile(c,n(l)),{target:`cli-config`,filePath:c,action:`created`,message:`Created CLI configuration`}}catch(e){return{target:`cli-config`,filePath:c,action:`error`,message:e instanceof Error?e.message:`Unknown error`}}}export{i as setupCliConfig};
1
+ import { generateContractsrcConfig } from "../config-generators.js";
2
+ import { deepMergePreserve, formatJson, safeParseJson } from "../file-merger.js";
3
+
4
+ //#region src/services/setup/targets/cli-config.ts
5
+ /**
6
+ * Setup .contractsrc.json
7
+ *
8
+ * In monorepo with package scope, creates config at package root.
9
+ */
10
+ async function setupCliConfig(fs, options, prompts) {
11
+ const targetRoot = options.isMonorepo && options.scope === "package" ? options.packageRoot ?? options.workspaceRoot : options.workspaceRoot;
12
+ const filePath = fs.join(targetRoot, ".contractsrc.json");
13
+ try {
14
+ const exists = await fs.exists(filePath);
15
+ const defaults = generateContractsrcConfig(options);
16
+ if (exists) {
17
+ const existing = safeParseJson(await fs.readFile(filePath));
18
+ if (!existing) return {
19
+ target: "cli-config",
20
+ filePath,
21
+ action: "error",
22
+ message: "Existing file is not valid JSON"
23
+ };
24
+ if (options.interactive) {
25
+ if (!await prompts.confirm(`${filePath} exists. Merge ContractSpec defaults?`)) return {
26
+ target: "cli-config",
27
+ filePath,
28
+ action: "skipped",
29
+ message: "User skipped merge"
30
+ };
31
+ }
32
+ const merged = deepMergePreserve(existing, defaults);
33
+ await fs.writeFile(filePath, formatJson(merged));
34
+ return {
35
+ target: "cli-config",
36
+ filePath,
37
+ action: "merged",
38
+ message: "Merged with existing configuration"
39
+ };
40
+ }
41
+ await fs.writeFile(filePath, formatJson(defaults));
42
+ return {
43
+ target: "cli-config",
44
+ filePath,
45
+ action: "created",
46
+ message: "Created CLI configuration"
47
+ };
48
+ } catch (error) {
49
+ return {
50
+ target: "cli-config",
51
+ filePath,
52
+ action: "error",
53
+ message: error instanceof Error ? error.message : "Unknown error"
54
+ };
55
+ }
56
+ }
57
+
58
+ //#endregion
59
+ export { setupCliConfig };
@@ -1 +1,47 @@
1
- import{generateCursorRules as e}from"../config-generators.js";async function t(t,n,r){let i=t.join(n.workspaceRoot,`.cursor`,`rules`),a=t.join(i,`contractspec.mdc`);try{let o=t.join(n.workspaceRoot,`.cursor`);await t.exists(o)||await t.mkdir(o),await t.exists(i)||await t.mkdir(i);let s=await t.exists(a),c=e(n);if(s)if(n.interactive){if(!await r.confirm(`${a} exists. Overwrite with latest rules?`))return{target:`cursor-rules`,filePath:a,action:`skipped`,message:`User kept existing rules`}}else return{target:`cursor-rules`,filePath:a,action:`skipped`,message:`File already exists`};return await t.writeFile(a,c),{target:`cursor-rules`,filePath:a,action:s?`merged`:`created`,message:s?`Updated Cursor rules`:`Created Cursor rules`}}catch(e){return{target:`cursor-rules`,filePath:a,action:`error`,message:e instanceof Error?e.message:`Unknown error`}}}export{t as setupCursorRules};
1
+ import { generateCursorRules } from "../config-generators.js";
2
+
3
+ //#region src/services/setup/targets/cursor-rules.ts
4
+ /**
5
+ * Setup .cursor/rules/contractspec.mdc
6
+ */
7
+ async function setupCursorRules(fs, options, prompts) {
8
+ const rulesDir = fs.join(options.workspaceRoot, ".cursor", "rules");
9
+ const filePath = fs.join(rulesDir, "contractspec.mdc");
10
+ try {
11
+ const cursorDir = fs.join(options.workspaceRoot, ".cursor");
12
+ if (!await fs.exists(cursorDir)) await fs.mkdir(cursorDir);
13
+ if (!await fs.exists(rulesDir)) await fs.mkdir(rulesDir);
14
+ const exists = await fs.exists(filePath);
15
+ const content = generateCursorRules(options);
16
+ if (exists) if (options.interactive) {
17
+ if (!await prompts.confirm(`${filePath} exists. Overwrite with latest rules?`)) return {
18
+ target: "cursor-rules",
19
+ filePath,
20
+ action: "skipped",
21
+ message: "User kept existing rules"
22
+ };
23
+ } else return {
24
+ target: "cursor-rules",
25
+ filePath,
26
+ action: "skipped",
27
+ message: "File already exists"
28
+ };
29
+ await fs.writeFile(filePath, content);
30
+ return {
31
+ target: "cursor-rules",
32
+ filePath,
33
+ action: exists ? "merged" : "created",
34
+ message: exists ? "Updated Cursor rules" : "Created Cursor rules"
35
+ };
36
+ } catch (error) {
37
+ return {
38
+ target: "cursor-rules",
39
+ filePath,
40
+ action: "error",
41
+ message: error instanceof Error ? error.message : "Unknown error"
42
+ };
43
+ }
44
+ }
45
+
46
+ //#endregion
47
+ export { setupCursorRules };
@@ -1 +1,59 @@
1
- import{generateClaudeMcpConfig as e,getClaudeDesktopConfigPath as t}from"../config-generators.js";import{deepMergePreserve as n,formatJson as r,safeParseJson as i}from"../file-merger.js";async function a(a,o,s){let c=t();try{let t=await a.exists(c),l=e();if(o.interactive&&!await s.confirm(`Configure Claude Desktop at ${c}?`))return{target:`mcp-claude`,filePath:c,action:`skipped`,message:`User skipped Claude Desktop configuration`};if(t){let e=i(await a.readFile(c));if(!e)return{target:`mcp-claude`,filePath:c,action:`error`,message:`Existing file is not valid JSON`};let t=n(e,l);return await a.writeFile(c,r(t)),{target:`mcp-claude`,filePath:c,action:`merged`,message:`Added ContractSpec to Claude Desktop`}}let u=c.substring(0,c.lastIndexOf(`/`));return await a.exists(u)||await a.mkdir(u),await a.writeFile(c,r(l)),{target:`mcp-claude`,filePath:c,action:`created`,message:`Created Claude Desktop configuration`}}catch(e){return{target:`mcp-claude`,filePath:c,action:`error`,message:e instanceof Error?e.message:`Unknown error`}}}export{a as setupMcpClaude};
1
+ import { generateClaudeMcpConfig, getClaudeDesktopConfigPath } from "../config-generators.js";
2
+ import { deepMergePreserve, formatJson, safeParseJson } from "../file-merger.js";
3
+
4
+ //#region src/services/setup/targets/mcp-claude.ts
5
+ /**
6
+ * Setup Claude Desktop MCP config.
7
+ * This modifies the user's global Claude config, so we're extra careful.
8
+ */
9
+ async function setupMcpClaude(fs, options, prompts) {
10
+ const filePath = getClaudeDesktopConfigPath();
11
+ try {
12
+ const exists = await fs.exists(filePath);
13
+ const defaults = generateClaudeMcpConfig();
14
+ if (options.interactive) {
15
+ if (!await prompts.confirm(`Configure Claude Desktop at ${filePath}?`)) return {
16
+ target: "mcp-claude",
17
+ filePath,
18
+ action: "skipped",
19
+ message: "User skipped Claude Desktop configuration"
20
+ };
21
+ }
22
+ if (exists) {
23
+ const existing = safeParseJson(await fs.readFile(filePath));
24
+ if (!existing) return {
25
+ target: "mcp-claude",
26
+ filePath,
27
+ action: "error",
28
+ message: "Existing file is not valid JSON"
29
+ };
30
+ const merged = deepMergePreserve(existing, defaults);
31
+ await fs.writeFile(filePath, formatJson(merged));
32
+ return {
33
+ target: "mcp-claude",
34
+ filePath,
35
+ action: "merged",
36
+ message: "Added ContractSpec to Claude Desktop"
37
+ };
38
+ }
39
+ const parentDir = filePath.substring(0, filePath.lastIndexOf("/"));
40
+ if (!await fs.exists(parentDir)) await fs.mkdir(parentDir);
41
+ await fs.writeFile(filePath, formatJson(defaults));
42
+ return {
43
+ target: "mcp-claude",
44
+ filePath,
45
+ action: "created",
46
+ message: "Created Claude Desktop configuration"
47
+ };
48
+ } catch (error) {
49
+ return {
50
+ target: "mcp-claude",
51
+ filePath,
52
+ action: "error",
53
+ message: error instanceof Error ? error.message : "Unknown error"
54
+ };
55
+ }
56
+ }
57
+
58
+ //#endregion
59
+ export { setupMcpClaude };
@@ -1 +1,58 @@
1
- import{generateCursorMcpConfig as e}from"../config-generators.js";import{deepMergePreserve as t,formatJson as n,safeParseJson as r}from"../file-merger.js";async function i(i,a,o){let s=i.join(a.workspaceRoot,`.cursor`),c=i.join(s,`mcp.json`);try{await i.exists(s)||await i.mkdir(s);let l=await i.exists(c),u=e();if(l){let e=r(await i.readFile(c));if(!e)return{target:`mcp-cursor`,filePath:c,action:`error`,message:`Existing file is not valid JSON`};if(a.interactive&&!await o.confirm(`${c} exists. Add ContractSpec MCP server?`))return{target:`mcp-cursor`,filePath:c,action:`skipped`,message:`User skipped merge`};let s=t(e,u);return await i.writeFile(c,n(s)),{target:`mcp-cursor`,filePath:c,action:`merged`,message:`Added ContractSpec MCP server`}}return await i.writeFile(c,n(u)),{target:`mcp-cursor`,filePath:c,action:`created`,message:`Created Cursor MCP configuration`}}catch(e){return{target:`mcp-cursor`,filePath:c,action:`error`,message:e instanceof Error?e.message:`Unknown error`}}}export{i as setupMcpCursor};
1
+ import { generateCursorMcpConfig } from "../config-generators.js";
2
+ import { deepMergePreserve, formatJson, safeParseJson } from "../file-merger.js";
3
+
4
+ //#region src/services/setup/targets/mcp-cursor.ts
5
+ /**
6
+ * Setup .cursor/mcp.json
7
+ */
8
+ async function setupMcpCursor(fs, options, prompts) {
9
+ const dirPath = fs.join(options.workspaceRoot, ".cursor");
10
+ const filePath = fs.join(dirPath, "mcp.json");
11
+ try {
12
+ if (!await fs.exists(dirPath)) await fs.mkdir(dirPath);
13
+ const exists = await fs.exists(filePath);
14
+ const defaults = generateCursorMcpConfig();
15
+ if (exists) {
16
+ const existing = safeParseJson(await fs.readFile(filePath));
17
+ if (!existing) return {
18
+ target: "mcp-cursor",
19
+ filePath,
20
+ action: "error",
21
+ message: "Existing file is not valid JSON"
22
+ };
23
+ if (options.interactive) {
24
+ if (!await prompts.confirm(`${filePath} exists. Add ContractSpec MCP server?`)) return {
25
+ target: "mcp-cursor",
26
+ filePath,
27
+ action: "skipped",
28
+ message: "User skipped merge"
29
+ };
30
+ }
31
+ const merged = deepMergePreserve(existing, defaults);
32
+ await fs.writeFile(filePath, formatJson(merged));
33
+ return {
34
+ target: "mcp-cursor",
35
+ filePath,
36
+ action: "merged",
37
+ message: "Added ContractSpec MCP server"
38
+ };
39
+ }
40
+ await fs.writeFile(filePath, formatJson(defaults));
41
+ return {
42
+ target: "mcp-cursor",
43
+ filePath,
44
+ action: "created",
45
+ message: "Created Cursor MCP configuration"
46
+ };
47
+ } catch (error) {
48
+ return {
49
+ target: "mcp-cursor",
50
+ filePath,
51
+ action: "error",
52
+ message: error instanceof Error ? error.message : "Unknown error"
53
+ };
54
+ }
55
+ }
56
+
57
+ //#endregion
58
+ export { setupMcpCursor };
@@ -1 +1,62 @@
1
- import{generateVscodeSettings as e}from"../config-generators.js";import{deepMergePreserve as t,formatJson as n,safeParseJson as r}from"../file-merger.js";async function i(i,a,o){let s=a.isMonorepo&&a.scope===`package`?a.packageRoot??a.workspaceRoot:a.workspaceRoot,c=i.join(s,`.vscode`),l=i.join(c,`settings.json`);try{await i.exists(c)||await i.mkdir(c);let s=await i.exists(l),u=e();if(s){let e=r(await i.readFile(l));if(!e)return{target:`vscode-settings`,filePath:l,action:`error`,message:`Existing file is not valid JSON`};if(a.interactive&&!await o.confirm(`${l} exists. Add ContractSpec settings?`))return{target:`vscode-settings`,filePath:l,action:`skipped`,message:`User skipped merge`};let s=t(e,u);return await i.writeFile(l,n(s)),{target:`vscode-settings`,filePath:l,action:`merged`,message:`Added ContractSpec settings`}}return await i.writeFile(l,n(u)),{target:`vscode-settings`,filePath:l,action:`created`,message:`Created VS Code settings`}}catch(e){return{target:`vscode-settings`,filePath:l,action:`error`,message:e instanceof Error?e.message:`Unknown error`}}}export{i as setupVscodeSettings};
1
+ import { generateVscodeSettings } from "../config-generators.js";
2
+ import { deepMergePreserve, formatJson, safeParseJson } from "../file-merger.js";
3
+
4
+ //#region src/services/setup/targets/vscode-settings.ts
5
+ /**
6
+ * Setup .vscode/settings.json
7
+ *
8
+ * VS Code settings are typically at workspace root, but in monorepo
9
+ * with package scope, can be at package root.
10
+ */
11
+ async function setupVscodeSettings(fs, options, prompts) {
12
+ const targetRoot = options.isMonorepo && options.scope === "package" ? options.packageRoot ?? options.workspaceRoot : options.workspaceRoot;
13
+ const dirPath = fs.join(targetRoot, ".vscode");
14
+ const filePath = fs.join(dirPath, "settings.json");
15
+ try {
16
+ if (!await fs.exists(dirPath)) await fs.mkdir(dirPath);
17
+ const exists = await fs.exists(filePath);
18
+ const defaults = generateVscodeSettings();
19
+ if (exists) {
20
+ const existing = safeParseJson(await fs.readFile(filePath));
21
+ if (!existing) return {
22
+ target: "vscode-settings",
23
+ filePath,
24
+ action: "error",
25
+ message: "Existing file is not valid JSON"
26
+ };
27
+ if (options.interactive) {
28
+ if (!await prompts.confirm(`${filePath} exists. Add ContractSpec settings?`)) return {
29
+ target: "vscode-settings",
30
+ filePath,
31
+ action: "skipped",
32
+ message: "User skipped merge"
33
+ };
34
+ }
35
+ const merged = deepMergePreserve(existing, defaults);
36
+ await fs.writeFile(filePath, formatJson(merged));
37
+ return {
38
+ target: "vscode-settings",
39
+ filePath,
40
+ action: "merged",
41
+ message: "Added ContractSpec settings"
42
+ };
43
+ }
44
+ await fs.writeFile(filePath, formatJson(defaults));
45
+ return {
46
+ target: "vscode-settings",
47
+ filePath,
48
+ action: "created",
49
+ message: "Created VS Code settings"
50
+ };
51
+ } catch (error) {
52
+ return {
53
+ target: "vscode-settings",
54
+ filePath,
55
+ action: "error",
56
+ message: error instanceof Error ? error.message : "Unknown error"
57
+ };
58
+ }
59
+ }
60
+
61
+ //#endregion
62
+ export { setupVscodeSettings };
@@ -1 +1,26 @@
1
- const e=[`cli-config`,`vscode-settings`,`mcp-cursor`,`mcp-claude`,`cursor-rules`,`agents-md`],t={"cli-config":`CLI Configuration (.contractsrc.json)`,"vscode-settings":`VS Code Settings (.vscode/settings.json)`,"mcp-cursor":`MCP for Cursor (.cursor/mcp.json)`,"mcp-claude":`MCP for Claude Desktop`,"cursor-rules":`Cursor AI Rules (.cursor/rules/)`,"agents-md":`Project AI Guide (AGENTS.md)`};export{e as ALL_SETUP_TARGETS,t as SETUP_TARGET_LABELS};
1
+ //#region src/services/setup/types.ts
2
+ /**
3
+ * All available setup targets.
4
+ */
5
+ const ALL_SETUP_TARGETS = [
6
+ "cli-config",
7
+ "vscode-settings",
8
+ "mcp-cursor",
9
+ "mcp-claude",
10
+ "cursor-rules",
11
+ "agents-md"
12
+ ];
13
+ /**
14
+ * Human-readable labels for setup targets.
15
+ */
16
+ const SETUP_TARGET_LABELS = {
17
+ "cli-config": "CLI Configuration (.contractsrc.json)",
18
+ "vscode-settings": "VS Code Settings (.vscode/settings.json)",
19
+ "mcp-cursor": "MCP for Cursor (.cursor/mcp.json)",
20
+ "mcp-claude": "MCP for Claude Desktop",
21
+ "cursor-rules": "Cursor AI Rules (.cursor/rules/)",
22
+ "agents-md": "Project AI Guide (AGENTS.md)"
23
+ };
24
+
25
+ //#endregion
26
+ export { ALL_SETUP_TARGETS, SETUP_TARGET_LABELS };
@@ -1 +1,62 @@
1
- import{validateSpec as e}from"./validate.js";import{buildSpec as t}from"./build.js";async function n(n,r,i={},a){let{fs:o,logger:s}=n,c=await o.glob({pattern:i.pattern}),l=i.outputDirs?.length?i.outputDirs:[void 0],u=[],d=a?.validate??(t=>e(t,{fs:o,logger:s})),f=a?.build??((e,n)=>t(e,{fs:o,logger:s},n?{...r,outputDir:n}:r,{...i.buildOptions??{},outputDir:n}));for(let e of c)for(let t of l){let n={specPath:e,outputDir:t};if(i.validate)try{n.validation=await d(e)}catch(e){n.error={phase:`validate`,message:e instanceof Error?e.message:String(e)},u.push(n);continue}if(i.dryRun)s.info(`[dry-run] syncSpecs skipped build`,{specPath:e,outputDir:t});else try{n.build=await f(e,t)}catch(e){n.error={phase:`build`,message:e instanceof Error?e.message:String(e)},u.push(n);continue}u.push(n)}return{specs:c,runs:u}}export{n as syncSpecs};
1
+ import { validateSpec } from "./validate.js";
2
+ import { buildSpec } from "./build.js";
3
+
4
+ //#region src/services/sync.ts
5
+ async function syncSpecs(adapters, config, options = {}, overrides) {
6
+ const { fs, logger } = adapters;
7
+ const specs = await fs.glob({ pattern: options.pattern });
8
+ const outputDirs = options.outputDirs?.length ? options.outputDirs : [void 0];
9
+ const runs = [];
10
+ const validateFn = overrides?.validate ?? ((specPath) => validateSpec(specPath, {
11
+ fs,
12
+ logger
13
+ }));
14
+ const buildFn = overrides?.build ?? ((specPath, outputDir) => buildSpec(specPath, {
15
+ fs,
16
+ logger
17
+ }, outputDir ? {
18
+ ...config,
19
+ outputDir
20
+ } : config, {
21
+ ...options.buildOptions ?? {},
22
+ outputDir
23
+ }));
24
+ for (const specPath of specs) for (const outputDir of outputDirs) {
25
+ const run = {
26
+ specPath,
27
+ outputDir
28
+ };
29
+ if (options.validate) try {
30
+ run.validation = await validateFn(specPath);
31
+ } catch (error) {
32
+ run.error = {
33
+ phase: "validate",
34
+ message: error instanceof Error ? error.message : String(error)
35
+ };
36
+ runs.push(run);
37
+ continue;
38
+ }
39
+ if (!options.dryRun) try {
40
+ run.build = await buildFn(specPath, outputDir);
41
+ } catch (error) {
42
+ run.error = {
43
+ phase: "build",
44
+ message: error instanceof Error ? error.message : String(error)
45
+ };
46
+ runs.push(run);
47
+ continue;
48
+ }
49
+ else logger.info("[dry-run] syncSpecs skipped build", {
50
+ specPath,
51
+ outputDir
52
+ });
53
+ runs.push(run);
54
+ }
55
+ return {
56
+ specs,
57
+ runs
58
+ };
59
+ }
60
+
61
+ //#endregion
62
+ export { syncSpecs };
@@ -1 +1,30 @@
1
- import{t as e}from"../libs/contracts/dist/tests/runner.js";import"../libs/contracts/dist/tests/index.js";async function t(t,n){let r=new e({registry:n}),i=[],a=0,o=0;for(let e of t){let t=await r.run(e);i.push(t),a+=t.passed,o+=t.failed}return{results:i,passed:a,failed:o}}export{t as runTests};
1
+ import { TestRunner } from "../libs/contracts/dist/tests/runner.js";
2
+ import "../libs/contracts/dist/tests/index.js";
3
+
4
+ //#region src/services/test.ts
5
+ /**
6
+ * Test service.
7
+ *
8
+ * Pure runner wrapper that executes TestSpec scenarios against a SpecRegistry.
9
+ * Loading/compiling spec modules (TS/ESM) is intentionally left to the caller.
10
+ */
11
+ async function runTests(specs, registry) {
12
+ const runner = new TestRunner({ registry });
13
+ const results = [];
14
+ let passed = 0;
15
+ let failed = 0;
16
+ for (const spec of specs) {
17
+ const result = await runner.run(spec);
18
+ results.push(result);
19
+ passed += result.passed;
20
+ failed += result.failed;
21
+ }
22
+ return {
23
+ results,
24
+ passed,
25
+ failed
26
+ };
27
+ }
28
+
29
+ //#endregion
30
+ export { runTests };